From 763f875441041010634893c9250a6b8ef5aab682 Mon Sep 17 00:00:00 2001 From: Ferhat Date: Fri, 27 Mar 2020 14:50:03 -0700 Subject: [PATCH] Treeshake debugFillProperties (#53303) --- .../lib/src/animation/listener_helpers.dart | 38 ++- .../lib/src/foundation/diagnostics.dart | 240 +++++++++++------- .../lib/src/gestures/pointer_router.dart | 11 +- .../src/gestures/pointer_signal_resolver.dart | 11 +- .../flutter/lib/src/gestures/recognizer.dart | 13 +- .../lib/src/painting/image_provider.dart | 41 ++- .../flutter/lib/src/scheduler/binding.dart | 17 +- .../lib/src/widgets/focus_manager.dart | 19 +- 8 files changed, 242 insertions(+), 148 deletions(-) diff --git a/packages/flutter/lib/src/animation/listener_helpers.dart b/packages/flutter/lib/src/animation/listener_helpers.dart index e8d66c7adc..ce4b2af8c4 100644 --- a/packages/flutter/lib/src/animation/listener_helpers.dart +++ b/packages/flutter/lib/src/animation/listener_helpers.dart @@ -119,6 +119,17 @@ mixin AnimationLocalListenersMixin { void notifyListeners() { final List localListeners = List.from(_listeners); for (final VoidCallback listener in localListeners) { + InformationCollector collector; + assert(() { + collector = () sync* { + yield DiagnosticsProperty( + 'The $runtimeType notifying listeners was', + this, + style: DiagnosticsTreeStyle.errorProperty, + ); + }; + return true; + }()); try { if (_listeners.contains(listener)) listener(); @@ -128,13 +139,7 @@ mixin AnimationLocalListenersMixin { stack: stack, library: 'animation library', context: ErrorDescription('while notifying listeners for $runtimeType'), - informationCollector: () sync* { - yield DiagnosticsProperty( - 'The $runtimeType notifying listeners was', - this, - style: DiagnosticsTreeStyle.errorProperty, - ); - }, + informationCollector: collector, )); } } @@ -192,18 +197,23 @@ mixin AnimationLocalStatusListenersMixin { if (_statusListeners.contains(listener)) listener(status); } catch (exception, stack) { - FlutterError.reportError(FlutterErrorDetails( - exception: exception, - stack: stack, - library: 'animation library', - context: ErrorDescription('while notifying status listeners for $runtimeType'), - informationCollector: () sync* { + InformationCollector collector; + assert(() { + collector = () sync* { yield DiagnosticsProperty( 'The $runtimeType notifying status listeners was', this, style: DiagnosticsTreeStyle.errorProperty, ); - }, + }; + return true; + }()); + FlutterError.reportError(FlutterErrorDetails( + exception: exception, + stack: stack, + library: 'animation library', + context: ErrorDescription('while notifying status listeners for $runtimeType'), + informationCollector: collector )); } } diff --git a/packages/flutter/lib/src/foundation/diagnostics.dart b/packages/flutter/lib/src/foundation/diagnostics.dart index 989329cb94..444ec3a51e 100644 --- a/packages/flutter/lib/src/foundation/diagnostics.dart +++ b/packages/flutter/lib/src/foundation/diagnostics.dart @@ -1112,7 +1112,21 @@ class TextTreeRenderer { }) { if (kReleaseMode) { return ''; + } else { + return _debugRender( + node, + prefixLineOne: prefixLineOne, + prefixOtherLines: prefixOtherLines, + parentConfiguration: parentConfiguration); } + } + + String _debugRender( + DiagnosticsNode node, { + String prefixLineOne = '', + String prefixOtherLines, + TextTreeConfiguration parentConfiguration, + }) { final bool isSingleLine = _isSingleLine(node.style) && parentConfiguration?.lineBreakProperties != true; prefixOtherLines ??= prefixLineOne; if (node.linePrefix != null) { @@ -1536,49 +1550,51 @@ abstract class DiagnosticsNode { /// plugin. @mustCallSuper Map toJsonMap(DiagnosticsSerializationDelegate delegate) { - if (kReleaseMode) { - return {}; - } - final bool hasChildren = getChildren().isNotEmpty; - return { - 'description': toDescription(), - 'type': runtimeType.toString(), - if (name != null) - 'name': name, - if (!showSeparator) - 'showSeparator': showSeparator, - if (level != DiagnosticLevel.info) - 'level': describeEnum(level), - if (showName == false) - 'showName': showName, - if (emptyBodyDescription != null) - 'emptyBodyDescription': emptyBodyDescription, - if (style != DiagnosticsTreeStyle.sparse) - 'style': describeEnum(style), - if (allowTruncate) - 'allowTruncate': allowTruncate, - if (hasChildren) - 'hasChildren': hasChildren, - if (linePrefix?.isNotEmpty == true) - 'linePrefix': linePrefix, - if (!allowWrap) - 'allowWrap': allowWrap, - if (allowNameWrap) - 'allowNameWrap': allowNameWrap, - ...delegate.additionalNodeProperties(this), - if (delegate.includeProperties) - 'properties': toJsonList( - delegate.filterProperties(getProperties(), this), - this, - delegate, - ), - if (delegate.subtreeDepth > 0) - 'children': toJsonList( - delegate.filterChildren(getChildren(), this), - this, - delegate, - ), - }; + Map result = {}; + assert(() { + final bool hasChildren = getChildren().isNotEmpty; + result = { + 'description': toDescription(), + 'type': runtimeType.toString(), + if (name != null) + 'name': name, + if (!showSeparator) + 'showSeparator': showSeparator, + if (level != DiagnosticLevel.info) + 'level': describeEnum(level), + if (showName == false) + 'showName': showName, + if (emptyBodyDescription != null) + 'emptyBodyDescription': emptyBodyDescription, + if (style != DiagnosticsTreeStyle.sparse) + 'style': describeEnum(style), + if (allowTruncate) + 'allowTruncate': allowTruncate, + if (hasChildren) + 'hasChildren': hasChildren, + if (linePrefix?.isNotEmpty == true) + 'linePrefix': linePrefix, + if (!allowWrap) + 'allowWrap': allowWrap, + if (allowNameWrap) + 'allowNameWrap': allowNameWrap, + ...delegate.additionalNodeProperties(this), + if (delegate.includeProperties) + 'properties': toJsonList( + delegate.filterProperties(getProperties(), this), + this, + delegate, + ), + if (delegate.subtreeDepth > 0) + 'children': toJsonList( + delegate.filterChildren(getChildren(), this), + this, + delegate, + ), + }; + return true; + }()); + return result; } /// Serializes a [List] of [DiagnosticsNode]s to a JSON list according to @@ -1622,22 +1638,28 @@ abstract class DiagnosticsNode { TextTreeConfiguration parentConfiguration, DiagnosticLevel minLevel = DiagnosticLevel.info, }) { - if (kReleaseMode) { - return super.toString(); - } + String result = super.toString(); assert(style != null); assert(minLevel != null); - if (_isSingleLine(style)) - return toStringDeep(parentConfiguration: parentConfiguration, minLevel: minLevel); + assert(() { + if (_isSingleLine(style)) { + result = toStringDeep( + parentConfiguration: parentConfiguration, minLevel: minLevel); + } else { + final String description = toDescription( + parentConfiguration: parentConfiguration); + assert(description != null); - final String description = toDescription(parentConfiguration: parentConfiguration); - assert(description != null); - - if (name == null || name.isEmpty || !showName) - return description; - - return description.contains('\n') ? '$name$_separator\n$description' - : '$name$_separator $description'; + if (name == null || name.isEmpty || !showName) { + result = description; + } else { + result = description.contains('\n') ? '$name$_separator\n$description' + : '$name$_separator $description'; + } + } + return true; + }()); + return result; } /// Returns a configuration specifying how this object should be rendered @@ -1699,19 +1721,21 @@ abstract class DiagnosticsNode { TextTreeConfiguration parentConfiguration, DiagnosticLevel minLevel = DiagnosticLevel.debug, }) { - if (kReleaseMode) { - return ''; - } - return TextTreeRenderer( - minLevel: minLevel, - wrapWidth: 65, - wrapWidthProperties: 65, - ).render( - this, - prefixLineOne: prefixLineOne, - prefixOtherLines: prefixOtherLines, - parentConfiguration: parentConfiguration, - ); + String result = ''; + assert(() { + result = TextTreeRenderer( + minLevel: minLevel, + wrapWidth: 65, + wrapWidthProperties: 65, + ).render( + this, + prefixLineOne: prefixLineOne, + prefixOtherLines: prefixOtherLines, + parentConfiguration: parentConfiguration, + ); + return true; + }()); + return result; } } @@ -2893,13 +2917,18 @@ class DiagnosticableNode extends DiagnosticsNode { /// /// It will cache the result to prevent duplicate operation. DiagnosticPropertiesBuilder get builder { - if (kReleaseMode) + if (kReleaseMode) { return null; - if (_cachedBuilder == null) { - _cachedBuilder = DiagnosticPropertiesBuilder(); - value?.debugFillProperties(_cachedBuilder); + } else { + assert(() { + if (_cachedBuilder == null) { + _cachedBuilder = DiagnosticPropertiesBuilder(); + value?.debugFillProperties(_cachedBuilder); + } + return true; + }()); + return _cachedBuilder; } - return _cachedBuilder; } @override @@ -2920,10 +2949,12 @@ class DiagnosticableNode extends DiagnosticsNode { @override String toDescription({ TextTreeConfiguration parentConfiguration }) { - if (kReleaseMode) { - return ''; - } - return value.toStringShort(); + String result = ''; + assert(() { + result = value.toStringShort(); + return true; + }()); + return result; } } @@ -3002,9 +3033,10 @@ class DiagnosticPropertiesBuilder { /// Add a property to the list of properties. void add(DiagnosticsNode property) { - if (!kReleaseMode) { + assert(() { properties.add(property); - } + return true; + }()); } /// List of properties accumulated so far. @@ -3376,15 +3408,21 @@ abstract class DiagnosticableTree with Diagnosticable { if (kReleaseMode) { return toString(); } - final StringBuffer result = StringBuffer(); - result.write(toString()); - result.write(joiner); - final DiagnosticPropertiesBuilder builder = DiagnosticPropertiesBuilder(); - debugFillProperties(builder); - result.write( - builder.properties.where((DiagnosticsNode n) => !n.isFiltered(minLevel)).join(joiner), - ); - return result.toString(); + String shallowString; + assert(() { + final StringBuffer result = StringBuffer(); + result.write(toString()); + result.write(joiner); + final DiagnosticPropertiesBuilder builder = DiagnosticPropertiesBuilder(); + debugFillProperties(builder); + result.write( + builder.properties.where((DiagnosticsNode n) => !n.isFiltered(minLevel)) + .join(joiner), + ); + shallowString = result.toString(); + return true; + }()); + return shallowString; } /// Returns a string representation of this node and its descendants. @@ -3463,15 +3501,21 @@ mixin DiagnosticableTreeMixin implements DiagnosticableTree { if (kReleaseMode) { return toString(); } - final StringBuffer result = StringBuffer(); - result.write(toStringShort()); - result.write(joiner); - final DiagnosticPropertiesBuilder builder = DiagnosticPropertiesBuilder(); - debugFillProperties(builder); - result.write( - builder.properties.where((DiagnosticsNode n) => !n.isFiltered(minLevel)).join(joiner), - ); - return result.toString(); + String shallowString; + assert(() { + final StringBuffer result = StringBuffer(); + result.write(toStringShort()); + result.write(joiner); + final DiagnosticPropertiesBuilder builder = DiagnosticPropertiesBuilder(); + debugFillProperties(builder); + result.write( + builder.properties.where((DiagnosticsNode n) => !n.isFiltered(minLevel)) + .join(joiner), + ); + shallowString = result.toString(); + return true; + }()); + return shallowString; } @override diff --git a/packages/flutter/lib/src/gestures/pointer_router.dart b/packages/flutter/lib/src/gestures/pointer_router.dart index 5512542a6e..9dfdb7d1df 100644 --- a/packages/flutter/lib/src/gestures/pointer_router.dart +++ b/packages/flutter/lib/src/gestures/pointer_router.dart @@ -75,6 +75,13 @@ class PointerRouter { event = event.transformed(transform); route(event); } catch (exception, stack) { + InformationCollector collector; + assert(() { + collector = () sync* { + yield DiagnosticsProperty('Event', event, style: DiagnosticsTreeStyle.errorProperty); + }; + return true; + }()); FlutterError.reportError(FlutterErrorDetailsForPointerRouter( exception: exception, stack: stack, @@ -83,9 +90,7 @@ class PointerRouter { router: this, route: route, event: event, - informationCollector: () sync* { - yield DiagnosticsProperty('Event', event, style: DiagnosticsTreeStyle.errorProperty); - }, + informationCollector: collector )); } } diff --git a/packages/flutter/lib/src/gestures/pointer_signal_resolver.dart b/packages/flutter/lib/src/gestures/pointer_signal_resolver.dart index bd15101784..6636f077a4 100644 --- a/packages/flutter/lib/src/gestures/pointer_signal_resolver.dart +++ b/packages/flutter/lib/src/gestures/pointer_signal_resolver.dart @@ -55,14 +55,19 @@ class PointerSignalResolver { try { _firstRegisteredCallback(_currentEvent); } catch (exception, stack) { + InformationCollector collector; + assert(() { + collector = () sync* { + yield DiagnosticsProperty('Event', event, style: DiagnosticsTreeStyle.errorProperty); + }; + return true; + }()); FlutterError.reportError(FlutterErrorDetails( exception: exception, stack: stack, library: 'gesture library', context: ErrorDescription('while resolving a PointerSignalEvent'), - informationCollector: () sync* { - yield DiagnosticsProperty('Event', event, style: DiagnosticsTreeStyle.errorProperty); - }, + informationCollector: collector )); } _firstRegisteredCallback = null; diff --git a/packages/flutter/lib/src/gestures/recognizer.dart b/packages/flutter/lib/src/gestures/recognizer.dart index f1125c5fbb..42ab30162f 100644 --- a/packages/flutter/lib/src/gestures/recognizer.dart +++ b/packages/flutter/lib/src/gestures/recognizer.dart @@ -181,15 +181,20 @@ abstract class GestureRecognizer extends GestureArenaMember with DiagnosticableT }()); result = callback(); } catch (exception, stack) { + InformationCollector collector; + assert(() { + collector = () sync* { + yield StringProperty('Handler', name); + yield DiagnosticsProperty('Recognizer', this, style: DiagnosticsTreeStyle.errorProperty); + }; + return true; + }()); FlutterError.reportError(FlutterErrorDetails( exception: exception, stack: stack, library: 'gesture', context: ErrorDescription('while handling a gesture'), - informationCollector: () sync* { - yield StringProperty('Handler', name); - yield DiagnosticsProperty('Recognizer', this, style: DiagnosticsTreeStyle.errorProperty); - }, + informationCollector: collector )); } return result; diff --git a/packages/flutter/lib/src/painting/image_provider.dart b/packages/flutter/lib/src/painting/image_provider.dart index 0678319204..1a3ac3f841 100644 --- a/packages/flutter/lib/src/painting/image_provider.dart +++ b/packages/flutter/lib/src/painting/image_provider.dart @@ -333,16 +333,21 @@ abstract class ImageProvider { await null; // wait an event turn in case a listener has been added to the image stream. final _ErrorImageCompleter imageCompleter = _ErrorImageCompleter(); stream.setCompleter(imageCompleter); + InformationCollector collector; + assert(() { + collector = () sync* { + yield DiagnosticsProperty('Image provider', this); + yield DiagnosticsProperty('Image configuration', configuration); + yield DiagnosticsProperty('Image key', key, defaultValue: null); + }; + return true; + }()); imageCompleter.setError( exception: exception, stack: stack, context: ErrorDescription('while resolving an image'), silent: true, // could be a network error or whatnot - informationCollector: () sync* { - yield DiagnosticsProperty('Image provider', this); - yield DiagnosticsProperty('Image configuration', configuration); - yield DiagnosticsProperty('Image key', key, defaultValue: null); - }, + informationCollector: collector ); }, ); @@ -384,13 +389,18 @@ abstract class ImageProvider { if (handleError != null) { handleError(exception, stack); } else { - FlutterError.onError(FlutterErrorDetails( - context: ErrorDescription('while checking the cache location of an image'), - informationCollector: () sync* { + InformationCollector collector; + assert(() { + collector = () sync* { yield DiagnosticsProperty('Image provider', this); yield DiagnosticsProperty('Image configuration', configuration); yield DiagnosticsProperty('Image key', key, defaultValue: null); - }, + }; + return true; + }()); + FlutterError.onError(FlutterErrorDetails( + context: ErrorDescription('while checking the cache location of an image'), + informationCollector: collector, exception: exception, stack: stack, )); @@ -626,13 +636,18 @@ abstract class AssetBundleImageProvider extends ImageProvider('Image provider', this); + yield DiagnosticsProperty('Image key', key); + }; + return true; + }()); return MultiFrameImageStreamCompleter( codec: _loadAsync(key, decode), scale: key.scale, - informationCollector: () sync* { - yield DiagnosticsProperty('Image provider', this); - yield DiagnosticsProperty('Image key', key); - }, + informationCollector: collector ); } diff --git a/packages/flutter/lib/src/scheduler/binding.dart b/packages/flutter/lib/src/scheduler/binding.dart index 7fde6ceadd..394c57f174 100644 --- a/packages/flutter/lib/src/scheduler/binding.dart +++ b/packages/flutter/lib/src/scheduler/binding.dart @@ -254,17 +254,22 @@ mixin SchedulerBinding on BindingBase, ServicesBinding { callback(timings); } } catch (exception, stack) { - FlutterError.reportError(FlutterErrorDetails( - exception: exception, - stack: stack, - context: ErrorDescription('while executing callbacks for FrameTiming'), - informationCollector: () sync* { + InformationCollector collector; + assert(() { + collector = () sync* { yield DiagnosticsProperty( 'The TimingsCallback that gets executed was', callback, style: DiagnosticsTreeStyle.errorProperty, ); - }, + }; + return true; + }()); + FlutterError.reportError(FlutterErrorDetails( + exception: exception, + stack: stack, + context: ErrorDescription('while executing callbacks for FrameTiming'), + informationCollector: collector )); } } diff --git a/packages/flutter/lib/src/widgets/focus_manager.dart b/packages/flutter/lib/src/widgets/focus_manager.dart index 57f1a69aa9..b410c75fb6 100644 --- a/packages/flutter/lib/src/widgets/focus_manager.dart +++ b/packages/flutter/lib/src/widgets/focus_manager.dart @@ -1469,18 +1469,23 @@ class FocusManager with DiagnosticableTreeMixin, ChangeNotifier { listener(_highlightMode); } } catch (exception, stack) { - FlutterError.reportError(FlutterErrorDetails( - exception: exception, - stack: stack, - library: 'widgets library', - context: ErrorDescription('while dispatching notifications for $runtimeType'), - informationCollector: () sync* { + InformationCollector collector; + assert(() { + collector = () sync* { yield DiagnosticsProperty( 'The $runtimeType sending notification was', this, style: DiagnosticsTreeStyle.errorProperty, ); - }, + }; + return true; + }()); + FlutterError.reportError(FlutterErrorDetails( + exception: exception, + stack: stack, + library: 'widgets library', + context: ErrorDescription('while dispatching notifications for $runtimeType'), + informationCollector: collector, )); } }