Unverified Commit 6d554827 authored by Todd Volkert's avatar Todd Volkert Committed by GitHub

Revert "Use conditional imports for flutter foundation libraries (#33663)" (#33825)

This reverts commit 90500a5d.
parent d4a83af4
......@@ -35,7 +35,6 @@ 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';
......
......@@ -2,6 +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 'package:flutter/foundation.dart';
......
......@@ -3,6 +3,7 @@
// found in the LICENSE file.
import 'dart:math' as math;
import 'dart:ui' show VoidCallback;
import 'package:flutter/foundation.dart';
......
......@@ -2,6 +2,8 @@
// 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';
......
// 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;
}
}
// 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.
// 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;
}
......@@ -8,6 +8,7 @@ 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.
///
......
......@@ -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';
......
......@@ -2,26 +2,25 @@
// 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 <https://www.dartlang.org/articles/numeric-computation/#smis-and-mints>
/// See <https://dart.dev/articles/numeric-computation/#smis-and-mints>
///
/// When compiling to JavaScript, this value is not supported since it is
/// larger than the maximum safe 32bit integer.
const int kMaxUnsignedSMI = _bitfield.kMaxUnsignedSMI;
const int kMaxUnsignedSMI = 0x3FFFFFFFFFFFFFFF;
/// 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.
abstract class BitField<T extends dynamic> {
class BitField<T extends dynamic> {
/// Creates a bit field of all zeros.
///
/// The given length must be at most 62.
factory BitField(int length) = _bitfield.BitField<T>;
BitField(this._length)
: assert(_length <= _smiBits),
_bits = _allZeros;
/// Creates a bit field filled with a particular value.
///
......@@ -29,20 +28,40 @@ abstract class BitField<T extends dynamic> {
/// the bits are filled with zeros.
///
/// The given length must be at most 62.
factory BitField.filled(int length, bool value) = _bitfield.BitField<T>.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://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.
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.
///
/// 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);
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.
///
/// 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 ]);
void reset([ bool value = false ]) {
_bits = value ? _allOnes : _allZeros;
}
}
......@@ -2,34 +2,32 @@
// 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:html implementation of [bitfield.kMaxUnsignedSMI].
/// Unsupported.
const int kMaxUnsignedSMI = 0;
/// The dart:html implementation of [bitfield.Bitfield].
class BitField<T extends dynamic> implements bitfield.BitField<T> {
/// The dart:html implementation of [bitfield.Bitfield].
// Can remove when we have metaclasses.
/// Unsupported.
class BitField<T extends dynamic> {
/// Unsupported.
// Ignored so that both bitfield implementations have the same API.
// ignore: avoid_unused_constructor_parameters
BitField(int length);
/// The dart:html implementation of [bitfield.Bitfield.filled].
// Can remove when we have metaclasses.
/// Unsupported.
// Ignored so that both bitfield implementations have the same API.
// ignore: avoid_unused_constructor_parameters
BitField.filled(int length, bool value);
@override
/// Unsupported.
bool operator [](T index) {
throw UnsupportedError('Not supported when compiling to JavaScript');
}
@override
/// Unsupported.
void operator []=(T index, bool value) {
throw UnsupportedError('Not supported when compiling to JavaScript');
}
@override
/// Unsupported.
void reset([ bool value = false ]) {
throw UnsupportedError('Not supported when compiling to JavaScript');
}
......
......@@ -3,9 +3,12 @@
// found in the LICENSE file.
import 'dart:async';
import 'dart:developer' show Timeline, Flow;
import 'dart:isolate';
import '_isolates_io.dart'
if (dart.library.html) '_isolates_web.dart' as _isolates;
import 'package:meta/meta.dart';
import 'constants.dart';
/// Signature for the callback passed to [compute].
///
......@@ -17,9 +20,6 @@ import '_isolates_io.dart'
/// {@macro flutter.foundation.compute.limitations}
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
/// (eventually) return the value returned by `callback`.
///
......@@ -44,6 +44,82 @@ typedef _ComputeImpl = Future<R> Function<Q, R>(ComputeCallback<Q, R> callback,
///
/// The `debugLabel` argument can be specified to provide a name to add to the
/// [Timeline]. This is useful when profiling an application.
// Remove when https://github.com/dart-lang/sdk/issues/37149 is fixed.
// ignore: prefer_const_declarations
final _ComputeImpl compute = _isolates.compute;
Future<R> compute<Q, R>(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 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,8 +2,23 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import '_platform_io.dart'
if (dart.library.html) '_platform_web.dart' as _platform;
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: <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
/// currently executing.
......@@ -33,20 +48,36 @@ import '_platform_io.dart'
// 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 => _platform.defaultTargetPlatform;
/// 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,
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;
}
/// Override the [defaultTargetPlatform].
......
......@@ -2,7 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'basic_types.dart';
import 'dart:ui' show VoidCallback;
import 'constants.dart';
/// DEPRECATED. `function` cannot be treeshaken out of release builds.
......
......@@ -41,11 +41,10 @@ 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.
......
......@@ -9,6 +9,7 @@ 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';
......
......@@ -7,6 +7,7 @@ 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';
......
......@@ -3,7 +3,7 @@
// found in the LICENSE file.
import 'dart:async';
import 'package:flutter/foundation.dart';
import 'dart:ui' show VoidCallback;
List<String> captureOutput(VoidCallback fn) {
final List<String> log = <String>[];
......
......@@ -2,6 +2,8 @@
// 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';
......
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