From 90500a5dc4341dd41f3ae0d99fc92daa5ffd2a9c Mon Sep 17 00:00:00 2001 From: Jonah Williams Date: Mon, 3 Jun 2019 14:56:15 -0700 Subject: [PATCH] Use conditional imports for flutter foundation libraries (#33663) --- packages/flutter/lib/foundation.dart | 1 + .../flutter/lib/src/animation/animation.dart | 1 - .../flutter/lib/src/animation/animations.dart | 1 - .../lib/src/animation/listener_helpers.dart | 2 - .../lib/src/foundation/_bitfield_io.dart | 48 ++++++++++ ...ld_unsupported.dart => _bitfield_web.dart} | 22 +++-- .../lib/src/foundation/_isolates_io.dart | 92 +++++++++++++++++++ .../lib/src/foundation/_isolates_web.dart | 14 +++ .../lib/src/foundation/_platform_io.dart | 34 +++++++ .../lib/src/foundation/_platform_web.dart | 24 +++++ .../lib/src/foundation/basic_types.dart | 1 - .../flutter/lib/src/foundation/binding.dart | 2 +- .../flutter/lib/src/foundation/bitfield.dart | 41 +++------ .../flutter/lib/src/foundation/isolates.dart | 92 ++----------------- .../flutter/lib/src/foundation/platform.dart | 63 ++++--------- .../flutter/lib/src/foundation/profile.dart | 3 +- .../flutter/lib/src/painting/basic_types.dart | 3 +- .../flutter/lib/src/rendering/object.dart | 1 - .../scroll_position_with_single_context.dart | 1 - .../test/foundation/capture_output.dart | 2 +- .../flutter/test/material/feedback_test.dart | 2 - 21 files changed, 265 insertions(+), 185 deletions(-) create mode 100644 packages/flutter/lib/src/foundation/_bitfield_io.dart rename packages/flutter/lib/src/foundation/{bitfield_unsupported.dart => _bitfield_web.dart} (60%) create mode 100644 packages/flutter/lib/src/foundation/_isolates_io.dart create mode 100644 packages/flutter/lib/src/foundation/_isolates_web.dart create mode 100644 packages/flutter/lib/src/foundation/_platform_io.dart create mode 100644 packages/flutter/lib/src/foundation/_platform_web.dart diff --git a/packages/flutter/lib/foundation.dart b/packages/flutter/lib/foundation.dart index f2e6791d19..725efc20a9 100644 --- a/packages/flutter/lib/foundation.dart +++ b/packages/flutter/lib/foundation.dart @@ -35,6 +35,7 @@ export 'src/foundation/annotations.dart'; export 'src/foundation/assertions.dart'; export 'src/foundation/basic_types.dart'; export 'src/foundation/binding.dart'; +export 'src/foundation/bitfield.dart'; export 'src/foundation/change_notifier.dart'; export 'src/foundation/collections.dart'; export 'src/foundation/consolidate_response.dart'; diff --git a/packages/flutter/lib/src/animation/animation.dart b/packages/flutter/lib/src/animation/animation.dart index 8522785351..3a6bd0a340 100644 --- a/packages/flutter/lib/src/animation/animation.dart +++ b/packages/flutter/lib/src/animation/animation.dart @@ -2,7 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -import 'dart:ui' show VoidCallback; import 'package:flutter/foundation.dart'; diff --git a/packages/flutter/lib/src/animation/animations.dart b/packages/flutter/lib/src/animation/animations.dart index 80cc60eecb..4f0dc26236 100644 --- a/packages/flutter/lib/src/animation/animations.dart +++ b/packages/flutter/lib/src/animation/animations.dart @@ -3,7 +3,6 @@ // found in the LICENSE file. import 'dart:math' as math; -import 'dart:ui' show VoidCallback; import 'package:flutter/foundation.dart'; diff --git a/packages/flutter/lib/src/animation/listener_helpers.dart b/packages/flutter/lib/src/animation/listener_helpers.dart index 2236ac5d3b..d2f8785a05 100644 --- a/packages/flutter/lib/src/animation/listener_helpers.dart +++ b/packages/flutter/lib/src/animation/listener_helpers.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. -import 'dart:ui' show VoidCallback; - import 'package:flutter/foundation.dart'; import 'animation.dart'; diff --git a/packages/flutter/lib/src/foundation/_bitfield_io.dart b/packages/flutter/lib/src/foundation/_bitfield_io.dart new file mode 100644 index 0000000000..f1205e55d1 --- /dev/null +++ b/packages/flutter/lib/src/foundation/_bitfield_io.dart @@ -0,0 +1,48 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'bitfield.dart' as bitfield; + +/// The dart:io implementation of [bitfield.kMaxUnsignedSMI]. +const int kMaxUnsignedSMI = 0x3FFFFFFFFFFFFFFF; + +/// The dart:io implementation of [bitfield.Bitfield]. +class BitField implements bitfield.BitField { + /// The dart:io implementation of [bitfield.Bitfield()]. + BitField(this._length) + : assert(_length <= _smiBits), + _bits = _allZeros; + + /// The dart:io implementation of [bitfield.Bitfield.filled]. + BitField.filled(this._length, bool value) + : assert(_length <= _smiBits), + _bits = value ? _allOnes : _allZeros; + + final int _length; + int _bits; + + static const int _smiBits = 62; // see https://www.dartlang.org/articles/numeric-computation/#smis-and-mints + static const int _allZeros = 0; + static const int _allOnes = kMaxUnsignedSMI; // 2^(_kSMIBits+1)-1 + + @override + bool operator [](T index) { + assert(index.index < _length); + return (_bits & 1 << index.index) > 0; + } + + @override + void operator []=(T index, bool value) { + assert(index.index < _length); + if (value) + _bits = _bits | (1 << index.index); + else + _bits = _bits & ~(1 << index.index); + } + + @override + void reset([ bool value = false ]) { + _bits = value ? _allOnes : _allZeros; + } +} diff --git a/packages/flutter/lib/src/foundation/bitfield_unsupported.dart b/packages/flutter/lib/src/foundation/_bitfield_web.dart similarity index 60% rename from packages/flutter/lib/src/foundation/bitfield_unsupported.dart rename to packages/flutter/lib/src/foundation/_bitfield_web.dart index c7baf470b2..2fa843a201 100644 --- a/packages/flutter/lib/src/foundation/bitfield_unsupported.dart +++ b/packages/flutter/lib/src/foundation/_bitfield_web.dart @@ -2,32 +2,34 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -/// Unsupported. +import 'bitfield.dart' as bitfield; + +/// The dart:html implementation of [bitfield.kMaxUnsignedSMI]. const int kMaxUnsignedSMI = 0; -/// Unsupported. -class BitField { - /// Unsupported. - // Ignored so that both bitfield implementations have the same API. +/// The dart:html implementation of [bitfield.Bitfield]. +class BitField implements bitfield.BitField { + /// The dart:html implementation of [bitfield.Bitfield]. + // Can remove when we have metaclasses. // ignore: avoid_unused_constructor_parameters BitField(int length); - /// Unsupported. - // Ignored so that both bitfield implementations have the same API. + /// The dart:html implementation of [bitfield.Bitfield.filled]. + // Can remove when we have metaclasses. // ignore: avoid_unused_constructor_parameters BitField.filled(int length, bool value); - /// Unsupported. + @override bool operator [](T index) { throw UnsupportedError('Not supported when compiling to JavaScript'); } - /// Unsupported. + @override void operator []=(T index, bool value) { throw UnsupportedError('Not supported when compiling to JavaScript'); } - /// Unsupported. + @override void reset([ bool value = false ]) { throw UnsupportedError('Not supported when compiling to JavaScript'); } diff --git a/packages/flutter/lib/src/foundation/_isolates_io.dart b/packages/flutter/lib/src/foundation/_isolates_io.dart new file mode 100644 index 0000000000..be2a41825d --- /dev/null +++ b/packages/flutter/lib/src/foundation/_isolates_io.dart @@ -0,0 +1,92 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'dart:async'; +import 'dart:developer'; +import 'dart:isolate'; +import 'package:meta/meta.dart'; + +import 'constants.dart'; +import 'isolates.dart' as isolates; + +/// The dart:io implementation of [isolate.compute]. +Future compute(isolates.ComputeCallback callback, Q message, { String debugLabel }) async { + if (!kReleaseMode) { + debugLabel ??= callback.toString(); + } + final Flow flow = Flow.begin(); + Timeline.startSync('$debugLabel: start', flow: flow); + final ReceivePort resultPort = ReceivePort(); + final ReceivePort errorPort = ReceivePort(); + Timeline.finishSync(); + final Isolate isolate = await Isolate.spawn<_IsolateConfiguration>>( + _spawn, + _IsolateConfiguration>( + callback, + message, + resultPort.sendPort, + debugLabel, + flow.id, + ), + errorsAreFatal: true, + onExit: resultPort.sendPort, + onError: errorPort.sendPort, + ); + final Completer result = Completer(); + errorPort.listen((dynamic errorData) { + assert(errorData is List); + assert(errorData.length == 2); + final Exception exception = Exception(errorData[0]); + final StackTrace stack = StackTrace.fromString(errorData[1]); + if (result.isCompleted) { + Zone.current.handleUncaughtError(exception, stack); + } else { + result.completeError(exception, stack); + } + }); + resultPort.listen((dynamic resultData) { + assert(resultData == null || resultData is R); + if (!result.isCompleted) + result.complete(resultData); + }); + await result.future; + Timeline.startSync('$debugLabel: end', flow: Flow.end(flow.id)); + resultPort.close(); + errorPort.close(); + isolate.kill(); + Timeline.finishSync(); + return result.future; +} + +@immutable +class _IsolateConfiguration { + const _IsolateConfiguration( + this.callback, + this.message, + this.resultPort, + this.debugLabel, + this.flowId, + ); + final isolates.ComputeCallback callback; + final Q message; + final SendPort resultPort; + final String debugLabel; + final int flowId; + + R apply() => callback(message); +} + +Future _spawn(_IsolateConfiguration> configuration) async { + R result; + await Timeline.timeSync( + '${configuration.debugLabel}', + () async { result = await configuration.apply(); }, + flow: Flow.step(configuration.flowId), + ); + Timeline.timeSync( + '${configuration.debugLabel}: returning result', + () { configuration.resultPort.send(result); }, + flow: Flow.step(configuration.flowId), + ); +} diff --git a/packages/flutter/lib/src/foundation/_isolates_web.dart b/packages/flutter/lib/src/foundation/_isolates_web.dart new file mode 100644 index 0000000000..00f249fc4a --- /dev/null +++ b/packages/flutter/lib/src/foundation/_isolates_web.dart @@ -0,0 +1,14 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'isolates.dart' as isolates; + +/// The dart:html implementation of [isolate.compute]. +Future compute(isolates.ComputeCallback callback, Q message, { String debugLabel }) async { + // To avoid blocking the UI immediately for an expensive function call, we + // pump a single frame to allow the framework to complete the current set + // of work. + await null; + return callback(message); +} diff --git a/packages/flutter/lib/src/foundation/_platform_io.dart b/packages/flutter/lib/src/foundation/_platform_io.dart new file mode 100644 index 0000000000..7726331ea1 --- /dev/null +++ b/packages/flutter/lib/src/foundation/_platform_io.dart @@ -0,0 +1,34 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'dart:io'; +import 'assertions.dart'; +import 'platform.dart' as platform; + +/// The dart:io implementation of [platform.defaultTargetPlatform]. +platform.TargetPlatform get defaultTargetPlatform { + platform.TargetPlatform result; + if (Platform.isIOS) { + result = platform.TargetPlatform.iOS; + } else if (Platform.isAndroid) { + result = platform.TargetPlatform.android; + } else if (Platform.isFuchsia) { + result = platform.TargetPlatform.fuchsia; + } + assert(() { + if (Platform.environment.containsKey('FLUTTER_TEST')) + result = platform.TargetPlatform.android; + return true; + }()); + if (platform.debugDefaultTargetPlatformOverride != null) + result = platform.debugDefaultTargetPlatformOverride; + if (result == null) { + throw FlutterError( + 'Unknown platform.\n' + '${Platform.operatingSystem} was not recognized as a target platform. ' + 'Consider updating the list of TargetPlatforms to include this platform.' + ); + } + return result; +} diff --git a/packages/flutter/lib/src/foundation/_platform_web.dart b/packages/flutter/lib/src/foundation/_platform_web.dart new file mode 100644 index 0000000000..155760f867 --- /dev/null +++ b/packages/flutter/lib/src/foundation/_platform_web.dart @@ -0,0 +1,24 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Can remove once analyzer summary includes dart:html. +import 'dart:html' as html; // ignore: uri_does_not_exist +import 'platform.dart' as platform; + +/// The dart:html implementation of [platform.defaultTargetPlatform]. +platform.TargetPlatform get defaultTargetPlatform { + platform.TargetPlatform result; + // The existence of this method is tested via the dart2js compile test. + final String userAgent = html.window.navigator.userAgent; + if (userAgent.contains('iPhone') + || userAgent.contains('iPad') + || userAgent.contains('iPod')) { + result = platform.TargetPlatform.iOS; + } else { + result = platform.TargetPlatform.android; + } + if (platform.debugDefaultTargetPlatformOverride != null) + result = platform.debugDefaultTargetPlatformOverride; + return result; +} diff --git a/packages/flutter/lib/src/foundation/basic_types.dart b/packages/flutter/lib/src/foundation/basic_types.dart index 4713cc4c77..7760dd17d9 100644 --- a/packages/flutter/lib/src/foundation/basic_types.dart +++ b/packages/flutter/lib/src/foundation/basic_types.dart @@ -8,7 +8,6 @@ import 'dart:collection'; // COMMON SIGNATURES export 'dart:ui' show VoidCallback; -export 'bitfield.dart' if (dart.library.html) 'bitfield_unsupported.dart'; /// Signature for callbacks that report that an underlying value has changed. /// diff --git a/packages/flutter/lib/src/foundation/binding.dart b/packages/flutter/lib/src/foundation/binding.dart index a5e9f6e505..5ab2145d8f 100644 --- a/packages/flutter/lib/src/foundation/binding.dart +++ b/packages/flutter/lib/src/foundation/binding.dart @@ -6,8 +6,8 @@ import 'dart:async'; import 'dart:convert' show json; import 'dart:developer' as developer; import 'dart:io' show exit; -// Before adding any more dart:ui imports, pleaes read the README. import 'dart:ui' as ui show saveCompilationTrace, Window, window; +// Before adding any more dart:ui imports, please read the README. import 'package:meta/meta.dart'; diff --git a/packages/flutter/lib/src/foundation/bitfield.dart b/packages/flutter/lib/src/foundation/bitfield.dart index b4b3b115dd..8ca3829070 100644 --- a/packages/flutter/lib/src/foundation/bitfield.dart +++ b/packages/flutter/lib/src/foundation/bitfield.dart @@ -2,25 +2,26 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +import '_bitfield_io.dart' + if (dart.library.html) '_bitfield_web.dart' as _bitfield; + /// The largest SMI value. /// -/// See +/// See /// /// When compiling to JavaScript, this value is not supported since it is /// larger than the maximum safe 32bit integer. -const int kMaxUnsignedSMI = 0x3FFFFFFFFFFFFFFF; +const int kMaxUnsignedSMI = _bitfield.kMaxUnsignedSMI; /// A BitField over an enum (or other class whose values implement "index"). /// Only the first 62 values of the enum can be used as indices. /// /// When compiling to JavaScript, this class is not supported. -class BitField { +abstract class BitField { /// Creates a bit field of all zeros. /// /// The given length must be at most 62. - BitField(this._length) - : assert(_length <= _smiBits), - _bits = _allZeros; + factory BitField(int length) = _bitfield.BitField; /// Creates a bit field filled with a particular value. /// @@ -28,40 +29,20 @@ class BitField { /// the bits are filled with zeros. /// /// The given length must be at most 62. - BitField.filled(this._length, bool value) - : assert(_length <= _smiBits), - _bits = value ? _allOnes : _allZeros; - - final int _length; - int _bits; - - static const int _smiBits = 62; // see https://dart.dev/articles/numeric-computation/#smis-and-mints - static const int _allZeros = 0; - static const int _allOnes = kMaxUnsignedSMI; // 2^(_kSMIBits+1)-1 + factory BitField.filled(int length, bool value) = _bitfield.BitField.filled; /// Returns whether the bit with the given index is set to one. - bool operator [](T index) { - assert(index.index < _length); - return (_bits & 1 << index.index) > 0; - } + bool operator [](T index); /// Sets the bit with the given index to the given value. /// /// If value is true, the bit with the given index is set to one. Otherwise, /// the bit is set to zero. - void operator []=(T index, bool value) { - assert(index.index < _length); - if (value) - _bits = _bits | (1 << index.index); - else - _bits = _bits & ~(1 << index.index); - } + void operator []=(T index, bool value); /// Sets all the bits to the given value. /// /// If the value is true, the bits are all set to one. Otherwise, the bits are /// all set to zero. Defaults to setting all the bits to zero. - void reset([ bool value = false ]) { - _bits = value ? _allOnes : _allZeros; - } + void reset([ bool value = false ]); } diff --git a/packages/flutter/lib/src/foundation/isolates.dart b/packages/flutter/lib/src/foundation/isolates.dart index 8afeb866a4..d0f2d3cdfc 100644 --- a/packages/flutter/lib/src/foundation/isolates.dart +++ b/packages/flutter/lib/src/foundation/isolates.dart @@ -3,12 +3,9 @@ // found in the LICENSE file. import 'dart:async'; -import 'dart:developer' show Timeline, Flow; -import 'dart:isolate'; -import 'package:meta/meta.dart'; - -import 'constants.dart'; +import '_isolates_io.dart' + if (dart.library.html) '_isolates_web.dart' as _isolates; /// Signature for the callback passed to [compute]. /// @@ -20,6 +17,9 @@ import 'constants.dart'; /// {@macro flutter.foundation.compute.limitations} typedef ComputeCallback = FutureOr Function(Q message); +// The signature of [compute]. +typedef _ComputeImpl = Future Function(ComputeCallback callback, Q message, { String debugLabel }); + /// Spawn an isolate, run `callback` on that isolate, passing it `message`, and /// (eventually) return the value returned by `callback`. /// @@ -44,82 +44,6 @@ typedef ComputeCallback = FutureOr Function(Q message); /// /// The `debugLabel` argument can be specified to provide a name to add to the /// [Timeline]. This is useful when profiling an application. -Future compute(ComputeCallback callback, Q message, { String debugLabel }) async { - if (!kReleaseMode) { - debugLabel ??= callback.toString(); - } - final Flow flow = Flow.begin(); - Timeline.startSync('$debugLabel: start', flow: flow); - final ReceivePort resultPort = ReceivePort(); - final ReceivePort errorPort = ReceivePort(); - Timeline.finishSync(); - final Isolate isolate = await Isolate.spawn<_IsolateConfiguration>>( - _spawn, - _IsolateConfiguration>( - callback, - message, - resultPort.sendPort, - debugLabel, - flow.id, - ), - errorsAreFatal: true, - onExit: resultPort.sendPort, - onError: errorPort.sendPort, - ); - final Completer result = Completer(); - errorPort.listen((dynamic errorData) { - assert(errorData is List); - assert(errorData.length == 2); - final Exception exception = Exception(errorData[0]); - final StackTrace stack = StackTrace.fromString(errorData[1]); - if (result.isCompleted) { - Zone.current.handleUncaughtError(exception, stack); - } else { - result.completeError(exception, stack); - } - }); - resultPort.listen((dynamic resultData) { - assert(resultData == null || resultData is R); - if (!result.isCompleted) - result.complete(resultData); - }); - await result.future; - Timeline.startSync('$debugLabel: end', flow: Flow.end(flow.id)); - resultPort.close(); - errorPort.close(); - isolate.kill(); - Timeline.finishSync(); - return result.future; -} - -@immutable -class _IsolateConfiguration { - const _IsolateConfiguration( - this.callback, - this.message, - this.resultPort, - this.debugLabel, - this.flowId, - ); - final ComputeCallback callback; - final Q message; - final SendPort resultPort; - final String debugLabel; - final int flowId; - - R apply() => callback(message); -} - -Future _spawn(_IsolateConfiguration> configuration) async { - R result; - await Timeline.timeSync( - '${configuration.debugLabel}', - () async { result = await configuration.apply(); }, - flow: Flow.step(configuration.flowId), - ); - Timeline.timeSync( - '${configuration.debugLabel}: returning result', - () { configuration.resultPort.send(result); }, - flow: Flow.step(configuration.flowId), - ); -} +// Remove when https://github.com/dart-lang/sdk/issues/37149 is fixed. +// ignore: prefer_const_declarations +final _ComputeImpl compute = _isolates.compute; diff --git a/packages/flutter/lib/src/foundation/platform.dart b/packages/flutter/lib/src/foundation/platform.dart index aaf6529d41..90b618af34 100644 --- a/packages/flutter/lib/src/foundation/platform.dart +++ b/packages/flutter/lib/src/foundation/platform.dart @@ -2,23 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -import 'dart:io' show Platform; - -import 'assertions.dart'; - -/// The platform that user interaction should adapt to target. -/// -/// The [defaultTargetPlatform] getter returns the current platform. -enum TargetPlatform { - /// Android: - android, - - /// Fuchsia: - fuchsia, - - /// iOS: - iOS, -} +import '_platform_io.dart' + if (dart.library.html) '_platform_web.dart' as _platform; /// The [TargetPlatform] that matches the platform on which the framework is /// currently executing. @@ -48,36 +33,20 @@ enum TargetPlatform { // that would mean we'd be stuck with that platform forever emulating the other, // and we'd never be able to introduce dedicated behavior for that platform // (since doing so would be a big breaking change). -TargetPlatform get defaultTargetPlatform { - // TODO(jonahwilliams): consider where this constant should live. - const bool kIsWeb = identical(1, 1.0); - TargetPlatform result; - if (kIsWeb) { - result = TargetPlatform.android; - } else { - if (Platform.isIOS) { - result = TargetPlatform.iOS; - } else if (Platform.isAndroid) { - result = TargetPlatform.android; - } else if (Platform.isFuchsia) { - result = TargetPlatform.fuchsia; - } - } - assert(() { - if (!kIsWeb && Platform.environment.containsKey('FLUTTER_TEST')) - result = TargetPlatform.android; - return true; - }()); - if (debugDefaultTargetPlatformOverride != null) - result = debugDefaultTargetPlatformOverride; - if (result == null) { - throw FlutterError( - 'Unknown platform.\n' - '${Platform.operatingSystem} was not recognized as a target platform. ' - 'Consider updating the list of TargetPlatforms to include this platform.' - ); - } - return result; +TargetPlatform get defaultTargetPlatform => _platform.defaultTargetPlatform; + +/// The platform that user interaction should adapt to target. +/// +/// The [defaultTargetPlatform] getter returns the current platform. +enum TargetPlatform { + /// Android: + android, + + /// Fuchsia: + fuchsia, + + /// iOS: + iOS, } /// Override the [defaultTargetPlatform]. diff --git a/packages/flutter/lib/src/foundation/profile.dart b/packages/flutter/lib/src/foundation/profile.dart index d1d5ff2f4a..f063c74a66 100644 --- a/packages/flutter/lib/src/foundation/profile.dart +++ b/packages/flutter/lib/src/foundation/profile.dart @@ -2,8 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -import 'dart:ui' show VoidCallback; - +import 'basic_types.dart'; import 'constants.dart'; /// DEPRECATED. `function` cannot be treeshaken out of release builds. diff --git a/packages/flutter/lib/src/painting/basic_types.dart b/packages/flutter/lib/src/painting/basic_types.dart index 0a1af230e6..7815f34953 100644 --- a/packages/flutter/lib/src/painting/basic_types.dart +++ b/packages/flutter/lib/src/painting/basic_types.dart @@ -41,10 +41,11 @@ export 'dart:ui' show TextPosition, TileMode, VertexMode, - VoidCallback, hashValues, hashList; +export 'package:flutter/foundation.dart' show VoidCallback; + // Intentionally not exported: // - Image, instantiateImageCodec, decodeImageFromList: // We use ui.* to make it very explicit that these are low-level image APIs. diff --git a/packages/flutter/lib/src/rendering/object.dart b/packages/flutter/lib/src/rendering/object.dart index 733db608de..a8b674b7a6 100644 --- a/packages/flutter/lib/src/rendering/object.dart +++ b/packages/flutter/lib/src/rendering/object.dart @@ -9,7 +9,6 @@ import 'package:flutter/animation.dart'; import 'package:flutter/foundation.dart'; import 'package:flutter/gestures.dart'; import 'package:flutter/painting.dart'; -import 'package:flutter/scheduler.dart'; import 'package:flutter/semantics.dart'; import 'package:vector_math/vector_math_64.dart'; diff --git a/packages/flutter/lib/src/widgets/scroll_position_with_single_context.dart b/packages/flutter/lib/src/widgets/scroll_position_with_single_context.dart index 6c39b2b9cf..7fc59bd85a 100644 --- a/packages/flutter/lib/src/widgets/scroll_position_with_single_context.dart +++ b/packages/flutter/lib/src/widgets/scroll_position_with_single_context.dart @@ -7,7 +7,6 @@ import 'dart:async'; import 'package:flutter/gestures.dart'; import 'package:flutter/physics.dart'; import 'package:flutter/rendering.dart'; -import 'package:flutter/scheduler.dart'; import 'basic.dart'; import 'framework.dart'; diff --git a/packages/flutter/test/foundation/capture_output.dart b/packages/flutter/test/foundation/capture_output.dart index 8bd3bef489..63fb5f4388 100644 --- a/packages/flutter/test/foundation/capture_output.dart +++ b/packages/flutter/test/foundation/capture_output.dart @@ -3,7 +3,7 @@ // found in the LICENSE file. import 'dart:async'; -import 'dart:ui' show VoidCallback; +import 'package:flutter/foundation.dart'; List captureOutput(VoidCallback fn) { final List log = []; diff --git a/packages/flutter/test/material/feedback_test.dart b/packages/flutter/test/material/feedback_test.dart index 603ed2c887..d35b421dde 100644 --- a/packages/flutter/test/material/feedback_test.dart +++ b/packages/flutter/test/material/feedback_test.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. -import 'dart:ui'; - import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:flutter_test/flutter_test.dart';