From 7d56be4c8de814022357633179a816b51ffca4b8 Mon Sep 17 00:00:00 2001 From: Polina Cherkasova Date: Tue, 25 Feb 2025 15:18:53 -0800 Subject: [PATCH] Clean up leak tracker instrumentation tech debt. (#164070) Fixes https://github.com/flutter/flutter/issues/137435 Tests are not needed because it is refactoring. Requested [exempt](https://discord.com/channels/608014603317936148/608018585025118217/1343801945982505001). @goderbauer , if looks good, can you merge it please, to avoid conflicts, as there are many files here? --- .../src/animation/animation_controller.dart | 25 ++-------- .../flutter/lib/src/animation/animations.dart | 16 +------ .../lib/src/foundation/change_notifier.dart | 28 +++++------ .../flutter/lib/src/gestures/multidrag.dart | 16 +------ .../flutter/lib/src/gestures/recognizer.dart | 16 +------ .../flutter/lib/src/material/material.dart | 16 +------ .../lib/src/material/mergeable_material.dart | 14 +----- packages/flutter/lib/src/material/tabs.dart | 14 +----- .../flutter/lib/src/material/time_picker.dart | 14 +----- .../lib/src/painting/decoration_image.dart | 28 ++--------- .../flutter/lib/src/painting/image_cache.dart | 14 +----- .../lib/src/painting/image_stream.dart | 30 ++---------- .../lib/src/painting/text_painter.dart | 18 +------- packages/flutter/lib/src/rendering/layer.dart | 14 +----- .../flutter/lib/src/rendering/object.dart | 46 +++---------------- .../flutter/lib/src/scheduler/binding.dart | 16 +------ .../flutter/lib/src/scheduler/ticker.dart | 17 +------ .../flutter/lib/src/semantics/binding.dart | 17 +------ .../flutter/lib/src/semantics/semantics.dart | 14 +----- .../flutter/lib/src/services/restoration.dart | 31 ++----------- .../src/widgets/app_lifecycle_listener.dart | 16 +------ packages/flutter/lib/src/widgets/banner.dart | 18 +------- .../src/widgets/disposable_build_context.dart | 16 +------ .../widgets/draggable_scrollable_sheet.dart | 14 +----- .../lib/src/widgets/focus_manager.dart | 14 +----- .../flutter/lib/src/widgets/framework.dart | 26 ++--------- packages/flutter/lib/src/widgets/heroes.dart | 31 ++----------- .../flutter/lib/src/widgets/navigator.dart | 28 ++--------- .../lib/src/widgets/nested_scroll_view.dart | 14 +----- packages/flutter/lib/src/widgets/overlay.dart | 23 +--------- .../lib/src/widgets/reorderable_list.dart | 14 +----- .../lib/src/widgets/scroll_activity.dart | 33 ++----------- .../lib/src/widgets/text_selection.dart | 32 ++----------- .../lib/src/widgets/widget_inspector.dart | 14 +----- 34 files changed, 99 insertions(+), 598 deletions(-) diff --git a/packages/flutter/lib/src/animation/animation_controller.dart b/packages/flutter/lib/src/animation/animation_controller.dart index 966cef2aab..537c71530f 100644 --- a/packages/flutter/lib/src/animation/animation_controller.dart +++ b/packages/flutter/lib/src/animation/animation_controller.dart @@ -23,8 +23,6 @@ export 'package:flutter/scheduler.dart' show TickerFuture, TickerProvider; export 'animation.dart' show Animation, AnimationStatus; export 'curves.dart' show Curve; -const String _flutterAnimationLibrary = 'package:flutter/animation.dart'; - // Examples can assume: // late AnimationController _controller, fadeAnimationController, sizeAnimationController; // late bool dismissed; @@ -255,9 +253,7 @@ class AnimationController extends Animation required TickerProvider vsync, }) : assert(upperBound >= lowerBound), _direction = _AnimationDirection.forward { - if (kFlutterMemoryAllocationsEnabled) { - _maybeDispatchObjectCreation(); - } + assert(debugMaybeDispatchCreated('animation', 'AnimationController', this)); _ticker = vsync.createTicker(_tick); _internalSetValue(value ?? lowerBound); } @@ -289,24 +285,11 @@ class AnimationController extends Animation }) : lowerBound = double.negativeInfinity, upperBound = double.infinity, _direction = _AnimationDirection.forward { - if (kFlutterMemoryAllocationsEnabled) { - _maybeDispatchObjectCreation(); - } + assert(debugMaybeDispatchCreated('animation', 'AnimationController', this)); _ticker = vsync.createTicker(_tick); _internalSetValue(value); } - /// Dispatches event of object creation to [FlutterMemoryAllocations.instance]. - void _maybeDispatchObjectCreation() { - if (kFlutterMemoryAllocationsEnabled) { - FlutterMemoryAllocations.instance.dispatchObjectCreated( - library: _flutterAnimationLibrary, - className: '$AnimationController', - object: this, - ); - } - } - /// The value at which this animation is deemed to be dismissed. final double lowerBound; @@ -946,9 +929,7 @@ class AnimationController extends Animation } return true; }()); - if (kFlutterMemoryAllocationsEnabled) { - FlutterMemoryAllocations.instance.dispatchObjectDisposed(object: this); - } + assert(debugMaybeDispatchDisposed(this)); _ticker!.dispose(); _ticker = null; clearStatusListeners(); diff --git a/packages/flutter/lib/src/animation/animations.dart b/packages/flutter/lib/src/animation/animations.dart index 062223485d..3b4d92f235 100644 --- a/packages/flutter/lib/src/animation/animations.dart +++ b/packages/flutter/lib/src/animation/animations.dart @@ -505,15 +505,7 @@ class TrainHoppingAnimation extends Animation this._nextTrain, { this.onSwitchedTrain, }) { - // TODO(polina-c): stop duplicating code across disposables - // https://github.com/flutter/flutter/issues/137435 - if (kFlutterMemoryAllocationsEnabled) { - FlutterMemoryAllocations.instance.dispatchObjectCreated( - library: 'package:flutter/animation.dart', - className: '$TrainHoppingAnimation', - object: this, - ); - } + assert(debugMaybeDispatchCreated('animation', 'TrainHoppingAnimation', this)); if (_nextTrain != null) { if (_currentTrain!.value == _nextTrain!.value) { _currentTrain = _nextTrain; @@ -598,11 +590,7 @@ class TrainHoppingAnimation extends Animation /// After this is called, this object is no longer usable. @override void dispose() { - // TODO(polina-c): stop duplicating code across disposables - // https://github.com/flutter/flutter/issues/137435 - if (kFlutterMemoryAllocationsEnabled) { - FlutterMemoryAllocations.instance.dispatchObjectDisposed(object: this); - } + assert(debugMaybeDispatchDisposed(this)); assert(_currentTrain != null); _currentTrain!.removeStatusListener(_statusChangeHandler); _currentTrain!.removeListener(_valueChangeHandler); diff --git a/packages/flutter/lib/src/foundation/change_notifier.dart b/packages/flutter/lib/src/foundation/change_notifier.dart index 063a295c53..026c9af30d 100644 --- a/packages/flutter/lib/src/foundation/change_notifier.dart +++ b/packages/flutter/lib/src/foundation/change_notifier.dart @@ -11,6 +11,7 @@ import 'dart:ui' show VoidCallback; import 'package:meta/meta.dart'; import 'assertions.dart'; +import 'debug.dart'; import 'diagnostics.dart'; import 'memory_allocations.dart'; @@ -100,8 +101,6 @@ abstract class ValueListenable extends Listenable { T get value; } -const String _flutterFoundationLibrary = 'package:flutter/foundation.dart'; - /// A class that can be extended or mixed in that provides a change notification /// API using [VoidCallback] for notifications. /// @@ -156,7 +155,7 @@ mixin class ChangeNotifier implements Listenable { /// /// As [ChangeNotifier] is used as mixin, it does not have constructor, /// so we use [addListener] to dispatch the event. - bool _creationDispatched = false; + bool _debugCreationDispatched = false; /// Used by subclasses to assert that the [ChangeNotifier] has not yet been /// disposed. @@ -232,16 +231,13 @@ mixin class ChangeNotifier implements Listenable { /// so that the method is tree-shaken away when the flag is false. @protected static void maybeDispatchObjectCreation(ChangeNotifier object) { - // Tree shaker does not include this method and the class MemoryAllocations - // if kFlutterMemoryAllocationsEnabled is false. - if (kFlutterMemoryAllocationsEnabled && !object._creationDispatched) { - FlutterMemoryAllocations.instance.dispatchObjectCreated( - library: _flutterFoundationLibrary, - className: '$ChangeNotifier', - object: object, - ); - object._creationDispatched = true; - } + assert(() { + if (!object._debugCreationDispatched) { + debugMaybeDispatchCreated('foundation', 'ChangeNotifier', object); + object._debugCreationDispatched = true; + } + return true; + }()); } /// Register a closure to be called when the object changes. @@ -387,11 +383,11 @@ mixin class ChangeNotifier implements Listenable { ); assert(() { _debugDisposed = true; + if (_debugCreationDispatched) { + assert(debugMaybeDispatchDisposed(this)); + } return true; }()); - if (kFlutterMemoryAllocationsEnabled && _creationDispatched) { - FlutterMemoryAllocations.instance.dispatchObjectDisposed(object: this); - } _listeners = _emptyListeners; _count = 0; } diff --git a/packages/flutter/lib/src/gestures/multidrag.dart b/packages/flutter/lib/src/gestures/multidrag.dart index d8d9c099b9..5865e4d62e 100644 --- a/packages/flutter/lib/src/gestures/multidrag.dart +++ b/packages/flutter/lib/src/gestures/multidrag.dart @@ -39,15 +39,7 @@ abstract class MultiDragPointerState { /// Creates per-pointer state for a [MultiDragGestureRecognizer]. MultiDragPointerState(this.initialPosition, this.kind, this.gestureSettings) : _velocityTracker = VelocityTracker.withKind(kind) { - // TODO(polina-c): stop duplicating code across disposables - // https://github.com/flutter/flutter/issues/137435 - if (kFlutterMemoryAllocationsEnabled) { - FlutterMemoryAllocations.instance.dispatchObjectCreated( - library: 'package:flutter/gestures.dart', - className: '$MultiDragPointerState', - object: this, - ); - } + assert(debugMaybeDispatchCreated('gestures', 'MultiDragPointerState', this)); } /// Device specific gesture configuration that should be preferred over @@ -195,11 +187,7 @@ abstract class MultiDragPointerState { @protected @mustCallSuper void dispose() { - // TODO(polina-c): stop duplicating code across disposables - // https://github.com/flutter/flutter/issues/137435 - if (kFlutterMemoryAllocationsEnabled) { - FlutterMemoryAllocations.instance.dispatchObjectDisposed(object: this); - } + assert(debugMaybeDispatchDisposed(this)); _arenaEntry?.resolve(GestureDisposition.rejected); _arenaEntry = null; assert(() { diff --git a/packages/flutter/lib/src/gestures/recognizer.dart b/packages/flutter/lib/src/gestures/recognizer.dart index f0e181391d..4fbf3dcf0e 100644 --- a/packages/flutter/lib/src/gestures/recognizer.dart +++ b/packages/flutter/lib/src/gestures/recognizer.dart @@ -142,15 +142,7 @@ abstract class GestureRecognizer extends GestureArenaMember with DiagnosticableT this.supportedDevices, this.allowedButtonsFilter = _defaultButtonAcceptBehavior, }) { - // TODO(polina-c): stop duplicating code across disposables - // https://github.com/flutter/flutter/issues/137435 - if (kFlutterMemoryAllocationsEnabled) { - FlutterMemoryAllocations.instance.dispatchObjectCreated( - library: 'package:flutter/gestures.dart', - className: '$GestureRecognizer', - object: this, - ); - } + assert(debugMaybeDispatchCreated('gestures', 'GestureRecognizer', this)); } /// The recognizer's owner. @@ -313,11 +305,7 @@ abstract class GestureRecognizer extends GestureArenaMember with DiagnosticableT /// GestureDetector widget calls this method). @mustCallSuper void dispose() { - // TODO(polina-c): stop duplicating code across disposables - // https://github.com/flutter/flutter/issues/137435 - if (kFlutterMemoryAllocationsEnabled) { - FlutterMemoryAllocations.instance.dispatchObjectDisposed(object: this); - } + assert(debugMaybeDispatchDisposed(this)); } /// Returns a very short pretty description of the gesture that the diff --git a/packages/flutter/lib/src/material/material.dart b/packages/flutter/lib/src/material/material.dart index a4905c2be7..b9fe052358 100644 --- a/packages/flutter/lib/src/material/material.dart +++ b/packages/flutter/lib/src/material/material.dart @@ -677,15 +677,7 @@ abstract class InkFeature { required this.referenceBox, this.onRemoved, }) : _controller = controller as _RenderInkFeatures { - // TODO(polina-c): stop duplicating code across disposables - // https://github.com/flutter/flutter/issues/137435 - if (kFlutterMemoryAllocationsEnabled) { - FlutterMemoryAllocations.instance.dispatchObjectCreated( - library: 'package:flutter/material.dart', - className: '$InkFeature', - object: this, - ); - } + assert(debugMaybeDispatchCreated('material', 'InkFeature', this)); } /// The [MaterialInkController] associated with this [InkFeature]. @@ -711,11 +703,7 @@ abstract class InkFeature { _debugDisposed = true; return true; }()); - // TODO(polina-c): stop duplicating code across disposables - // https://github.com/flutter/flutter/issues/137435 - if (kFlutterMemoryAllocationsEnabled) { - FlutterMemoryAllocations.instance.dispatchObjectDisposed(object: this); - } + assert(debugMaybeDispatchDisposed(this)); _controller._removeFeature(this); onRemoved?.call(); } diff --git a/packages/flutter/lib/src/material/mergeable_material.dart b/packages/flutter/lib/src/material/mergeable_material.dart index 57c246fc49..3f98d7835d 100644 --- a/packages/flutter/lib/src/material/mergeable_material.dart +++ b/packages/flutter/lib/src/material/mergeable_material.dart @@ -146,15 +146,7 @@ class _AnimationTuple { required this.endAnimation, required this.gapAnimation, }) { - // TODO(polina-c): stop duplicating code across disposables - // https://github.com/flutter/flutter/issues/137435 - if (kFlutterMemoryAllocationsEnabled) { - FlutterMemoryAllocations.instance.dispatchObjectCreated( - library: 'package:flutter/material.dart', - className: '$_AnimationTuple', - object: this, - ); - } + assert(debugMaybeDispatchCreated('material', '_AnimationTuple', this)); } final AnimationController controller; @@ -165,9 +157,7 @@ class _AnimationTuple { @mustCallSuper void dispose() { - if (kFlutterMemoryAllocationsEnabled) { - FlutterMemoryAllocations.instance.dispatchObjectDisposed(object: this); - } + assert(debugMaybeDispatchDisposed(this)); controller.dispose(); startAnimation.dispose(); endAnimation.dispose(); diff --git a/packages/flutter/lib/src/material/tabs.dart b/packages/flutter/lib/src/material/tabs.dart index 31ce0b1877..67d8cafd42 100644 --- a/packages/flutter/lib/src/material/tabs.dart +++ b/packages/flutter/lib/src/material/tabs.dart @@ -480,15 +480,7 @@ class _IndicatorPainter extends CustomPainter { required this.indicatorAnimation, required this.textDirection, }) : super(repaint: controller.animation) { - // TODO(polina-c): stop duplicating code across disposables - // https://github.com/flutter/flutter/issues/137435 - if (kFlutterMemoryAllocationsEnabled) { - FlutterMemoryAllocations.instance.dispatchObjectCreated( - library: 'package:flutter/material.dart', - className: '$_IndicatorPainter', - object: this, - ); - } + assert(debugMaybeDispatchCreated('material', '_IndicatorPainter', this)); if (old != null) { saveTabOffsets(old._currentTabOffsets, old._currentTextDirection); } @@ -521,9 +513,7 @@ class _IndicatorPainter extends CustomPainter { } void dispose() { - if (kFlutterMemoryAllocationsEnabled) { - FlutterMemoryAllocations.instance.dispatchObjectDisposed(object: this); - } + assert(debugMaybeDispatchDisposed(this)); _painter?.dispose(); } diff --git a/packages/flutter/lib/src/material/time_picker.dart b/packages/flutter/lib/src/material/time_picker.dart index e3472a14bb..e210e3d965 100644 --- a/packages/flutter/lib/src/material/time_picker.dart +++ b/packages/flutter/lib/src/material/time_picker.dart @@ -957,15 +957,7 @@ class _DialPainter extends CustomPainter { required this.textDirection, required this.selectedValue, }) : super(repaint: PaintingBinding.instance.systemFonts) { - // TODO(polina-c): stop duplicating code across disposables - // https://github.com/flutter/flutter/issues/137435 - if (kFlutterMemoryAllocationsEnabled) { - FlutterMemoryAllocations.instance.dispatchObjectCreated( - library: 'package:flutter/material.dart', - className: '$_DialPainter', - object: this, - ); - } + assert(debugMaybeDispatchCreated('material', '_DialPainter', this)); } final List<_TappableLabel> primaryLabels; @@ -982,9 +974,7 @@ class _DialPainter extends CustomPainter { final int selectedValue; void dispose() { - if (kFlutterMemoryAllocationsEnabled) { - FlutterMemoryAllocations.instance.dispatchObjectDisposed(object: this); - } + assert(debugMaybeDispatchDisposed(this)); for (final _TappableLabel label in primaryLabels) { label.painter.dispose(); } diff --git a/packages/flutter/lib/src/painting/decoration_image.dart b/packages/flutter/lib/src/painting/decoration_image.dart index 2e6f3225cb..aa7e2f4159 100644 --- a/packages/flutter/lib/src/painting/decoration_image.dart +++ b/packages/flutter/lib/src/painting/decoration_image.dart @@ -319,15 +319,7 @@ abstract interface class DecorationImagePainter { class _DecorationImagePainter implements DecorationImagePainter { _DecorationImagePainter._(this._details, this._onChanged) { - // TODO(polina-c): stop duplicating code across disposables - // https://github.com/flutter/flutter/issues/137435 - if (kFlutterMemoryAllocationsEnabled) { - FlutterMemoryAllocations.instance.dispatchObjectCreated( - library: 'package:flutter/painting.dart', - className: '$_DecorationImagePainter', - object: this, - ); - } + assert(debugMaybeDispatchCreated('painting', '_DecorationImagePainter', this)); } final DecorationImage _details; @@ -438,9 +430,7 @@ class _DecorationImagePainter implements DecorationImagePainter { @override void dispose() { - if (kFlutterMemoryAllocationsEnabled) { - FlutterMemoryAllocations.instance.dispatchObjectDisposed(object: this); - } + assert(debugMaybeDispatchDisposed(this)); _imageStream?.removeListener(ImageStreamListener(_handleImage, onError: _details.onError)); _image?.dispose(); _image = null; @@ -862,15 +852,7 @@ class _BlendedDecorationImage implements DecorationImage { class _BlendedDecorationImagePainter implements DecorationImagePainter { _BlendedDecorationImagePainter._(this.a, this.b, this.t) { - // TODO(polina-c): stop duplicating code across disposables - // https://github.com/flutter/flutter/issues/137435 - if (kFlutterMemoryAllocationsEnabled) { - FlutterMemoryAllocations.instance.dispatchObjectCreated( - library: 'package:flutter/painting.dart', - className: '$_BlendedDecorationImagePainter', - object: this, - ); - } + assert(debugMaybeDispatchCreated('painting', '_BlendedDecorationImagePainter', this)); } final DecorationImagePainter? a; @@ -901,9 +883,7 @@ class _BlendedDecorationImagePainter implements DecorationImagePainter { @override void dispose() { - if (kFlutterMemoryAllocationsEnabled) { - FlutterMemoryAllocations.instance.dispatchObjectDisposed(object: this); - } + assert(debugMaybeDispatchDisposed(this)); a?.dispose(); b?.dispose(); } diff --git a/packages/flutter/lib/src/painting/image_cache.dart b/packages/flutter/lib/src/painting/image_cache.dart index 6ae238efa2..1e15e2cab1 100644 --- a/packages/flutter/lib/src/painting/image_cache.dart +++ b/packages/flutter/lib/src/painting/image_cache.dart @@ -595,15 +595,7 @@ class ImageCacheStatus { /// [ImageCache._cache]. abstract class _CachedImageBase { _CachedImageBase(this.completer, {this.sizeBytes}) : handle = completer.keepAlive() { - // TODO(polina-c): stop duplicating code across disposables - // https://github.com/flutter/flutter/issues/137435 - if (kFlutterMemoryAllocationsEnabled) { - FlutterMemoryAllocations.instance.dispatchObjectCreated( - library: 'package:flutter/painting.dart', - className: '$_CachedImageBase', - object: this, - ); - } + assert(debugMaybeDispatchCreated('painting', '_CachedImageBase', this)); } final ImageStreamCompleter completer; @@ -613,9 +605,7 @@ abstract class _CachedImageBase { @mustCallSuper void dispose() { assert(handle != null); - if (kFlutterMemoryAllocationsEnabled) { - FlutterMemoryAllocations.instance.dispatchObjectDisposed(object: this); - } + assert(debugMaybeDispatchDisposed(this)); // Give any interested parties a chance to listen to the stream before we // potentially dispose it. SchedulerBinding.instance.addPostFrameCallback((Duration timeStamp) { diff --git a/packages/flutter/lib/src/painting/image_stream.dart b/packages/flutter/lib/src/painting/image_stream.dart index 91d486c1cf..88fac19b65 100644 --- a/packages/flutter/lib/src/painting/image_stream.dart +++ b/packages/flutter/lib/src/painting/image_stream.dart @@ -16,8 +16,6 @@ import 'dart:ui' as ui show Codec, FrameInfo, Image; import 'package:flutter/foundation.dart'; import 'package:flutter/scheduler.dart'; -const String _flutterPaintingLibrary = 'package:flutter/painting.dart'; - /// A [dart:ui.Image] object with its corresponding scale. /// /// ImageInfo objects are used by [ImageStream] objects to represent the @@ -47,13 +45,7 @@ class ImageInfo { /// /// See details for disposing contract in the class description. ImageInfo({required this.image, this.scale = 1.0, this.debugLabel}) { - if (kFlutterMemoryAllocationsEnabled) { - MemoryAllocations.instance.dispatchObjectCreated( - library: _flutterPaintingLibrary, - className: '$ImageInfo', - object: this, - ); - } + assert(debugMaybeDispatchCreated('painting', 'ImageInfo', this)); } /// Creates an [ImageInfo] with a cloned [image]. @@ -144,9 +136,7 @@ class ImageInfo { /// and no clones of it or the image it contains can be made. void dispose() { assert((image.debugGetOpenHandleStackTraces()?.length ?? 1) > 0); - if (kFlutterMemoryAllocationsEnabled) { - MemoryAllocations.instance.dispatchObjectDisposed(object: this); - } + assert(debugMaybeDispatchDisposed(this)); image.dispose(); } @@ -460,15 +450,7 @@ class ImageStream with Diagnosticable { class ImageStreamCompleterHandle { ImageStreamCompleterHandle._(ImageStreamCompleter this._completer) { _completer!._keepAliveHandles += 1; - // TODO(polina-c): stop duplicating code across disposables - // https://github.com/flutter/flutter/issues/137435 - if (kFlutterMemoryAllocationsEnabled) { - FlutterMemoryAllocations.instance.dispatchObjectCreated( - library: _flutterPaintingLibrary, - className: '$ImageStreamCompleterHandle', - object: this, - ); - } + assert(debugMaybeDispatchCreated('painting', 'ImageStreamCompleterHandle', this)); } ImageStreamCompleter? _completer; @@ -485,11 +467,7 @@ class ImageStreamCompleterHandle { _completer!._keepAliveHandles -= 1; _completer!._maybeDispose(); _completer = null; - // TODO(polina-c): stop duplicating code across disposables - // https://github.com/flutter/flutter/issues/137435 - if (kFlutterMemoryAllocationsEnabled) { - FlutterMemoryAllocations.instance.dispatchObjectDisposed(object: this); - } + assert(debugMaybeDispatchDisposed(this)); } } diff --git a/packages/flutter/lib/src/painting/text_painter.dart b/packages/flutter/lib/src/painting/text_painter.dart index 58176bca97..ede8f8cd1f 100644 --- a/packages/flutter/lib/src/painting/text_painter.dart +++ b/packages/flutter/lib/src/painting/text_painter.dart @@ -561,8 +561,6 @@ class _LineCaretMetrics { } } -const String _flutterPaintingLibrary = 'package:flutter/painting.dart'; - /// An object that paints a [TextSpan] tree into a [Canvas]. /// /// To use a [TextPainter], follow these steps: @@ -628,15 +626,7 @@ class TextPainter { _strutStyle = strutStyle, _textWidthBasis = textWidthBasis, _textHeightBehavior = textHeightBehavior { - // TODO(polina-c): stop duplicating code across disposables - // https://github.com/flutter/flutter/issues/137435 - if (kFlutterMemoryAllocationsEnabled) { - FlutterMemoryAllocations.instance.dispatchObjectCreated( - library: _flutterPaintingLibrary, - className: '$TextPainter', - object: this, - ); - } + assert(debugMaybeDispatchCreated('painting', 'TextPainter', this)); } /// Computes the width of a configured [TextPainter]. @@ -1786,11 +1776,7 @@ class TextPainter { _disposed = true; return true; }()); - // TODO(polina-c): stop duplicating code across disposables - // https://github.com/flutter/flutter/issues/137435 - if (kFlutterMemoryAllocationsEnabled) { - FlutterMemoryAllocations.instance.dispatchObjectDisposed(object: this); - } + assert(debugMaybeDispatchDisposed(this)); _layoutTemplate?.dispose(); _layoutTemplate = null; _layoutCache?.paragraph.dispose(); diff --git a/packages/flutter/lib/src/rendering/layer.dart b/packages/flutter/lib/src/rendering/layer.dart index 269750f6cf..379c3a67f9 100644 --- a/packages/flutter/lib/src/rendering/layer.dart +++ b/packages/flutter/lib/src/rendering/layer.dart @@ -80,8 +80,6 @@ class AnnotationResult { } } -const String _flutterRenderingLibrary = 'package:flutter/rendering.dart'; - /// A composited layer. /// /// During painting, the render tree generates a tree of composited layers that @@ -146,13 +144,7 @@ const String _flutterRenderingLibrary = 'package:flutter/rendering.dart'; abstract class Layer with DiagnosticableTreeMixin { /// Creates an instance of Layer. Layer() { - if (kFlutterMemoryAllocationsEnabled) { - FlutterMemoryAllocations.instance.dispatchObjectCreated( - library: _flutterRenderingLibrary, - className: '$Layer', - object: this, - ); - } + assert(debugMaybeDispatchCreated('rendering', 'Layer', this)); } final Map _callbacks = {}; @@ -342,9 +334,7 @@ abstract class Layer with DiagnosticableTreeMixin { _debugDisposed = true; return true; }()); - if (kFlutterMemoryAllocationsEnabled) { - FlutterMemoryAllocations.instance.dispatchObjectDisposed(object: this); - } + assert(debugMaybeDispatchDisposed(this)); _engineLayer?.dispose(); _engineLayer = null; } diff --git a/packages/flutter/lib/src/rendering/object.dart b/packages/flutter/lib/src/rendering/object.dart index 139f1c7049..70d3371103 100644 --- a/packages/flutter/lib/src/rendering/object.dart +++ b/packages/flutter/lib/src/rendering/object.dart @@ -884,16 +884,7 @@ typedef LayoutCallback = void Function(T constraints); class _LocalSemanticsHandle implements SemanticsHandle { _LocalSemanticsHandle._(PipelineOwner owner, this.listener) : _owner = owner { - // TODO(polina-c): stop duplicating code across disposables - // https://github.com/flutter/flutter/issues/137435 - if (kFlutterMemoryAllocationsEnabled) { - FlutterMemoryAllocations.instance.dispatchObjectCreated( - library: 'package:flutter/rendering.dart', - className: '$_LocalSemanticsHandle', - object: this, - ); - } - + assert(debugMaybeDispatchCreated('rendering', '_LocalSemanticsHandle', this)); if (listener != null) { _owner.semanticsOwner!.addListener(listener!); } @@ -906,12 +897,7 @@ class _LocalSemanticsHandle implements SemanticsHandle { @override void dispose() { - // TODO(polina-c): stop duplicating code across disposables - // https://github.com/flutter/flutter/issues/137435 - if (kFlutterMemoryAllocationsEnabled) { - FlutterMemoryAllocations.instance.dispatchObjectDisposed(object: this); - } - + assert(debugMaybeDispatchDisposed(this)); if (listener != null) { _owner.semanticsOwner!.removeListener(listener!); } @@ -974,15 +960,7 @@ base class PipelineOwner with DiagnosticableTreeMixin { this.onSemanticsUpdate, this.onSemanticsOwnerDisposed, }) { - // TODO(polina-c): stop duplicating code across disposables - // https://github.com/flutter/flutter/issues/137435 - if (kFlutterMemoryAllocationsEnabled) { - FlutterMemoryAllocations.instance.dispatchObjectCreated( - library: 'package:flutter/rendering.dart', - className: '$PipelineOwner', - object: this, - ); - } + assert(debugMaybeDispatchCreated('rendering', 'PipelineOwner', this)); } /// Called when a render object associated with this pipeline owner wishes to @@ -1598,9 +1576,7 @@ base class PipelineOwner with DiagnosticableTreeMixin { assert(rootNode == null); assert(_manifold == null); assert(_debugParent == null); - if (kFlutterMemoryAllocationsEnabled) { - FlutterMemoryAllocations.instance.dispatchObjectDisposed(object: this); - } + assert(debugMaybeDispatchDisposed(this)); _semanticsOwner?.dispose(); _semanticsOwner = null; _nodesNeedingLayout.clear(); @@ -1664,8 +1640,6 @@ abstract class PipelineManifold implements Listenable { void requestVisualUpdate(); } -const String _flutterRenderingLibrary = 'package:flutter/rendering.dart'; - /// An object in the render tree. /// /// The [RenderObject] class hierarchy is the core of the rendering @@ -1794,13 +1768,7 @@ const String _flutterRenderingLibrary = 'package:flutter/rendering.dart'; abstract class RenderObject with DiagnosticableTreeMixin implements HitTestTarget { /// Initializes internal fields for subclasses. RenderObject() { - if (kFlutterMemoryAllocationsEnabled) { - FlutterMemoryAllocations.instance.dispatchObjectCreated( - library: _flutterRenderingLibrary, - className: '$RenderObject', - object: this, - ); - } + assert(debugMaybeDispatchCreated('rendering', 'RenderObject', this)); _needsCompositing = isRepaintBoundary || alwaysNeedsCompositing; _wasRepaintBoundary = isRepaintBoundary; } @@ -1861,9 +1829,7 @@ abstract class RenderObject with DiagnosticableTreeMixin implements HitTestTarge @mustCallSuper void dispose() { assert(!_debugDisposed); - if (kFlutterMemoryAllocationsEnabled) { - FlutterMemoryAllocations.instance.dispatchObjectDisposed(object: this); - } + assert(debugMaybeDispatchDisposed(this)); _layerHandle.layer = null; assert(() { // TODO(dnfield): Enable this assert once clients have had a chance to diff --git a/packages/flutter/lib/src/scheduler/binding.dart b/packages/flutter/lib/src/scheduler/binding.dart index d28e747dbf..0bf3d0cb2c 100644 --- a/packages/flutter/lib/src/scheduler/binding.dart +++ b/packages/flutter/lib/src/scheduler/binding.dart @@ -212,15 +212,7 @@ typedef _PerformanceModeCleanupCallback = VoidCallback; /// The component that makes the request is responsible for disposing the handle. class PerformanceModeRequestHandle { PerformanceModeRequestHandle._(_PerformanceModeCleanupCallback this._cleanup) { - // TODO(polina-c): stop duplicating code across disposables - // https://github.com/flutter/flutter/issues/137435 - if (kFlutterMemoryAllocationsEnabled) { - FlutterMemoryAllocations.instance.dispatchObjectCreated( - library: 'package:flutter/scheduler.dart', - className: '$PerformanceModeRequestHandle', - object: this, - ); - } + assert(debugMaybeDispatchCreated('scheduler', 'PerformanceModeRequestHandle', this)); } _PerformanceModeCleanupCallback? _cleanup; @@ -231,11 +223,7 @@ class PerformanceModeRequestHandle { /// This method must only be called once per object. void dispose() { assert(_cleanup != null); - // TODO(polina-c): stop duplicating code across disposables - // https://github.com/flutter/flutter/issues/137435 - if (kFlutterMemoryAllocationsEnabled) { - FlutterMemoryAllocations.instance.dispatchObjectDisposed(object: this); - } + assert(debugMaybeDispatchDisposed(this)); _cleanup!(); _cleanup = null; } diff --git a/packages/flutter/lib/src/scheduler/ticker.dart b/packages/flutter/lib/src/scheduler/ticker.dart index dfe8090ca1..b088dab795 100644 --- a/packages/flutter/lib/src/scheduler/ticker.dart +++ b/packages/flutter/lib/src/scheduler/ticker.dart @@ -86,15 +86,7 @@ class Ticker { _debugCreationStack = StackTrace.current; return true; }()); - // TODO(polina-c): stop duplicating code across disposables - // https://github.com/flutter/flutter/issues/137435 - if (kFlutterMemoryAllocationsEnabled) { - FlutterMemoryAllocations.instance.dispatchObjectCreated( - library: 'package:flutter/scheduler.dart', - className: '$Ticker', - object: this, - ); - } + assert(debugMaybeDispatchCreated('scheduler', 'Ticker', this)); } TickerFuture? _future; @@ -354,12 +346,7 @@ class Ticker { /// with a [TickerCanceled] error. @mustCallSuper void dispose() { - // TODO(polina-c): stop duplicating code across disposables - // https://github.com/flutter/flutter/issues/137435 - if (kFlutterMemoryAllocationsEnabled) { - FlutterMemoryAllocations.instance.dispatchObjectDisposed(object: this); - } - + assert(debugMaybeDispatchDisposed(this)); if (_future != null) { final TickerFuture localFuture = _future!; _future = null; diff --git a/packages/flutter/lib/src/semantics/binding.dart b/packages/flutter/lib/src/semantics/binding.dart index a7c9f186e9..e09ab65384 100644 --- a/packages/flutter/lib/src/semantics/binding.dart +++ b/packages/flutter/lib/src/semantics/binding.dart @@ -227,15 +227,7 @@ mixin SemanticsBinding on BindingBase { /// To obtain a [SemanticsHandle], call [SemanticsBinding.ensureSemantics]. class SemanticsHandle { SemanticsHandle._(this._onDispose) { - // TODO(polina-c): stop duplicating code across disposables - // https://github.com/flutter/flutter/issues/137435 - if (kFlutterMemoryAllocationsEnabled) { - FlutterMemoryAllocations.instance.dispatchObjectCreated( - library: 'package:flutter/semantics.dart', - className: '$SemanticsHandle', - object: this, - ); - } + assert(debugMaybeDispatchCreated('semantics', 'SemanticsHandle', this)); } final VoidCallback _onDispose; @@ -246,12 +238,7 @@ class SemanticsHandle { /// framework will stop generating semantics information. @mustCallSuper void dispose() { - // TODO(polina-c): stop duplicating code across disposables - // https://github.com/flutter/flutter/issues/137435 - if (kFlutterMemoryAllocationsEnabled) { - FlutterMemoryAllocations.instance.dispatchObjectDisposed(object: this); - } - + assert(debugMaybeDispatchDisposed(this)); _onDispose(); } } diff --git a/packages/flutter/lib/src/semantics/semantics.dart b/packages/flutter/lib/src/semantics/semantics.dart index e4d3117968..75e898c61e 100644 --- a/packages/flutter/lib/src/semantics/semantics.dart +++ b/packages/flutter/lib/src/semantics/semantics.dart @@ -3761,15 +3761,7 @@ class _TraversalSortNode implements Comparable<_TraversalSortNode> { class SemanticsOwner extends ChangeNotifier { /// Creates a [SemanticsOwner] that manages zero or more [SemanticsNode] objects. SemanticsOwner({required this.onSemanticsUpdate}) { - // TODO(polina-c): stop duplicating code across disposables - // https://github.com/flutter/flutter/issues/137435 - if (kFlutterMemoryAllocationsEnabled) { - FlutterMemoryAllocations.instance.dispatchObjectCreated( - library: 'package:flutter/semantics.dart', - className: '$SemanticsOwner', - object: this, - ); - } + assert(debugMaybeDispatchCreated('semantics', 'SemanticsOwner', this)); } /// The [onSemanticsUpdate] callback is expected to dispatch [SemanticsUpdate]s @@ -3791,9 +3783,7 @@ class SemanticsOwner extends ChangeNotifier { @override void dispose() { - if (kFlutterMemoryAllocationsEnabled) { - FlutterMemoryAllocations.instance.dispatchObjectDisposed(object: this); - } + assert(debugMaybeDispatchDisposed(this)); _dirtyNodes.clear(); _nodes.clear(); _detachedNodes.clear(); diff --git a/packages/flutter/lib/src/services/restoration.dart b/packages/flutter/lib/src/services/restoration.dart index cc7f1671ad..1716a2f8a5 100644 --- a/packages/flutter/lib/src/services/restoration.dart +++ b/packages/flutter/lib/src/services/restoration.dart @@ -518,9 +518,7 @@ class RestorationBucket { _debugOwner = debugOwner; return true; }()); - if (kFlutterMemoryAllocationsEnabled) { - _maybeDispatchObjectCreation(); - } + assert(debugMaybeDispatchCreated('services', 'RestorationBucket', this)); } /// Creates the root [RestorationBucket] for the provided restoration @@ -554,9 +552,7 @@ class RestorationBucket { _debugOwner = manager; return true; }()); - if (kFlutterMemoryAllocationsEnabled) { - _maybeDispatchObjectCreation(); - } + assert(debugMaybeDispatchCreated('services', 'RestorationBucket', this)); } /// Creates a child bucket initialized with the data that the provided @@ -580,9 +576,7 @@ class RestorationBucket { _debugOwner = debugOwner; return true; }()); - if (kFlutterMemoryAllocationsEnabled) { - _maybeDispatchObjectCreation(); - } + assert(debugMaybeDispatchCreated('services', 'RestorationBucket', this)); } static const String _childrenMapKey = 'c'; @@ -961,19 +955,6 @@ class RestorationBucket { _parent?._addChildData(this); } - // TODO(polina-c): stop duplicating code across disposables - // https://github.com/flutter/flutter/issues/137435 - /// Dispatches event of object creation to [FlutterMemoryAllocations.instance]. - void _maybeDispatchObjectCreation() { - if (kFlutterMemoryAllocationsEnabled) { - FlutterMemoryAllocations.instance.dispatchObjectCreated( - library: 'package:flutter/services.dart', - className: '$RestorationBucket', - object: this, - ); - } - } - /// Deletes the bucket and all the data stored in it from the bucket /// hierarchy. /// @@ -988,11 +969,7 @@ class RestorationBucket { /// This method must only be called by the object's owner. void dispose() { assert(_debugAssertNotDisposed()); - // TODO(polina-c): stop duplicating code across disposables - // https://github.com/flutter/flutter/issues/137435 - if (kFlutterMemoryAllocationsEnabled) { - FlutterMemoryAllocations.instance.dispatchObjectDisposed(object: this); - } + assert(debugMaybeDispatchDisposed(this)); _visitChildren(_dropChild, concurrentModification: true); _claimedChildren.clear(); _childrenToAdd.clear(); diff --git a/packages/flutter/lib/src/widgets/app_lifecycle_listener.dart b/packages/flutter/lib/src/widgets/app_lifecycle_listener.dart index 72be1e49a2..5622dab2f7 100644 --- a/packages/flutter/lib/src/widgets/app_lifecycle_listener.dart +++ b/packages/flutter/lib/src/widgets/app_lifecycle_listener.dart @@ -76,15 +76,7 @@ class AppLifecycleListener with WidgetsBindingObserver, Diagnosticable { this.onStateChange, }) : binding = binding ?? WidgetsBinding.instance, _lifecycleState = (binding ?? WidgetsBinding.instance).lifecycleState { - // TODO(polina-c): stop duplicating code across disposables - // https://github.com/flutter/flutter/issues/137435 - if (kFlutterMemoryAllocationsEnabled) { - FlutterMemoryAllocations.instance.dispatchObjectCreated( - library: 'package:flutter/widgets.dart', - className: '$AppLifecycleListener', - object: this, - ); - } + assert(debugMaybeDispatchCreated('widgets', 'AppLifecycleListener', this)); this.binding.addObserver(this); } @@ -186,11 +178,7 @@ class AppLifecycleListener with WidgetsBindingObserver, Diagnosticable { @mustCallSuper void dispose() { assert(_debugAssertNotDisposed()); - // TODO(polina-c): stop duplicating code across disposables - // https://github.com/flutter/flutter/issues/137435 - if (kFlutterMemoryAllocationsEnabled) { - FlutterMemoryAllocations.instance.dispatchObjectDisposed(object: this); - } + assert(debugMaybeDispatchDisposed(this)); binding.removeObserver(this); assert(() { _debugDisposed = true; diff --git a/packages/flutter/lib/src/widgets/banner.dart b/packages/flutter/lib/src/widgets/banner.dart index a98ff263ac..dcc483ee39 100644 --- a/packages/flutter/lib/src/widgets/banner.dart +++ b/packages/flutter/lib/src/widgets/banner.dart @@ -29,8 +29,6 @@ const TextStyle _kTextStyle = TextStyle( height: 1.0, ); -const String _flutterWidgetsLibrary = 'package:flutter/widgets.dart'; - /// Where to show a [Banner]. /// /// The start and end locations are relative to the ambient [Directionality] @@ -71,15 +69,7 @@ class BannerPainter extends CustomPainter { this.textStyle = _kTextStyle, this.shadow = _kShadow, }) : super(repaint: PaintingBinding.instance.systemFonts) { - // TODO(polina-c): stop duplicating code across disposables - // https://github.com/flutter/flutter/issues/137435 - if (kFlutterMemoryAllocationsEnabled) { - FlutterMemoryAllocations.instance.dispatchObjectCreated( - library: _flutterWidgetsLibrary, - className: '$BannerPainter', - object: this, - ); - } + assert(debugMaybeDispatchCreated('widgets', 'BannerPainter', this)); } /// The message to show in the banner. @@ -138,11 +128,7 @@ class BannerPainter extends CustomPainter { /// /// After calling this method, this object is no longer usable. void dispose() { - // TODO(polina-c): stop duplicating code across disposables - // https://github.com/flutter/flutter/issues/137435 - if (kFlutterMemoryAllocationsEnabled) { - FlutterMemoryAllocations.instance.dispatchObjectDisposed(object: this); - } + assert(debugMaybeDispatchDisposed(this)); _textPainter?.dispose(); _textPainter = null; } diff --git a/packages/flutter/lib/src/widgets/disposable_build_context.dart b/packages/flutter/lib/src/widgets/disposable_build_context.dart index 03bf402086..7647674747 100644 --- a/packages/flutter/lib/src/widgets/disposable_build_context.dart +++ b/packages/flutter/lib/src/widgets/disposable_build_context.dart @@ -34,15 +34,7 @@ class DisposableBuildContext { _state.mounted, 'A DisposableBuildContext was given a BuildContext for an Element that is not mounted.', ) { - // TODO(polina-c): stop duplicating code across disposables - // https://github.com/flutter/flutter/issues/137435 - if (kFlutterMemoryAllocationsEnabled) { - FlutterMemoryAllocations.instance.dispatchObjectCreated( - library: 'package:flutter/widgets.dart', - className: '$DisposableBuildContext', - object: this, - ); - } + assert(debugMaybeDispatchCreated('widgets', 'DisposableBuildContext', this)); } T? _state; @@ -77,11 +69,7 @@ class DisposableBuildContext { /// Creators of this object must call [dispose] when their [Element] is /// unmounted, i.e. when [State.dispose] is called. void dispose() { - // TODO(polina-c): stop duplicating code across disposables - // https://github.com/flutter/flutter/issues/137435 - if (kFlutterMemoryAllocationsEnabled) { - FlutterMemoryAllocations.instance.dispatchObjectDisposed(object: this); - } + assert(debugMaybeDispatchDisposed(this)); _state = null; } } diff --git a/packages/flutter/lib/src/widgets/draggable_scrollable_sheet.dart b/packages/flutter/lib/src/widgets/draggable_scrollable_sheet.dart index 4687743a5a..4110266db9 100644 --- a/packages/flutter/lib/src/widgets/draggable_scrollable_sheet.dart +++ b/packages/flutter/lib/src/widgets/draggable_scrollable_sheet.dart @@ -510,15 +510,7 @@ class _DraggableSheetExtent { availablePixels = double.infinity, hasDragged = hasDragged ?? false, hasChanged = hasChanged ?? false { - // TODO(polina-c): stop duplicating code across disposables - // https://github.com/flutter/flutter/issues/137435 - if (kFlutterMemoryAllocationsEnabled) { - FlutterMemoryAllocations.instance.dispatchObjectCreated( - library: 'package:flutter/widgets.dart', - className: '$_DraggableSheetExtent', - object: this, - ); - } + assert(debugMaybeDispatchCreated('widgets', '_DraggableSheetExtent', this)); } VoidCallback? _cancelActivity; @@ -615,9 +607,7 @@ class _DraggableSheetExtent { } void dispose() { - if (kFlutterMemoryAllocationsEnabled) { - FlutterMemoryAllocations.instance.dispatchObjectDisposed(object: this); - } + assert(debugMaybeDispatchDisposed(this)); _currentSize.dispose(); } diff --git a/packages/flutter/lib/src/widgets/focus_manager.dart b/packages/flutter/lib/src/widgets/focus_manager.dart index 8fb574db3f..5d337f9ecd 100644 --- a/packages/flutter/lib/src/widgets/focus_manager.dart +++ b/packages/flutter/lib/src/widgets/focus_manager.dart @@ -2062,15 +2062,7 @@ class FocusManager with DiagnosticableTreeMixin, ChangeNotifier { // value, and ChangeNotifier requires using VoidCallback. class _HighlightModeManager { _HighlightModeManager() { - // TODO(polina-c): stop duplicating code across disposables - // https://github.com/flutter/flutter/issues/137435 - if (kFlutterMemoryAllocationsEnabled) { - FlutterMemoryAllocations.instance.dispatchObjectCreated( - library: 'package:flutter/widgets.dart', - className: '$_HighlightModeManager', - object: this, - ); - } + assert(debugMaybeDispatchCreated('widgets', '_HighlightModeManager', this)); } // If null, no interactions have occurred yet and the default highlight mode for the current @@ -2136,9 +2128,7 @@ class _HighlightModeManager { @mustCallSuper void dispose() { - if (kFlutterMemoryAllocationsEnabled) { - FlutterMemoryAllocations.instance.dispatchObjectDisposed(object: this); - } + assert(debugMaybeDispatchDisposed(this)); if (ServicesBinding.instance.keyEventManager.keyMessageHandler == handleKeyMessage) { GestureBinding.instance.pointerRouter.removeGlobalRoute(handlePointerEvent); ServicesBinding.instance.keyEventManager.keyMessageHandler = null; diff --git a/packages/flutter/lib/src/widgets/framework.dart b/packages/flutter/lib/src/widgets/framework.dart index 7b1af3d45c..8e85b267ef 100644 --- a/packages/flutter/lib/src/widgets/framework.dart +++ b/packages/flutter/lib/src/widgets/framework.dart @@ -822,8 +822,6 @@ enum _StateLifecycle { /// The signature of [State.setState] functions. typedef StateSetter = void Function(VoidCallback fn); -const String _flutterWidgetsLibrary = 'package:flutter/widgets.dart'; - /// The logic and internal state for a [StatefulWidget]. /// /// State is information that (1) can be read synchronously when the widget is @@ -1009,13 +1007,7 @@ abstract class State with Diagnosticable { @mustCallSuper void initState() { assert(_debugLifecycleState == _StateLifecycle.created); - if (kFlutterMemoryAllocationsEnabled) { - FlutterMemoryAllocations.instance.dispatchObjectCreated( - library: _flutterWidgetsLibrary, - className: '$State', - object: this, - ); - } + assert(debugMaybeDispatchCreated('widgets', 'State', this)); } /// Called whenever the widget configuration changes. @@ -1345,9 +1337,7 @@ abstract class State with Diagnosticable { _debugLifecycleState = _StateLifecycle.defunct; return true; }()); - if (kFlutterMemoryAllocationsEnabled) { - FlutterMemoryAllocations.instance.dispatchObjectDisposed(object: this); - } + assert(debugMaybeDispatchDisposed(this)); } /// Describes the part of the user interface represented by this widget. @@ -3513,13 +3503,7 @@ abstract class Element extends DiagnosticableTree implements BuildContext { /// /// Typically called by an override of [Widget.createElement]. Element(Widget widget) : _widget = widget { - if (kFlutterMemoryAllocationsEnabled) { - FlutterMemoryAllocations.instance.dispatchObjectCreated( - library: _flutterWidgetsLibrary, - className: '$Element', - object: this, - ); - } + assert(debugMaybeDispatchCreated('widgets', 'Element', this)); } Element? _parent; @@ -4764,9 +4748,7 @@ abstract class Element extends DiagnosticableTree implements BuildContext { assert(_lifecycleState == _ElementLifecycle.inactive); assert(_widget != null); // Use the private property to avoid a CastError during hot reload. assert(owner != null); - if (kFlutterMemoryAllocationsEnabled) { - FlutterMemoryAllocations.instance.dispatchObjectDisposed(object: this); - } + assert(debugMaybeDispatchDisposed(this)); // Use the private property to avoid a CastError during hot reload. final Key? key = _widget?.key; if (key is GlobalKey) { diff --git a/packages/flutter/lib/src/widgets/heroes.dart b/packages/flutter/lib/src/widgets/heroes.dart index 4c4f11484f..2027a28208 100644 --- a/packages/flutter/lib/src/widgets/heroes.dart +++ b/packages/flutter/lib/src/widgets/heroes.dart @@ -518,15 +518,7 @@ class _HeroFlightManifest { // Builds the in-flight hero widget. class _HeroFlight { _HeroFlight(this.onFlightEnded) { - // TODO(polina-c): stop duplicating code across disposables - // https://github.com/flutter/flutter/issues/137435 - if (kFlutterMemoryAllocationsEnabled) { - FlutterMemoryAllocations.instance.dispatchObjectCreated( - library: 'package:flutter/widgets.dart', - className: '$_HeroFlight', - object: this, - ); - } + assert(debugMaybeDispatchCreated('widgets', '_HeroFlight', this)); _proxyAnimation = ProxyAnimation()..addStatusListener(_handleAnimationUpdate); } @@ -633,9 +625,7 @@ class _HeroFlight { /// Releases resources. @mustCallSuper void dispose() { - if (kFlutterMemoryAllocationsEnabled) { - FlutterMemoryAllocations.instance.dispatchObjectDisposed(object: this); - } + assert(debugMaybeDispatchDisposed(this)); if (overlayEntry != null) { overlayEntry!.remove(); overlayEntry!.dispose(); @@ -824,15 +814,7 @@ class HeroController extends NavigatorObserver { /// The [createRectTween] argument is optional. If null, the controller uses a /// linear [Tween]. HeroController({this.createRectTween}) { - // TODO(polina-c): stop duplicating code across disposables - // https://github.com/flutter/flutter/issues/137435 - if (kFlutterMemoryAllocationsEnabled) { - FlutterMemoryAllocations.instance.dispatchObjectCreated( - library: 'package:flutter/widgets.dart', - className: '$HeroController', - object: this, - ); - } + assert(debugMaybeDispatchCreated('widgets', 'HeroController', this)); } /// Used to create [RectTween]s that interpolate the position of heroes in flight. @@ -1106,12 +1088,7 @@ class HeroController extends NavigatorObserver { /// Releases resources. @mustCallSuper void dispose() { - // TODO(polina-c): stop duplicating code across disposables - // https://github.com/flutter/flutter/issues/137435 - if (kFlutterMemoryAllocationsEnabled) { - FlutterMemoryAllocations.instance.dispatchObjectDisposed(object: this); - } - + assert(debugMaybeDispatchDisposed(this)); for (final _HeroFlight flight in _flights.values) { flight.dispose(); } diff --git a/packages/flutter/lib/src/widgets/navigator.dart b/packages/flutter/lib/src/widgets/navigator.dart index ad36987072..cb38a83f97 100644 --- a/packages/flutter/lib/src/widgets/navigator.dart +++ b/packages/flutter/lib/src/widgets/navigator.dart @@ -171,13 +171,7 @@ abstract class Route extends _RoutePlaceholder { Route({RouteSettings? settings, bool? requestFocus}) : _settings = settings ?? const RouteSettings(), _requestFocus = requestFocus { - if (kFlutterMemoryAllocationsEnabled) { - FlutterMemoryAllocations.instance.dispatchObjectCreated( - library: 'package:flutter/widgets.dart', - className: '$Route<$T>', - object: this, - ); - } + assert(debugMaybeDispatchCreated('widgets', 'Route', this)); } /// When the route state is updated, request focus if the current route is at the top. @@ -578,9 +572,7 @@ abstract class Route extends _RoutePlaceholder { _navigator = null; _restorationScopeId.dispose(); _disposeCompleter.complete(); - if (kFlutterMemoryAllocationsEnabled) { - FlutterMemoryAllocations.instance.dispatchObjectDisposed(object: this); - } + assert(debugMaybeDispatchDisposed(this)); } /// Whether this route is the top-most route on the navigator. @@ -3149,15 +3141,7 @@ class _RouteEntry extends RouteTransitionRecord { initialState == _RouteLifecycle.replace, ), currentState = initialState { - // TODO(polina-c): stop duplicating code across disposables - // https://github.com/flutter/flutter/issues/137435 - if (kFlutterMemoryAllocationsEnabled) { - FlutterMemoryAllocations.instance.dispatchObjectCreated( - library: 'package:flutter/widgets.dart', - className: '$_RouteEntry', - object: this, - ); - } + assert(debugMaybeDispatchCreated('widgets', '_RouteEntry', this)); } @override @@ -3395,11 +3379,7 @@ class _RouteEntry extends RouteTransitionRecord { /// before disposing. void forcedDispose() { assert(currentState.index < _RouteLifecycle.disposed.index); - // TODO(polina-c): stop duplicating code across disposables - // https://github.com/flutter/flutter/issues/137435 - if (kFlutterMemoryAllocationsEnabled) { - FlutterMemoryAllocations.instance.dispatchObjectDisposed(object: this); - } + assert(debugMaybeDispatchDisposed(this)); currentState = _RouteLifecycle.disposed; route.dispose(); } diff --git a/packages/flutter/lib/src/widgets/nested_scroll_view.dart b/packages/flutter/lib/src/widgets/nested_scroll_view.dart index 357e274323..c5c95ffa78 100644 --- a/packages/flutter/lib/src/widgets/nested_scroll_view.dart +++ b/packages/flutter/lib/src/widgets/nested_scroll_view.dart @@ -618,15 +618,7 @@ class _NestedScrollCoordinator implements ScrollActivityDelegate, ScrollHoldCont this._onHasScrolledBodyChanged, this._floatHeaderSlivers, ) { - // TODO(polina-c): stop duplicating code across disposables - // https://github.com/flutter/flutter/issues/137435 - if (kFlutterMemoryAllocationsEnabled) { - FlutterMemoryAllocations.instance.dispatchObjectCreated( - library: 'package:flutter/widgets.dart', - className: '$_NestedScrollCoordinator', - object: this, - ); - } + assert(debugMaybeDispatchCreated('widgets', '_NestedScrollCoordinator', this)); final double initialScrollOffset = _parent?.initialScrollOffset ?? 0.0; _outerController = _NestedScrollController( this, @@ -1136,9 +1128,7 @@ class _NestedScrollCoordinator implements ScrollActivityDelegate, ScrollHoldCont @mustCallSuper void dispose() { - if (kFlutterMemoryAllocationsEnabled) { - FlutterMemoryAllocations.instance.dispatchObjectDisposed(object: this); - } + assert(debugMaybeDispatchDisposed(this)); _currentDrag?.dispose(); _currentDrag = null; _outerController.dispose(); diff --git a/packages/flutter/lib/src/widgets/overlay.dart b/packages/flutter/lib/src/widgets/overlay.dart index fbac6338ed..805947f26d 100644 --- a/packages/flutter/lib/src/widgets/overlay.dart +++ b/packages/flutter/lib/src/widgets/overlay.dart @@ -27,8 +27,6 @@ import 'framework.dart'; import 'lookup_boundary.dart'; import 'ticker_provider.dart'; -const String _flutterWidgetsLibrary = 'package:flutter/widgets.dart'; - // Examples can assume: // late BuildContext context; @@ -98,9 +96,7 @@ class OverlayEntry implements Listenable { this.canSizeOverlay = false, }) : _opaque = opaque, _maintainState = maintainState { - if (kFlutterMemoryAllocationsEnabled) { - _maybeDispatchObjectCreation(); - } + assert(debugMaybeDispatchCreated('widgets', 'OverlayEntry', this)); } /// This entry will include the widget built by this builder in the overlay at @@ -180,19 +176,6 @@ class OverlayEntry implements Listenable { ValueNotifier<_OverlayEntryWidgetState?>? _overlayEntryStateNotifier = ValueNotifier<_OverlayEntryWidgetState?>(null); - // TODO(polina-c): stop duplicating code across disposables - // https://github.com/flutter/flutter/issues/137435 - /// Dispatches event of object creation to [FlutterMemoryAllocations.instance]. - void _maybeDispatchObjectCreation() { - if (kFlutterMemoryAllocationsEnabled) { - FlutterMemoryAllocations.instance.dispatchObjectCreated( - library: _flutterWidgetsLibrary, - className: '$OverlayEntry', - object: this, - ); - } - } - @override void addListener(VoidCallback listener) { assert(!_disposedByOwner); @@ -272,9 +255,7 @@ class OverlayEntry implements Listenable { _overlay == null, 'An OverlayEntry must first be removed from the Overlay before dispose is called.', ); - if (kFlutterMemoryAllocationsEnabled) { - FlutterMemoryAllocations.instance.dispatchObjectDisposed(object: this); - } + assert(debugMaybeDispatchDisposed(this)); _disposedByOwner = true; if (!mounted) { // If we're still mounted when disposed, then this will be disposed in diff --git a/packages/flutter/lib/src/widgets/reorderable_list.dart b/packages/flutter/lib/src/widgets/reorderable_list.dart index b1359507af..8fe60bf1f3 100644 --- a/packages/flutter/lib/src/widgets/reorderable_list.dart +++ b/packages/flutter/lib/src/widgets/reorderable_list.dart @@ -1398,15 +1398,7 @@ class _DragInfo extends Drag { this.proxyDecorator, required this.tickerProvider, }) { - // TODO(polina-c): stop duplicating code across disposables - // https://github.com/flutter/flutter/issues/137435 - if (kFlutterMemoryAllocationsEnabled) { - FlutterMemoryAllocations.instance.dispatchObjectCreated( - library: 'package:flutter/widgets.dart', - className: '$_DragInfo', - object: this, - ); - } + assert(debugMaybeDispatchCreated('widgets', '_DragInfo', this)); final RenderBox itemRenderBox = item.context.findRenderObject()! as RenderBox; listState = item._listState; index = item.index; @@ -1449,9 +1441,7 @@ class _DragInfo extends Drag { late Offset _rawDragPosition; void dispose() { - if (kFlutterMemoryAllocationsEnabled) { - FlutterMemoryAllocations.instance.dispatchObjectDisposed(object: this); - } + assert(debugMaybeDispatchDisposed(this)); _proxyAnimation?.dispose(); } diff --git a/packages/flutter/lib/src/widgets/scroll_activity.dart b/packages/flutter/lib/src/widgets/scroll_activity.dart index 13de2d51be..350c8af0b4 100644 --- a/packages/flutter/lib/src/widgets/scroll_activity.dart +++ b/packages/flutter/lib/src/widgets/scroll_activity.dart @@ -67,15 +67,7 @@ abstract class ScrollActivityDelegate { abstract class ScrollActivity { /// Initializes [delegate] for subclasses. ScrollActivity(this._delegate) { - // TODO(polina-c): stop duplicating code across disposables - // https://github.com/flutter/flutter/issues/137435 - if (kFlutterMemoryAllocationsEnabled) { - FlutterMemoryAllocations.instance.dispatchObjectCreated( - library: 'package:flutter/widgets.dart', - className: '$ScrollActivity', - object: this, - ); - } + assert(debugMaybeDispatchCreated('widgets', 'ScrollActivity', this)); } /// The delegate that this activity will use to actuate the scroll view. @@ -172,12 +164,7 @@ abstract class ScrollActivity { /// Called when the scroll view stops performing this activity. @mustCallSuper void dispose() { - // TODO(polina-c): stop duplicating code across disposables - // https://github.com/flutter/flutter/issues/137435 - if (kFlutterMemoryAllocationsEnabled) { - FlutterMemoryAllocations.instance.dispatchObjectDisposed(object: this); - } - + assert(debugMaybeDispatchDisposed(this)); _isDisposed = true; } @@ -285,15 +272,7 @@ class ScrollDragController implements Drag { _lastNonStationaryTimestamp = details.sourceTimeStamp, _kind = details.kind, _offsetSinceLastStop = motionStartDistanceThreshold == null ? null : 0.0 { - // TODO(polina-c): stop duplicating code across disposables - // https://github.com/flutter/flutter/issues/137435 - if (kFlutterMemoryAllocationsEnabled) { - FlutterMemoryAllocations.instance.dispatchObjectCreated( - library: 'package:flutter/widgets.dart', - className: '$ScrollDragController', - object: this, - ); - } + assert(debugMaybeDispatchCreated('widgets', 'ScrollDragController', this)); } /// The object that will actuate the scroll view as the user drags. @@ -470,11 +449,7 @@ class ScrollDragController implements Drag { /// Called by the delegate when it is no longer sending events to this object. @mustCallSuper void dispose() { - // TODO(polina-c): stop duplicating code across disposables - // https://github.com/flutter/flutter/issues/137435 - if (kFlutterMemoryAllocationsEnabled) { - FlutterMemoryAllocations.instance.dispatchObjectDisposed(object: this); - } + assert(debugMaybeDispatchDisposed(this)); _lastDetails = null; onDragCanceled?.call(); } diff --git a/packages/flutter/lib/src/widgets/text_selection.dart b/packages/flutter/lib/src/widgets/text_selection.dart index db1bb2da6e..1703359c72 100644 --- a/packages/flutter/lib/src/widgets/text_selection.dart +++ b/packages/flutter/lib/src/widgets/text_selection.dart @@ -348,15 +348,7 @@ class TextSelectionOverlay { required TextMagnifierConfiguration magnifierConfiguration, }) : _handlesVisible = handlesVisible, _value = value { - // TODO(polina-c): stop duplicating code across disposables - // https://github.com/flutter/flutter/issues/137435 - if (kFlutterMemoryAllocationsEnabled) { - FlutterMemoryAllocations.instance.dispatchObjectCreated( - library: 'package:flutter/widgets.dart', - className: '$TextSelectionOverlay', - object: this, - ); - } + assert(debugMaybeDispatchCreated('widgets', 'TextSelectionOverlay', this)); renderObject.selectionStartInViewport.addListener(_updateTextSelectionOverlayVisibilities); renderObject.selectionEndInViewport.addListener(_updateTextSelectionOverlayVisibilities); _updateTextSelectionOverlayVisibilities(); @@ -607,11 +599,7 @@ class TextSelectionOverlay { /// {@macro flutter.widgets.SelectionOverlay.dispose} void dispose() { - // TODO(polina-c): stop duplicating code across disposables - // https://github.com/flutter/flutter/issues/137435 - if (kFlutterMemoryAllocationsEnabled) { - FlutterMemoryAllocations.instance.dispatchObjectDisposed(object: this); - } + assert(debugMaybeDispatchDisposed(this)); _selectionOverlay.dispose(); renderObject.selectionStartInViewport.removeListener(_updateTextSelectionOverlayVisibilities); renderObject.selectionEndInViewport.removeListener(_updateTextSelectionOverlayVisibilities); @@ -1050,15 +1038,7 @@ class SelectionOverlay { _selectionEndpoints = selectionEndpoints, _toolbarLocation = toolbarLocation, assert(debugCheckHasOverlay(context)) { - // TODO(polina-c): stop duplicating code across disposables - // https://github.com/flutter/flutter/issues/137435 - if (kFlutterMemoryAllocationsEnabled) { - FlutterMemoryAllocations.instance.dispatchObjectCreated( - library: 'package:flutter/widgets.dart', - className: '$SelectionOverlay', - object: this, - ); - } + assert(debugMaybeDispatchCreated('widgets', 'SelectionOverlay', this)); } /// {@macro flutter.widgets.SelectionOverlay.context} @@ -1619,11 +1599,7 @@ class SelectionOverlay { /// Disposes this object and release resources. /// {@endtemplate} void dispose() { - // TODO(polina-c): stop duplicating code across disposables - // https://github.com/flutter/flutter/issues/137435 - if (kFlutterMemoryAllocationsEnabled) { - FlutterMemoryAllocations.instance.dispatchObjectDisposed(object: this); - } + assert(debugMaybeDispatchDisposed(this)); hide(); _magnifierInfo.dispose(); } diff --git a/packages/flutter/lib/src/widgets/widget_inspector.dart b/packages/flutter/lib/src/widgets/widget_inspector.dart index d4fd4c2eb2..9270c9091f 100644 --- a/packages/flutter/lib/src/widgets/widget_inspector.dart +++ b/packages/flutter/lib/src/widgets/widget_inspector.dart @@ -357,15 +357,7 @@ class _ScreenshotContainerLayer extends OffsetLayer { /// a screenshot. class _ScreenshotData { _ScreenshotData({required this.target}) : containerLayer = _ScreenshotContainerLayer() { - // TODO(polina-c): stop duplicating code across disposables - // https://github.com/flutter/flutter/issues/137435 - if (kFlutterMemoryAllocationsEnabled) { - FlutterMemoryAllocations.instance.dispatchObjectCreated( - library: 'package:flutter/widgets.dart', - className: '$_ScreenshotData', - object: this, - ); - } + assert(debugMaybeDispatchCreated('widgets', '_ScreenshotData', this)); } /// Target to take a screenshot of. @@ -407,9 +399,7 @@ class _ScreenshotData { /// Releases allocated resources. @mustCallSuper void dispose() { - if (kFlutterMemoryAllocationsEnabled) { - FlutterMemoryAllocations.instance.dispatchObjectDisposed(object: this); - } + assert(debugMaybeDispatchDisposed(this)); containerLayer.dispose(); } }