Unverified Commit 978a2e7b authored by Alexandre Ardhuin's avatar Alexandre Ardhuin Committed by GitHub

migrate foundation to nullsafety (#61188)

* migrate foundation to nullsafety

* address review comments
parent cb7770b3
......@@ -5,3 +5,7 @@ include: ../analysis_options.yaml
analyzer:
enable-experiment:
- non-nullable
errors:
always_require_non_null_named_parameters: false # not needed with nnbd
void_checks: false # https://github.com/dart-lang/linter/issues/2185
unnecessary_null_comparison: false # https://github.com/dart-lang/language/issues/1018 , turned off until https://github.com/flutter/flutter/issues/61042
......@@ -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
/// Core Flutter framework primitives.
///
/// The features defined in this library are the lowest-level utility
......
......@@ -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 'bitfield.dart' as bitfield;
/// The dart:io implementation of [bitfield.kMaxUnsignedSMI].
......
......@@ -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 'bitfield.dart' as bitfield;
/// The dart:html implementation of [bitfield.kMaxUnsignedSMI].
......
......@@ -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:developer';
import 'dart:isolate';
......@@ -13,7 +11,7 @@ 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 {
Future<R> compute<Q, R>(isolates.ComputeCallback<Q, R> callback, Q message, { String? debugLabel }) async {
debugLabel ??= kReleaseMode ? 'compute' : callback.toString();
final Flow flow = Flow.begin();
Timeline.startSync('$debugLabel: start', flow: flow);
......
......@@ -2,12 +2,10 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// @dart = 2.8
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 {
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.
......
......@@ -2,15 +2,13 @@
// 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:io';
import 'assertions.dart';
import 'platform.dart' as platform;
/// The dart:io implementation of [platform.defaultTargetPlatform].
platform.TargetPlatform get defaultTargetPlatform {
platform.TargetPlatform result;
platform.TargetPlatform? result;
if (Platform.isAndroid) {
result = platform.TargetPlatform.android;
} else if (Platform.isIOS) {
......@@ -38,5 +36,5 @@ platform.TargetPlatform get defaultTargetPlatform {
'Consider updating the list of TargetPlatforms to include this platform.'
);
}
return result;
return result!;
}
......@@ -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:html' as html;
import 'platform.dart' as platform;
......@@ -14,7 +12,7 @@ platform.TargetPlatform get defaultTargetPlatform {
// platforms configuration for Flutter.
platform.TargetPlatform result = _browserPlatform();
if (platform.debugDefaultTargetPlatformOverride != null)
result = platform.debugDefaultTargetPlatformOverride;
result = platform.debugDefaultTargetPlatformOverride!;
return result;
}
......
......@@ -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
// Examples can assume:
// class Cat { }
......
......@@ -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:meta/meta.dart';
import 'basic_types.dart';
......@@ -46,9 +44,9 @@ class PartialStackFrame {
/// Creates a new [PartialStackFrame] instance. All arguments are required and
/// must not be null.
const PartialStackFrame({
@required this.package,
@required this.className,
@required this.method,
required this.package,
required this.className,
required this.method,
}) : assert(className != null),
assert(method != null),
assert(package != null);
......@@ -102,7 +100,7 @@ abstract class StackFilter {
/// `reasons`.
///
/// To elide a frame or number of frames, set the string
void filter(List<StackFrame> stackFrames, List<String> reasons);
void filter(List<StackFrame> stackFrames, List<String?> reasons);
}
......@@ -120,8 +118,8 @@ class RepetitiveStackFrameFilter extends StackFilter {
/// Creates a new RepetitiveStackFrameFilter. All parameters are required and must not be
/// null.
const RepetitiveStackFrameFilter({
@required this.frames,
@required this.replacement,
required this.frames,
required this.replacement,
}) : assert(frames != null),
assert(replacement != null);
......@@ -141,7 +139,7 @@ class RepetitiveStackFrameFilter extends StackFilter {
List<String> get _replacements => List<String>.filled(numFrames, replacement);
@override
void filter(List<StackFrame> stackFrames, List<String> reasons) {
void filter(List<StackFrame> stackFrames, List<String?> reasons) {
for (int index = 0; index < stackFrames.length - numFrames; index += 1) {
if (_matchesFrames(stackFrames.skip(index).take(numFrames).toList())) {
reasons.setRange(index, index + numFrames, _replacements);
......@@ -222,8 +220,12 @@ abstract class _ErrorDiagnostic extends DiagnosticsProperty<List<Object>> {
level: level,
);
@override
List<Object> get value => super.value!;
@override
String valueToString({ TextTreeConfiguration parentConfiguration }) {
String valueToString({ TextTreeConfiguration? parentConfiguration }) {
return value.join('');
}
}
......@@ -400,13 +402,13 @@ class FlutterErrorDetails with Diagnosticable {
/// Creates a copy of the error details but with the given fields replaced
/// with new values.
FlutterErrorDetails copyWith({
DiagnosticsNode context,
DiagnosticsNode? context,
dynamic exception,
InformationCollector informationCollector,
String library,
bool silent,
StackTrace stack,
IterableFilter<String> stackFilter,
InformationCollector? informationCollector,
String? library,
bool? silent,
StackTrace? stack,
IterableFilter<String>? stackFilter,
}) {
return FlutterErrorDetails(
context: context ?? this.context,
......@@ -448,12 +450,12 @@ class FlutterErrorDetails with Diagnosticable {
/// callback, then [FlutterError.defaultStackFilter] is used instead. That
/// function expects the stack to be in the format used by
/// [StackTrace.toString].
final StackTrace stack;
final StackTrace? stack;
/// A human-readable brief name describing the library that caught the error
/// message. This is used by the default error handler in the header dumped to
/// the console.
final String library;
final String? library;
/// A [DiagnosticsNode] that provides a human-readable description of where
/// the error was caught (as opposed to where it was thrown).
......@@ -494,7 +496,7 @@ class FlutterErrorDetails with Diagnosticable {
/// applicable.
/// * [FlutterError], which is the most common place to use
/// [FlutterErrorDetails].
final DiagnosticsNode context;
final DiagnosticsNode? context;
/// A callback which filters the [stack] trace. Receives an iterable of
/// strings representing the frames encoded in the way that
......@@ -510,7 +512,7 @@ class FlutterErrorDetails with Diagnosticable {
/// that function, however, does not always follow this format.
///
/// This won't be called if [stack] is null.
final IterableFilter<String> stackFilter;
final IterableFilter<String>? stackFilter;
/// A callback which, when called with a [StringBuffer] will write to that buffer
/// information that could help with debugging the problem.
......@@ -520,7 +522,7 @@ class FlutterErrorDetails with Diagnosticable {
///
/// The text written to the information argument may contain newlines but should
/// not end with a newline.
final InformationCollector informationCollector;
final InformationCollector? informationCollector;
/// Whether this error should be ignored by the default error reporting
/// behavior in release mode.
......@@ -544,13 +546,13 @@ class FlutterErrorDetails with Diagnosticable {
/// prettier, to handle exceptions that stringify to empty strings, to handle
/// objects that don't inherit from [Exception] or [Error], and so forth.
String exceptionAsString() {
String longMessage;
String? longMessage;
if (exception is AssertionError) {
// Regular _AssertionErrors thrown by assert() put the message last, after
// some code snippets. This leads to ugly messages. To avoid this, we move
// the assertion message up to before the code snippets, separated by a
// newline, if we recognize that format is being used.
final Object message = exception.message;
final Object? message = exception.message;
final String fullMessage = exception.toString();
if (message is String && message != fullMessage) {
if (fullMessage.length > message.length) {
......@@ -583,7 +585,7 @@ class FlutterErrorDetails with Diagnosticable {
return longMessage;
}
Diagnosticable _exceptionToDiagnosticable() {
Diagnosticable? _exceptionToDiagnosticable() {
if (exception is FlutterError) {
return exception as FlutterError;
}
......@@ -606,12 +608,12 @@ class FlutterErrorDetails with Diagnosticable {
if (kReleaseMode) {
return DiagnosticsNode.message(formatException());
}
final Diagnosticable diagnosticable = _exceptionToDiagnosticable();
DiagnosticsNode summary;
final Diagnosticable? diagnosticable = _exceptionToDiagnosticable();
DiagnosticsNode? summary;
if (diagnosticable != null) {
final DiagnosticPropertiesBuilder builder = DiagnosticPropertiesBuilder();
debugFillProperties(builder);
summary = builder.properties.firstWhere((DiagnosticsNode node) => node.level == DiagnosticLevel.summary, orElse: () => null);
summary = builder.properties.cast<DiagnosticsNode?>().firstWhere((DiagnosticsNode? node) => node!.level == DiagnosticLevel.summary, orElse: () => null);
}
return summary ?? ErrorSummary(formatException());
}
......@@ -620,7 +622,7 @@ class FlutterErrorDetails with Diagnosticable {
void debugFillProperties(DiagnosticPropertiesBuilder properties) {
super.debugFillProperties(properties);
final DiagnosticsNode verb = ErrorDescription('thrown${ context != null ? ErrorDescription(" $context") : ""}');
final Diagnosticable diagnosticable = _exceptionToDiagnosticable();
final Diagnosticable? diagnosticable = _exceptionToDiagnosticable();
if (exception is NullThrownError) {
properties.add(ErrorDescription('The null value was $verb.'));
} else if (exception is num) {
......@@ -659,7 +661,7 @@ class FlutterErrorDetails with Diagnosticable {
// If not: Error is in user code (user violated assertion in framework).
// If so: Error is in Framework. We either need an assertion higher up
// in the stack, or we've violated our own assertions.
final List<StackFrame> stackFrames = StackFrame.fromStackTrace(FlutterError.demangleStackTrace(stack))
final List<StackFrame> stackFrames = StackFrame.fromStackTrace(FlutterError.demangleStackTrace(stack!))
.skipWhile((StackFrame frame) => frame.packageScheme == 'dart')
.toList();
final bool ourFault = stackFrames.length >= 2
......@@ -677,11 +679,11 @@ class FlutterErrorDetails with Diagnosticable {
}
}
properties.add(ErrorSpacer());
properties.add(DiagnosticsStackTrace('When the exception was thrown, this was the stack', stack, stackFilter: stackFilter));
properties.add(DiagnosticsStackTrace('When the exception was thrown, this was the stack', stack!, stackFilter: stackFilter));
}
if (informationCollector != null) {
properties.add(ErrorSpacer());
informationCollector().forEach(properties.add);
informationCollector!().forEach(properties.add);
}
}
......@@ -696,7 +698,7 @@ class FlutterErrorDetails with Diagnosticable {
}
@override
DiagnosticsNode toDiagnosticsNode({ String name, DiagnosticsTreeStyle style }) {
DiagnosticsNode toDiagnosticsNode({ String? name, DiagnosticsTreeStyle? style }) {
return _FlutterErrorDetailsNode(
name: name,
value: this,
......@@ -866,9 +868,6 @@ class FlutterError extends Error with DiagnosticableTreeMixin implements Asserti
///
/// If the error handler throws an exception, it will not be caught by the
/// Flutter framework.
///
/// Set this to null to silently catch and ignore errors. This is not
/// recommended.
static FlutterExceptionHandler onError = (FlutterErrorDetails details) => presentError(details);
/// Called by the Flutter framework before attempting to parse a [StackTrace].
......@@ -1005,17 +1004,17 @@ class FlutterError extends Error with DiagnosticableTreeMixin implements Asserti
final String package = '${frame.packageScheme}:${frame.package}';
if (removedPackagesAndClasses.containsKey(className)) {
skipped += 1;
removedPackagesAndClasses[className] += 1;
removedPackagesAndClasses.update(className, (int value) => value + 1);
parsedFrames.removeAt(index);
index -= 1;
} else if (removedPackagesAndClasses.containsKey(package)) {
skipped += 1;
removedPackagesAndClasses[package] += 1;
removedPackagesAndClasses.update(package, (int value) => value + 1);
parsedFrames.removeAt(index);
index -= 1;
}
}
final List<String> reasons = List<String>(parsedFrames.length);
final List<String?> reasons = List<String?>.filled(parsedFrames.length, null, growable: false);
for (final StackFilter filter in _stackFilters) {
filter.filter(parsedFrames, reasons);
}
......@@ -1062,7 +1061,7 @@ class FlutterError extends Error with DiagnosticableTreeMixin implements Asserti
@override
void debugFillProperties(DiagnosticPropertiesBuilder properties) {
diagnostics?.forEach(properties.add);
diagnostics.forEach(properties.add);
}
@override
......@@ -1079,12 +1078,11 @@ class FlutterError extends Error with DiagnosticableTreeMixin implements Asserti
return diagnostics.map((DiagnosticsNode node) => renderer.render(node).trimRight()).join('\n');
}
/// Calls [onError] with the given details, unless it is null.
/// Calls [onError] with the given details.
static void reportError(FlutterErrorDetails details) {
assert(details != null);
assert(details.exception != null);
if (onError != null)
onError(details);
onError(details);
}
}
......@@ -1099,7 +1097,7 @@ class FlutterError extends Error with DiagnosticableTreeMixin implements Asserti
/// included.
///
/// The `label` argument, if present, will be printed before the stack.
void debugPrintStack({StackTrace stackTrace, String label, int maxFrames}) {
void debugPrintStack({StackTrace? stackTrace, String? label, int? maxFrames}) {
if (label != null)
debugPrint(label);
if (stackTrace == null) {
......@@ -1136,8 +1134,8 @@ class DiagnosticsStackTrace extends DiagnosticsBlock {
/// [showSeparator] indicates whether to include a ':' after the [name].
DiagnosticsStackTrace(
String name,
StackTrace stack, {
IterableFilter<String> stackFilter,
StackTrace? stack, {
IterableFilter<String>? stackFilter,
bool showSeparator = true,
}) : super(
name: name,
......@@ -1151,7 +1149,7 @@ class DiagnosticsStackTrace extends DiagnosticsBlock {
/// Creates a diagnostic describing a single frame from a StackTrace.
DiagnosticsStackTrace.singleFrame(
String name, {
@required String frame,
required String frame,
bool showSeparator = true,
}) : super(
name: name,
......@@ -1161,8 +1159,8 @@ class DiagnosticsStackTrace extends DiagnosticsBlock {
);
static List<DiagnosticsNode> _applyStackFilter(
StackTrace stack,
IterableFilter<String> stackFilter,
StackTrace? stack,
IterableFilter<String>? stackFilter,
) {
if (stack == null)
return <DiagnosticsNode>[];
......@@ -1178,9 +1176,9 @@ class DiagnosticsStackTrace extends DiagnosticsBlock {
class _FlutterErrorDetailsNode extends DiagnosticableNode<FlutterErrorDetails> {
_FlutterErrorDetailsNode({
String name,
@required FlutterErrorDetails value,
@required DiagnosticsTreeStyle style,
String? name,
required FlutterErrorDetails value,
required DiagnosticsTreeStyle? style,
}) : super(
name: name,
value: value,
......@@ -1188,8 +1186,8 @@ class _FlutterErrorDetailsNode extends DiagnosticableNode<FlutterErrorDetails> {
);
@override
DiagnosticPropertiesBuilder get builder {
final DiagnosticPropertiesBuilder builder = super.builder;
DiagnosticPropertiesBuilder? get builder {
final DiagnosticPropertiesBuilder? builder = super.builder;
if (builder == null){
return null;
}
......
......@@ -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';
......@@ -207,7 +205,7 @@ class _LazyListIterator<E> implements Iterator<E> {
E get current {
assert(_index >= 0); // called "current" before "moveNext()"
if (_index < 0 || _index == _owner._results.length)
return null;
throw StateError('current can not be call after moveNext has returned false');
return _owner._results[_index];
}
......
......@@ -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:convert' show json;
import 'dart:developer' as developer;
......@@ -316,8 +314,8 @@ abstract class BindingBase {
/// {@macro flutter.foundation.bindingBase.registerServiceExtension}
@protected
void registerSignalServiceExtension({
@required String name,
@required AsyncCallback callback,
required String name,
required AsyncCallback callback,
}) {
assert(name != null);
assert(callback != null);
......@@ -346,9 +344,9 @@ abstract class BindingBase {
/// {@macro flutter.foundation.bindingBase.registerServiceExtension}
@protected
void registerBoolServiceExtension({
@required String name,
@required AsyncValueGetter<bool> getter,
@required AsyncValueSetter<bool> setter,
required String name,
required AsyncValueGetter<bool> getter,
required AsyncValueSetter<bool> setter,
}) {
assert(name != null);
assert(getter != null);
......@@ -380,9 +378,9 @@ abstract class BindingBase {
/// {@macro flutter.foundation.bindingBase.registerServiceExtension}
@protected
void registerNumericServiceExtension({
@required String name,
@required AsyncValueGetter<double> getter,
@required AsyncValueSetter<double> setter,
required String name,
required AsyncValueGetter<double> getter,
required AsyncValueSetter<double> setter,
}) {
assert(name != null);
assert(getter != null);
......@@ -391,7 +389,7 @@ abstract class BindingBase {
name: name,
callback: (Map<String, String> parameters) async {
if (parameters.containsKey(name)) {
await setter(double.parse(parameters[name]));
await setter(double.parse(parameters[name]!));
_postExtensionStateChangedEvent(name, (await getter()).toString());
}
return <String, dynamic>{name: (await getter()).toString()};
......@@ -442,9 +440,9 @@ abstract class BindingBase {
/// {@macro flutter.foundation.bindingBase.registerServiceExtension}
@protected
void registerStringServiceExtension({
@required String name,
@required AsyncValueGetter<String> getter,
@required AsyncValueSetter<String> setter,
required String name,
required AsyncValueGetter<String> getter,
required AsyncValueSetter<String> setter,
}) {
assert(name != null);
assert(getter != null);
......@@ -453,7 +451,7 @@ abstract class BindingBase {
name: name,
callback: (Map<String, String> parameters) async {
if (parameters.containsKey('value')) {
await setter(parameters['value']);
await setter(parameters['value']!);
_postExtensionStateChangedEvent(name, await getter());
}
return <String, dynamic>{'value': await getter()};
......@@ -514,8 +512,8 @@ abstract class BindingBase {
/// {@endtemplate}
@protected
void registerServiceExtension({
@required String name,
@required ServiceExtensionCallback callback,
required String name,
required ServiceExtensionCallback callback,
}) {
assert(name != null);
assert(callback != null);
......@@ -543,8 +541,8 @@ abstract class BindingBase {
});
dynamic caughtException;
StackTrace caughtStack;
Map<String, dynamic> result;
StackTrace? caughtStack;
late Map<String, dynamic> result;
try {
result = await callback(parameters);
} catch (exception, stack) {
......
......@@ -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 '_bitfield_io.dart'
if (dart.library.html) '_bitfield_web.dart' as _bitfield;
......
......@@ -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:meta/meta.dart';
import 'assertions.dart';
......@@ -65,7 +63,7 @@ abstract class Listenable {
/// will lead to memory leaks or exceptions.
///
/// The list may contain nulls; they are ignored.
factory Listenable.merge(List<Listenable> listenables) = _MergingListenable;
factory Listenable.merge(List<Listenable?> listenables) = _MergingListenable;
/// Register a closure to be called when the object notifies its listeners.
void addListener(VoidCallback listener);
......@@ -100,7 +98,7 @@ abstract class ValueListenable<T> extends Listenable {
///
/// * [ValueNotifier], which is a [ChangeNotifier] that wraps a single value.
class ChangeNotifier implements Listenable {
ObserverList<VoidCallback> _listeners = ObserverList<VoidCallback>();
ObserverList<VoidCallback>? _listeners = ObserverList<VoidCallback>();
bool _debugAssertNotDisposed() {
assert(() {
......@@ -133,7 +131,7 @@ class ChangeNotifier implements Listenable {
@protected
bool get hasListeners {
assert(_debugAssertNotDisposed());
return _listeners.isNotEmpty;
return _listeners!.isNotEmpty;
}
/// Register a closure to be called when the object changes.
......@@ -142,7 +140,7 @@ class ChangeNotifier implements Listenable {
@override
void addListener(VoidCallback listener) {
assert(_debugAssertNotDisposed());
_listeners.add(listener);
_listeners!.add(listener);
}
/// Remove a previously registered closure from the list of closures that are
......@@ -167,7 +165,7 @@ class ChangeNotifier implements Listenable {
@override
void removeListener(VoidCallback listener) {
assert(_debugAssertNotDisposed());
_listeners.remove(listener);
_listeners!.remove(listener);
}
/// Discards any resources used by the object. After this is called, the
......@@ -202,10 +200,10 @@ class ChangeNotifier implements Listenable {
void notifyListeners() {
assert(_debugAssertNotDisposed());
if (_listeners != null) {
final List<VoidCallback> localListeners = List<VoidCallback>.from(_listeners);
final List<VoidCallback> localListeners = List<VoidCallback>.from(_listeners!);
for (final VoidCallback listener in localListeners) {
try {
if (_listeners.contains(listener))
if (_listeners!.contains(listener))
listener();
} catch (exception, stack) {
FlutterError.reportError(FlutterErrorDetails(
......@@ -230,18 +228,18 @@ class ChangeNotifier implements Listenable {
class _MergingListenable extends Listenable {
_MergingListenable(this._children);
final List<Listenable> _children;
final List<Listenable?> _children;
@override
void addListener(VoidCallback listener) {
for (final Listenable child in _children) {
for (final Listenable? child in _children) {
child?.addListener(listener);
}
}
@override
void removeListener(VoidCallback listener) {
for (final Listenable child in _children) {
for (final Listenable? child in _children) {
child?.removeListener(listener);
}
}
......
......@@ -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
// TODO(ianh): These should be on the Set and List classes themselves.
/// Compares two sets for deep equality.
......@@ -21,7 +19,7 @@
///
/// * [listEquals], which does something similar for lists.
/// * [mapEquals], which does something similar for maps.
bool setEquals<T>(Set<T> a, Set<T> b) {
bool setEquals<T>(Set<T>? a, Set<T>? b) {
if (a == null)
return b == null;
if (b == null || a.length != b.length)
......@@ -50,7 +48,7 @@ bool setEquals<T>(Set<T> a, Set<T> b) {
///
/// * [setEquals], which does something similar for sets.
/// * [mapEquals], which does something similar for maps.
bool listEquals<T>(List<T> a, List<T> b) {
bool listEquals<T>(List<T>? a, List<T>? b) {
if (a == null)
return b == null;
if (b == null || a.length != b.length)
......@@ -79,7 +77,7 @@ bool listEquals<T>(List<T> a, List<T> b) {
///
/// * [setEquals], which does something similar for sets.
/// * [listEquals], which does something similar for lists.
bool mapEquals<T, U>(Map<T, U> a, Map<T, U> b) {
bool mapEquals<T, U>(Map<T, U>? a, Map<T, U>? b) {
if (a == null)
return b == null;
if (b == null || a.length != b.length)
......@@ -145,8 +143,8 @@ const int _kMergeSortLimit = 32;
void mergeSort<T>(
List<T> list, {
int start = 0,
int end,
int Function(T, T) compare,
int? end,
int Function(T, T)? compare,
}) {
end ??= list.length;
compare ??= _defaultCompare<T>();
......@@ -156,7 +154,7 @@ void mergeSort<T>(
return;
}
if (length < _kMergeSortLimit) {
_insertionSort(list, compare: compare, start: start, end: end);
_insertionSort<T>(list, compare: compare, start: start, end: end);
return;
}
// Special case the first split instead of directly calling _mergeSort,
......@@ -168,11 +166,11 @@ void mergeSort<T>(
final int firstLength = middle - start;
final int secondLength = end - middle;
// secondLength is always the same as firstLength, or one greater.
final List<T> scratchSpace = List<T>(secondLength);
_mergeSort(list, compare, middle, end, scratchSpace, 0);
final List<T?> scratchSpace = List<T?>.filled(secondLength, null, growable: false);
_mergeSort<T>(list, compare, middle, end, scratchSpace, 0);
final int firstTarget = end - firstLength;
_mergeSort(list, compare, start, middle, list, firstTarget);
_merge(compare, list, firstTarget, end, scratchSpace, 0, secondLength, list, start);
_mergeSort<T>(list, compare, start, middle, list, firstTarget);
_merge<T>(compare, list, firstTarget, end, scratchSpace, 0, secondLength, list, start);
}
/// Returns a [Comparator] that asserts that its first argument is comparable.
......@@ -202,9 +200,9 @@ Comparator<T> _defaultCompare<T>() {
/// they started in.
void _insertionSort<T>(
List<T> list, {
int Function(T, T) compare,
int Function(T, T)? compare,
int start = 0,
int end,
int? end,
}) {
// If the same method could have both positional and named optional
// parameters, this should be (list, [start, end], {compare}).
......@@ -238,7 +236,7 @@ void _movingInsertionSort<T>(
int Function(T, T) compare,
int start,
int end,
List<T> target,
List<T?> target,
int targetOffset,
) {
final int length = end - start;
......@@ -252,7 +250,7 @@ void _movingInsertionSort<T>(
int max = targetOffset + i;
while (min < max) {
final int mid = min + ((max - min) >> 1);
if (compare(element, target[mid]) < 0) {
if (compare(element, target[mid] as T) < 0) {
max = mid;
} else {
min = mid + 1;
......@@ -275,12 +273,12 @@ void _mergeSort<T>(
int Function(T, T) compare,
int start,
int end,
List<T> target,
List<T?> target,
int targetOffset,
) {
final int length = end - start;
if (length < _kMergeSortLimit) {
_movingInsertionSort(list, compare, start, end, target, targetOffset);
_movingInsertionSort<T>(list, compare, start, end, target, targetOffset);
return;
}
final int middle = start + (length >> 1);
......@@ -289,11 +287,11 @@ void _mergeSort<T>(
// Here secondLength >= firstLength (differs by at most one).
final int targetMiddle = targetOffset + firstLength;
// Sort the second half into the end of the target area.
_mergeSort(list, compare, middle, end, target, targetMiddle);
_mergeSort<T>(list, compare, middle, end, target, targetMiddle);
// Sort the first half into the end of the source area.
_mergeSort(list, compare, start, middle, list, middle);
_mergeSort<T>(list, compare, start, middle, list, middle);
// Merge the two parts into the target area.
_merge(
_merge<T>(
compare,
list,
middle,
......@@ -318,10 +316,10 @@ void _merge<T>(
List<T> firstList,
int firstStart,
int firstEnd,
List<T> secondList,
List<T?> secondList,
int secondStart,
int secondEnd,
List<T> target,
List<T?> target,
int targetOffset,
) {
// No empty lists reaches here.
......@@ -330,7 +328,7 @@ void _merge<T>(
int cursor1 = firstStart;
int cursor2 = secondStart;
T firstElement = firstList[cursor1++];
T secondElement = secondList[cursor2++];
T secondElement = secondList[cursor2++] as T;
while (true) {
if (compare(firstElement, secondElement) <= 0) {
target[targetOffset++] = firstElement;
......@@ -342,7 +340,7 @@ void _merge<T>(
} else {
target[targetOffset++] = secondElement;
if (cursor2 != secondEnd) {
secondElement = secondList[cursor2++];
secondElement = secondList[cursor2++] as T;
continue;
}
// Second list empties first. Flushing first list here.
......
......@@ -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:convert';
import 'dart:io';
......@@ -25,7 +23,7 @@ import 'dart:typed_data';
/// until the request has been fully processed).
///
/// This is used in [consolidateHttpClientResponseBytes].
typedef BytesReceivedCallback = void Function(int cumulative, int total);
typedef BytesReceivedCallback = void Function(int cumulative, int? total);
/// Efficiently converts the response body of an [HttpClientResponse] into a
/// [Uint8List].
......@@ -48,14 +46,14 @@ typedef BytesReceivedCallback = void Function(int cumulative, int total);
Future<Uint8List> consolidateHttpClientResponseBytes(
HttpClientResponse response, {
bool autoUncompress = true,
BytesReceivedCallback onBytesReceived,
BytesReceivedCallback? onBytesReceived,
}) {
assert(autoUncompress != null);
final Completer<Uint8List> completer = Completer<Uint8List>.sync();
final _OutputBuffer output = _OutputBuffer();
ByteConversionSink sink = output;
int expectedContentLength = response.contentLength;
int? expectedContentLength = response.contentLength;
if (expectedContentLength == -1)
expectedContentLength = null;
switch (response.compressionState) {
......@@ -76,7 +74,7 @@ Future<Uint8List> consolidateHttpClientResponseBytes(
}
int bytesReceived = 0;
StreamSubscription<List<int>> subscription;
late final StreamSubscription<List<int>> subscription;
subscription = response.listen((List<int> chunk) {
sink.add(chunk);
if (onBytesReceived != null) {
......@@ -98,14 +96,14 @@ Future<Uint8List> consolidateHttpClientResponseBytes(
}
class _OutputBuffer extends ByteConversionSinkBase {
List<List<int>> _chunks = <List<int>>[];
List<List<int>>? _chunks = <List<int>>[];
int _contentLength = 0;
Uint8List _bytes;
Uint8List? _bytes;
@override
void add(List<int> chunk) {
assert(_bytes == null);
_chunks.add(chunk);
_chunks!.add(chunk);
_contentLength += chunk.length;
}
......@@ -117,8 +115,8 @@ class _OutputBuffer extends ByteConversionSinkBase {
}
_bytes = Uint8List(_contentLength);
int offset = 0;
for (final List<int> chunk in _chunks) {
_bytes.setRange(offset, offset + chunk.length, chunk);
for (final List<int> chunk in _chunks!) {
_bytes!.setRange(offset, offset + chunk.length, chunk);
offset += chunk.length;
}
_chunks = null;
......@@ -126,6 +124,6 @@ class _OutputBuffer extends ByteConversionSinkBase {
Uint8List get bytes {
assert(_bytes != null);
return _bytes;
return _bytes!;
}
}
......@@ -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
/// A constant that is true if the application was compiled in release mode.
///
/// More specifically, this is a constant that is true if the application was
......
......@@ -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:ui' as ui show Brightness;
......@@ -54,7 +52,7 @@ bool debugInstrumentationEnabled = false;
/// * [Timeline], which is used to record synchronous tracing events for
/// visualization in Chrome's tracing format. This method does not
/// implicitly add any timeline events.
Future<T> debugInstrumentAction<T>(String description, Future<T> action()) {
Future<T> debugInstrumentAction<T>(String description, Future<T> action()) async {
bool instrument = false;
assert(() {
instrument = debugInstrumentationEnabled;
......@@ -62,10 +60,12 @@ Future<T> debugInstrumentAction<T>(String description, Future<T> action()) {
}());
if (instrument) {
final Stopwatch stopwatch = Stopwatch()..start();
return action().whenComplete(() {
try {
return await action();
} finally {
stopwatch.stop();
debugPrint('Action "$description" took ${stopwatch.elapsed}');
});
}
} else {
return action();
}
......@@ -87,17 +87,17 @@ const Map<String, String> timelineArgumentsIndicatingLandmarkEvent = <String, St
/// Configure [debugFormatDouble] using [num.toStringAsPrecision].
///
/// Defaults to null, which uses the default logic of [debugFormatDouble].
int debugDoublePrecision;
int? debugDoublePrecision;
/// Formats a double to have standard formatting.
///
/// This behavior can be overridden by [debugDoublePrecision].
String debugFormatDouble(double value) {
String debugFormatDouble(double? value) {
if (value == null) {
return 'null';
}
if (debugDoublePrecision != null) {
return value.toStringAsPrecision(debugDoublePrecision);
return value.toStringAsPrecision(debugDoublePrecision!);
}
return value.toStringAsFixed(1);
}
......@@ -109,4 +109,4 @@ String debugFormatDouble(double value) {
///
/// * [WidgetsApp], which uses the [debugBrightnessOverride] setting in debug mode
/// to construct a [MediaQueryData].
ui.Brightness debugBrightnessOverride;
ui.Brightness? debugBrightnessOverride;
......@@ -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:math' as math;
import 'package:meta/meta.dart';
......@@ -203,13 +201,13 @@ class TextTreeConfiguration {
///
/// All of the arguments must not be null.
TextTreeConfiguration({
@required this.prefixLineOne,
@required this.prefixOtherLines,
@required this.prefixLastChildLineOne,
@required this.prefixOtherLinesRootNode,
@required this.linkCharacter,
@required this.propertyPrefixIfChildren,
@required this.propertyPrefixNoChildren,
required this.prefixLineOne,
required this.prefixOtherLines,
required this.prefixLastChildLineOne,
required this.prefixOtherLinesRootNode,
required this.linkCharacter,
required this.propertyPrefixIfChildren,
required this.propertyPrefixNoChildren,
this.lineBreak = '\n',
this.lineBreakProperties = true,
this.afterName = ':',
......@@ -786,8 +784,8 @@ enum _WordWrapParseMode { inSpace, inWord, atBreak }
/// [prefixOtherLines].
class _PrefixedStringBuilder {
_PrefixedStringBuilder({
@required this.prefixLineOne,
@required String prefixOtherLines,
required this.prefixLineOne,
required String? prefixOtherLines,
this.wrapWidth}) :
_prefixOtherLines = prefixOtherLines;
......@@ -798,24 +796,24 @@ class _PrefixedStringBuilder {
///
/// The prefix can be modified while the string is being built in which case
/// subsequent lines will be added with the modified prefix.
String get prefixOtherLines => _nextPrefixOtherLines ?? _prefixOtherLines;
String _prefixOtherLines;
set prefixOtherLines(String prefix) {
String? get prefixOtherLines => _nextPrefixOtherLines ?? _prefixOtherLines;
String? _prefixOtherLines;
set prefixOtherLines(String? prefix) {
_prefixOtherLines = prefix;
_nextPrefixOtherLines = null;
}
String _nextPrefixOtherLines;
void incrementPrefixOtherLines(String suffix, {@required bool updateCurrentLine}) {
String? _nextPrefixOtherLines;
void incrementPrefixOtherLines(String suffix, {required bool updateCurrentLine}) {
if (_currentLine.isEmpty || updateCurrentLine) {
_prefixOtherLines = prefixOtherLines + suffix;
_prefixOtherLines = prefixOtherLines! + suffix;
_nextPrefixOtherLines = null;
} else {
_nextPrefixOtherLines = prefixOtherLines + suffix;
_nextPrefixOtherLines = prefixOtherLines! + suffix;
}
}
final int wrapWidth;
final int? wrapWidth;
/// Buffer containing lines that have already been completely laid out.
final StringBuffer _buffer = StringBuffer();
......@@ -827,7 +825,7 @@ class _PrefixedStringBuilder {
/// Whether the string being built already has more than 1 line.
bool get requiresMultipleLines => _numLines > 1 || (_numLines == 1 && _currentLine.isNotEmpty) ||
(_currentLine.length + _getCurrentPrefix(true).length > wrapWidth);
(_currentLine.length + _getCurrentPrefix(true)!.length > wrapWidth!);
bool get isCurrentLineEmpty => _currentLine.isEmpty;
......@@ -850,9 +848,9 @@ class _PrefixedStringBuilder {
final Iterable<String> lines = _wordWrapLine(
text,
_wrappableRanges,
wrapWidth,
startOffset: firstLine ? prefixLineOne.length : _prefixOtherLines.length,
otherLineOffset: firstLine ? _prefixOtherLines.length : _prefixOtherLines.length,
wrapWidth!,
startOffset: firstLine ? prefixLineOne.length : _prefixOtherLines!.length,
otherLineOffset: firstLine ? _prefixOtherLines!.length : _prefixOtherLines!.length,
);
int i = 0;
final int length = lines.length;
......@@ -887,8 +885,8 @@ class _PrefixedStringBuilder {
bool addPrefix = false;
int index = 0;
_WordWrapParseMode mode = _WordWrapParseMode.inSpace;
int lastWordStart;
int lastWordEnd;
late int lastWordStart;
int? lastWordEnd;
int start = 0;
int currentChunk = 0;
......@@ -1000,8 +998,8 @@ class _PrefixedStringBuilder {
void _writeLine(
String line, {
@required bool includeLineBreak,
@required bool firstLine,
required bool includeLineBreak,
required bool firstLine,
}) {
line = '${_getCurrentPrefix(firstLine)}$line';
_buffer.write(line.trimRight());
......@@ -1010,7 +1008,7 @@ class _PrefixedStringBuilder {
_numLines++;
}
String _getCurrentPrefix(bool firstLine) {
String? _getCurrentPrefix(bool firstLine) {
return _buffer.isEmpty ? prefixLineOne : (firstLine ? _prefixOtherLines : _prefixOtherLines);
}
......@@ -1035,7 +1033,7 @@ class _PrefixedStringBuilder {
/// Finishes the current line with a stretched version of text.
void writeStretched(String text, int targetLineLength) {
write(text);
final int currentLineLength = _currentLine.length + _getCurrentPrefix(_buffer.isEmpty).length;
final int currentLineLength = _currentLine.length + _getCurrentPrefix(_buffer.isEmpty)!.length;
assert (_currentLine.length > 0);
final int targetLength = targetLineLength - currentLineLength;
if (targetLength > 0) {
......@@ -1063,7 +1061,7 @@ class _NoDefaultValue {
/// Marker object indicating that a [DiagnosticsNode] has no default value.
const _NoDefaultValue kNoDefaultValue = _NoDefaultValue();
bool _isSingleLine(DiagnosticsTreeStyle style) {
bool _isSingleLine(DiagnosticsTreeStyle? style) {
return style == DiagnosticsTreeStyle.singleLine;
}
......@@ -1107,11 +1105,11 @@ class TextTreeRenderer {
/// parent to the child should be consistent with the parent's style as the
/// single line style does not provide any meaningful style for how children
/// should be connected to their parents.
TextTreeConfiguration _childTextConfiguration(
TextTreeConfiguration? _childTextConfiguration(
DiagnosticsNode child,
TextTreeConfiguration textStyle,
) {
final DiagnosticsTreeStyle childStyle = child?.style;
final DiagnosticsTreeStyle? childStyle = child.style;
return (_isSingleLine(childStyle) || childStyle == DiagnosticsTreeStyle.errorProperty) ? textStyle : child.textTreeConfiguration;
}
......@@ -1119,8 +1117,8 @@ class TextTreeRenderer {
String render(
DiagnosticsNode node, {
String prefixLineOne = '',
String prefixOtherLines,
TextTreeConfiguration parentConfiguration,
String? prefixOtherLines,
TextTreeConfiguration? parentConfiguration,
}) {
if (kReleaseMode) {
return '';
......@@ -1136,17 +1134,17 @@ class TextTreeRenderer {
String _debugRender(
DiagnosticsNode node, {
String prefixLineOne = '',
String prefixOtherLines,
TextTreeConfiguration parentConfiguration,
String? prefixOtherLines,
TextTreeConfiguration? parentConfiguration,
}) {
final bool isSingleLine = _isSingleLine(node.style) && parentConfiguration?.lineBreakProperties != true;
prefixOtherLines ??= prefixLineOne;
if (node.linePrefix != null) {
prefixLineOne += node.linePrefix;
prefixOtherLines += node.linePrefix;
prefixLineOne += node.linePrefix!;
prefixOtherLines += node.linePrefix!;
}
final TextTreeConfiguration config = node.textTreeConfiguration;
final TextTreeConfiguration config = node.textTreeConfiguration!;
if (prefixOtherLines.isEmpty)
prefixOtherLines += config.prefixOtherLinesRootNode;
......@@ -1192,14 +1190,14 @@ class TextTreeRenderer {
List<DiagnosticsNode> children = node.getChildren();
String description = node.toDescription(parentConfiguration: parentConfiguration);
String? description = node.toDescription(parentConfiguration: parentConfiguration);
if (config.beforeName.isNotEmpty) {
builder.write(config.beforeName);
}
final bool wrapName = !isSingleLine && node.allowNameWrap;
final bool wrapDescription = !isSingleLine && node.allowWrap;
final bool uppercaseTitle = node.style == DiagnosticsTreeStyle.error;
String name = node.name;
String? name = node.name;
if (uppercaseTitle) {
name = name?.toUpperCase();
}
......@@ -1244,7 +1242,7 @@ class TextTreeRenderer {
}
}
if (config.suffixLineOne.isNotEmpty) {
builder.writeStretched(config.suffixLineOne, builder.wrapWidth);
builder.writeStretched(config.suffixLineOne, builder.wrapWidth!);
}
final Iterable<DiagnosticsNode> propertiesIterable = node.getProperties().where(
......@@ -1287,7 +1285,7 @@ class TextTreeRenderer {
properties.isEmpty &&
children.isEmpty &&
prefixLineOne.isNotEmpty) {
builder.write(node.emptyBodyDescription);
builder.write(node.emptyBodyDescription!);
if (config.lineBreakProperties)
builder.write(config.lineBreak);
}
......@@ -1297,7 +1295,7 @@ class TextTreeRenderer {
if (i > 0)
builder.write(config.propertySeparator);
final TextTreeConfiguration propertyStyle = property.textTreeConfiguration;
final TextTreeConfiguration propertyStyle = property.textTreeConfiguration!;
if (_isSingleLine(property.style)) {
// We have to treat single line properties slightly differently to deal
// with cases where a single line properties output may not have single
......@@ -1337,7 +1335,7 @@ class TextTreeRenderer {
if (children.isEmpty &&
config.addBlankLineIfNoChildren &&
builder.requiresMultipleLines &&
builder.prefixOtherLines.trimRight().isNotEmpty
builder.prefixOtherLines!.trimRight().isNotEmpty
) {
builder.write(config.lineBreak);
}
......@@ -1345,7 +1343,7 @@ class TextTreeRenderer {
if (children.isNotEmpty && config.showChildren) {
if (config.isBlankLineBetweenPropertiesAndChildren &&
properties.isNotEmpty &&
children.first.textTreeConfiguration.isBlankLineBetweenPropertiesAndChildren) {
children.first.textTreeConfiguration!.isBlankLineBetweenPropertiesAndChildren) {
builder.write(config.lineBreak);
}
......@@ -1354,7 +1352,7 @@ class TextTreeRenderer {
for (int i = 0; i < children.length; i++) {
final DiagnosticsNode child = children[i];
assert(child != null);
final TextTreeConfiguration childConfig = _childTextConfiguration(child, config);
final TextTreeConfiguration childConfig = _childTextConfiguration(child, config)!;
if (i == children.length - 1) {
final String lastChildPrefixLineOne = '$prefixChildrenRaw${childConfig.prefixLastChildLineOne}';
final String childPrefixOtherLines = '$prefixChildrenRaw${childConfig.childLinkSpace}${childConfig.prefixOtherLines}';
......@@ -1370,13 +1368,13 @@ class TextTreeRenderer {
if (childConfig.mandatoryFooter.isNotEmpty) {
builder.writeStretched(
childConfig.mandatoryFooter,
math.max(builder.wrapWidth, _wrapWidthProperties + childPrefixOtherLines.length),
math.max(builder.wrapWidth!, _wrapWidthProperties + childPrefixOtherLines.length),
);
}
builder.write(config.lineBreak);
}
} else {
final TextTreeConfiguration nextChildStyle = _childTextConfiguration(children[i + 1], config);
final TextTreeConfiguration nextChildStyle = _childTextConfiguration(children[i + 1], config)!;
final String childPrefixLineOne = '$prefixChildrenRaw${childConfig.prefixLineOne}';
final String childPrefixOtherLines ='$prefixChildrenRaw${nextChildStyle.linkCharacter}${childConfig.prefixOtherLines}';
builder.writeRawLines(render(
......@@ -1391,7 +1389,7 @@ class TextTreeRenderer {
if (childConfig.mandatoryFooter.isNotEmpty) {
builder.writeStretched(
childConfig.mandatoryFooter,
math.max(builder.wrapWidth, _wrapWidthProperties + childPrefixOtherLines.length),
math.max(builder.wrapWidth!, _wrapWidthProperties + childPrefixOtherLines.length),
);
}
builder.write(config.lineBreak);
......@@ -1400,7 +1398,7 @@ class TextTreeRenderer {
}
}
if (parentConfiguration == null && config.mandatoryFooter.isNotEmpty) {
builder.writeStretched(config.mandatoryFooter, builder.wrapWidth);
builder.writeStretched(config.mandatoryFooter, builder.wrapWidth!);
builder.write(config.lineBreak);
}
return builder.build();
......@@ -1423,7 +1421,7 @@ abstract class DiagnosticsNode {
/// The [style], [showName], and [showSeparator] arguments must not
/// be null.
DiagnosticsNode({
@required this.name,
required this.name,
this.style,
this.showName = true,
this.showSeparator = true,
......@@ -1472,7 +1470,7 @@ abstract class DiagnosticsNode {
/// (see [showSeparator]).
///
/// The name will be omitted if the [showName] property is false.
final String name;
final String? name;
/// Returns a description with a short summary of the node itself not
/// including children or properties.
......@@ -1480,7 +1478,7 @@ abstract class DiagnosticsNode {
/// `parentConfiguration` specifies how the parent is rendered as text art.
/// For example, if the parent does not line break between properties, the
/// description of a property should also be a single line if possible.
String toDescription({ TextTreeConfiguration parentConfiguration });
String? toDescription({ TextTreeConfiguration? parentConfiguration });
/// Whether to show a separator between [name] and description.
///
......@@ -1514,16 +1512,16 @@ abstract class DiagnosticsNode {
final bool showName;
/// Prefix to include at the start of each line
final String linePrefix;
final String? linePrefix;
/// Description to show if the node has no displayed properties or children.
String get emptyBodyDescription => null;
String? get emptyBodyDescription => null;
/// The actual object this is diagnostics data for.
Object get value;
Object? get value;
/// Hint for how the node should be displayed.
final DiagnosticsTreeStyle style;
final DiagnosticsTreeStyle? style;
/// Whether to wrap text on onto multiple lines or not.
bool get allowWrap => false;
......@@ -1561,11 +1559,11 @@ abstract class DiagnosticsNode {
/// by this method and interactive tree views in the Flutter IntelliJ
/// plugin.
@mustCallSuper
Map<String, Object> toJsonMap(DiagnosticsSerializationDelegate delegate) {
Map<String, Object> result = <String, Object>{};
Map<String, Object?> toJsonMap(DiagnosticsSerializationDelegate delegate) {
Map<String, Object?> result = <String, Object?>{};
assert(() {
final bool hasChildren = getChildren().isNotEmpty;
result = <String, Object>{
result = <String, Object?>{
'description': toDescription(),
'type': runtimeType.toString(),
if (name != null)
......@@ -1579,7 +1577,7 @@ abstract class DiagnosticsNode {
if (emptyBodyDescription != null)
'emptyBodyDescription': emptyBodyDescription,
if (style != DiagnosticsTreeStyle.sparse)
'style': describeEnum(style),
'style': describeEnum(style!),
if (allowTruncate)
'allowTruncate': allowTruncate,
if (hasChildren)
......@@ -1614,21 +1612,21 @@ abstract class DiagnosticsNode {
///
/// The provided `nodes` may be properties or children of the `parent`
/// [DiagnosticsNode].
static List<Map<String, Object>> toJsonList(
List<DiagnosticsNode> nodes,
DiagnosticsNode parent,
static List<Map<String, Object?>> toJsonList(
List<DiagnosticsNode>? nodes,
DiagnosticsNode? parent,
DiagnosticsSerializationDelegate delegate,
) {
bool truncated = false;
if (nodes == null)
return const <Map<String, Object>>[];
return const <Map<String, Object?>>[];
final int originalNodeCount = nodes.length;
nodes = delegate.truncateNodesList(nodes, parent);
if (nodes.length != originalNodeCount) {
nodes.add(DiagnosticsNode.message('...'));
truncated = true;
}
final List<Map<String, Object>> json = nodes.map<Map<String, Object>>((DiagnosticsNode node) {
final List<Map<String, Object?>> json = nodes.map<Map<String, Object?>>((DiagnosticsNode node) {
return node.toJsonMap(delegate.delegateForNode(node));
}).toList();
if (truncated)
......@@ -1650,7 +1648,7 @@ abstract class DiagnosticsNode {
/// not print at all.
@override
String toString({
TextTreeConfiguration parentConfiguration,
TextTreeConfiguration? parentConfiguration,
DiagnosticLevel minLevel = DiagnosticLevel.info,
}) {
String result = super.toString();
......@@ -1661,11 +1659,11 @@ abstract class DiagnosticsNode {
result = toStringDeep(
parentConfiguration: parentConfiguration, minLevel: minLevel);
} else {
final String description = toDescription(
parentConfiguration: parentConfiguration);
String? description = toDescription(parentConfiguration: parentConfiguration);
assert(description != null);
description = description!;
if (name == null || name.isEmpty || !showName) {
if (name == null || name!.isEmpty || !showName) {
result = description;
} else {
result = description.contains('\n') ? '$name$_separator\n$description'
......@@ -1680,9 +1678,9 @@ abstract class DiagnosticsNode {
/// Returns a configuration specifying how this object should be rendered
/// as text art.
@protected
TextTreeConfiguration get textTreeConfiguration {
TextTreeConfiguration? get textTreeConfiguration {
assert(style != null);
switch (style) {
switch (style!) {
case DiagnosticsTreeStyle.none:
return null;
case DiagnosticsTreeStyle.dense:
......@@ -1710,7 +1708,6 @@ abstract class DiagnosticsNode {
case DiagnosticsTreeStyle.flat:
return flatTextConfiguration;
}
return null;
}
/// Returns a string representation of this node and its descendants.
......@@ -1735,8 +1732,8 @@ abstract class DiagnosticsNode {
/// children.
String toStringDeep({
String prefixLineOne = '',
String prefixOtherLines,
TextTreeConfiguration parentConfiguration,
String? prefixOtherLines,
TextTreeConfiguration? parentConfiguration,
DiagnosticLevel minLevel = DiagnosticLevel.debug,
}) {
String result = '';
......@@ -1817,13 +1814,13 @@ class StringProperty extends DiagnosticsProperty<String> {
/// The [showName], [quoted], [style], and [level] arguments must not be null.
StringProperty(
String name,
String value, {
String description,
String tooltip,
String? value, {
String? description,
String? tooltip,
bool showName = true,
Object defaultValue = kNoDefaultValue,
Object? defaultValue = kNoDefaultValue,
this.quoted = true,
String ifEmpty,
String? ifEmpty,
DiagnosticsTreeStyle style = DiagnosticsTreeStyle.singleLine,
DiagnosticLevel level = DiagnosticLevel.info,
}) : assert(showName != null),
......@@ -1846,15 +1843,15 @@ class StringProperty extends DiagnosticsProperty<String> {
final bool quoted;
@override
Map<String, Object> toJsonMap(DiagnosticsSerializationDelegate delegate) {
final Map<String, Object> json = super.toJsonMap(delegate);
Map<String, Object?> toJsonMap(DiagnosticsSerializationDelegate delegate) {
final Map<String, Object?> json = super.toJsonMap(delegate);
json['quoted'] = quoted;
return json;
}
@override
String valueToString({ TextTreeConfiguration parentConfiguration }) {
String text = _description ?? value;
String valueToString({ TextTreeConfiguration? parentConfiguration }) {
String? text = _description ?? value;
if (parentConfiguration != null &&
!parentConfiguration.lineBreakProperties &&
text != null) {
......@@ -1868,7 +1865,7 @@ class StringProperty extends DiagnosticsProperty<String> {
// An empty value would not appear empty after being surrounded with
// quotes so we have to handle this case separately.
if (ifEmpty != null && text.isEmpty)
return ifEmpty;
return ifEmpty!;
return '"$text"';
}
return text.toString();
......@@ -1878,12 +1875,12 @@ class StringProperty extends DiagnosticsProperty<String> {
abstract class _NumProperty<T extends num> extends DiagnosticsProperty<T> {
_NumProperty(
String name,
T value, {
String ifNull,
T? value, {
String? ifNull,
this.unit,
bool showName = true,
Object defaultValue = kNoDefaultValue,
String tooltip,
Object? defaultValue = kNoDefaultValue,
String? tooltip,
DiagnosticsTreeStyle style = DiagnosticsTreeStyle.singleLine,
DiagnosticLevel level = DiagnosticLevel.info,
}) : super(
......@@ -1900,11 +1897,11 @@ abstract class _NumProperty<T extends num> extends DiagnosticsProperty<T> {
_NumProperty.lazy(
String name,
ComputePropertyValueCallback<T> computeValue, {
String ifNull,
String? ifNull,
this.unit,
bool showName = true,
Object defaultValue = kNoDefaultValue,
String tooltip,
Object? defaultValue = kNoDefaultValue,
String? tooltip,
DiagnosticsTreeStyle style = DiagnosticsTreeStyle.singleLine,
DiagnosticLevel level = DiagnosticLevel.info,
}) : super.lazy(
......@@ -1919,8 +1916,8 @@ abstract class _NumProperty<T extends num> extends DiagnosticsProperty<T> {
);
@override
Map<String, Object> toJsonMap(DiagnosticsSerializationDelegate delegate) {
final Map<String, Object> json = super.toJsonMap(delegate);
Map<String, Object?> toJsonMap(DiagnosticsSerializationDelegate delegate) {
final Map<String, Object?> json = super.toJsonMap(delegate);
if (unit != null)
json['unit'] = unit;
......@@ -1933,13 +1930,13 @@ abstract class _NumProperty<T extends num> extends DiagnosticsProperty<T> {
/// Unit must be acceptable to display immediately after a number with no
/// spaces. For example: 'physical pixels per logical pixel' should be a
/// [tooltip] not a [unit].
final String unit;
final String? unit;
/// String describing just the numeric [value] without a unit suffix.
String numberToString();
@override
String valueToString({ TextTreeConfiguration parentConfiguration }) {
String valueToString({ TextTreeConfiguration? parentConfiguration }) {
if (value == null)
return value.toString();
......@@ -1955,11 +1952,11 @@ class DoubleProperty extends _NumProperty<double> {
/// The [showName], [style], and [level] arguments must not be null.
DoubleProperty(
String name,
double value, {
String ifNull,
String unit,
String tooltip,
Object defaultValue = kNoDefaultValue,
double? value, {
String? ifNull,
String? unit,
String? tooltip,
Object? defaultValue = kNoDefaultValue,
bool showName = true,
DiagnosticsTreeStyle style = DiagnosticsTreeStyle.singleLine,
DiagnosticLevel level = DiagnosticLevel.info,
......@@ -1987,11 +1984,11 @@ class DoubleProperty extends _NumProperty<double> {
DoubleProperty.lazy(
String name,
ComputePropertyValueCallback<double> computeValue, {
String ifNull,
String? ifNull,
bool showName = true,
String unit,
String tooltip,
Object defaultValue = kNoDefaultValue,
String? unit,
String? tooltip,
Object? defaultValue = kNoDefaultValue,
DiagnosticLevel level = DiagnosticLevel.info,
}) : assert(showName != null),
assert(level != null),
......@@ -2019,11 +2016,11 @@ class IntProperty extends _NumProperty<int> {
/// The [showName], [style], and [level] arguments must not be null.
IntProperty(
String name,
int value, {
String ifNull,
int? value, {
String? ifNull,
bool showName = true,
String unit,
Object defaultValue = kNoDefaultValue,
String? unit,
Object? defaultValue = kNoDefaultValue,
DiagnosticsTreeStyle style = DiagnosticsTreeStyle.singleLine,
DiagnosticLevel level = DiagnosticLevel.info,
}) : assert(showName != null),
......@@ -2057,10 +2054,10 @@ class PercentProperty extends DoubleProperty {
PercentProperty(
String name,
double fraction, {
String ifNull,
String? ifNull,
bool showName = true,
String tooltip,
String unit,
String? tooltip,
String? unit,
DiagnosticLevel level = DiagnosticLevel.info,
}) : assert(showName != null),
assert(level != null),
......@@ -2075,7 +2072,7 @@ class PercentProperty extends DoubleProperty {
);
@override
String valueToString({ TextTreeConfiguration parentConfiguration }) {
String valueToString({ TextTreeConfiguration? parentConfiguration }) {
if (value == null)
return value.toString();
return unit != null ? '${numberToString()} $unit' : numberToString();
......@@ -2083,9 +2080,10 @@ class PercentProperty extends DoubleProperty {
@override
String numberToString() {
if (value == null)
final double? v = value;
if (v == null)
return value.toString();
return '${(value.clamp(0.0, 1.0) * 100.0).toStringAsFixed(1)}%';
return '${(v.clamp(0.0, 1.0) * 100.0).toStringAsFixed(1)}%';
}
}
......@@ -2137,11 +2135,11 @@ class FlagProperty extends DiagnosticsProperty<bool> {
/// The [showName] and [level] arguments must not be null.
FlagProperty(
String name, {
@required bool value,
required bool? value,
this.ifTrue,
this.ifFalse,
bool showName = false,
Object defaultValue,
Object? defaultValue,
DiagnosticLevel level = DiagnosticLevel.info,
}) : assert(showName != null),
assert(level != null),
......@@ -2155,8 +2153,8 @@ class FlagProperty extends DiagnosticsProperty<bool> {
);
@override
Map<String, Object> toJsonMap(DiagnosticsSerializationDelegate delegate) {
final Map<String, Object> json = super.toJsonMap(delegate);
Map<String, Object?> toJsonMap(DiagnosticsSerializationDelegate delegate) {
final Map<String, Object?> json = super.toJsonMap(delegate);
if (ifTrue != null)
json['ifTrue'] = ifTrue;
if (ifFalse != null)
......@@ -2169,22 +2167,22 @@ class FlagProperty extends DiagnosticsProperty<bool> {
///
/// If not specified and [value] equals true the property's priority [level]
/// will be [DiagnosticLevel.hidden].
final String ifTrue;
final String? ifTrue;
/// Description to use if the property value is false.
///
/// If not specified and [value] equals false, the property's priority [level]
/// will be [DiagnosticLevel.hidden].
final String ifFalse;
final String? ifFalse;
@override
String valueToString({ TextTreeConfiguration parentConfiguration }) {
String valueToString({ TextTreeConfiguration? parentConfiguration }) {
if (value == true) {
if (ifTrue != null)
return ifTrue;
return ifTrue!;
} else if (value == false) {
if (ifFalse != null)
return ifFalse;
return ifFalse!;
}
return super.valueToString(parentConfiguration: parentConfiguration);
}
......@@ -2233,10 +2231,10 @@ class IterableProperty<T> extends DiagnosticsProperty<Iterable<T>> {
/// The [style], [showName], [showSeparator], and [level] arguments must not be null.
IterableProperty(
String name,
Iterable<T> value, {
Object defaultValue = kNoDefaultValue,
String ifNull,
String ifEmpty = '[]',
Iterable<T>? value, {
Object? defaultValue = kNoDefaultValue,
String? ifNull,
String? ifEmpty = '[]',
DiagnosticsTreeStyle style = DiagnosticsTreeStyle.singleLine,
bool showName = true,
bool showSeparator = true,
......@@ -2258,14 +2256,14 @@ class IterableProperty<T> extends DiagnosticsProperty<Iterable<T>> {
);
@override
String valueToString({TextTreeConfiguration parentConfiguration}) {
String valueToString({TextTreeConfiguration? parentConfiguration}) {
if (value == null)
return value.toString();
if (value.isEmpty)
if (value!.isEmpty)
return ifEmpty ?? '[]';
final Iterable<String> formattedValues = value.map((T v) {
final Iterable<String> formattedValues = value!.map((T v) {
if (T == double && v is double) {
return debugFormatDouble(v);
} else {
......@@ -2291,16 +2289,16 @@ class IterableProperty<T> extends DiagnosticsProperty<Iterable<T>> {
/// null.
@override
DiagnosticLevel get level {
if (ifEmpty == null && value != null && value.isEmpty && super.level != DiagnosticLevel.hidden)
if (ifEmpty == null && value != null && value!.isEmpty && super.level != DiagnosticLevel.hidden)
return DiagnosticLevel.fine;
return super.level;
}
@override
Map<String, Object> toJsonMap(DiagnosticsSerializationDelegate delegate) {
final Map<String, Object> json = super.toJsonMap(delegate);
Map<String, Object?> toJsonMap(DiagnosticsSerializationDelegate delegate) {
final Map<String, Object?> json = super.toJsonMap(delegate);
if (value != null) {
json['values'] = value.map<String>((T value) => value.toString()).toList();
json['values'] = value!.map<String>((T value) => value.toString()).toList();
}
return json;
}
......@@ -2321,8 +2319,8 @@ class EnumProperty<T> extends DiagnosticsProperty<T> {
/// The [level] argument must also not be null.
EnumProperty(
String name,
T value, {
Object defaultValue = kNoDefaultValue,
T? value, {
Object? defaultValue = kNoDefaultValue,
DiagnosticLevel level = DiagnosticLevel.info,
}) : assert(level != null),
super (
......@@ -2333,10 +2331,10 @@ class EnumProperty<T> extends DiagnosticsProperty<T> {
);
@override
String valueToString({ TextTreeConfiguration parentConfiguration }) {
String valueToString({ TextTreeConfiguration? parentConfiguration }) {
if (value == null)
return value.toString();
return describeEnum(value);
return describeEnum(value!);
}
}
......@@ -2371,9 +2369,9 @@ class ObjectFlagProperty<T> extends DiagnosticsProperty<T> {
/// least one of [ifPresent] and [ifNull] must not be null.
ObjectFlagProperty(
String name,
T value, {
T? value, {
this.ifPresent,
String ifNull,
String? ifNull,
bool showName = false,
DiagnosticLevel level = DiagnosticLevel.info,
}) : assert(ifPresent != null || ifNull != null),
......@@ -2395,7 +2393,7 @@ class ObjectFlagProperty<T> extends DiagnosticsProperty<T> {
/// The [name] and [level] arguments must not be null.
ObjectFlagProperty.has(
String name,
T value, {
T? value, {
DiagnosticLevel level = DiagnosticLevel.info,
}) : assert(name != null),
assert(level != null),
......@@ -2412,16 +2410,16 @@ class ObjectFlagProperty<T> extends DiagnosticsProperty<T> {
/// If the property [value] is not null and [ifPresent] is null, the
/// [level] for the property is [DiagnosticLevel.hidden] and the description
/// from superclass is used.
final String ifPresent;
final String? ifPresent;
@override
String valueToString({ TextTreeConfiguration parentConfiguration }) {
String valueToString({ TextTreeConfiguration? parentConfiguration }) {
if (value != null) {
if (ifPresent != null)
return ifPresent;
return ifPresent!;
} else {
if (ifNull != null)
return ifNull;
return ifNull!;
}
return super.valueToString(parentConfiguration: parentConfiguration);
}
......@@ -2452,8 +2450,8 @@ class ObjectFlagProperty<T> extends DiagnosticsProperty<T> {
}
@override
Map<String, Object> toJsonMap(DiagnosticsSerializationDelegate delegate) {
final Map<String, Object> json = super.toJsonMap(delegate);
Map<String, Object?> toJsonMap(DiagnosticsSerializationDelegate delegate) {
final Map<String, Object?> json = super.toJsonMap(delegate);
if (ifPresent != null)
json['ifPresent'] = ifPresent;
return json;
......@@ -2490,7 +2488,7 @@ class FlagsSummary<T> extends DiagnosticsProperty<Map<String, T>> {
FlagsSummary(
String name,
Map<String, T> value, {
String ifEmpty,
String? ifEmpty,
bool showName = true,
bool showSeparator = true,
DiagnosticLevel level = DiagnosticLevel.info,
......@@ -2508,10 +2506,13 @@ class FlagsSummary<T> extends DiagnosticsProperty<Map<String, T>> {
);
@override
String valueToString({TextTreeConfiguration parentConfiguration}) {
Map<String, T> get value => super.value as Map<String, T>;
@override
String valueToString({TextTreeConfiguration? parentConfiguration}) {
assert(value != null);
if (!_hasNonNullEntry() && ifEmpty != null)
return ifEmpty;
return ifEmpty!;
final Iterable<String> formattedValues = _formattedValues();
if (parentConfiguration != null && !parentConfiguration.lineBreakProperties) {
......@@ -2536,14 +2537,14 @@ class FlagsSummary<T> extends DiagnosticsProperty<Map<String, T>> {
}
@override
Map<String, Object> toJsonMap(DiagnosticsSerializationDelegate delegate) {
final Map<String, Object> json = super.toJsonMap(delegate);
Map<String, Object?> toJsonMap(DiagnosticsSerializationDelegate delegate) {
final Map<String, Object?> json = super.toJsonMap(delegate);
if (value.isNotEmpty)
json['values'] = _formattedValues().toList();
return json;
}
bool _hasNonNullEntry() => value.values.any((Object o) => o != null);
bool _hasNonNullEntry() => value.values.any((T o) => o != null);
// An iterable of each entry's description in [value].
//
......@@ -2585,17 +2586,17 @@ class DiagnosticsProperty<T> extends DiagnosticsNode {
/// level. For example, if the property value is null and [missingIfNull] is
/// true, [level] is raised to [DiagnosticLevel.warning].
DiagnosticsProperty(
String name,
T value, {
String description,
String ifNull,
String? name,
T? value, {
String? description,
String? ifNull,
this.ifEmpty,
bool showName = true,
bool showSeparator = true,
this.defaultValue = kNoDefaultValue,
this.tooltip,
this.missingIfNull = false,
String linePrefix,
String? linePrefix,
this.expandableValue = false,
this.allowWrap = true,
this.allowNameWrap = true,
......@@ -2632,10 +2633,10 @@ class DiagnosticsProperty<T> extends DiagnosticsNode {
/// level. For example, if calling `computeValue` throws an exception, [level]
/// will always return [DiagnosticLevel.error].
DiagnosticsProperty.lazy(
String name,
String? name,
ComputePropertyValueCallback<T> computeValue, {
String description,
String ifNull,
String? description,
String? ifNull,
this.ifEmpty,
bool showName = true,
bool showSeparator = true,
......@@ -2666,7 +2667,7 @@ class DiagnosticsProperty<T> extends DiagnosticsNode {
style: style,
);
final String _description;
final String? _description;
/// Whether to expose properties and children of the value as properties and
/// children.
......@@ -2679,9 +2680,9 @@ class DiagnosticsProperty<T> extends DiagnosticsNode {
final bool allowNameWrap;
@override
Map<String, Object> toJsonMap(DiagnosticsSerializationDelegate delegate) {
final T v = value;
List<Map<String, Object>> properties;
Map<String, Object?> toJsonMap(DiagnosticsSerializationDelegate delegate) {
final T? v = value;
List<Map<String, Object?>>? properties;
if (delegate.expandPropertyValues && delegate.includeProperties && v is Diagnosticable && getProperties().isEmpty) {
// Exclude children for expanded nodes to avoid cycles.
delegate = delegate.copyWith(subtreeDepth: 0, includeProperties: false);
......@@ -2691,7 +2692,7 @@ class DiagnosticsProperty<T> extends DiagnosticsNode {
delegate,
);
}
final Map<String, Object> json = super.toJsonMap(delegate);
final Map<String, Object?> json = super.toJsonMap(delegate);
if (properties != null) {
json['properties'] = properties;
}
......@@ -2732,28 +2733,28 @@ class DiagnosticsProperty<T> extends DiagnosticsNode {
/// `parentConfiguration` specifies how the parent is rendered as text art.
/// For example, if the parent places all properties on one line, the value
/// of the property should be displayed without line breaks if possible.
String valueToString({ TextTreeConfiguration parentConfiguration }) {
final T v = value;
String valueToString({ TextTreeConfiguration? parentConfiguration }) {
final T? v = value;
// DiagnosticableTree values are shown using the shorter toStringShort()
// instead of the longer toString() because the toString() for a
// DiagnosticableTree value is likely too large to be useful.
return (v is DiagnosticableTree ? v.toStringShort() : v.toString()) ?? '';
return v is DiagnosticableTree ? v.toStringShort() : v.toString();
}
@override
String toDescription({ TextTreeConfiguration parentConfiguration }) {
String toDescription({ TextTreeConfiguration? parentConfiguration }) {
if (_description != null)
return _addTooltip(_description);
return _addTooltip(_description!);
if (exception != null)
return 'EXCEPTION (${exception.runtimeType})';
if (ifNull != null && value == null)
return _addTooltip(ifNull);
return _addTooltip(ifNull!);
String result = valueToString(parentConfiguration: parentConfiguration);
if (result.isEmpty && ifEmpty != null)
result = ifEmpty;
result = ifEmpty!;
return _addTooltip(result);
}
......@@ -2768,10 +2769,10 @@ class DiagnosticsProperty<T> extends DiagnosticsNode {
}
/// Description if the property [value] is null.
final String ifNull;
final String? ifNull;
/// Description if the property description would otherwise be empty.
final String ifEmpty;
final String? ifEmpty;
/// Optional tooltip typically describing the property.
///
......@@ -2779,7 +2780,7 @@ class DiagnosticsProperty<T> extends DiagnosticsNode {
///
/// If present, the tooltip is added in parenthesis after the raw value when
/// generating the string description.
final String tooltip;
final String? tooltip;
/// Whether a [value] of null causes the property to have [level]
/// [DiagnosticLevel.warning] warning that the property is missing a [value].
......@@ -2809,21 +2810,21 @@ class DiagnosticsProperty<T> extends DiagnosticsNode {
///
/// * [valueToString], which converts the property value to a string.
@override
T get value {
T? get value {
_maybeCacheValue();
return _value;
}
T _value;
T? _value;
bool _valueComputed;
Object _exception;
Object? _exception;
/// Exception thrown if accessing the property [value] threw an exception.
///
/// Returns null if computing the property value did not throw an exception.
Object get exception {
Object? get exception {
_maybeCacheValue();
return _exception;
}
......@@ -2835,7 +2836,7 @@ class DiagnosticsProperty<T> extends DiagnosticsNode {
_valueComputed = true;
assert(_computeValue != null);
try {
_value = _computeValue();
_value = _computeValue!();
} catch (exception) {
_exception = exception;
_value = null;
......@@ -2847,7 +2848,7 @@ class DiagnosticsProperty<T> extends DiagnosticsNode {
/// value is uninteresting.
///
/// [defaultValue] has type [T] or is [kNoDefaultValue].
final Object defaultValue;
final Object? defaultValue;
final DiagnosticLevel _defaultLevel;
......@@ -2879,12 +2880,12 @@ class DiagnosticsProperty<T> extends DiagnosticsNode {
return _defaultLevel;
}
final ComputePropertyValueCallback<T> _computeValue;
final ComputePropertyValueCallback<T>? _computeValue;
@override
List<DiagnosticsNode> getProperties() {
if (expandableValue) {
final T object = value;
final T? object = value;
if (object is DiagnosticsNode) {
return object.getProperties();
}
......@@ -2898,7 +2899,7 @@ class DiagnosticsProperty<T> extends DiagnosticsNode {
@override
List<DiagnosticsNode> getChildren() {
if (expandableValue) {
final T object = value;
final T? object = value;
if (object is DiagnosticsNode) {
return object.getChildren();
}
......@@ -2917,9 +2918,9 @@ class DiagnosticableNode<T extends Diagnosticable> extends DiagnosticsNode {
///
/// The [value] argument must not be null.
DiagnosticableNode({
String name,
@required this.value,
@required DiagnosticsTreeStyle style,
String? name,
required this.value,
required DiagnosticsTreeStyle? style,
}) : assert(value != null),
super(
name: name,
......@@ -2929,19 +2930,19 @@ class DiagnosticableNode<T extends Diagnosticable> extends DiagnosticsNode {
@override
final T value;
DiagnosticPropertiesBuilder _cachedBuilder;
DiagnosticPropertiesBuilder? _cachedBuilder;
/// Retrieve the [DiagnosticPropertiesBuilder] of current node.
///
/// It will cache the result to prevent duplicate operation.
DiagnosticPropertiesBuilder get builder {
DiagnosticPropertiesBuilder? get builder {
if (kReleaseMode) {
return null;
} else {
assert(() {
if (_cachedBuilder == null) {
_cachedBuilder = DiagnosticPropertiesBuilder();
value?.debugFillProperties(_cachedBuilder);
value.debugFillProperties(_cachedBuilder!);
}
return true;
}());
......@@ -2951,14 +2952,14 @@ class DiagnosticableNode<T extends Diagnosticable> extends DiagnosticsNode {
@override
DiagnosticsTreeStyle get style {
return kReleaseMode ? DiagnosticsTreeStyle.none : super.style ?? builder.defaultDiagnosticsTreeStyle;
return kReleaseMode ? DiagnosticsTreeStyle.none : super.style ?? builder!.defaultDiagnosticsTreeStyle;
}
@override
String get emptyBodyDescription => (kReleaseMode || kProfileMode) ? '' : builder.emptyBodyDescription;
String? get emptyBodyDescription => (kReleaseMode || kProfileMode) ? '' : builder!.emptyBodyDescription;
@override
List<DiagnosticsNode> getProperties() => (kReleaseMode || kProfileMode) ? const <DiagnosticsNode>[] : builder.properties;
List<DiagnosticsNode> getProperties() => (kReleaseMode || kProfileMode) ? const <DiagnosticsNode>[] : builder!.properties;
@override
List<DiagnosticsNode> getChildren() {
......@@ -2966,7 +2967,7 @@ class DiagnosticableNode<T extends Diagnosticable> extends DiagnosticsNode {
}
@override
String toDescription({ TextTreeConfiguration parentConfiguration }) {
String toDescription({ TextTreeConfiguration? parentConfiguration }) {
String result = '';
assert(() {
result = value.toStringShort();
......@@ -2980,9 +2981,9 @@ class DiagnosticableNode<T extends Diagnosticable> extends DiagnosticsNode {
class DiagnosticableTreeNode extends DiagnosticableNode<DiagnosticableTree> {
/// Creates a [DiagnosticableTreeNode].
DiagnosticableTreeNode({
String name,
@required DiagnosticableTree value,
@required DiagnosticsTreeStyle style,
String? name,
required DiagnosticableTree value,
required DiagnosticsTreeStyle? style,
}) : super(
name: name,
value: value,
......@@ -2990,16 +2991,12 @@ class DiagnosticableTreeNode extends DiagnosticableNode<DiagnosticableTree> {
);
@override
List<DiagnosticsNode> getChildren() {
if (value != null)
return value.debugDescribeChildren();
return const <DiagnosticsNode>[];
}
List<DiagnosticsNode> getChildren() => value.debugDescribeChildren();
}
/// Returns a 5 character long hexadecimal string generated from
/// [Object.hashCode]'s 20 least-significant bits.
String shortHash(Object object) {
String shortHash(Object? object) {
return object.hashCode.toUnsigned(20).toRadixString(16).padLeft(5, '0');
}
......@@ -3012,7 +3009,7 @@ String shortHash(Object object) {
/// distinguish instances of the same class (hash collisions are
/// possible, but rare enough that its use in debug output is useful).
/// * [Object.runtimeType], the [Type] of an object.
String describeIdentity(Object object) => '${objectRuntimeType(object, '<optimized out>')}#${shortHash(object)}';
String describeIdentity(Object? object) => '${objectRuntimeType(object, '<optimized out>')}#${shortHash(object)}';
// This method exists as a workaround for https://github.com/dart-lang/sdk/issues/30021
/// Returns a short description of an enum value.
......@@ -3064,7 +3061,7 @@ class DiagnosticPropertiesBuilder {
DiagnosticsTreeStyle defaultDiagnosticsTreeStyle = DiagnosticsTreeStyle.sparse;
/// Description to show if the node has no displayed properties or children.
String emptyBodyDescription;
String? emptyBodyDescription;
}
// Examples can assume:
......@@ -3105,7 +3102,7 @@ mixin Diagnosticable {
@override
String toString({ DiagnosticLevel minLevel = DiagnosticLevel.info }) {
String fullString;
String? fullString;
assert(() {
fullString = toDiagnosticsNode(style: DiagnosticsTreeStyle.singleLine).toString(minLevel: minLevel);
return true;
......@@ -3122,7 +3119,7 @@ mixin Diagnosticable {
/// Typically the [style] argument is only specified to indicate an atypical
/// relationship between the parent and the node. For example, pass
/// [DiagnosticsTreeStyle.offstage] to indicate that a node is offstage.
DiagnosticsNode toDiagnosticsNode({ String name, DiagnosticsTreeStyle style }) {
DiagnosticsNode toDiagnosticsNode({ String? name, DiagnosticsTreeStyle? style }) {
return DiagnosticableNode<Diagnosticable>(
name: name,
value: this,
......@@ -3377,14 +3374,14 @@ abstract class DiagnosticableTree with Diagnosticable {
///
/// * [toString], for a brief description of the object.
/// * [toStringDeep], for a description of the subtree rooted at this object.
String toStringShallow({
String? toStringShallow({
String joiner = ', ',
DiagnosticLevel minLevel = DiagnosticLevel.debug,
}) {
if (kReleaseMode) {
return toString();
}
String shallowString;
String? shallowString;
assert(() {
final StringBuffer result = StringBuffer();
result.write(toString());
......@@ -3421,7 +3418,7 @@ abstract class DiagnosticableTree with Diagnosticable {
/// children.
String toStringDeep({
String prefixLineOne = '',
String prefixOtherLines,
String? prefixOtherLines,
DiagnosticLevel minLevel = DiagnosticLevel.debug,
}) {
return toDiagnosticsNode().toStringDeep(prefixLineOne: prefixLineOne, prefixOtherLines: prefixOtherLines, minLevel: minLevel);
......@@ -3431,7 +3428,7 @@ abstract class DiagnosticableTree with Diagnosticable {
String toStringShort() => describeIdentity(this);
@override
DiagnosticsNode toDiagnosticsNode({ String name, DiagnosticsTreeStyle style }) {
DiagnosticsNode toDiagnosticsNode({ String? name, DiagnosticsTreeStyle? style }) {
return DiagnosticableTreeNode(
name: name,
value: this,
......@@ -3470,14 +3467,14 @@ mixin DiagnosticableTreeMixin implements DiagnosticableTree {
}
@override
String toStringShallow({
String? toStringShallow({
String joiner = ', ',
DiagnosticLevel minLevel = DiagnosticLevel.debug,
}) {
if (kReleaseMode) {
return toString();
}
String shallowString;
String? shallowString;
assert(() {
final StringBuffer result = StringBuffer();
result.write(toStringShort());
......@@ -3497,7 +3494,7 @@ mixin DiagnosticableTreeMixin implements DiagnosticableTree {
@override
String toStringDeep({
String prefixLineOne = '',
String prefixOtherLines,
String? prefixOtherLines,
DiagnosticLevel minLevel = DiagnosticLevel.debug,
}) {
return toDiagnosticsNode().toStringDeep(prefixLineOne: prefixLineOne, prefixOtherLines: prefixOtherLines, minLevel: minLevel);
......@@ -3507,7 +3504,7 @@ mixin DiagnosticableTreeMixin implements DiagnosticableTree {
String toStringShort() => describeIdentity(this);
@override
DiagnosticsNode toDiagnosticsNode({ String name, DiagnosticsTreeStyle style }) {
DiagnosticsNode toDiagnosticsNode({ String? name, DiagnosticsTreeStyle? style }) {
return DiagnosticableTreeNode(
name: name,
value: this,
......@@ -3531,13 +3528,13 @@ class DiagnosticsBlock extends DiagnosticsNode {
/// Creates a diagnostic with properties specified by [properties] and
/// children specified by [children].
DiagnosticsBlock({
String name,
String? name,
DiagnosticsTreeStyle style = DiagnosticsTreeStyle.whitespace,
bool showName = true,
bool showSeparator = true,
String linePrefix,
String? linePrefix,
this.value,
String description,
String? description,
this.level = DiagnosticLevel.info,
this.allowTruncate = false,
List<DiagnosticsNode> children = const<DiagnosticsNode>[],
......@@ -3558,9 +3555,9 @@ class DiagnosticsBlock extends DiagnosticsNode {
@override
final DiagnosticLevel level;
final String _description;
final String? _description;
@override
final Object value;
final Object? value;
@override
final bool allowTruncate;
......@@ -3572,7 +3569,7 @@ class DiagnosticsBlock extends DiagnosticsNode {
List<DiagnosticsNode> getProperties() => _properties;
@override
String toDescription({TextTreeConfiguration parentConfiguration}) => _description;
String? toDescription({TextTreeConfiguration? parentConfiguration}) => _description;
}
/// A delegate that configures how a hierarchy of [DiagnosticsNode]s should be
......@@ -3597,7 +3594,7 @@ abstract class DiagnosticsSerializationDelegate {
///
/// This method is called for every [DiagnosticsNode] that's included in
/// the serialization.
Map<String, Object> additionalNodeProperties(DiagnosticsNode node);
Map<String, Object?> additionalNodeProperties(DiagnosticsNode node);
/// Filters the list of [DiagnosticsNode]s that will be included as children
/// for the given `owner` node.
......@@ -3635,7 +3632,7 @@ abstract class DiagnosticsSerializationDelegate {
/// result that are not included in the current serialization.
///
/// By default, `nodes` is returned as-is.
List<DiagnosticsNode> truncateNodesList(List<DiagnosticsNode> nodes, DiagnosticsNode owner);
List<DiagnosticsNode> truncateNodesList(List<DiagnosticsNode> nodes, DiagnosticsNode? owner);
/// Returns the [DiagnosticsSerializationDelegate] to be used
/// for adding the provided [DiagnosticsNode] to the serialization.
......@@ -3689,8 +3686,8 @@ class _DefaultDiagnosticsSerializationDelegate implements DiagnosticsSerializati
});
@override
Map<String, Object> additionalNodeProperties(DiagnosticsNode node) {
return const <String, Object>{};
Map<String, Object?> additionalNodeProperties(DiagnosticsNode node) {
return const <String, Object?>{};
}
@override
......@@ -3718,12 +3715,12 @@ class _DefaultDiagnosticsSerializationDelegate implements DiagnosticsSerializati
final int subtreeDepth;
@override
List<DiagnosticsNode> truncateNodesList(List<DiagnosticsNode> nodes, DiagnosticsNode owner) {
List<DiagnosticsNode> truncateNodesList(List<DiagnosticsNode> nodes, DiagnosticsNode? owner) {
return nodes;
}
@override
DiagnosticsSerializationDelegate copyWith({int subtreeDepth, bool includeProperties}) {
DiagnosticsSerializationDelegate copyWith({int? subtreeDepth, bool? includeProperties}) {
return _DefaultDiagnosticsSerializationDelegate(
subtreeDepth: subtreeDepth ?? this.subtreeDepth,
includeProperties: includeProperties ?? this.includeProperties,
......
......@@ -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 '_isolates_io.dart'
......@@ -20,7 +18,7 @@ import '_isolates_io.dart'
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 });
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`.
......
......@@ -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:ui' show hashValues;
import 'package:meta/meta.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:meta/meta.dart' show visibleForTesting;
......@@ -49,7 +47,7 @@ abstract class LicenseEntry {
const LicenseEntry();
/// The names of the packages that this license entry applies to.
Iterable<String> get packages;
Iterable<String>? get packages;
/// The paragraphs of the license, each as a [LicenseParagraph] consisting of
/// a string and some formatting information. Paragraphs can include newline
......@@ -125,7 +123,7 @@ class LicenseEntryWithLineBreaks extends LicenseEntry {
const LicenseEntryWithLineBreaks(this.packages, this.text);
@override
final List<String> packages;
final List<String>? packages;
/// The text of the license.
///
......@@ -148,7 +146,7 @@ class LicenseEntryWithLineBreaks extends LicenseEntry {
int currentPosition = 0;
int lastLineIndent = 0;
int currentLineIndent = 0;
int currentParagraphIndentation;
int? currentParagraphIndentation;
_LicenseEntryWithLineBreaksParserState state = _LicenseEntryWithLineBreaksParserState.beforeParagraph;
final List<String> lines = <String>[];
......@@ -160,7 +158,7 @@ class LicenseEntryWithLineBreaks extends LicenseEntry {
LicenseParagraph getParagraph() {
assert(lines.isNotEmpty);
assert(currentParagraphIndentation != null);
final LicenseParagraph result = LicenseParagraph(lines.join(' '), currentParagraphIndentation);
final LicenseParagraph result = LicenseParagraph(lines.join(' '), currentParagraphIndentation!);
assert(result.text.trimLeft() == result.text);
assert(result.text.isNotEmpty);
lines.clear();
......@@ -295,7 +293,7 @@ class LicenseRegistry {
// ignore: unused_element
LicenseRegistry._();
static List<LicenseEntryCollector> _collectors;
static List<LicenseEntryCollector>? _collectors;
/// Adds licenses to the registry.
///
......@@ -306,7 +304,7 @@ class LicenseRegistry {
/// licenses, the closure will not be called.
static void addLicense(LicenseEntryCollector collector) {
_collectors ??= <LicenseEntryCollector>[];
_collectors.add(collector);
_collectors!.add(collector);
}
/// Returns the licenses that have been registered.
......@@ -315,7 +313,7 @@ class LicenseRegistry {
static Stream<LicenseEntry> get licenses async* {
if (_collectors == null)
return;
for (final LicenseEntryCollector collector in _collectors)
for (final LicenseEntryCollector collector in _collectors!)
yield* collector();
}
......
......@@ -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:meta/meta.dart';
// This file gets mutated by //dev/devicelab/bin/tasks/flutter_test_performance.dart
......@@ -71,8 +69,8 @@ class AbstractNode {
/// The owner for this node (null if unattached).
///
/// The entire subtree that this node belongs to will have the same owner.
Object get owner => _owner;
Object _owner;
Object? get owner => _owner;
Object? _owner;
/// Whether this node is in a tree whose root is attached to something.
///
......@@ -107,12 +105,12 @@ class AbstractNode {
void detach() {
assert(_owner != null);
_owner = null;
assert(parent == null || attached == parent.attached);
assert(parent == null || attached == parent!.attached);
}
/// The parent of this node in the tree.
AbstractNode get parent => _parent;
AbstractNode _parent;
AbstractNode? get parent => _parent;
AbstractNode? _parent;
/// Mark the given node as being a child of this node.
///
......@@ -125,13 +123,13 @@ class AbstractNode {
assert(() {
AbstractNode node = this;
while (node.parent != null)
node = node.parent;
node = node.parent!;
assert(node != child); // indicates we are about to create a cycle
return true;
}());
child._parent = this;
if (attached)
child.attach(_owner);
child.attach(_owner!);
redepthChild(child);
}
......
......@@ -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
/// Framework code should use this method in favor of calling `toString` on
/// [Object.runtimeType].
///
......@@ -11,7 +9,7 @@
/// negatively impact performance. If asserts are enabled, this method will
/// return `object.runtimeType.toString()`; otherwise, it will return the
/// [optimizedValue], which must be a simple constant string.
String objectRuntimeType(Object object, String optimizedValue) {
String objectRuntimeType(Object? object, String optimizedValue) {
assert(() {
optimizedValue = object.runtimeType.toString();
return true;
......
......@@ -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:collection';
/// A list optimized for the observer pattern when there are small numbers of
......@@ -29,7 +27,7 @@ import 'dart:collection';
class ObserverList<T> extends Iterable<T> {
final List<T> _list = <T>[];
bool _isDirty = false;
HashSet<T> _set;
late final HashSet<T> _set = HashSet<T>();
/// Adds an item to the end of this list.
///
......@@ -46,21 +44,17 @@ class ObserverList<T> extends Iterable<T> {
/// Returns whether the item was present in the list.
bool remove(T item) {
_isDirty = true;
_set?.clear(); // Clear the set so that we don't leak items.
_set.clear(); // Clear the set so that we don't leak items.
return _list.remove(item);
}
@override
bool contains(Object element) {
bool contains(Object? element) {
if (_list.length < 3)
return _list.contains(element);
if (_isDirty) {
if (_set == null) {
_set = HashSet<T>.from(_list);
} else {
_set.addAll(_list);
}
_set.addAll(_list);
_isDirty = false;
}
......@@ -107,7 +101,7 @@ class HashedObserverList<T> extends Iterable<T> {
///
/// Returns whether the item was present in the list.
bool remove(T item) {
final int value = _map[item];
final int? value = _map[item];
if (value == null) {
return false;
}
......@@ -120,7 +114,7 @@ class HashedObserverList<T> extends Iterable<T> {
}
@override
bool contains(Object element) => _map.containsKey(element);
bool contains(Object? element) => _map.containsKey(element);
@override
Iterator<T> get iterator => _map.keys.iterator;
......
......@@ -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 '_platform_io.dart'
if (dart.library.html) '_platform_web.dart' as _platform;
......@@ -79,4 +77,4 @@ enum TargetPlatform {
/// button, which will make those widgets unusable since iOS has no such button.
///
/// In general, therefore, this property should not be used in release builds.
TargetPlatform debugDefaultTargetPlatformOverride;
TargetPlatform? debugDefaultTargetPlatformOverride;
......@@ -2,13 +2,11 @@
// 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';
/// Signature for [debugPrint] implementations.
typedef DebugPrintCallback = void Function(String message, { int wrapWidth });
typedef DebugPrintCallback = void Function(String? message, { int? wrapWidth });
/// Prints a message to the console, which you can access using the "flutter"
/// tool's "logs" command ("flutter logs").
......@@ -32,8 +30,8 @@ DebugPrintCallback debugPrint = debugPrintThrottled;
/// Alternative implementation of [debugPrint] that does not throttle.
/// Used by tests.
void debugPrintSynchronously(String message, { int wrapWidth }) {
if (wrapWidth != null) {
void debugPrintSynchronously(String? message, { int? wrapWidth }) {
if (message != null && wrapWidth != null) {
print(message.split('\n').expand<String>((String line) => debugWordWrap(line, wrapWidth)).join('\n'));
} else {
print(message);
......@@ -42,7 +40,7 @@ void debugPrintSynchronously(String message, { int wrapWidth }) {
/// Implementation of [debugPrint] that throttles messages. This avoids dropping
/// messages on platforms that rate-limit their logging (for example, Android).
void debugPrintThrottled(String message, { int wrapWidth }) {
void debugPrintThrottled(String? message, { int? wrapWidth }) {
final List<String> messageLines = message?.split('\n') ?? <String>['null'];
if (wrapWidth != null) {
_debugPrintBuffer.addAll(messageLines.expand<String>((String line) => debugWordWrap(line, wrapWidth)));
......@@ -57,7 +55,7 @@ const int _kDebugPrintCapacity = 12 * 1024;
const Duration _kDebugPrintPauseTime = Duration(seconds: 1);
final Queue<String> _debugPrintBuffer = Queue<String>();
final Stopwatch _debugPrintStopwatch = Stopwatch();
Completer<void> _debugPrintCompleter;
Completer<void>? _debugPrintCompleter;
bool _debugPrintScheduled = false;
void _debugPrintTask() {
_debugPrintScheduled = false;
......@@ -112,15 +110,15 @@ Iterable<String> debugWordWrap(String message, int width, { String wrapIndent =
yield message;
return;
}
final Match prefixMatch = _indentPattern.matchAsPrefix(message);
final String prefix = wrapIndent + ' ' * prefixMatch.group(0).length;
final Match prefixMatch = _indentPattern.matchAsPrefix(message)!;
final String prefix = wrapIndent + ' ' * prefixMatch.group(0)!.length;
int start = 0;
int startForLengthCalculations = 0;
bool addPrefix = false;
int index = prefix.length;
_WordWrapParseMode mode = _WordWrapParseMode.inSpace;
int lastWordStart;
int lastWordEnd;
late int lastWordStart;
int? lastWordEnd;
while (true) {
switch (mode) {
case _WordWrapParseMode.inSpace: // at start of break point (or start of line); can't break until next break
......
......@@ -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:typed_data';
import 'package:typed_data/typed_buffers.dart' show Uint8Buffer;
......@@ -16,86 +14,86 @@ import 'package:typed_data/typed_buffers.dart' show Uint8Buffer;
/// The byte order used is [Endian.host] throughout.
class WriteBuffer {
/// Creates an interface for incrementally building a [ByteData] instance.
WriteBuffer() {
_buffer = Uint8Buffer();
_eightBytes = ByteData(8);
WriteBuffer()
: _buffer = Uint8Buffer(),
_eightBytes = ByteData(8) {
_eightBytesAsList = _eightBytes.buffer.asUint8List();
}
Uint8Buffer _buffer;
ByteData _eightBytes;
Uint8List _eightBytesAsList;
Uint8Buffer? _buffer;
final ByteData _eightBytes;
late Uint8List _eightBytesAsList;
/// Write a Uint8 into the buffer.
void putUint8(int byte) {
_buffer.add(byte);
_buffer!.add(byte);
}
/// Write a Uint16 into the buffer.
void putUint16(int value, {Endian endian}) {
void putUint16(int value, {Endian? endian}) {
_eightBytes.setUint16(0, value, endian ?? Endian.host);
_buffer.addAll(_eightBytesAsList, 0, 2);
_buffer!.addAll(_eightBytesAsList, 0, 2);
}
/// Write a Uint32 into the buffer.
void putUint32(int value, {Endian endian}) {
void putUint32(int value, {Endian? endian}) {
_eightBytes.setUint32(0, value, endian ?? Endian.host);
_buffer.addAll(_eightBytesAsList, 0, 4);
_buffer!.addAll(_eightBytesAsList, 0, 4);
}
/// Write an Int32 into the buffer.
void putInt32(int value, {Endian endian}) {
void putInt32(int value, {Endian? endian}) {
_eightBytes.setInt32(0, value, endian ?? Endian.host);
_buffer.addAll(_eightBytesAsList, 0, 4);
_buffer!.addAll(_eightBytesAsList, 0, 4);
}
/// Write an Int64 into the buffer.
void putInt64(int value, {Endian endian}) {
void putInt64(int value, {Endian? endian}) {
_eightBytes.setInt64(0, value, endian ?? Endian.host);
_buffer.addAll(_eightBytesAsList, 0, 8);
_buffer!.addAll(_eightBytesAsList, 0, 8);
}
/// Write an Float64 into the buffer.
void putFloat64(double value, {Endian endian}) {
void putFloat64(double value, {Endian? endian}) {
_alignTo(8);
_eightBytes.setFloat64(0, value, endian ?? Endian.host);
_buffer.addAll(_eightBytesAsList);
_buffer!.addAll(_eightBytesAsList);
}
/// Write all the values from a [Uint8List] into the buffer.
void putUint8List(Uint8List list) {
_buffer.addAll(list);
_buffer!.addAll(list);
}
/// Write all the values from an [Int32List] into the buffer.
void putInt32List(Int32List list) {
_alignTo(4);
_buffer.addAll(list.buffer.asUint8List(list.offsetInBytes, 4 * list.length));
_buffer!.addAll(list.buffer.asUint8List(list.offsetInBytes, 4 * list.length));
}
/// Write all the values from an [Int64List] into the buffer.
void putInt64List(Int64List list) {
_alignTo(8);
_buffer.addAll(list.buffer.asUint8List(list.offsetInBytes, 8 * list.length));
_buffer!.addAll(list.buffer.asUint8List(list.offsetInBytes, 8 * list.length));
}
/// Write all the values from a [Float64List] into the buffer.
void putFloat64List(Float64List list) {
_alignTo(8);
_buffer.addAll(list.buffer.asUint8List(list.offsetInBytes, 8 * list.length));
_buffer!.addAll(list.buffer.asUint8List(list.offsetInBytes, 8 * list.length));
}
void _alignTo(int alignment) {
final int mod = _buffer.length % alignment;
final int mod = _buffer!.length % alignment;
if (mod != 0) {
for (int i = 0; i < alignment - mod; i++)
_buffer.add(0);
_buffer!.add(0);
}
}
/// Finalize and return the written [ByteData].
ByteData done() {
final ByteData result = _buffer.buffer.asByteData(0, _buffer.lengthInBytes);
final ByteData result = _buffer!.buffer.asByteData(0, _buffer!.lengthInBytes);
_buffer = null;
return result;
}
......@@ -124,35 +122,35 @@ class ReadBuffer {
}
/// Reads a Uint16 from the buffer.
int getUint16({Endian endian}) {
int getUint16({Endian? endian}) {
final int value = data.getUint16(_position, endian ?? Endian.host);
_position += 2;
return value;
}
/// Reads a Uint32 from the buffer.
int getUint32({Endian endian}) {
int getUint32({Endian? endian}) {
final int value = data.getUint32(_position, endian ?? Endian.host);
_position += 4;
return value;
}
/// Reads an Int32 from the buffer.
int getInt32({Endian endian}) {
int getInt32({Endian? endian}) {
final int value = data.getInt32(_position, endian ?? Endian.host);
_position += 4;
return value;
}
/// Reads an Int64 from the buffer.
int getInt64({Endian endian}) {
int getInt64({Endian? endian}) {
final int value = data.getInt64(_position, endian ?? Endian.host);
_position += 8;
return value;
}
/// Reads a Float64 from the buffer.
double getFloat64({Endian endian}) {
double getFloat64({Endian? endian}) {
_alignTo(8);
final double value = data.getFloat64(_position, endian ?? Endian.host);
_position += 8;
......
......@@ -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:ui' show hashValues;
import 'package:meta/meta.dart';
......@@ -29,16 +27,16 @@ class StackFrame {
/// All parameters must not be null. The [className] may be the empty string
/// if there is no class (e.g. for a top level library method).
const StackFrame({
@required this.number,
@required this.column,
@required this.line,
@required this.packageScheme,
@required this.package,
@required this.packagePath,
required this.number,
required this.column,
required this.line,
required this.packageScheme,
required this.package,
required this.packagePath,
this.className = '',
@required this.method,
required this.method,
this.isConstructor = false,
@required this.source,
required this.source,
}) : assert(number != null),
assert(column != null),
assert(line != null),
......@@ -92,11 +90,11 @@ class StackFrame {
// On the Web in non-debug builds the stack trace includes the exception
// message that precedes the stack trace itself. fromStackTraceLine will
// return null in that case. We will skip it here.
.skipWhile((StackFrame frame) => frame == null)
.whereType<StackFrame>()
.toList();
}
static StackFrame _parseWebFrame(String line) {
static StackFrame? _parseWebFrame(String line) {
if (kDebugMode) {
return _parseWebDebugFrame(line);
} else {
......@@ -111,15 +109,16 @@ class StackFrame {
final RegExp parser = hasPackage
? RegExp(r'^(package.+) (\d+):(\d+)\s+(.+)$')
: RegExp(r'^(.+) (\d+):(\d+)\s+(.+)$');
final Match match = parser.firstMatch(line);
Match? match = parser.firstMatch(line);
assert(match != null, 'Expected $line to match $parser.');
match = match!;
String package = '<unknown>';
String packageScheme = '<unknown>';
String packagePath = '<unknown>';
if (hasPackage) {
packageScheme = 'package';
final Uri packageUri = Uri.parse(match.group(1));
final Uri packageUri = Uri.parse(match.group(1)!);
package = packageUri.pathSegments[0];
packagePath = packageUri.path.replaceFirst(packageUri.pathSegments[0] + '/', '');
}
......@@ -129,10 +128,10 @@ class StackFrame {
packageScheme: packageScheme,
package: package,
packagePath: packagePath,
line: int.parse(match.group(2)),
column: int.parse(match.group(3)),
line: int.parse(match.group(2)!),
column: int.parse(match.group(3)!),
className: '<unknown>',
method: match.group(4),
method: match.group(4)!,
source: line,
);
}
......@@ -145,8 +144,8 @@ class StackFrame {
// Parses `line` as a stack frame in profile and release Web builds. If not
// recognized as a stack frame, returns null.
static StackFrame _parseWebNonDebugFrame(String line) {
final Match match = _webNonDebugFramePattern.firstMatch(line);
static StackFrame? _parseWebNonDebugFrame(String line) {
final Match? match = _webNonDebugFramePattern.firstMatch(line);
if (match == null) {
// On the Web in non-debug builds the stack trace includes the exception
// message that precedes the stack trace itself. Example:
......@@ -162,7 +161,7 @@ class StackFrame {
return null;
}
final List<String> classAndMethod = match.group(1).split('.');
final List<String> classAndMethod = match.group(1)!.split('.');
final String className = classAndMethod.length > 1 ? classAndMethod.first : '<unknown>';
final String method = classAndMethod.length > 1
? classAndMethod.skip(1).join('.')
......@@ -182,7 +181,7 @@ class StackFrame {
}
/// Parses a single [StackFrame] from a single line of a [StackTrace].
static StackFrame fromStackTraceLine(String line) {
static StackFrame? fromStackTraceLine(String line) {
assert(line != null);
if (line == '<asynchronous suspension>') {
return asynchronousSuspension;
......@@ -203,12 +202,13 @@ class StackFrame {
}
final RegExp parser = RegExp(r'^#(\d+) +(.+) \((.+?):?(\d+){0,1}:?(\d+){0,1}\)$');
final Match match = parser.firstMatch(line);
Match? match = parser.firstMatch(line);
assert(match != null, 'Expected $line to match $parser.');
match = match!;
bool isConstructor = false;
String className = '';
String method = match.group(2).replaceAll('.<anonymous closure>', '');
String method = match.group(2)!.replaceAll('.<anonymous closure>', '');
if (method.startsWith('new')) {
className = method.split(' ')[1];
method = '';
......@@ -224,7 +224,7 @@ class StackFrame {
method = parts[1];
}
final Uri packageUri = Uri.parse(match.group(3));
final Uri packageUri = Uri.parse(match.group(3)!);
String package = '<unknown>';
String packagePath = packageUri.path;
if (packageUri.scheme == 'dart' || packageUri.scheme == 'package') {
......@@ -233,14 +233,14 @@ class StackFrame {
}
return StackFrame(
number: int.parse(match.group(1)),
number: int.parse(match.group(1)!),
className: className,
method: method,
packageScheme: packageUri.scheme,
package: package,
packagePath: packagePath,
line: match.group(4) == null ? -1 : int.parse(match.group(4)),
column: match.group(5) == null ? -1 : int.parse(match.group(5)),
line: match.group(4) == null ? -1 : int.parse(match.group(4)!),
column: match.group(5) == null ? -1 : int.parse(match.group(5)!),
isConstructor: isConstructor,
source: line,
);
......
......@@ -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';
/// A [Future] whose [then] implementation calls the callback immediately.
......@@ -36,18 +34,18 @@ class SynchronousFuture<T> implements Future<T> {
}
@override
Future<T> catchError(Function onError, { bool test(Object error) }) => Completer<T>().future;
Future<T> catchError(Function onError, { bool test(Object error)? }) => Completer<T>().future;
@override
Future<E> then<E>(FutureOr<E> f(T value), { Function onError }) {
final dynamic result = f(_value);
if (result is Future<E>)
Future<R> then<R>(FutureOr<R> onValue(T value), { Function? onError }) {
final dynamic result = onValue(_value);
if (result is Future<R>)
return result;
return SynchronousFuture<E>(result as E);
return SynchronousFuture<R>(result as R);
}
@override
Future<T> timeout(Duration timeLimit, { FutureOr<T> onTimeout() }) {
Future<T> timeout(Duration timeLimit, { FutureOr<T> onTimeout()? }) {
return Future<T>.value(_value).timeout(timeLimit, onTimeout: onTimeout);
}
......
......@@ -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
/// Constants for useful Unicode characters.
///
/// Currently, these characters are all related to bidirectional text.
......
......@@ -2,6 +2,8 @@
// 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_test/flutter_test.dart';
import 'package:flutter/rendering.dart';
import 'package:flutter/widgets.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