From bd660d98472f01c57ece4dcf2a7a8810ea4e402d Mon Sep 17 00:00:00 2001 From: Paul Berry Date: Wed, 29 Jun 2022 21:19:05 +0000 Subject: [PATCH] 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 Commit-Queue: Paul Berry --- .../lib/src/flow_analysis/flow_analysis.dart | 50 +++++++++++++++++-- 1 file changed, 45 insertions(+), 5 deletions(-) diff --git a/pkg/_fe_analyzer_shared/lib/src/flow_analysis/flow_analysis.dart b/pkg/_fe_analyzer_shared/lib/src/flow_analysis/flow_analysis.dart index 3256bdcac96..d91b11e3627 100644 --- a/pkg/_fe_analyzer_shared/lib/src/flow_analysis/flow_analysis.dart +++ b/pkg/_fe_analyzer_shared/lib/src/flow_analysis/flow_analysis.dart @@ -1032,6 +1032,10 @@ abstract class FlowAnalysis implements FlowAnalysis { + static int _nextCallbackId = 0; + + static Expando _description = new Expando(); + FlowAnalysis _wrapped; bool _exceptionOccurred = false; @@ -1538,16 +1542,18 @@ class FlowAnalysisDebug Function() whyNotPromoted(Expression target) { - return _wrap( - 'whyNotPromoted($target)', () => _wrapped.whyNotPromoted(target), + return _wrap('whyNotPromoted($target)', + () => _trackWhyNotPromoted(_wrapped.whyNotPromoted(target)), isQuery: true); } @override Map 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 _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 Function() _trackWhyNotPromoted( + Map Function() callback) { + String callbackToString = '#CALLBACK${_nextCallbackId++}'; + Map Function() wrappedCallback = + () => _wrap('$callbackToString()', callback, isQuery: true); + _description[wrappedCallback] = callbackToString; + return wrappedCallback; + } + T _wrap(String description, T callback(), {bool isQuery: false, bool? isPure}) { isPure ??= isQuery; @@ -1578,10 +1597,18 @@ class FlowAnalysisDebug $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 { 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 { if (nonPromotionHistory != null) { parts.add('nonPromotionHistory: $nonPromotionHistory'); } + if (properties.isNotEmpty) { + parts.add('properties: $properties'); + } return 'VariableModel(${parts.join(', ')})'; } @@ -3357,6 +3390,9 @@ class VariableReference variableInfo[variable] = variableModel; } + @override + String toString() => 'VariableReference($variable)'; + @override VariableModel? _getInfo( Map> variableInfo) => @@ -5025,6 +5061,10 @@ class _PropertyGetReference target.storeInfo(variableInfo, targetInfo.setProperties(newProperties)); } + @override + String toString() => + '_PropertyGetReference($target, $propertyName, $propertyMember)'; + @override VariableModel? _getInfo( Map> variableInfo) {