mirror of
https://github.com/dart-lang/sdk
synced 2024-11-05 18:22:09 +00:00
Flow analysis: additional debug support.
I've found these changes helpful as part of developing the new "field promotion" feature. These changes have no effect unless the `FlowAnalysisDebug` class is used. Bug: https://github.com/dart-lang/language/issues/2020 Change-Id: I7badadc14bf901e77b8c166920aedf902093d7e1 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/250220 Reviewed-by: Konstantin Shcheglov <scheglov@google.com> Commit-Queue: Paul Berry <paulberry@google.com>
This commit is contained in:
parent
a602f74ac0
commit
bd660d9847
1 changed files with 45 additions and 5 deletions
|
@ -1032,6 +1032,10 @@ abstract class FlowAnalysis<Node extends Object, Statement extends Node,
|
|||
class FlowAnalysisDebug<Node extends Object, Statement extends Node,
|
||||
Expression extends Object, Variable extends Object, Type extends Object>
|
||||
implements FlowAnalysis<Node, Statement, Expression, Variable, Type> {
|
||||
static int _nextCallbackId = 0;
|
||||
|
||||
static Expando<String> _description = new Expando<String>();
|
||||
|
||||
FlowAnalysis<Node, Statement, Expression, Variable, Type> _wrapped;
|
||||
|
||||
bool _exceptionOccurred = false;
|
||||
|
@ -1538,16 +1542,18 @@ class FlowAnalysisDebug<Node extends Object, Statement extends Node,
|
|||
|
||||
@override
|
||||
Map<Type, NonPromotionReason> Function() whyNotPromoted(Expression target) {
|
||||
return _wrap(
|
||||
'whyNotPromoted($target)', () => _wrapped.whyNotPromoted(target),
|
||||
return _wrap('whyNotPromoted($target)',
|
||||
() => _trackWhyNotPromoted(_wrapped.whyNotPromoted(target)),
|
||||
isQuery: true);
|
||||
}
|
||||
|
||||
@override
|
||||
Map<Type, NonPromotionReason> Function() whyNotPromotedImplicitThis(
|
||||
Type staticType) {
|
||||
return _wrap('whyNotPromotedImplicitThis($staticType)',
|
||||
() => _wrapped.whyNotPromotedImplicitThis(staticType),
|
||||
return _wrap(
|
||||
'whyNotPromotedImplicitThis($staticType)',
|
||||
() => _trackWhyNotPromoted(
|
||||
_wrapped.whyNotPromotedImplicitThis(staticType)),
|
||||
isQuery: true);
|
||||
}
|
||||
|
||||
|
@ -1561,6 +1567,19 @@ class FlowAnalysisDebug<Node extends Object, Statement extends Node,
|
|||
@override
|
||||
void _dumpState() => _wrapped._dumpState();
|
||||
|
||||
/// Wraps [callback] so that when it is called, the call (and its return
|
||||
/// value) will be printed to the console. Also registers the wrapped
|
||||
/// callback in [_description] so that it will be given a unique identifier
|
||||
/// when printed to the console.
|
||||
Map<Type, NonPromotionReason> Function() _trackWhyNotPromoted(
|
||||
Map<Type, NonPromotionReason> Function() callback) {
|
||||
String callbackToString = '#CALLBACK${_nextCallbackId++}';
|
||||
Map<Type, NonPromotionReason> Function() wrappedCallback =
|
||||
() => _wrap('$callbackToString()', callback, isQuery: true);
|
||||
_description[wrappedCallback] = callbackToString;
|
||||
return wrappedCallback;
|
||||
}
|
||||
|
||||
T _wrap<T>(String description, T callback(),
|
||||
{bool isQuery: false, bool? isPure}) {
|
||||
isPure ??= isQuery;
|
||||
|
@ -1578,10 +1597,18 @@ class FlowAnalysisDebug<Node extends Object, Statement extends Node,
|
|||
_wrapped._dumpState();
|
||||
}
|
||||
if (isQuery) {
|
||||
print(' => $result');
|
||||
print(' => ${_describe(result)}');
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
static String _describe(Object? value) {
|
||||
if (value != null && value is! String && value is! num && value is! bool) {
|
||||
String? description = _description[value];
|
||||
if (description != null) return description;
|
||||
}
|
||||
return value.toString();
|
||||
}
|
||||
}
|
||||
|
||||
/// An instance of the [FlowModel] class represents the information gathered by
|
||||
|
@ -2613,6 +2640,9 @@ class ReferenceWithType<Variable extends Object, Type extends Object> {
|
|||
final Type type;
|
||||
|
||||
ReferenceWithType(this.reference, this.type);
|
||||
|
||||
@override
|
||||
String toString() => 'ReferenceWithType($reference, $type)';
|
||||
}
|
||||
|
||||
/// Data structure representing a unique value that a variable might take on
|
||||
|
@ -2859,6 +2889,9 @@ class VariableModel<Variable extends Object, Type extends Object> {
|
|||
if (nonPromotionHistory != null) {
|
||||
parts.add('nonPromotionHistory: $nonPromotionHistory');
|
||||
}
|
||||
if (properties.isNotEmpty) {
|
||||
parts.add('properties: $properties');
|
||||
}
|
||||
return 'VariableModel(${parts.join(', ')})';
|
||||
}
|
||||
|
||||
|
@ -3357,6 +3390,9 @@ class VariableReference<Variable extends Object, Type extends Object>
|
|||
variableInfo[variable] = variableModel;
|
||||
}
|
||||
|
||||
@override
|
||||
String toString() => 'VariableReference($variable)';
|
||||
|
||||
@override
|
||||
VariableModel<Variable, Type>? _getInfo(
|
||||
Map<Variable?, VariableModel<Variable, Type>> variableInfo) =>
|
||||
|
@ -5025,6 +5061,10 @@ class _PropertyGetReference<Variable extends Object, Type extends Object>
|
|||
target.storeInfo(variableInfo, targetInfo.setProperties(newProperties));
|
||||
}
|
||||
|
||||
@override
|
||||
String toString() =>
|
||||
'_PropertyGetReference($target, $propertyName, $propertyMember)';
|
||||
|
||||
@override
|
||||
VariableModel<Variable, Type>? _getInfo(
|
||||
Map<Variable?, VariableModel<Variable, Type>> variableInfo) {
|
||||
|
|
Loading…
Reference in a new issue