migrate scheduler to nullsafety (#61570)
diff --git a/packages/flutter/lib/scheduler.dart b/packages/flutter/lib/scheduler.dart index 2652ea3..f1cbdc2 100644 --- a/packages/flutter/lib/scheduler.dart +++ b/packages/flutter/lib/scheduler.dart
@@ -2,8 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// @dart = 2.8 - /// The Flutter Scheduler library. /// /// To use, import `package:flutter/scheduler.dart`.
diff --git a/packages/flutter/lib/src/scheduler/binding.dart b/packages/flutter/lib/src/scheduler/binding.dart index cbcbbdc..0d7ec55 100644 --- a/packages/flutter/lib/src/scheduler/binding.dart +++ b/packages/flutter/lib/src/scheduler/binding.dart
@@ -2,8 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// @dart = 2.8 - import 'dart:async'; import 'dart:collection'; import 'dart:developer' show Flow, Timeline; @@ -57,7 +55,7 @@ /// See also: /// /// * [defaultSchedulingStrategy], the default [SchedulingStrategy] for [SchedulerBinding.schedulingStrategy]. -typedef SchedulingStrategy = bool Function({ int priority, SchedulerBinding scheduler }); +typedef SchedulingStrategy = bool Function({ required int priority, required SchedulerBinding scheduler }); class _TaskEntry<T> { _TaskEntry(this.task, this.priority, this.debugLabel, this.flow) { @@ -65,15 +63,14 @@ debugStack = StackTrace.current; return true; }()); - completer = Completer<T>(); } final TaskCallback<T> task; final int priority; - final String debugLabel; - final Flow flow; + final String? debugLabel; + final Flow? flow; - StackTrace debugStack; - Completer<T> completer; + late StackTrace debugStack; + final Completer<T> completer = Completer<T>(); void run() { if (!kReleaseMode) { @@ -82,7 +79,7 @@ () { completer.complete(task()); }, - flow: flow != null ? Flow.step(flow.id) : null, + flow: flow != null ? Flow.step(flow!.id) : null, ); } else { completer.complete(task()); @@ -123,8 +120,8 @@ final FrameCallback callback; - static StackTrace debugCurrentCallbackStack; - StackTrace debugStack; + static StackTrace? debugCurrentCallbackStack; + StackTrace? debugStack; } /// The various phases that a [SchedulerBinding] goes through during @@ -292,7 +289,7 @@ callback(timings); } } catch (exception, stack) { - InformationCollector collector; + InformationCollector? collector; assert(() { collector = () sync* { yield DiagnosticsProperty<TimingsCallback>( @@ -314,8 +311,8 @@ } /// The current [SchedulerBinding], if one has been created. - static SchedulerBinding get instance => _instance; - static SchedulerBinding _instance; + static SchedulerBinding? get instance => _instance; + static SchedulerBinding? _instance; @override void initServiceExtensions() { @@ -340,8 +337,8 @@ /// /// The preferred way to watch for changes to this value is using /// [WidgetsBindingObserver.didChangeAppLifecycleState]. - AppLifecycleState get lifecycleState => _lifecycleState; - AppLifecycleState _lifecycleState; + AppLifecycleState? get lifecycleState => _lifecycleState; + AppLifecycleState? _lifecycleState; /// Called when the application lifecycle state changes. /// @@ -398,8 +395,8 @@ Future<T> scheduleTask<T>( TaskCallback<T> task, Priority priority, { - String debugLabel, - Flow flow, + String? debugLabel, + Flow? flow, }) { final bool isFirstTask = _taskQueue.isEmpty; final _TaskEntry<T> entry = _TaskEntry<T>( @@ -462,7 +459,7 @@ _taskQueue.removeFirst(); entry.run(); } catch (exception, exceptionStack) { - StackTrace callbackStack; + StackTrace? callbackStack; assert(() { callbackStack = entry.debugStack; return true; @@ -585,7 +582,7 @@ ); } for (final int id in callbacks.keys) { - final _FrameCallbackEntry entry = callbacks[id]; + final _FrameCallbackEntry entry = callbacks[id]!; yield DiagnosticsStackTrace('── callback $id ──', entry.debugStack, showSeparator: false); } }, @@ -622,7 +619,7 @@ debugPrint( FlutterError.defaultStackFilter( FlutterError.demangleStackTrace( - _FrameCallbackEntry.debugCurrentCallbackStack, + _FrameCallbackEntry.debugCurrentCallbackStack!, ).toString().trimRight().split('\n') ).join('\n') ); @@ -677,7 +674,7 @@ _postFrameCallbacks.add(callback); } - Completer<void> _nextFrameCompleter; + Completer<void>? _nextFrameCompleter; /// Returns a Future that completes after the frame completes. /// @@ -694,11 +691,11 @@ scheduleFrame(); _nextFrameCompleter = Completer<void>(); addPostFrameCallback((Duration timeStamp) { - _nextFrameCompleter.complete(); + _nextFrameCompleter!.complete(); _nextFrameCompleter = null; }); } - return _nextFrameCompleter.future; + return _nextFrameCompleter!.future; } /// Whether this scheduler has requested that [handleBeginFrame] be called soon. @@ -885,7 +882,7 @@ }); } - Duration _firstRawTimeStampInEpoch; + Duration? _firstRawTimeStampInEpoch; Duration _epochStart = Duration.zero; Duration _lastRawTimeStamp = Duration.zero; @@ -920,7 +917,7 @@ /// These mechanisms together combine to ensure that the durations we give /// during frame callbacks are monotonically increasing. Duration _adjustForEpoch(Duration rawTimeStamp) { - final Duration rawDurationSinceEpoch = _firstRawTimeStampInEpoch == null ? Duration.zero : rawTimeStamp - _firstRawTimeStampInEpoch; + final Duration rawDurationSinceEpoch = _firstRawTimeStampInEpoch == null ? Duration.zero : rawTimeStamp - _firstRawTimeStampInEpoch!; return Duration(microseconds: (rawDurationSinceEpoch.inMicroseconds / timeDilation).round() + _epochStart.inMicroseconds); } @@ -931,9 +928,9 @@ /// produced. Duration get currentFrameTimeStamp { assert(_currentFrameTimeStamp != null); - return _currentFrameTimeStamp; + return _currentFrameTimeStamp!; } - Duration _currentFrameTimeStamp; + Duration? _currentFrameTimeStamp; /// The raw time stamp as provided by the engine to [Window.onBeginFrame] /// for the frame currently being processed. @@ -952,7 +949,7 @@ } int _debugFrameNumber = 0; - String _debugBanner; + String? _debugBanner; bool _ignoreNextEngineDrawFrame = false; void _handleBeginFrame(Duration rawTimeStamp) { @@ -995,7 +992,7 @@ /// [debugPrintEndFrameBanner] to true. This allows you to distinguish log /// statements printed during a frame from those printed between frames (e.g. /// in response to events or timers). - void handleBeginFrame(Duration rawTimeStamp) { + void handleBeginFrame(Duration? rawTimeStamp) { Timeline.startSync('Frame', arguments: timelineArgumentsIndicatingLandmarkEvent); _firstRawTimeStampInEpoch ??= rawTimeStamp; _currentFrameTimeStamp = _adjustForEpoch(rawTimeStamp ?? _lastRawTimeStamp); @@ -1008,7 +1005,7 @@ if (debugPrintBeginFrameBanner || debugPrintEndFrameBanner) { final StringBuffer frameTimeStampDescription = StringBuffer(); if (rawTimeStamp != null) { - _debugDescribeTimeStamp(_currentFrameTimeStamp, frameTimeStampDescription); + _debugDescribeTimeStamp(_currentFrameTimeStamp!, frameTimeStampDescription); } else { frameTimeStampDescription.write('(warm-up frame)'); } @@ -1029,7 +1026,7 @@ _transientCallbacks = <int, _FrameCallbackEntry>{}; callbacks.forEach((int id, _FrameCallbackEntry callbackEntry) { if (!_removedIds.contains(id)) - _invokeFrameCallback(callbackEntry.callback, _currentFrameTimeStamp, callbackEntry.debugStack); + _invokeFrameCallback(callbackEntry.callback, _currentFrameTimeStamp!, callbackEntry.debugStack); }); _removedIds.clear(); } finally { @@ -1053,7 +1050,7 @@ // PERSISTENT FRAME CALLBACKS _schedulerPhase = SchedulerPhase.persistentCallbacks; for (final FrameCallback callback in _persistentCallbacks) - _invokeFrameCallback(callback, _currentFrameTimeStamp); + _invokeFrameCallback(callback, _currentFrameTimeStamp!); // POST-FRAME CALLBACKS _schedulerPhase = SchedulerPhase.postFrameCallbacks; @@ -1061,13 +1058,13 @@ List<FrameCallback>.from(_postFrameCallbacks); _postFrameCallbacks.clear(); for (final FrameCallback callback in localPostFrameCallbacks) - _invokeFrameCallback(callback, _currentFrameTimeStamp); + _invokeFrameCallback(callback, _currentFrameTimeStamp!); } finally { _schedulerPhase = SchedulerPhase.idle; Timeline.finishSync(); // end the Frame assert(() { if (debugPrintEndFrameBanner) - debugPrint('▀' * _debugBanner.length); + debugPrint('▀' * _debugBanner!.length); _debugBanner = null; return true; }()); @@ -1106,7 +1103,7 @@ // Wraps the callback in a try/catch and forwards any error to // [debugSchedulerExceptionHandler], if set. If not set, then simply prints // the error. - void _invokeFrameCallback(FrameCallback callback, Duration timeStamp, [ StackTrace callbackStack ]) { + void _invokeFrameCallback(FrameCallback callback, Duration timeStamp, [ StackTrace? callbackStack ]) { assert(callback != null); assert(_FrameCallbackEntry.debugCurrentCallbackStack == null); assert(() { @@ -1143,7 +1140,7 @@ /// If there are any frame callbacks registered, only runs tasks with /// a [Priority] of [Priority.animation] or higher. Otherwise, runs /// all tasks. -bool defaultSchedulingStrategy({ int priority, SchedulerBinding scheduler }) { +bool defaultSchedulingStrategy({ required int priority, required SchedulerBinding scheduler }) { if (scheduler.transientCallbackCount > 0) return priority >= Priority.animation.value; return true;
diff --git a/packages/flutter/lib/src/scheduler/debug.dart b/packages/flutter/lib/src/scheduler/debug.dart index dc21d03..82af69f 100644 --- a/packages/flutter/lib/src/scheduler/debug.dart +++ b/packages/flutter/lib/src/scheduler/debug.dart
@@ -2,8 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// @dart = 2.8 - import 'package:flutter/foundation.dart'; // Any changes to this file should be reflected in the debugAssertAllSchedulerVarsUnset()
diff --git a/packages/flutter/lib/src/scheduler/priority.dart b/packages/flutter/lib/src/scheduler/priority.dart index 8b108d6..12cecc9 100644 --- a/packages/flutter/lib/src/scheduler/priority.dart +++ b/packages/flutter/lib/src/scheduler/priority.dart
@@ -2,8 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// @dart = 2.8 - import 'package:flutter/foundation.dart'; /// A task priority, as passed to [SchedulerBinding.scheduleTask].
diff --git a/packages/flutter/lib/src/scheduler/ticker.dart b/packages/flutter/lib/src/scheduler/ticker.dart index 0c02f4f..1842401 100644 --- a/packages/flutter/lib/src/scheduler/ticker.dart +++ b/packages/flutter/lib/src/scheduler/ticker.dart
@@ -2,8 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// @dart = 2.8 - import 'dart:async'; import 'package:flutter/foundation.dart'; @@ -71,7 +69,7 @@ }()); } - TickerFuture _future; + TickerFuture? _future; /// Whether this ticker has been silenced. /// @@ -115,9 +113,9 @@ return false; if (muted) return false; - if (SchedulerBinding.instance.framesEnabled) + if (SchedulerBinding.instance!.framesEnabled) return true; - if (SchedulerBinding.instance.schedulerPhase != SchedulerPhase.idle) + if (SchedulerBinding.instance!.schedulerPhase != SchedulerPhase.idle) return true; // for example, we might be in a warm-up frame or forced frame return false; } @@ -130,7 +128,7 @@ /// [isTicking]. bool get isActive => _future != null; - Duration _startTime; + Duration? _startTime; /// Starts the clock for this [Ticker]. If the ticker is not [muted], then this /// also starts calling the ticker's callback once per animation frame. @@ -163,10 +161,10 @@ if (shouldScheduleTick) { scheduleTick(); } - if (SchedulerBinding.instance.schedulerPhase.index > SchedulerPhase.idle.index && - SchedulerBinding.instance.schedulerPhase.index < SchedulerPhase.postFrameCallbacks.index) - _startTime = SchedulerBinding.instance.currentFrameTimeStamp; - return _future; + if (SchedulerBinding.instance!.schedulerPhase.index > SchedulerPhase.idle.index && + SchedulerBinding.instance!.schedulerPhase.index < SchedulerPhase.postFrameCallbacks.index) + _startTime = SchedulerBinding.instance!.currentFrameTimeStamp; + return _future!; } /// Adds a debug representation of a [Ticker] optimized for including in error @@ -197,7 +195,7 @@ // We take the _future into a local variable so that isTicking is false // when we actually complete the future (isTicking uses _future to // determine its state). - final TickerFuture localFuture = _future; + final TickerFuture localFuture = _future!; _future = null; _startTime = null; assert(!isActive); @@ -213,7 +211,7 @@ final TickerCallback _onTick; - int _animationId; + int? _animationId; /// Whether this [Ticker] has already scheduled a frame callback. @protected @@ -237,7 +235,7 @@ _animationId = null; _startTime ??= timeStamp; - _onTick(timeStamp - _startTime); + _onTick(timeStamp - _startTime!); // The onTick callback may have scheduled another tick already, for // example by calling stop then start again. @@ -252,7 +250,7 @@ void scheduleTick({ bool rescheduling = false }) { assert(!scheduled); assert(shouldScheduleTick); - _animationId = SchedulerBinding.instance.scheduleFrameCallback(_tick, rescheduling: rescheduling); + _animationId = SchedulerBinding.instance!.scheduleFrameCallback(_tick, rescheduling: rescheduling); } /// Cancels the frame callback that was requested by [scheduleTick], if any. @@ -264,7 +262,7 @@ @protected void unscheduleTick() { if (scheduled) { - SchedulerBinding.instance.cancelFrameCallbackWithId(_animationId); + SchedulerBinding.instance!.cancelFrameCallbackWithId(_animationId!); _animationId = null; } assert(!shouldScheduleTick); @@ -301,7 +299,7 @@ @mustCallSuper void dispose() { if (_future != null) { - final TickerFuture localFuture = _future; + final TickerFuture localFuture = _future!; _future = null; assert(!isActive); unscheduleTick(); @@ -319,8 +317,8 @@ /// An optional label can be provided for debugging purposes. /// /// This label will appear in the [toString] output in debug builds. - final String debugLabel; - StackTrace _debugCreationStack; + final String? debugLabel; + late StackTrace _debugCreationStack; @override String toString({ bool debugIncludeStack = false }) { @@ -374,14 +372,14 @@ } final Completer<void> _primaryCompleter = Completer<void>(); - Completer<void> _secondaryCompleter; - bool _completed; // null means unresolved, true means complete, false means canceled + Completer<void>? _secondaryCompleter; + bool? _completed; // null means unresolved, true means complete, false means canceled void _complete() { assert(_completed == null); _completed = true; - _primaryCompleter.complete(null); - _secondaryCompleter?.complete(null); + _primaryCompleter.complete(); + _secondaryCompleter?.complete(); } void _cancel(Ticker ticker) { @@ -415,14 +413,14 @@ if (_secondaryCompleter == null) { _secondaryCompleter = Completer<void>(); if (_completed != null) { - if (_completed) { - _secondaryCompleter.complete(); + if (_completed!) { + _secondaryCompleter!.complete(); } else { - _secondaryCompleter.completeError(const TickerCanceled()); + _secondaryCompleter!.completeError(const TickerCanceled()); } } } - return _secondaryCompleter.future; + return _secondaryCompleter!.future; } @override @@ -431,17 +429,17 @@ } @override - Future<void> catchError(Function onError, { bool test(dynamic error) }) { + Future<void> catchError(Function onError, { bool Function(Object)? test }) { return _primaryCompleter.future.catchError(onError, test: test); } @override - Future<R> then<R>(FutureOr<R> onValue(void value), { Function onError }) { + Future<R> then<R>(FutureOr<R> onValue(void value), { Function? onError }) { return _primaryCompleter.future.then<R>(onValue, onError: onError); } @override - Future<void> timeout(Duration timeLimit, { dynamic onTimeout() }) { + Future<void> timeout(Duration timeLimit, { FutureOr<void> Function()? onTimeout }) { return _primaryCompleter.future.timeout(timeLimit, onTimeout: onTimeout); } @@ -451,7 +449,7 @@ } @override - String toString() => '${describeIdentity(this)}(${ _completed == null ? "active" : _completed ? "complete" : "canceled" })'; + String toString() => '${describeIdentity(this)}(${ _completed == null ? "active" : _completed! ? "complete" : "canceled" })'; } /// Exception thrown by [Ticker] objects on the [TickerFuture.orCancel] future @@ -464,7 +462,7 @@ /// /// This may be null in the case that the [Future] created for /// [TickerFuture.orCancel] was created after the ticker was canceled. - final Ticker ticker; + final Ticker? ticker; @override String toString() {