Unverified Commit 7442eeaf authored by Jonah Williams's avatar Jonah Williams Committed by GitHub
parent f319f337
...@@ -35,6 +35,7 @@ export 'src/foundation/annotations.dart'; ...@@ -35,6 +35,7 @@ export 'src/foundation/annotations.dart';
export 'src/foundation/assertions.dart'; export 'src/foundation/assertions.dart';
export 'src/foundation/basic_types.dart'; export 'src/foundation/basic_types.dart';
export 'src/foundation/binding.dart'; export 'src/foundation/binding.dart';
export 'src/foundation/bitfield.dart';
export 'src/foundation/change_notifier.dart'; export 'src/foundation/change_notifier.dart';
export 'src/foundation/collections.dart'; export 'src/foundation/collections.dart';
export 'src/foundation/consolidate_response.dart'; export 'src/foundation/consolidate_response.dart';
......
...@@ -2,7 +2,6 @@ ...@@ -2,7 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
import 'dart:ui' show VoidCallback;
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
......
...@@ -3,7 +3,6 @@ ...@@ -3,7 +3,6 @@
// found in the LICENSE file. // found in the LICENSE file.
import 'dart:math' as math; import 'dart:math' as math;
import 'dart:ui' show VoidCallback;
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
......
...@@ -2,8 +2,6 @@ ...@@ -2,8 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
import 'dart:ui' show VoidCallback;
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
import 'animation.dart'; import 'animation.dart';
......
// 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<T extends dynamic> implements bitfield.BitField<T> {
/// 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;
}
}
...@@ -2,32 +2,34 @@ ...@@ -2,32 +2,34 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
/// Unsupported. import 'bitfield.dart' as bitfield;
/// The dart:html implementation of [bitfield.kMaxUnsignedSMI].
const int kMaxUnsignedSMI = 0; const int kMaxUnsignedSMI = 0;
/// Unsupported. /// The dart:html implementation of [bitfield.Bitfield].
class BitField<T extends dynamic> { class BitField<T extends dynamic> implements bitfield.BitField<T> {
/// Unsupported. /// The dart:html implementation of [bitfield.Bitfield].
// Ignored so that both bitfield implementations have the same API. // Can remove when we have metaclasses.
// ignore: avoid_unused_constructor_parameters // ignore: avoid_unused_constructor_parameters
BitField(int length); BitField(int length);
/// Unsupported. /// The dart:html implementation of [bitfield.Bitfield.filled].
// Ignored so that both bitfield implementations have the same API. // Can remove when we have metaclasses.
// ignore: avoid_unused_constructor_parameters // ignore: avoid_unused_constructor_parameters
BitField.filled(int length, bool value); BitField.filled(int length, bool value);
/// Unsupported. @override
bool operator [](T index) { bool operator [](T index) {
throw UnsupportedError('Not supported when compiling to JavaScript'); throw UnsupportedError('Not supported when compiling to JavaScript');
} }
/// Unsupported. @override
void operator []=(T index, bool value) { void operator []=(T index, bool value) {
throw UnsupportedError('Not supported when compiling to JavaScript'); throw UnsupportedError('Not supported when compiling to JavaScript');
} }
/// Unsupported. @override
void reset([ bool value = false ]) { void reset([ bool value = false ]) {
throw UnsupportedError('Not supported when compiling to JavaScript'); throw UnsupportedError('Not supported when compiling to JavaScript');
} }
......
// 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<R> compute<Q, R>(isolates.ComputeCallback<Q, R> 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<Q, FutureOr<R>>>(
_spawn,
_IsolateConfiguration<Q, FutureOr<R>>(
callback,
message,
resultPort.sendPort,
debugLabel,
flow.id,
),
errorsAreFatal: true,
onExit: resultPort.sendPort,
onError: errorPort.sendPort,
);
final Completer<R> result = Completer<R>();
errorPort.listen((dynamic errorData) {
assert(errorData is List<dynamic>);
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<Q, R> {
const _IsolateConfiguration(
this.callback,
this.message,
this.resultPort,
this.debugLabel,
this.flowId,
);
final isolates.ComputeCallback<Q, R> callback;
final Q message;
final SendPort resultPort;
final String debugLabel;
final int flowId;
R apply() => callback(message);
}
Future<void> _spawn<Q, R>(_IsolateConfiguration<Q, FutureOr<R>> 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),
);
}
// 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<R> compute<Q, R>(isolates.ComputeCallback<Q, R> 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);
}
// 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;
}
// 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 'platform.dart' as platform;
/// The dart:html implementation of [platform.defaultTargetPlatform].
platform.TargetPlatform get defaultTargetPlatform {
// To getter a better guess at the targetPlatform we need to be able to
// reference the window, but that won't be availible until we fix the
// platforms configuration for Flutter.
platform.TargetPlatform result = platform.TargetPlatform.android;
if (platform.debugDefaultTargetPlatformOverride != null)
result = platform.debugDefaultTargetPlatformOverride;
return result;
}
...@@ -8,7 +8,6 @@ import 'dart:collection'; ...@@ -8,7 +8,6 @@ import 'dart:collection';
// COMMON SIGNATURES // COMMON SIGNATURES
export 'dart:ui' show VoidCallback; 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. /// Signature for callbacks that report that an underlying value has changed.
/// ///
......
...@@ -6,8 +6,8 @@ import 'dart:async'; ...@@ -6,8 +6,8 @@ import 'dart:async';
import 'dart:convert' show json; import 'dart:convert' show json;
import 'dart:developer' as developer; import 'dart:developer' as developer;
import 'dart:io' show exit; 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; 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'; import 'package:meta/meta.dart';
......
...@@ -2,25 +2,26 @@ ...@@ -2,25 +2,26 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
import '_bitfield_io.dart'
if (dart.library.html) '_bitfield_web.dart' as _bitfield;
/// The largest SMI value. /// The largest SMI value.
/// ///
/// See <https://dart.dev/articles/numeric-computation/#smis-and-mints> /// See <https://www.dartlang.org/articles/numeric-computation/#smis-and-mints>
/// ///
/// When compiling to JavaScript, this value is not supported since it is /// When compiling to JavaScript, this value is not supported since it is
/// larger than the maximum safe 32bit integer. /// 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"). /// 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. /// Only the first 62 values of the enum can be used as indices.
/// ///
/// When compiling to JavaScript, this class is not supported. /// When compiling to JavaScript, this class is not supported.
class BitField<T extends dynamic> { abstract class BitField<T extends dynamic> {
/// Creates a bit field of all zeros. /// Creates a bit field of all zeros.
/// ///
/// The given length must be at most 62. /// The given length must be at most 62.
BitField(this._length) factory BitField(int length) = _bitfield.BitField<T>;
: assert(_length <= _smiBits),
_bits = _allZeros;
/// Creates a bit field filled with a particular value. /// Creates a bit field filled with a particular value.
/// ///
...@@ -28,40 +29,20 @@ class BitField<T extends dynamic> { ...@@ -28,40 +29,20 @@ class BitField<T extends dynamic> {
/// the bits are filled with zeros. /// the bits are filled with zeros.
/// ///
/// The given length must be at most 62. /// The given length must be at most 62.
BitField.filled(this._length, bool value) factory BitField.filled(int length, bool value) = _bitfield.BitField<T>.filled;
: 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
/// Returns whether the bit with the given index is set to one. /// Returns whether the bit with the given index is set to one.
bool operator [](T index) { bool operator [](T index);
assert(index.index < _length);
return (_bits & 1 << index.index) > 0;
}
/// Sets the bit with the given index to the given value. /// 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, /// If value is true, the bit with the given index is set to one. Otherwise,
/// the bit is set to zero. /// the bit is set to zero.
void operator []=(T index, bool value) { void operator []=(T index, bool value);
assert(index.index < _length);
if (value)
_bits = _bits | (1 << index.index);
else
_bits = _bits & ~(1 << index.index);
}
/// Sets all the bits to the given 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 /// 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. /// all set to zero. Defaults to setting all the bits to zero.
void reset([ bool value = false ]) { void reset([ bool value = false ]);
_bits = value ? _allOnes : _allZeros;
}
} }
...@@ -3,12 +3,9 @@ ...@@ -3,12 +3,9 @@
// found in the LICENSE file. // found in the LICENSE file.
import 'dart:async'; import 'dart:async';
import 'dart:developer' show Timeline, Flow;
import 'dart:isolate';
import 'package:meta/meta.dart'; import '_isolates_io.dart'
if (dart.library.html) '_isolates_web.dart' as _isolates;
import 'constants.dart';
/// Signature for the callback passed to [compute]. /// Signature for the callback passed to [compute].
/// ///
...@@ -20,6 +17,9 @@ import 'constants.dart'; ...@@ -20,6 +17,9 @@ import 'constants.dart';
/// {@macro flutter.foundation.compute.limitations} /// {@macro flutter.foundation.compute.limitations}
typedef ComputeCallback<Q, R> = FutureOr<R> Function(Q message); typedef ComputeCallback<Q, R> = FutureOr<R> Function(Q message);
// The signature of [compute].
typedef _ComputeImpl = Future<R> Function<Q, R>(ComputeCallback<Q, R> callback, Q message, { String debugLabel });
/// Spawn an isolate, run `callback` on that isolate, passing it `message`, and /// Spawn an isolate, run `callback` on that isolate, passing it `message`, and
/// (eventually) return the value returned by `callback`. /// (eventually) return the value returned by `callback`.
/// ///
...@@ -44,82 +44,6 @@ typedef ComputeCallback<Q, R> = FutureOr<R> Function(Q message); ...@@ -44,82 +44,6 @@ typedef ComputeCallback<Q, R> = FutureOr<R> Function(Q message);
/// ///
/// The `debugLabel` argument can be specified to provide a name to add to the /// The `debugLabel` argument can be specified to provide a name to add to the
/// [Timeline]. This is useful when profiling an application. /// [Timeline]. This is useful when profiling an application.
Future<R> compute<Q, R>(ComputeCallback<Q, R> callback, Q message, { String debugLabel }) async { // Remove when https://github.com/dart-lang/sdk/issues/37149 is fixed.
if (!kReleaseMode) { // ignore: prefer_const_declarations
debugLabel ??= callback.toString(); final _ComputeImpl compute = _isolates.compute;
}
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<Q, FutureOr<R>>>(
_spawn,
_IsolateConfiguration<Q, FutureOr<R>>(
callback,
message,
resultPort.sendPort,
debugLabel,
flow.id,
),
errorsAreFatal: true,
onExit: resultPort.sendPort,
onError: errorPort.sendPort,
);
final Completer<R> result = Completer<R>();
errorPort.listen((dynamic errorData) {
assert(errorData is List<dynamic>);
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<Q, R> {
const _IsolateConfiguration(
this.callback,
this.message,
this.resultPort,
this.debugLabel,
this.flowId,
);
final ComputeCallback<Q, R> callback;
final Q message;
final SendPort resultPort;
final String debugLabel;
final int flowId;
R apply() => callback(message);
}
Future<void> _spawn<Q, R>(_IsolateConfiguration<Q, FutureOr<R>> 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),
);
}
...@@ -2,23 +2,8 @@ ...@@ -2,23 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
import 'dart:io' show Platform; import '_platform_io.dart'
if (dart.library.html) '_platform_web.dart' as _platform;
import 'assertions.dart';
/// The platform that user interaction should adapt to target.
///
/// The [defaultTargetPlatform] getter returns the current platform.
enum TargetPlatform {
/// Android: <https://www.android.com/>
android,
/// Fuchsia: <https://fuchsia.googlesource.com/>
fuchsia,
/// iOS: <http://www.apple.com/ios/>
iOS,
}
/// The [TargetPlatform] that matches the platform on which the framework is /// The [TargetPlatform] that matches the platform on which the framework is
/// currently executing. /// currently executing.
...@@ -48,36 +33,20 @@ enum TargetPlatform { ...@@ -48,36 +33,20 @@ enum TargetPlatform {
// that would mean we'd be stuck with that platform forever emulating the other, // 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 // and we'd never be able to introduce dedicated behavior for that platform
// (since doing so would be a big breaking change). // (since doing so would be a big breaking change).
TargetPlatform get defaultTargetPlatform { TargetPlatform get defaultTargetPlatform => _platform.defaultTargetPlatform;
// TODO(jonahwilliams): consider where this constant should live.
const bool kIsWeb = identical(1, 1.0); /// The platform that user interaction should adapt to target.
TargetPlatform result; ///
if (kIsWeb) { /// The [defaultTargetPlatform] getter returns the current platform.
result = TargetPlatform.android; enum TargetPlatform {
} else { /// Android: <https://www.android.com/>
if (Platform.isIOS) { android,
result = TargetPlatform.iOS;
} else if (Platform.isAndroid) { /// Fuchsia: <https://fuchsia.googlesource.com/>
result = TargetPlatform.android; fuchsia,
} else if (Platform.isFuchsia) {
result = TargetPlatform.fuchsia; /// iOS: <http://www.apple.com/ios/>
} iOS,
}
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;
} }
/// Override the [defaultTargetPlatform]. /// Override the [defaultTargetPlatform].
......
...@@ -2,8 +2,7 @@ ...@@ -2,8 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
import 'dart:ui' show VoidCallback; import 'basic_types.dart';
import 'constants.dart'; import 'constants.dart';
/// DEPRECATED. `function` cannot be treeshaken out of release builds. /// DEPRECATED. `function` cannot be treeshaken out of release builds.
......
...@@ -41,10 +41,11 @@ export 'dart:ui' show ...@@ -41,10 +41,11 @@ export 'dart:ui' show
TextPosition, TextPosition,
TileMode, TileMode,
VertexMode, VertexMode,
VoidCallback,
hashValues, hashValues,
hashList; hashList;
export 'package:flutter/foundation.dart' show VoidCallback;
// Intentionally not exported: // Intentionally not exported:
// - Image, instantiateImageCodec, decodeImageFromList: // - Image, instantiateImageCodec, decodeImageFromList:
// We use ui.* to make it very explicit that these are low-level image APIs. // We use ui.* to make it very explicit that these are low-level image APIs.
......
...@@ -9,7 +9,6 @@ import 'package:flutter/animation.dart'; ...@@ -9,7 +9,6 @@ import 'package:flutter/animation.dart';
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
import 'package:flutter/gestures.dart'; import 'package:flutter/gestures.dart';
import 'package:flutter/painting.dart'; import 'package:flutter/painting.dart';
import 'package:flutter/scheduler.dart';
import 'package:flutter/semantics.dart'; import 'package:flutter/semantics.dart';
import 'package:vector_math/vector_math_64.dart'; import 'package:vector_math/vector_math_64.dart';
......
...@@ -7,7 +7,6 @@ import 'dart:async'; ...@@ -7,7 +7,6 @@ import 'dart:async';
import 'package:flutter/gestures.dart'; import 'package:flutter/gestures.dart';
import 'package:flutter/physics.dart'; import 'package:flutter/physics.dart';
import 'package:flutter/rendering.dart'; import 'package:flutter/rendering.dart';
import 'package:flutter/scheduler.dart';
import 'basic.dart'; import 'basic.dart';
import 'framework.dart'; import 'framework.dart';
......
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
// found in the LICENSE file. // found in the LICENSE file.
import 'dart:async'; import 'dart:async';
import 'dart:ui' show VoidCallback; import 'package:flutter/foundation.dart';
List<String> captureOutput(VoidCallback fn) { List<String> captureOutput(VoidCallback fn) {
final List<String> log = <String>[]; final List<String> log = <String>[];
......
...@@ -2,8 +2,6 @@ ...@@ -2,8 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
import 'dart:ui';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment