[Core Libraries] Eliminate the fork in the core libraries.

Move the nnbd core libraries from sdk_nnbd to sdk, and updates
references in build files and elsewhere accordingly.

Change-Id: I09760fe1e006657aacdfe80f3b22fdf6f7e30a9f
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/151121
Commit-Queue: Leaf Petersen <leafp@google.com>
Reviewed-by: Bob Nystrom <rnystrom@google.com>
This commit is contained in:
Leaf Petersen 2020-06-16 23:37:36 +00:00
parent 29e93bcdbd
commit d44457f79d
785 changed files with 12338 additions and 209608 deletions

View file

@ -80,24 +80,12 @@ group("runtime_precompiled") {
] ]
} }
if (dont_use_nnbd) { group("create_sdk") {
group("create_sdk") { public_deps = [ "sdk:create_sdk" ]
public_deps = [ "sdk:create_sdk" ]
}
} else {
group("create_sdk") {
public_deps = [ "sdk_nnbd:create_sdk" ]
}
} }
if (dont_use_nnbd) { group("create_platform_sdk") {
group("create_platform_sdk") { public_deps = [ "sdk:create_platform_sdk" ]
public_deps = [ "sdk:create_platform_sdk" ]
}
} else {
group("create_platform_sdk") {
public_deps = [ "sdk_nnbd:create_platform_sdk" ]
}
} }
group("dart2js") { group("dart2js") {

View file

@ -19,49 +19,6 @@ def is_cpp_file(path):
return path.endswith('.cc') or path.endswith('.h') return path.endswith('.cc') or path.endswith('.h')
def _CheckNnbdSdkSync(input_api, output_api):
files = [git_file.LocalPath() for git_file in input_api.AffectedTextFiles()]
unsynchronized_files = []
for file in files:
if file.startswith('sdk/'):
nnbd_file = 'sdk_nnbd/' + file[4:]
if not nnbd_file in files:
unsynchronized_files.append(nnbd_file)
if unsynchronized_files:
return [
output_api.PresubmitPromptWarning(
'Changes were made to sdk/ that were not made to sdk_nnbd/\n'
'Please update these files as well:\n'
'\n'
'%s' % ('\n'.join(unsynchronized_files)))
]
return []
def _CheckSdkDdcRuntimeSync(input_api, output_api):
files = [git_file.LocalPath() for git_file in input_api.AffectedTextFiles()]
unsynchronized_files = []
runtime_lib = 'lib/_internal/js_dev_runtime/private/ddc_runtime/'
for nnbd_file in files:
if nnbd_file.startswith('sdk_nnbd/' + runtime_lib):
file = 'sdk/' + nnbd_file[9:]
if not file in files:
unsynchronized_files.append(file)
if unsynchronized_files:
return [
output_api.PresubmitPromptWarning(
'Changes were made to '
'sdk_nnbd/lib/_internal/js_dev_runtime/private/ddc_runtime/ '
'that were not made to '
'sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/ '
'Please copy those changes (without Null Safety syntax) to '
'these files as well:\n'
'\n'
'%s' % ('\n'.join(unsynchronized_files)))
]
return []
def _CheckNnbdTestSync(input_api, output_api): def _CheckNnbdTestSync(input_api, output_api):
"""Make sure that any forked SDK tests are kept in sync. If a CL touches """Make sure that any forked SDK tests are kept in sync. If a CL touches
a test, the test's counterpart (if it exists at all) should be in the CL a test, the test's counterpart (if it exists at all) should be in the CL
@ -369,8 +326,6 @@ def _CheckTestMatrixValid(input_api, output_api):
def _CommonChecks(input_api, output_api): def _CommonChecks(input_api, output_api):
results = [] results = []
results.extend(_CheckNnbdSdkSync(input_api, output_api))
results.extend(_CheckSdkDdcRuntimeSync(input_api, output_api))
results.extend(_CheckNnbdTestSync(input_api, output_api)) results.extend(_CheckNnbdTestSync(input_api, output_api))
results.extend(_CheckValidHostsInDEPS(input_api, output_api)) results.extend(_CheckValidHostsInDEPS(input_api, output_api))
results.extend(_CheckDartFormat(input_api, output_api)) results.extend(_CheckDartFormat(input_api, output_api))

View file

@ -28,7 +28,6 @@
'filepath': ( 'filepath': (
'^pkg/compiler|' '^pkg/compiler|'
'^sdk/lib/_internal/js_runtime|' '^sdk/lib/_internal/js_runtime|'
'^sdk_nnbd/lib/_internal/js_runtime|'
'^tests/compiler/dart2js' '^tests/compiler/dart2js'
) )
}, },
@ -36,7 +35,6 @@
'filepath': ( 'filepath': (
'^pkg/dev_compiler|' '^pkg/dev_compiler|'
'^sdk/lib/_internal/js_dev_runtime|' '^sdk/lib/_internal/js_dev_runtime|'
'^sdk_nnbd/lib/_internal/js_dev_runtime|'
'^tests/compiler/dartdevc_native' '^tests/compiler/dartdevc_native'
) )
}, },

View file

@ -29,7 +29,7 @@ export 'diagnostic_helper.dart';
bool isDart2jsNnbd = bool isDart2jsNnbd =
!Platform.environment['DART_CONFIGURATION'].endsWith('Legacy'); !Platform.environment['DART_CONFIGURATION'].endsWith('Legacy');
String sdkPath = isDart2jsNnbd ? 'sdk_nnbd/lib' : 'sdk/lib'; String sdkPath = 'sdk/lib';
String sdkLibrariesSpecificationPath = '$sdkPath/libraries.json'; String sdkLibrariesSpecificationPath = '$sdkPath/libraries.json';

View file

@ -132,10 +132,7 @@ class SourceToDillStep implements IOModularStep {
return; return;
} }
sources = ['dart:core']; sources = ['dart:core'];
extraArgs = [ extraArgs = ['--libraries-file', '$rootScheme:///sdk/lib/libraries.json'];
'--libraries-file',
'$rootScheme:///sdk_nnbd/lib/libraries.json'
];
assert(transitiveDependencies.isEmpty); assert(transitiveDependencies.isEmpty);
} else { } else {
sources = module.sources.map(sourceToImportUri).toList(); sources = module.sources.map(sourceToImportUri).toList();
@ -342,7 +339,7 @@ class RunD8 implements IOModularStep {
if (_options.verbose) print("\nstep: d8 on $module"); if (_options.verbose) print("\nstep: d8 on $module");
List<String> d8Args = [ List<String> d8Args = [
sdkRoot sdkRoot
.resolve('sdk_nnbd/lib/_internal/js_runtime/lib/preambles/d8.js') .resolve('sdk/lib/_internal/js_runtime/lib/preambles/d8.js')
.toFilePath(), .toFilePath(),
root.resolveUri(toUri(module, jsId)).toFilePath(), root.resolveUri(toUri(module, jsId)).toFilePath(),
]; ];

View file

@ -339,9 +339,7 @@ Map placeSourceMap(Map sourceMap, String sourceMapPath, String multiRootScheme,
// TODO(sigmund): extract all source-map normalization outside ddc. This // TODO(sigmund): extract all source-map normalization outside ddc. This
// custom logic is BUILD specific and could be shared with other tools // custom logic is BUILD specific and could be shared with other tools
// like dart2js. // like dart2js.
var shortPath = uri.path var shortPath = uri.path.replaceAll('/sdk/', '/dart-sdk/');
.replaceAll('/sdk/', '/dart-sdk/')
.replaceAll('/sdk_nnbd/', '/dart-sdk/');
var multiRootPath = "${multiRootOutputPath ?? ''}$shortPath"; var multiRootPath = "${multiRootOutputPath ?? ''}$shortPath";
multiRootPath = p.url.relative(multiRootPath, from: sourceMapDir); multiRootPath = p.url.relative(multiRootPath, from: sourceMapDir);
return multiRootPath; return multiRootPath;

View file

@ -77,7 +77,7 @@ class SourceToSummaryDillStep implements IOModularStep {
sources = ['dart:core']; sources = ['dart:core'];
extraArgs = [ extraArgs = [
'--libraries-file', '--libraries-file',
'$rootScheme:///sdk_nnbd/lib/libraries.json', '$rootScheme:///sdk/lib/libraries.json',
'--enable-experiment', '--enable-experiment',
'non-nullable', 'non-nullable',
]; ];
@ -157,7 +157,7 @@ class DDCStep implements IOModularStep {
extraArgs = [ extraArgs = [
'--compile-sdk', '--compile-sdk',
'--libraries-file', '--libraries-file',
'$rootScheme:///sdk_nnbd/lib/libraries.json', '$rootScheme:///sdk/lib/libraries.json',
'--enable-experiment', '--enable-experiment',
'non-nullable', 'non-nullable',
]; ];

View file

@ -77,7 +77,7 @@ class SourceToSummaryDillStep implements IOModularStep {
sources = ['dart:core']; sources = ['dart:core'];
extraArgs = [ extraArgs = [
'--libraries-file', '--libraries-file',
'$rootScheme:///sdk_nnbd/lib/libraries.json', '$rootScheme:///sdk/lib/libraries.json',
]; ];
assert(transitiveDependencies.isEmpty); assert(transitiveDependencies.isEmpty);
} else { } else {
@ -159,7 +159,7 @@ class DDCStep implements IOModularStep {
extraArgs = [ extraArgs = [
'--compile-sdk', '--compile-sdk',
'--libraries-file', '--libraries-file',
'$rootScheme:///sdk_nnbd/lib/libraries.json', '$rootScheme:///sdk/lib/libraries.json',
]; ];
assert(transitiveDependencies.isEmpty); assert(transitiveDependencies.isEmpty);
} else { } else {

View file

@ -37,7 +37,7 @@ void main(List<String> argv) {
var librariesJson = args['libraries'] != null var librariesJson = args['libraries'] != null
? resolveInputUri(args['libraries'] as String) ? resolveInputUri(args['libraries'] as String)
: Platform.script.resolve('../../../sdk_nnbd/lib/libraries.json'); : Platform.script.resolve('../../../sdk/lib/libraries.json');
var target = args['target'] as String; var target = args['target'] as String;
patch.main([ patch.main([
'--libraries', '--libraries',
@ -115,8 +115,7 @@ main() {}
var result = Process.runSync(dart.toFilePath(), [ var result = Process.runSync(dart.toFilePath(), [
// The NNBD dart binaries / snapshots require this flag to be enabled at // The NNBD dart binaries / snapshots require this flag to be enabled at
// VM level. // VM level.
if (analyzerSnapshot.contains('NNBD')) if (analyzerSnapshot.contains('NNBD')) '--enable-experiment=non-nullable',
'--enable-experiment=non-nullable',
analyzerSnapshot, analyzerSnapshot,
'--dart-sdk=${sdkDir}', '--dart-sdk=${sdkDir}',
'--format', '--format',
@ -198,7 +197,7 @@ main() {}
final _parser = ArgParser() final _parser = ArgParser()
..addOption('libraries', ..addOption('libraries',
help: 'Path to the nnbd libraries.json (defaults to the one under ' help: 'Path to the nnbd libraries.json (defaults to the one under '
'sdk_nnbd/lib/libraries.json.') 'sdk/lib/libraries.json.')
..addOption('out', ..addOption('out',
help: 'Path to an output folder (defaults to a new tmp folder).') help: 'Path to an output folder (defaults to a new tmp folder).')
..addOption('target', ..addOption('target',

View file

@ -9,7 +9,7 @@ part 'experimental_flags_generated.dart';
/// The set of experiments enabled for SDK and packages. /// The set of experiments enabled for SDK and packages.
/// ///
/// This are derived from an `allowed_experiments.json` file whose default is /// This are derived from an `allowed_experiments.json` file whose default is
/// located in `sdk_nnbd/lib/_internal/allowed_experiments.json`. /// located in `sdk/lib/_internal/allowed_experiments.json`.
class AllowedExperimentalFlags { class AllowedExperimentalFlags {
/// The set of experiments that are enabled for all SDK libraries other than /// The set of experiments that are enabled for all SDK libraries other than
/// for those which are specified in [sdkLibraryExperiments]. /// for those which are specified in [sdkLibraryExperiments].

View file

@ -12,7 +12,7 @@ library;
// //
// class C extends Iterable<Object> { // class C extends Iterable<Object> {
// ^ // ^
// org-dartlang-sdk:///sdk_nnbd/lib/core/iterable.dart:158:19: Context: 'Iterable.iterator' is defined here. // sdk/lib/core/iterable.dart:158:19: Context: 'Iterable.iterator' is defined here.
// Iterator<E> get iterator; // Iterator<E> get iterator;
// ^^^^^^^^ // ^^^^^^^^
// //

View file

@ -12,14 +12,14 @@ library;
// //
// class C extends Iterable<Object> { // class C extends Iterable<Object> {
// ^ // ^
// org-dartlang-sdk:///sdk_nnbd/lib/core/iterable.dart:158:19: Context: 'Iterable.iterator' is defined here. // sdk/lib/core/iterable.dart:158:19: Context: 'Iterable.iterator' is defined here.
// Iterator<E> get iterator; // Iterator<E> get iterator;
// ^^^^^^^^ // ^^^^^^^^
// //
// pkg/front_end/testcases/general/sdk_diagnostic.dart:12:8: Error: Too few positional arguments: 1 required, 0 given. // pkg/front_end/testcases/general/sdk_diagnostic.dart:12:8: Error: Too few positional arguments: 1 required, 0 given.
// print(incorrectArgument: "fisk"); // print(incorrectArgument: "fisk");
// ^ // ^
// org-dartlang-sdk:///sdk_nnbd/lib/core/print.dart:8:6: Context: Found this candidate, but the arguments don't match. // sdk/lib/core/print.dart:8:6: Context: Found this candidate, but the arguments don't match.
// void print(Object? object) { // void print(Object? object) {
// ^^^^^ // ^^^^^
// //

View file

@ -12,14 +12,14 @@ library;
// //
// class C extends Iterable<Object> { // class C extends Iterable<Object> {
// ^ // ^
// org-dartlang-sdk:///sdk_nnbd/lib/core/iterable.dart:158:19: Context: 'Iterable.iterator' is defined here. // sdk/lib/core/iterable.dart:158:19: Context: 'Iterable.iterator' is defined here.
// Iterator<E> get iterator; // Iterator<E> get iterator;
// ^^^^^^^^ // ^^^^^^^^
// //
// pkg/front_end/testcases/general/sdk_diagnostic.dart:12:8: Error: Too few positional arguments: 1 required, 0 given. // pkg/front_end/testcases/general/sdk_diagnostic.dart:12:8: Error: Too few positional arguments: 1 required, 0 given.
// print(incorrectArgument: "fisk"); // print(incorrectArgument: "fisk");
// ^ // ^
// org-dartlang-sdk:///sdk_nnbd/lib/core/print.dart:8:6: Context: Found this candidate, but the arguments don't match. // sdk/lib/core/print.dart:8:6: Context: Found this candidate, but the arguments don't match.
// void print(Object? object) { // void print(Object? object) {
// ^^^^^ // ^^^^^
// //

View file

@ -12,7 +12,7 @@ library;
// //
// class C extends Iterable<Object> { // class C extends Iterable<Object> {
// ^ // ^
// org-dartlang-sdk:///sdk_nnbd/lib/core/iterable.dart:158:19: Context: 'Iterable.iterator' is defined here. // org-dartlang-sdk:///sdk/lib/core/iterable.dart:158:19: Context: 'Iterable.iterator' is defined here.
// Iterator<E> get iterator; // Iterator<E> get iterator;
// ^^^^^^^^ // ^^^^^^^^
// //

View file

@ -12,14 +12,14 @@ library;
// //
// class C extends Iterable<Object> { // class C extends Iterable<Object> {
// ^ // ^
// org-dartlang-sdk:///sdk_nnbd/lib/core/iterable.dart:158:19: Context: 'Iterable.iterator' is defined here. // org-dartlang-sdk:///sdk/lib/core/iterable.dart:158:19: Context: 'Iterable.iterator' is defined here.
// Iterator<E> get iterator; // Iterator<E> get iterator;
// ^^^^^^^^ // ^^^^^^^^
// //
// pkg/front_end/testcases/general_nnbd_opt_out/sdk_diagnostic.dart:14:8: Error: Too few positional arguments: 1 required, 0 given. // pkg/front_end/testcases/general_nnbd_opt_out/sdk_diagnostic.dart:14:8: Error: Too few positional arguments: 1 required, 0 given.
// print(incorrectArgument: "fisk"); // print(incorrectArgument: "fisk");
// ^ // ^
// org-dartlang-sdk:///sdk_nnbd/lib/core/print.dart:8:6: Context: Found this candidate, but the arguments don't match. // org-dartlang-sdk:///sdk/lib/core/print.dart:8:6: Context: Found this candidate, but the arguments don't match.
// void print(Object? object) { // void print(Object? object) {
// ^^^^^ // ^^^^^
// //

View file

@ -12,14 +12,14 @@ library;
// //
// class C extends Iterable<Object> { // class C extends Iterable<Object> {
// ^ // ^
// org-dartlang-sdk:///sdk_nnbd/lib/core/iterable.dart:158:19: Context: 'Iterable.iterator' is defined here. // org-dartlang-sdk:///sdk/lib/core/iterable.dart:158:19: Context: 'Iterable.iterator' is defined here.
// Iterator<E> get iterator; // Iterator<E> get iterator;
// ^^^^^^^^ // ^^^^^^^^
// //
// pkg/front_end/testcases/general_nnbd_opt_out/sdk_diagnostic.dart:14:8: Error: Too few positional arguments: 1 required, 0 given. // pkg/front_end/testcases/general_nnbd_opt_out/sdk_diagnostic.dart:14:8: Error: Too few positional arguments: 1 required, 0 given.
// print(incorrectArgument: "fisk"); // print(incorrectArgument: "fisk");
// ^ // ^
// org-dartlang-sdk:///sdk_nnbd/lib/core/print.dart:8:6: Context: Found this candidate, but the arguments don't match. // org-dartlang-sdk:///sdk/lib/core/print.dart:8:6: Context: Found this candidate, but the arguments don't match.
// void print(Object? object) { // void print(Object? object) {
// ^^^^^ // ^^^^^
// //

View file

@ -12,14 +12,14 @@ library;
// //
// class C extends Iterable<Object> { // class C extends Iterable<Object> {
// ^ // ^
// org-dartlang-sdk:///sdk_nnbd/lib/core/iterable.dart:158:19: Context: 'Iterable.iterator' is defined here. // sdk/lib/core/iterable.dart:158:19: Context: 'Iterable.iterator' is defined here.
// Iterator<E> get iterator; // Iterator<E> get iterator;
// ^^^^^^^^ // ^^^^^^^^
// //
// pkg/front_end/testcases/general_nnbd_opt_out/sdk_diagnostic.dart:14:8: Error: Too few positional arguments: 1 required, 0 given. // pkg/front_end/testcases/general_nnbd_opt_out/sdk_diagnostic.dart:14:8: Error: Too few positional arguments: 1 required, 0 given.
// print(incorrectArgument: "fisk"); // print(incorrectArgument: "fisk");
// ^ // ^
// org-dartlang-sdk:///sdk_nnbd/lib/core/print.dart:8:6: Context: Found this candidate, but the arguments don't match. // sdk/lib/core/print.dart:8:6: Context: Found this candidate, but the arguments don't match.
// void print(Object? object) { // void print(Object? object) {
// ^^^^^ // ^^^^^
// //

View file

@ -12,14 +12,14 @@ library;
// //
// class C extends Iterable<Object> { // class C extends Iterable<Object> {
// ^ // ^
// org-dartlang-sdk:///sdk_nnbd/lib/core/iterable.dart:158:19: Context: 'Iterable.iterator' is defined here. // sdk/lib/core/iterable.dart:158:19: Context: 'Iterable.iterator' is defined here.
// Iterator<E> get iterator; // Iterator<E> get iterator;
// ^^^^^^^^ // ^^^^^^^^
// //
// pkg/front_end/testcases/general_nnbd_opt_out/sdk_diagnostic.dart:14:8: Error: Too few positional arguments: 1 required, 0 given. // pkg/front_end/testcases/general_nnbd_opt_out/sdk_diagnostic.dart:14:8: Error: Too few positional arguments: 1 required, 0 given.
// print(incorrectArgument: "fisk"); // print(incorrectArgument: "fisk");
// ^ // ^
// org-dartlang-sdk:///sdk_nnbd/lib/core/print.dart:8:6: Context: Found this candidate, but the arguments don't match. // sdk/lib/core/print.dart:8:6: Context: Found this candidate, but the arguments don't match.
// void print(Object? object) { // void print(Object? object) {
// ^^^^^ // ^^^^^
// //

View file

@ -10,13 +10,13 @@ library from "org-dartlang-test:///main.dart" as main {
abstract member-signature get length() → dart.core::int*; abstract member-signature get length() → dart.core::int*;
abstract member-signature operator [](dart.core::int* index) → dart.core::int*; abstract member-signature operator [](dart.core::int* index) → dart.core::int*;
abstract member-signature operator []=(dart.core::int* index, generic-covariant-impl dart.core::int* value) → void; abstract member-signature operator []=(dart.core::int* index, generic-covariant-impl dart.core::int* value) → void;
get /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ iterator() → dart.core::Iterator<dart.core::int*> get /*isNonNullableByDefault, from org-dartlang-sdk:///sdk/lib/collection/list.dart */ iterator() → dart.core::Iterator<dart.core::int*>
return new dart._internal::ListIterator::•<dart.core::int*>(this); return new dart._internal::ListIterator::•<dart.core::int*>(this);
method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ elementAt(dart.core::int index) → dart.core::int* method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk/lib/collection/list.dart */ elementAt(dart.core::int index) → dart.core::int*
return this.{dart.core::List::[]}(index); return this.{dart.core::List::[]}(index);
method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ followedBy(generic-covariant-impl dart.core::Iterable<dart.core::int*> other) → dart.core::Iterable<dart.core::int*> method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk/lib/collection/list.dart */ followedBy(generic-covariant-impl dart.core::Iterable<dart.core::int*> other) → dart.core::Iterable<dart.core::int*>
return dart._internal::FollowedByIterable::firstEfficient<dart.core::int*>(this, other); return dart._internal::FollowedByIterable::firstEfficient<dart.core::int*>(this, other);
method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ forEach((dart.core::int*) → void action) → void { method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk/lib/collection/list.dart */ forEach((dart.core::int*) → void action) → void {
dart.core::int length = this.{dart.core::List::length}; dart.core::int length = this.{dart.core::List::length};
for (dart.core::int i = 0; i.{dart.core::num::<}(length); i = i.{dart.core::num::+}(1)) { for (dart.core::int i = 0; i.{dart.core::num::<}(length); i = i.{dart.core::num::+}(1)) {
action.call(this.{dart.core::List::[]}(i)); action.call(this.{dart.core::List::[]}(i));
@ -26,11 +26,11 @@ library from "org-dartlang-test:///main.dart" as main {
} }
} }
@#C3 @#C3
get /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ isEmpty() → dart.core::bool get /*isNonNullableByDefault, from org-dartlang-sdk:///sdk/lib/collection/list.dart */ isEmpty() → dart.core::bool
return this.{dart.core::List::length}.{dart.core::num::==}(0); return this.{dart.core::List::length}.{dart.core::num::==}(0);
get /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ isNotEmpty() → dart.core::bool get /*isNonNullableByDefault, from org-dartlang-sdk:///sdk/lib/collection/list.dart */ isNotEmpty() → dart.core::bool
return !this.{dart.collection::ListMixin::isEmpty}; return !this.{dart.collection::ListMixin::isEmpty};
method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ contains(dart.core::Object? element) → dart.core::bool { method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk/lib/collection/list.dart */ contains(dart.core::Object? element) → dart.core::bool {
dart.core::int length = this.{dart.core::List::length}; dart.core::int length = this.{dart.core::List::length};
for (dart.core::int i = 0; i.{dart.core::num::<}(length); i = i.{dart.core::num::+}(1)) { for (dart.core::int i = 0; i.{dart.core::num::<}(length); i = i.{dart.core::num::+}(1)) {
if(this.{dart.core::List::[]}(i).{dart.core::Object::==}(element)) if(this.{dart.core::List::[]}(i).{dart.core::Object::==}(element))
@ -41,7 +41,7 @@ library from "org-dartlang-test:///main.dart" as main {
} }
return false; return false;
} }
method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ every((dart.core::int*) → dart.core::bool test) → dart.core::bool { method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk/lib/collection/list.dart */ every((dart.core::int*) → dart.core::bool test) → dart.core::bool {
dart.core::int length = this.{dart.core::List::length}; dart.core::int length = this.{dart.core::List::length};
for (dart.core::int i = 0; i.{dart.core::num::<}(length); i = i.{dart.core::num::+}(1)) { for (dart.core::int i = 0; i.{dart.core::num::<}(length); i = i.{dart.core::num::+}(1)) {
if(!test.call(this.{dart.core::List::[]}(i))) if(!test.call(this.{dart.core::List::[]}(i)))
@ -52,7 +52,7 @@ library from "org-dartlang-test:///main.dart" as main {
} }
return true; return true;
} }
method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ any((dart.core::int*) → dart.core::bool test) → dart.core::bool { method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk/lib/collection/list.dart */ any((dart.core::int*) → dart.core::bool test) → dart.core::bool {
dart.core::int length = this.{dart.core::List::length}; dart.core::int length = this.{dart.core::List::length};
for (dart.core::int i = 0; i.{dart.core::num::<}(length); i = i.{dart.core::num::+}(1)) { for (dart.core::int i = 0; i.{dart.core::num::<}(length); i = i.{dart.core::num::+}(1)) {
if(test.call(this.{dart.core::List::[]}(i))) if(test.call(this.{dart.core::List::[]}(i)))
@ -63,7 +63,7 @@ library from "org-dartlang-test:///main.dart" as main {
} }
return false; return false;
} }
method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ firstWhere((dart.core::int*) → dart.core::bool test, {generic-covariant-impl () →? dart.core::int* orElse = #C2}) → dart.core::int* { method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk/lib/collection/list.dart */ firstWhere((dart.core::int*) → dart.core::bool test, {generic-covariant-impl () →? dart.core::int* orElse = #C2}) → dart.core::int* {
dart.core::int length = this.{dart.core::List::length}; dart.core::int length = this.{dart.core::List::length};
for (dart.core::int i = 0; i.{dart.core::num::<}(length); i = i.{dart.core::num::+}(1)) { for (dart.core::int i = 0; i.{dart.core::num::<}(length); i = i.{dart.core::num::+}(1)) {
dart.core::int* element = this.{dart.core::List::[]}(i); dart.core::int* element = this.{dart.core::List::[]}(i);
@ -77,7 +77,7 @@ library from "org-dartlang-test:///main.dart" as main {
return orElse{() → dart.core::int*}.call(); return orElse{() → dart.core::int*}.call();
throw dart._internal::IterableElementError::noElement(); throw dart._internal::IterableElementError::noElement();
} }
method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ lastWhere((dart.core::int*) → dart.core::bool test, {generic-covariant-impl () →? dart.core::int* orElse = #C2}) → dart.core::int* { method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk/lib/collection/list.dart */ lastWhere((dart.core::int*) → dart.core::bool test, {generic-covariant-impl () →? dart.core::int* orElse = #C2}) → dart.core::int* {
dart.core::int length = this.{dart.core::List::length}; dart.core::int length = this.{dart.core::List::length};
for (dart.core::int i = length.{dart.core::num::-}(1); i.{dart.core::num::>=}(0); i = i.{dart.core::num::-}(1)) { for (dart.core::int i = length.{dart.core::num::-}(1); i.{dart.core::num::>=}(0); i = i.{dart.core::num::-}(1)) {
dart.core::int* element = this.{dart.core::List::[]}(i); dart.core::int* element = this.{dart.core::List::[]}(i);
@ -91,7 +91,7 @@ library from "org-dartlang-test:///main.dart" as main {
return orElse{() → dart.core::int*}.call(); return orElse{() → dart.core::int*}.call();
throw dart._internal::IterableElementError::noElement(); throw dart._internal::IterableElementError::noElement();
} }
method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ singleWhere((dart.core::int*) → dart.core::bool test, {generic-covariant-impl () →? dart.core::int* orElse = #C2}) → dart.core::int* { method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk/lib/collection/list.dart */ singleWhere((dart.core::int*) → dart.core::bool test, {generic-covariant-impl () →? dart.core::int* orElse = #C2}) → dart.core::int* {
dart.core::int length = this.{dart.core::List::length}; dart.core::int length = this.{dart.core::List::length};
late dart.core::int* match; late dart.core::int* match;
dart.core::bool matchFound = false; dart.core::bool matchFound = false;
@ -114,7 +114,7 @@ library from "org-dartlang-test:///main.dart" as main {
return orElse{() → dart.core::int*}.call(); return orElse{() → dart.core::int*}.call();
throw dart._internal::IterableElementError::noElement(); throw dart._internal::IterableElementError::noElement();
} }
method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ join([dart.core::String separator = #C4]) → dart.core::String { method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk/lib/collection/list.dart */ join([dart.core::String separator = #C4]) → dart.core::String {
if(this.{dart.core::List::length}.{dart.core::num::==}(0)) if(this.{dart.core::List::length}.{dart.core::num::==}(0))
return ""; return "";
dart.core::StringBuffer buffer = let final dart.core::StringBuffer #t1 = new dart.core::StringBuffer::•() in block { dart.core::StringBuffer buffer = let final dart.core::StringBuffer #t1 = new dart.core::StringBuffer::•() in block {
@ -122,15 +122,15 @@ library from "org-dartlang-test:///main.dart" as main {
} =>#t1; } =>#t1;
return buffer.{dart.core::StringBuffer::toString}(); return buffer.{dart.core::StringBuffer::toString}();
} }
method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ where((dart.core::int*) → dart.core::bool test) → dart.core::Iterable<dart.core::int*> method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk/lib/collection/list.dart */ where((dart.core::int*) → dart.core::bool test) → dart.core::Iterable<dart.core::int*>
return new dart._internal::WhereIterable::•<dart.core::int*>(this, test); return new dart._internal::WhereIterable::•<dart.core::int*>(this, test);
method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ whereType<T extends dart.core::Object? = dynamic>() → dart.core::Iterable<main::_WithListMixin&Object&ListMixin::whereType::T%> method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk/lib/collection/list.dart */ whereType<T extends dart.core::Object? = dynamic>() → dart.core::Iterable<main::_WithListMixin&Object&ListMixin::whereType::T%>
return new dart._internal::WhereTypeIterable::•<main::_WithListMixin&Object&ListMixin::whereType::T%>(this); return new dart._internal::WhereTypeIterable::•<main::_WithListMixin&Object&ListMixin::whereType::T%>(this);
method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ map<T extends dart.core::Object? = dynamic>((dart.core::int*) → main::_WithListMixin&Object&ListMixin::map::T% f) → dart.core::Iterable<main::_WithListMixin&Object&ListMixin::map::T%> method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk/lib/collection/list.dart */ map<T extends dart.core::Object? = dynamic>((dart.core::int*) → main::_WithListMixin&Object&ListMixin::map::T% f) → dart.core::Iterable<main::_WithListMixin&Object&ListMixin::map::T%>
return new dart._internal::MappedListIterable::•<dart.core::int*, main::_WithListMixin&Object&ListMixin::map::T%>(this, f); return new dart._internal::MappedListIterable::•<dart.core::int*, main::_WithListMixin&Object&ListMixin::map::T%>(this, f);
method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ expand<T extends dart.core::Object? = dynamic>((dart.core::int*) → dart.core::Iterable<main::_WithListMixin&Object&ListMixin::expand::T%> f) → dart.core::Iterable<main::_WithListMixin&Object&ListMixin::expand::T%> method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk/lib/collection/list.dart */ expand<T extends dart.core::Object? = dynamic>((dart.core::int*) → dart.core::Iterable<main::_WithListMixin&Object&ListMixin::expand::T%> f) → dart.core::Iterable<main::_WithListMixin&Object&ListMixin::expand::T%>
return new dart._internal::ExpandIterable::•<dart.core::int*, main::_WithListMixin&Object&ListMixin::expand::T%>(this, f); return new dart._internal::ExpandIterable::•<dart.core::int*, main::_WithListMixin&Object&ListMixin::expand::T%>(this, f);
method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ reduce(generic-covariant-impl (dart.core::int*, dart.core::int*) → dart.core::int* combine) → dart.core::int* { method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk/lib/collection/list.dart */ reduce(generic-covariant-impl (dart.core::int*, dart.core::int*) → dart.core::int* combine) → dart.core::int* {
dart.core::int length = this.{dart.core::List::length}; dart.core::int length = this.{dart.core::List::length};
if(length.{dart.core::num::==}(0)) if(length.{dart.core::num::==}(0))
throw dart._internal::IterableElementError::noElement(); throw dart._internal::IterableElementError::noElement();
@ -143,7 +143,7 @@ library from "org-dartlang-test:///main.dart" as main {
} }
return value; return value;
} }
method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ fold<T extends dart.core::Object? = dynamic>(main::_WithListMixin&Object&ListMixin::fold::T% initialValue, (main::_WithListMixin&Object&ListMixin::fold::T%, dart.core::int*) → main::_WithListMixin&Object&ListMixin::fold::T% combine) → main::_WithListMixin&Object&ListMixin::fold::T% { method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk/lib/collection/list.dart */ fold<T extends dart.core::Object? = dynamic>(main::_WithListMixin&Object&ListMixin::fold::T% initialValue, (main::_WithListMixin&Object&ListMixin::fold::T%, dart.core::int*) → main::_WithListMixin&Object&ListMixin::fold::T% combine) → main::_WithListMixin&Object&ListMixin::fold::T% {
main::_WithListMixin&Object&ListMixin::fold::T% value = initialValue; main::_WithListMixin&Object&ListMixin::fold::T% value = initialValue;
dart.core::int length = this.{dart.core::List::length}; dart.core::int length = this.{dart.core::List::length};
for (dart.core::int i = 0; i.{dart.core::num::<}(length); i = i.{dart.core::num::+}(1)) { for (dart.core::int i = 0; i.{dart.core::num::<}(length); i = i.{dart.core::num::+}(1)) {
@ -154,17 +154,17 @@ library from "org-dartlang-test:///main.dart" as main {
} }
return value; return value;
} }
method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ skip(dart.core::int count) → dart.core::Iterable<dart.core::int*> method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk/lib/collection/list.dart */ skip(dart.core::int count) → dart.core::Iterable<dart.core::int*>
return new dart._internal::SubListIterable::•<dart.core::int*>(this, count, null); return new dart._internal::SubListIterable::•<dart.core::int*>(this, count, null);
method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ skipWhile((dart.core::int*) → dart.core::bool test) → dart.core::Iterable<dart.core::int*> { method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk/lib/collection/list.dart */ skipWhile((dart.core::int*) → dart.core::bool test) → dart.core::Iterable<dart.core::int*> {
return new dart._internal::SkipWhileIterable::•<dart.core::int*>(this, test); return new dart._internal::SkipWhileIterable::•<dart.core::int*>(this, test);
} }
method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ take(dart.core::int count) → dart.core::Iterable<dart.core::int*> method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk/lib/collection/list.dart */ take(dart.core::int count) → dart.core::Iterable<dart.core::int*>
return new dart._internal::SubListIterable::•<dart.core::int*>(this, 0, count); return new dart._internal::SubListIterable::•<dart.core::int*>(this, 0, count);
method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ takeWhile((dart.core::int*) → dart.core::bool test) → dart.core::Iterable<dart.core::int*> { method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk/lib/collection/list.dart */ takeWhile((dart.core::int*) → dart.core::bool test) → dart.core::Iterable<dart.core::int*> {
return new dart._internal::TakeWhileIterable::•<dart.core::int*>(this, test); return new dart._internal::TakeWhileIterable::•<dart.core::int*>(this, test);
} }
method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ toList({dart.core::bool growable = #C5}) → dart.core::List<dart.core::int*> { method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk/lib/collection/list.dart */ toList({dart.core::bool growable = #C5}) → dart.core::List<dart.core::int*> {
if(this.{dart.collection::ListMixin::isEmpty}) if(this.{dart.collection::ListMixin::isEmpty})
return dart.core::List::empty<dart.core::int*>(growable: growable); return dart.core::List::empty<dart.core::int*>(growable: growable);
dart.core::int* first = this.{dart.core::List::[]}(0); dart.core::int* first = this.{dart.core::List::[]}(0);
@ -174,14 +174,14 @@ library from "org-dartlang-test:///main.dart" as main {
} }
return result; return result;
} }
method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ toSet() → dart.core::Set<dart.core::int*> { method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk/lib/collection/list.dart */ toSet() → dart.core::Set<dart.core::int*> {
dart.core::Set<dart.core::int*> result = dart.collection::LinkedHashSet::•<dart.core::int*>(); dart.core::Set<dart.core::int*> result = dart.collection::LinkedHashSet::•<dart.core::int*>();
for (dart.core::int i = 0; i.{dart.core::num::<}(this.{dart.core::List::length}); i = i.{dart.core::num::+}(1)) { for (dart.core::int i = 0; i.{dart.core::num::<}(this.{dart.core::List::length}); i = i.{dart.core::num::+}(1)) {
result.{dart.core::Set::add}(this.{dart.core::List::[]}(i)); result.{dart.core::Set::add}(this.{dart.core::List::[]}(i));
} }
return result; return result;
} }
method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ addAll(generic-covariant-impl dart.core::Iterable<dart.core::int*> iterable) → void { method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk/lib/collection/list.dart */ addAll(generic-covariant-impl dart.core::Iterable<dart.core::int*> iterable) → void {
dart.core::int i = this.{dart.core::List::length}; dart.core::int i = this.{dart.core::List::length};
{ {
dart.core::Iterator<dart.core::int*> :sync-for-iterator = iterable.{dart.core::Iterable::iterator}; dart.core::Iterator<dart.core::int*> :sync-for-iterator = iterable.{dart.core::Iterable::iterator};
@ -195,7 +195,7 @@ library from "org-dartlang-test:///main.dart" as main {
} }
} }
} }
method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ remove(dart.core::Object? element) → dart.core::bool { method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk/lib/collection/list.dart */ remove(dart.core::Object? element) → dart.core::bool {
for (dart.core::int i = 0; i.{dart.core::num::<}(this.{dart.core::List::length}); i = i.{dart.core::num::+}(1)) { for (dart.core::int i = 0; i.{dart.core::num::<}(this.{dart.core::List::length}); i = i.{dart.core::num::+}(1)) {
if(this.{dart.core::List::[]}(i).{dart.core::Object::==}(element)) { if(this.{dart.core::List::[]}(i).{dart.core::Object::==}(element)) {
this.{dart.collection::ListMixin::_closeGap}(i, i.{dart.core::num::+}(1)); this.{dart.collection::ListMixin::_closeGap}(i, i.{dart.core::num::+}(1));
@ -204,7 +204,7 @@ library from "org-dartlang-test:///main.dart" as main {
} }
return false; return false;
} }
method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ _closeGap(dart.core::int start, dart.core::int end) → void { method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk/lib/collection/list.dart */ _closeGap(dart.core::int start, dart.core::int end) → void {
dart.core::int length = this.{dart.core::List::length}; dart.core::int length = this.{dart.core::List::length};
assert(0.{dart.core::num::<=}(start)); assert(0.{dart.core::num::<=}(start));
assert(start.{dart.core::num::<}(end)); assert(start.{dart.core::num::<}(end));
@ -215,13 +215,13 @@ library from "org-dartlang-test:///main.dart" as main {
} }
this.{dart.core::List::length} = length.{dart.core::num::-}(size); this.{dart.core::List::length} = length.{dart.core::num::-}(size);
} }
method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ removeWhere((dart.core::int*) → dart.core::bool test) → void { method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk/lib/collection/list.dart */ removeWhere((dart.core::int*) → dart.core::bool test) → void {
this.{dart.collection::ListMixin::_filter}(test, false); this.{dart.collection::ListMixin::_filter}(test, false);
} }
method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ retainWhere((dart.core::int*) → dart.core::bool test) → void { method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk/lib/collection/list.dart */ retainWhere((dart.core::int*) → dart.core::bool test) → void {
this.{dart.collection::ListMixin::_filter}(test, true); this.{dart.collection::ListMixin::_filter}(test, true);
} }
method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ _filter((dart.core::int*) → dart.core::bool test, dart.core::bool retainMatching) → void { method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk/lib/collection/list.dart */ _filter((dart.core::int*) → dart.core::bool test, dart.core::bool retainMatching) → void {
dart.core::List<dart.core::int*> retained = <dart.core::int*>[]; dart.core::List<dart.core::int*> retained = <dart.core::int*>[];
dart.core::int length = this.{dart.core::List::length}; dart.core::int length = this.{dart.core::List::length};
for (dart.core::int i = 0; i.{dart.core::num::<}(length); i = i.{dart.core::num::+}(1)) { for (dart.core::int i = 0; i.{dart.core::num::<}(length); i = i.{dart.core::num::+}(1)) {
@ -238,12 +238,12 @@ library from "org-dartlang-test:///main.dart" as main {
this.{dart.core::List::length} = retained.{dart.core::List::length}; this.{dart.core::List::length} = retained.{dart.core::List::length};
} }
} }
method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ cast<R extends dart.core::Object? = dynamic>() → dart.core::List<main::_WithListMixin&Object&ListMixin::cast::R%> method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk/lib/collection/list.dart */ cast<R extends dart.core::Object? = dynamic>() → dart.core::List<main::_WithListMixin&Object&ListMixin::cast::R%>
return dart.core::List::castFrom<dart.core::int*, main::_WithListMixin&Object&ListMixin::cast::R%>(this); return dart.core::List::castFrom<dart.core::int*, main::_WithListMixin&Object&ListMixin::cast::R%>(this);
method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ sort([(dart.core::int*, dart.core::int*) →? dart.core::int compare = #C2]) → void { method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk/lib/collection/list.dart */ sort([(dart.core::int*, dart.core::int*) →? dart.core::int compare = #C2]) → void {
dart._internal::Sort::sort<dart.core::int*>(this, let final (dart.core::int*, dart.core::int*) →? dart.core::int #t2 = compare in #t2.{dart.core::Object::==}(null) ?{(dart.core::int*, dart.core::int*) → dart.core::int} #C6 : #t2{(dart.core::int*, dart.core::int*) → dart.core::int}); dart._internal::Sort::sort<dart.core::int*>(this, let final (dart.core::int*, dart.core::int*) →? dart.core::int #t2 = compare in #t2.{dart.core::Object::==}(null) ?{(dart.core::int*, dart.core::int*) → dart.core::int} #C6 : #t2{(dart.core::int*, dart.core::int*) → dart.core::int});
} }
method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ shuffle([dart.math::Random? random = #C2]) → void { method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk/lib/collection/list.dart */ shuffle([dart.math::Random? random = #C2]) → void {
random.{dart.core::Object::==}(null) ?{dart.math::Random} random = dart.math::Random::•() : null; random.{dart.core::Object::==}(null) ?{dart.math::Random} random = dart.math::Random::•() : null;
if(random{dart.math::Random}.{dart.core::Object::==}(null)) if(random{dart.math::Random}.{dart.core::Object::==}(null))
throw "!"; throw "!";
@ -256,10 +256,10 @@ library from "org-dartlang-test:///main.dart" as main {
this.{dart.core::List::[]=}(pos, tmp); this.{dart.core::List::[]=}(pos, tmp);
} }
} }
method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ asMap() → dart.core::Map<dart.core::int, dart.core::int*> { method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk/lib/collection/list.dart */ asMap() → dart.core::Map<dart.core::int, dart.core::int*> {
return new dart._internal::ListMapView::•<dart.core::int*>(this); return new dart._internal::ListMapView::•<dart.core::int*>(this);
} }
operator /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ +(generic-covariant-impl dart.core::List<dart.core::int*> other) → dart.core::List<dart.core::int*> operator /*isNonNullableByDefault, from org-dartlang-sdk:///sdk/lib/collection/list.dart */ +(generic-covariant-impl dart.core::List<dart.core::int*> other) → dart.core::List<dart.core::int*>
return block { return block {
final dart.core::List<dart.core::int*> #t3 = <dart.core::int*>[]; final dart.core::List<dart.core::int*> #t3 = <dart.core::int*>[];
{ {
@ -277,7 +277,7 @@ library from "org-dartlang-test:///main.dart" as main {
} }
} }
} =>#t3; } =>#t3;
method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ sublist(dart.core::int start, [dart.core::int? end = #C2]) → dart.core::List<dart.core::int*> { method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk/lib/collection/list.dart */ sublist(dart.core::int start, [dart.core::int? end = #C2]) → dart.core::List<dart.core::int*> {
dart.core::int listLength = this.{dart.core::List::length}; dart.core::int listLength = this.{dart.core::List::length};
end.{dart.core::num::==}(null) ?{dart.core::int} end = listLength : null; end.{dart.core::num::==}(null) ?{dart.core::int} end = listLength : null;
if(end{dart.core::int}.{dart.core::num::==}(null)) if(end{dart.core::int}.{dart.core::num::==}(null))
@ -285,24 +285,24 @@ library from "org-dartlang-test:///main.dart" as main {
dart.core::RangeError::checkValidRange(start, end{dart.core::int}, listLength); dart.core::RangeError::checkValidRange(start, end{dart.core::int}, listLength);
return dart.core::List::from<dart.core::int*>(this.{dart.collection::ListMixin::getRange}(start, end{dart.core::int})); return dart.core::List::from<dart.core::int*>(this.{dart.collection::ListMixin::getRange}(start, end{dart.core::int}));
} }
method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ getRange(dart.core::int start, dart.core::int end) → dart.core::Iterable<dart.core::int*> { method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk/lib/collection/list.dart */ getRange(dart.core::int start, dart.core::int end) → dart.core::Iterable<dart.core::int*> {
dart.core::RangeError::checkValidRange(start, end, this.{dart.core::List::length}); dart.core::RangeError::checkValidRange(start, end, this.{dart.core::List::length});
return new dart._internal::SubListIterable::•<dart.core::int*>(this, start, end); return new dart._internal::SubListIterable::•<dart.core::int*>(this, start, end);
} }
method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ removeRange(dart.core::int start, dart.core::int end) → void { method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk/lib/collection/list.dart */ removeRange(dart.core::int start, dart.core::int end) → void {
dart.core::RangeError::checkValidRange(start, end, this.{dart.core::List::length}); dart.core::RangeError::checkValidRange(start, end, this.{dart.core::List::length});
if(end.{dart.core::num::>}(start)) { if(end.{dart.core::num::>}(start)) {
this.{dart.collection::ListMixin::_closeGap}(start, end); this.{dart.collection::ListMixin::_closeGap}(start, end);
} }
} }
method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ fillRange(dart.core::int start, dart.core::int end, [generic-covariant-impl dart.core::int? fill = #C2]) → void { method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk/lib/collection/list.dart */ fillRange(dart.core::int start, dart.core::int end, [generic-covariant-impl dart.core::int? fill = #C2]) → void {
dart.core::int* value = let dart.core::int? #t6 = fill in #t6.==(null) ?{dart.core::int*} #t6 : #t6{dart.core::int*}; dart.core::int* value = let dart.core::int? #t6 = fill in #t6.==(null) ?{dart.core::int*} #t6 : #t6{dart.core::int*};
dart.core::RangeError::checkValidRange(start, end, this.{dart.core::List::length}); dart.core::RangeError::checkValidRange(start, end, this.{dart.core::List::length});
for (dart.core::int i = start; i.{dart.core::num::<}(end); i = i.{dart.core::num::+}(1)) { for (dart.core::int i = start; i.{dart.core::num::<}(end); i = i.{dart.core::num::+}(1)) {
this.{dart.core::List::[]=}(i, value); this.{dart.core::List::[]=}(i, value);
} }
} }
method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ setRange(dart.core::int start, dart.core::int end, generic-covariant-impl dart.core::Iterable<dart.core::int*> iterable, [dart.core::int skipCount = #C7]) → void { method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk/lib/collection/list.dart */ setRange(dart.core::int start, dart.core::int end, generic-covariant-impl dart.core::Iterable<dart.core::int*> iterable, [dart.core::int skipCount = #C7]) → void {
dart.core::RangeError::checkValidRange(start, end, this.{dart.core::List::length}); dart.core::RangeError::checkValidRange(start, end, this.{dart.core::List::length});
dart.core::int length = end.{dart.core::num::-}(start); dart.core::int length = end.{dart.core::num::-}(start);
if(length.{dart.core::num::==}(0)) if(length.{dart.core::num::==}(0))
@ -332,7 +332,7 @@ library from "org-dartlang-test:///main.dart" as main {
} }
} }
} }
method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ replaceRange(dart.core::int start, dart.core::int end, generic-covariant-impl dart.core::Iterable<dart.core::int*> newContents) → void { method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk/lib/collection/list.dart */ replaceRange(dart.core::int start, dart.core::int end, generic-covariant-impl dart.core::Iterable<dart.core::int*> newContents) → void {
dart.core::RangeError::checkValidRange(start, end, this.{dart.core::List::length}); dart.core::RangeError::checkValidRange(start, end, this.{dart.core::List::length});
if(start.{dart.core::num::==}(this.{dart.core::List::length})) { if(start.{dart.core::num::==}(this.{dart.core::List::length})) {
this.{dart.collection::ListMixin::addAll}(newContents); this.{dart.collection::ListMixin::addAll}(newContents);
@ -382,7 +382,7 @@ library from "org-dartlang-test:///main.dart" as main {
this.{dart.collection::ListMixin::setRange}(start, insertEnd, newContents); this.{dart.collection::ListMixin::setRange}(start, insertEnd, newContents);
} }
} }
method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ indexOf(generic-covariant-impl dart.core::Object? element, [dart.core::int start = #C7]) → dart.core::int { method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk/lib/collection/list.dart */ indexOf(generic-covariant-impl dart.core::Object? element, [dart.core::int start = #C7]) → dart.core::int {
if(start.{dart.core::num::<}(0)) if(start.{dart.core::num::<}(0))
start = 0; start = 0;
for (dart.core::int i = start; i.{dart.core::num::<}(this.{dart.core::List::length}); i = i.{dart.core::num::+}(1)) { for (dart.core::int i = start; i.{dart.core::num::<}(this.{dart.core::List::length}); i = i.{dart.core::num::+}(1)) {
@ -391,7 +391,7 @@ library from "org-dartlang-test:///main.dart" as main {
} }
return 1.{dart.core::int::unary-}(); return 1.{dart.core::int::unary-}();
} }
method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ indexWhere((dart.core::int*) → dart.core::bool test, [dart.core::int start = #C7]) → dart.core::int { method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk/lib/collection/list.dart */ indexWhere((dart.core::int*) → dart.core::bool test, [dart.core::int start = #C7]) → dart.core::int {
if(start.{dart.core::num::<}(0)) if(start.{dart.core::num::<}(0))
start = 0; start = 0;
for (dart.core::int i = start; i.{dart.core::num::<}(this.{dart.core::List::length}); i = i.{dart.core::num::+}(1)) { for (dart.core::int i = start; i.{dart.core::num::<}(this.{dart.core::List::length}); i = i.{dart.core::num::+}(1)) {
@ -400,7 +400,7 @@ library from "org-dartlang-test:///main.dart" as main {
} }
return 1.{dart.core::int::unary-}(); return 1.{dart.core::int::unary-}();
} }
method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ lastIndexOf(generic-covariant-impl dart.core::Object? element, [dart.core::int? start = #C2]) → dart.core::int { method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk/lib/collection/list.dart */ lastIndexOf(generic-covariant-impl dart.core::Object? element, [dart.core::int? start = #C2]) → dart.core::int {
if(start.{dart.core::num::==}(null) || start{dart.core::int}.{dart.core::num::>=}(this.{dart.core::List::length})) if(start.{dart.core::num::==}(null) || start{dart.core::int}.{dart.core::num::>=}(this.{dart.core::List::length}))
start = this.{dart.core::List::length}.{dart.core::num::-}(1); start = this.{dart.core::List::length}.{dart.core::num::-}(1);
if(start{dart.core::int}.{dart.core::num::==}(null)) if(start{dart.core::int}.{dart.core::num::==}(null))
@ -411,7 +411,7 @@ library from "org-dartlang-test:///main.dart" as main {
} }
return 1.{dart.core::int::unary-}(); return 1.{dart.core::int::unary-}();
} }
method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ lastIndexWhere((dart.core::int*) → dart.core::bool test, [dart.core::int? start = #C2]) → dart.core::int { method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk/lib/collection/list.dart */ lastIndexWhere((dart.core::int*) → dart.core::bool test, [dart.core::int? start = #C2]) → dart.core::int {
if(start.{dart.core::num::==}(null) || start{dart.core::int}.{dart.core::num::>=}(this.{dart.core::List::length})) if(start.{dart.core::num::==}(null) || start{dart.core::int}.{dart.core::num::>=}(this.{dart.core::List::length}))
start = this.{dart.core::List::length}.{dart.core::num::-}(1); start = this.{dart.core::List::length}.{dart.core::num::-}(1);
if(start{dart.core::int}.{dart.core::num::==}(null)) if(start{dart.core::int}.{dart.core::num::==}(null))
@ -422,7 +422,7 @@ library from "org-dartlang-test:///main.dart" as main {
} }
return 1.{dart.core::int::unary-}(); return 1.{dart.core::int::unary-}();
} }
method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ insert(dart.core::int index, generic-covariant-impl dart.core::int* element) → void { method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk/lib/collection/list.dart */ insert(dart.core::int index, generic-covariant-impl dart.core::int* element) → void {
dart.core::ArgumentError::checkNotNull<dart.core::int>(index, "index"); dart.core::ArgumentError::checkNotNull<dart.core::int>(index, "index");
dart.core::RangeError::checkValueInInterval(index, 0, this.{dart.core::List::length}, "index"); dart.core::RangeError::checkValueInInterval(index, 0, this.{dart.core::List::length}, "index");
if(index.{dart.core::num::==}(this.{dart.core::List::length})) { if(index.{dart.core::num::==}(this.{dart.core::List::length})) {
@ -433,12 +433,12 @@ library from "org-dartlang-test:///main.dart" as main {
this.{dart.collection::ListMixin::setRange}(index.{dart.core::num::+}(1), this.{dart.core::List::length}, this, index); this.{dart.collection::ListMixin::setRange}(index.{dart.core::num::+}(1), this.{dart.core::List::length}, this, index);
this.{dart.core::List::[]=}(index, element); this.{dart.core::List::[]=}(index, element);
} }
method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ removeAt(dart.core::int index) → dart.core::int* { method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk/lib/collection/list.dart */ removeAt(dart.core::int index) → dart.core::int* {
dart.core::int* result = this.{dart.core::List::[]}(index); dart.core::int* result = this.{dart.core::List::[]}(index);
this.{dart.collection::ListMixin::_closeGap}(index, index.{dart.core::num::+}(1)); this.{dart.collection::ListMixin::_closeGap}(index, index.{dart.core::num::+}(1));
return result; return result;
} }
method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ insertAll(dart.core::int index, generic-covariant-impl dart.core::Iterable<dart.core::int*> iterable) → void { method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk/lib/collection/list.dart */ insertAll(dart.core::int index, generic-covariant-impl dart.core::Iterable<dart.core::int*> iterable) → void {
dart.core::RangeError::checkValueInInterval(index, 0, this.{dart.core::List::length}, "index"); dart.core::RangeError::checkValueInInterval(index, 0, this.{dart.core::List::length}, "index");
if(index.{dart.core::num::==}(this.{dart.core::List::length})) { if(index.{dart.core::num::==}(this.{dart.core::List::length})) {
this.{dart.collection::ListMixin::addAll}(iterable); this.{dart.collection::ListMixin::addAll}(iterable);
@ -465,7 +465,7 @@ library from "org-dartlang-test:///main.dart" as main {
} }
this.{dart.collection::ListMixin::setAll}(index, iterable); this.{dart.collection::ListMixin::setAll}(index, iterable);
} }
method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ setAll(dart.core::int index, generic-covariant-impl dart.core::Iterable<dart.core::int*> iterable) → void { method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk/lib/collection/list.dart */ setAll(dart.core::int index, generic-covariant-impl dart.core::Iterable<dart.core::int*> iterable) → void {
if(iterable is{ForNonNullableByDefault} dart.core::List<dynamic>) { if(iterable is{ForNonNullableByDefault} dart.core::List<dynamic>) {
this.{dart.collection::ListMixin::setRange}(index, index.{dart.core::num::+}(iterable.{dart.core::Iterable::length}), iterable); this.{dart.collection::ListMixin::setRange}(index, index.{dart.core::num::+}(iterable.{dart.core::Iterable::length}), iterable);
} }
@ -481,9 +481,9 @@ library from "org-dartlang-test:///main.dart" as main {
} }
} }
} }
get /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ reversed() → dart.core::Iterable<dart.core::int*> get /*isNonNullableByDefault, from org-dartlang-sdk:///sdk/lib/collection/list.dart */ reversed() → dart.core::Iterable<dart.core::int*>
return new dart._internal::ReversedListIterable::•<dart.core::int*>(this); return new dart._internal::ReversedListIterable::•<dart.core::int*>(this);
method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ toString() → dart.core::String method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk/lib/collection/list.dart */ toString() → dart.core::String
return dart.collection::IterableBase::iterableToFullString(this, "[", "]"); return dart.collection::IterableBase::iterableToFullString(this, "[", "]");
abstract member-signature get _identityHashCode() → dart.core::int*; abstract member-signature get _identityHashCode() → dart.core::int*;
abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → dart.core::bool*; abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → dart.core::bool*;
@ -495,40 +495,40 @@ library from "org-dartlang-test:///main.dart" as main {
abstract member-signature method noSuchMethod(dart.core::Invocation* invocation) → dynamic; abstract member-signature method noSuchMethod(dart.core::Invocation* invocation) → dynamic;
abstract member-signature get runtimeType() → dart.core::Type*; abstract member-signature get runtimeType() → dart.core::Type*;
abstract member-signature set length(dart.core::int* newLength) → void; abstract member-signature set length(dart.core::int* newLength) → void;
get /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ first() → dart.core::int* { get /*isNonNullableByDefault, from org-dartlang-sdk:///sdk/lib/collection/list.dart */ first() → dart.core::int* {
if(this.{dart.core::List::length}.{dart.core::num::==}(0)) if(this.{dart.core::List::length}.{dart.core::num::==}(0))
throw dart._internal::IterableElementError::noElement(); throw dart._internal::IterableElementError::noElement();
return this.{dart.core::List::[]}(0); return this.{dart.core::List::[]}(0);
} }
set /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ first(generic-covariant-impl dart.core::int* value) → void { set /*isNonNullableByDefault, from org-dartlang-sdk:///sdk/lib/collection/list.dart */ first(generic-covariant-impl dart.core::int* value) → void {
if(this.{dart.core::List::length}.{dart.core::num::==}(0)) if(this.{dart.core::List::length}.{dart.core::num::==}(0))
throw dart._internal::IterableElementError::noElement(); throw dart._internal::IterableElementError::noElement();
this.{dart.core::List::[]=}(0, value); this.{dart.core::List::[]=}(0, value);
} }
get /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ last() → dart.core::int* { get /*isNonNullableByDefault, from org-dartlang-sdk:///sdk/lib/collection/list.dart */ last() → dart.core::int* {
if(this.{dart.core::List::length}.{dart.core::num::==}(0)) if(this.{dart.core::List::length}.{dart.core::num::==}(0))
throw dart._internal::IterableElementError::noElement(); throw dart._internal::IterableElementError::noElement();
return this.{dart.core::List::[]}(this.{dart.core::List::length}.{dart.core::num::-}(1)); return this.{dart.core::List::[]}(this.{dart.core::List::length}.{dart.core::num::-}(1));
} }
set /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ last(generic-covariant-impl dart.core::int* value) → void { set /*isNonNullableByDefault, from org-dartlang-sdk:///sdk/lib/collection/list.dart */ last(generic-covariant-impl dart.core::int* value) → void {
if(this.{dart.core::List::length}.{dart.core::num::==}(0)) if(this.{dart.core::List::length}.{dart.core::num::==}(0))
throw dart._internal::IterableElementError::noElement(); throw dart._internal::IterableElementError::noElement();
this.{dart.core::List::[]=}(this.{dart.core::List::length}.{dart.core::num::-}(1), value); this.{dart.core::List::[]=}(this.{dart.core::List::length}.{dart.core::num::-}(1), value);
} }
get /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ single() → dart.core::int* { get /*isNonNullableByDefault, from org-dartlang-sdk:///sdk/lib/collection/list.dart */ single() → dart.core::int* {
if(this.{dart.core::List::length}.{dart.core::num::==}(0)) if(this.{dart.core::List::length}.{dart.core::num::==}(0))
throw dart._internal::IterableElementError::noElement(); throw dart._internal::IterableElementError::noElement();
if(this.{dart.core::List::length}.{dart.core::num::>}(1)) if(this.{dart.core::List::length}.{dart.core::num::>}(1))
throw dart._internal::IterableElementError::tooMany(); throw dart._internal::IterableElementError::tooMany();
return this.{dart.core::List::[]}(0); return this.{dart.core::List::[]}(0);
} }
method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ add(generic-covariant-impl dart.core::int* element) → void { method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk/lib/collection/list.dart */ add(generic-covariant-impl dart.core::int* element) → void {
this.{dart.core::List::[]=}(let final dart.core::int #t9 = this.{dart.core::List::length} in let final dart.core::int #t10 = this.{dart.core::List::length} = #t9.{dart.core::num::+}(1) in #t9, element); this.{dart.core::List::[]=}(let final dart.core::int #t9 = this.{dart.core::List::length} in let final dart.core::int #t10 = this.{dart.core::List::length} = #t9.{dart.core::num::+}(1) in #t9, element);
} }
method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ clear() → void { method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk/lib/collection/list.dart */ clear() → void {
this.{dart.core::List::length} = 0; this.{dart.core::List::length} = 0;
} }
method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ removeLast() → dart.core::int* { method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk/lib/collection/list.dart */ removeLast() → dart.core::int* {
if(this.{dart.core::List::length}.{dart.core::num::==}(0)) { if(this.{dart.core::List::length}.{dart.core::num::==}(0)) {
throw dart._internal::IterableElementError::noElement(); throw dart._internal::IterableElementError::noElement();
} }
@ -536,7 +536,7 @@ library from "org-dartlang-test:///main.dart" as main {
this.{dart.core::List::length} = this.{dart.core::List::length}.{dart.core::num::-}(1); this.{dart.core::List::length} = this.{dart.core::List::length}.{dart.core::num::-}(1);
return result; return result;
} }
static method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ _compareAny(dynamic a, dynamic b) → dart.core::int { static method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk/lib/collection/list.dart */ _compareAny(dynamic a, dynamic b) → dart.core::int {
return dart.core::Comparable::compare(a as{ForNonNullableByDefault} dart.core::Comparable<dynamic>, b as{ForNonNullableByDefault} dart.core::Comparable<dynamic>); return dart.core::Comparable::compare(a as{ForNonNullableByDefault} dart.core::Comparable<dynamic>, b as{ForNonNullableByDefault} dart.core::Comparable<dynamic>);
} }
} }

View file

@ -10,13 +10,13 @@ library from "org-dartlang-test:///main.dart" as main {
abstract member-signature get length() → dart.core::int*; abstract member-signature get length() → dart.core::int*;
abstract member-signature operator [](dart.core::int* index) → dart.core::int*; abstract member-signature operator [](dart.core::int* index) → dart.core::int*;
abstract member-signature operator []=(dart.core::int* index, generic-covariant-impl dart.core::int* value) → void; abstract member-signature operator []=(dart.core::int* index, generic-covariant-impl dart.core::int* value) → void;
get /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ iterator() → dart.core::Iterator<dart.core::int*> get /*isNonNullableByDefault, from org-dartlang-sdk:///sdk/lib/collection/list.dart */ iterator() → dart.core::Iterator<dart.core::int*>
return new dart._internal::ListIterator::•<dart.core::int*>(this); return new dart._internal::ListIterator::•<dart.core::int*>(this);
method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ elementAt(dart.core::int index) → dart.core::int* method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk/lib/collection/list.dart */ elementAt(dart.core::int index) → dart.core::int*
return this.{dart.core::List::[]}(index); return this.{dart.core::List::[]}(index);
method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ followedBy(generic-covariant-impl dart.core::Iterable<dart.core::int*> other) → dart.core::Iterable<dart.core::int*> method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk/lib/collection/list.dart */ followedBy(generic-covariant-impl dart.core::Iterable<dart.core::int*> other) → dart.core::Iterable<dart.core::int*>
return dart._internal::FollowedByIterable::firstEfficient<dart.core::int*>(this, other); return dart._internal::FollowedByIterable::firstEfficient<dart.core::int*>(this, other);
method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ forEach((dart.core::int*) → void action) → void { method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk/lib/collection/list.dart */ forEach((dart.core::int*) → void action) → void {
dart.core::int length = this.{dart.core::List::length}; dart.core::int length = this.{dart.core::List::length};
for (dart.core::int i = 0; i.{dart.core::num::<}(length); i = i.{dart.core::num::+}(1)) { for (dart.core::int i = 0; i.{dart.core::num::<}(length); i = i.{dart.core::num::+}(1)) {
action.call(this.{dart.core::List::[]}(i)); action.call(this.{dart.core::List::[]}(i));
@ -26,11 +26,11 @@ library from "org-dartlang-test:///main.dart" as main {
} }
} }
@#C3 @#C3
get /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ isEmpty() → dart.core::bool get /*isNonNullableByDefault, from org-dartlang-sdk:///sdk/lib/collection/list.dart */ isEmpty() → dart.core::bool
return this.{dart.core::List::length}.{dart.core::num::==}(0); return this.{dart.core::List::length}.{dart.core::num::==}(0);
get /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ isNotEmpty() → dart.core::bool get /*isNonNullableByDefault, from org-dartlang-sdk:///sdk/lib/collection/list.dart */ isNotEmpty() → dart.core::bool
return !this.{dart.collection::ListMixin::isEmpty}; return !this.{dart.collection::ListMixin::isEmpty};
method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ contains(dart.core::Object? element) → dart.core::bool { method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk/lib/collection/list.dart */ contains(dart.core::Object? element) → dart.core::bool {
dart.core::int length = this.{dart.core::List::length}; dart.core::int length = this.{dart.core::List::length};
for (dart.core::int i = 0; i.{dart.core::num::<}(length); i = i.{dart.core::num::+}(1)) { for (dart.core::int i = 0; i.{dart.core::num::<}(length); i = i.{dart.core::num::+}(1)) {
if(this.{dart.core::List::[]}(i).{dart.core::Object::==}(element)) if(this.{dart.core::List::[]}(i).{dart.core::Object::==}(element))
@ -41,7 +41,7 @@ library from "org-dartlang-test:///main.dart" as main {
} }
return false; return false;
} }
method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ every((dart.core::int*) → dart.core::bool test) → dart.core::bool { method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk/lib/collection/list.dart */ every((dart.core::int*) → dart.core::bool test) → dart.core::bool {
dart.core::int length = this.{dart.core::List::length}; dart.core::int length = this.{dart.core::List::length};
for (dart.core::int i = 0; i.{dart.core::num::<}(length); i = i.{dart.core::num::+}(1)) { for (dart.core::int i = 0; i.{dart.core::num::<}(length); i = i.{dart.core::num::+}(1)) {
if(!test.call(this.{dart.core::List::[]}(i))) if(!test.call(this.{dart.core::List::[]}(i)))
@ -52,7 +52,7 @@ library from "org-dartlang-test:///main.dart" as main {
} }
return true; return true;
} }
method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ any((dart.core::int*) → dart.core::bool test) → dart.core::bool { method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk/lib/collection/list.dart */ any((dart.core::int*) → dart.core::bool test) → dart.core::bool {
dart.core::int length = this.{dart.core::List::length}; dart.core::int length = this.{dart.core::List::length};
for (dart.core::int i = 0; i.{dart.core::num::<}(length); i = i.{dart.core::num::+}(1)) { for (dart.core::int i = 0; i.{dart.core::num::<}(length); i = i.{dart.core::num::+}(1)) {
if(test.call(this.{dart.core::List::[]}(i))) if(test.call(this.{dart.core::List::[]}(i)))
@ -63,7 +63,7 @@ library from "org-dartlang-test:///main.dart" as main {
} }
return false; return false;
} }
method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ firstWhere((dart.core::int*) → dart.core::bool test, {generic-covariant-impl () →? dart.core::int* orElse = #C2}) → dart.core::int* { method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk/lib/collection/list.dart */ firstWhere((dart.core::int*) → dart.core::bool test, {generic-covariant-impl () →? dart.core::int* orElse = #C2}) → dart.core::int* {
dart.core::int length = this.{dart.core::List::length}; dart.core::int length = this.{dart.core::List::length};
for (dart.core::int i = 0; i.{dart.core::num::<}(length); i = i.{dart.core::num::+}(1)) { for (dart.core::int i = 0; i.{dart.core::num::<}(length); i = i.{dart.core::num::+}(1)) {
dart.core::int* element = this.{dart.core::List::[]}(i); dart.core::int* element = this.{dart.core::List::[]}(i);
@ -77,7 +77,7 @@ library from "org-dartlang-test:///main.dart" as main {
return orElse{() → dart.core::int*}.call(); return orElse{() → dart.core::int*}.call();
throw dart._internal::IterableElementError::noElement(); throw dart._internal::IterableElementError::noElement();
} }
method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ lastWhere((dart.core::int*) → dart.core::bool test, {generic-covariant-impl () →? dart.core::int* orElse = #C2}) → dart.core::int* { method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk/lib/collection/list.dart */ lastWhere((dart.core::int*) → dart.core::bool test, {generic-covariant-impl () →? dart.core::int* orElse = #C2}) → dart.core::int* {
dart.core::int length = this.{dart.core::List::length}; dart.core::int length = this.{dart.core::List::length};
for (dart.core::int i = length.{dart.core::num::-}(1); i.{dart.core::num::>=}(0); i = i.{dart.core::num::-}(1)) { for (dart.core::int i = length.{dart.core::num::-}(1); i.{dart.core::num::>=}(0); i = i.{dart.core::num::-}(1)) {
dart.core::int* element = this.{dart.core::List::[]}(i); dart.core::int* element = this.{dart.core::List::[]}(i);
@ -91,7 +91,7 @@ library from "org-dartlang-test:///main.dart" as main {
return orElse{() → dart.core::int*}.call(); return orElse{() → dart.core::int*}.call();
throw dart._internal::IterableElementError::noElement(); throw dart._internal::IterableElementError::noElement();
} }
method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ singleWhere((dart.core::int*) → dart.core::bool test, {generic-covariant-impl () →? dart.core::int* orElse = #C2}) → dart.core::int* { method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk/lib/collection/list.dart */ singleWhere((dart.core::int*) → dart.core::bool test, {generic-covariant-impl () →? dart.core::int* orElse = #C2}) → dart.core::int* {
dart.core::int length = this.{dart.core::List::length}; dart.core::int length = this.{dart.core::List::length};
late dart.core::int* match; late dart.core::int* match;
dart.core::bool matchFound = false; dart.core::bool matchFound = false;
@ -114,7 +114,7 @@ library from "org-dartlang-test:///main.dart" as main {
return orElse{() → dart.core::int*}.call(); return orElse{() → dart.core::int*}.call();
throw dart._internal::IterableElementError::noElement(); throw dart._internal::IterableElementError::noElement();
} }
method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ join([dart.core::String separator = #C4]) → dart.core::String { method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk/lib/collection/list.dart */ join([dart.core::String separator = #C4]) → dart.core::String {
if(this.{dart.core::List::length}.{dart.core::num::==}(0)) if(this.{dart.core::List::length}.{dart.core::num::==}(0))
return ""; return "";
dart.core::StringBuffer buffer = let final dart.core::StringBuffer #t1 = new dart.core::StringBuffer::•() in block { dart.core::StringBuffer buffer = let final dart.core::StringBuffer #t1 = new dart.core::StringBuffer::•() in block {
@ -122,15 +122,15 @@ library from "org-dartlang-test:///main.dart" as main {
} =>#t1; } =>#t1;
return buffer.{dart.core::StringBuffer::toString}(); return buffer.{dart.core::StringBuffer::toString}();
} }
method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ where((dart.core::int*) → dart.core::bool test) → dart.core::Iterable<dart.core::int*> method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk/lib/collection/list.dart */ where((dart.core::int*) → dart.core::bool test) → dart.core::Iterable<dart.core::int*>
return new dart._internal::WhereIterable::•<dart.core::int*>(this, test); return new dart._internal::WhereIterable::•<dart.core::int*>(this, test);
method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ whereType<T extends dart.core::Object? = dynamic>() → dart.core::Iterable<main::_WithListMixin&Object&ListMixin::whereType::T%> method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk/lib/collection/list.dart */ whereType<T extends dart.core::Object? = dynamic>() → dart.core::Iterable<main::_WithListMixin&Object&ListMixin::whereType::T%>
return new dart._internal::WhereTypeIterable::•<main::_WithListMixin&Object&ListMixin::whereType::T%>(this); return new dart._internal::WhereTypeIterable::•<main::_WithListMixin&Object&ListMixin::whereType::T%>(this);
method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ map<T extends dart.core::Object? = dynamic>((dart.core::int*) → main::_WithListMixin&Object&ListMixin::map::T% f) → dart.core::Iterable<main::_WithListMixin&Object&ListMixin::map::T%> method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk/lib/collection/list.dart */ map<T extends dart.core::Object? = dynamic>((dart.core::int*) → main::_WithListMixin&Object&ListMixin::map::T% f) → dart.core::Iterable<main::_WithListMixin&Object&ListMixin::map::T%>
return new dart._internal::MappedListIterable::•<dart.core::int*, main::_WithListMixin&Object&ListMixin::map::T%>(this, f); return new dart._internal::MappedListIterable::•<dart.core::int*, main::_WithListMixin&Object&ListMixin::map::T%>(this, f);
method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ expand<T extends dart.core::Object? = dynamic>((dart.core::int*) → dart.core::Iterable<main::_WithListMixin&Object&ListMixin::expand::T%> f) → dart.core::Iterable<main::_WithListMixin&Object&ListMixin::expand::T%> method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk/lib/collection/list.dart */ expand<T extends dart.core::Object? = dynamic>((dart.core::int*) → dart.core::Iterable<main::_WithListMixin&Object&ListMixin::expand::T%> f) → dart.core::Iterable<main::_WithListMixin&Object&ListMixin::expand::T%>
return new dart._internal::ExpandIterable::•<dart.core::int*, main::_WithListMixin&Object&ListMixin::expand::T%>(this, f); return new dart._internal::ExpandIterable::•<dart.core::int*, main::_WithListMixin&Object&ListMixin::expand::T%>(this, f);
method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ reduce(generic-covariant-impl (dart.core::int*, dart.core::int*) → dart.core::int* combine) → dart.core::int* { method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk/lib/collection/list.dart */ reduce(generic-covariant-impl (dart.core::int*, dart.core::int*) → dart.core::int* combine) → dart.core::int* {
dart.core::int length = this.{dart.core::List::length}; dart.core::int length = this.{dart.core::List::length};
if(length.{dart.core::num::==}(0)) if(length.{dart.core::num::==}(0))
throw dart._internal::IterableElementError::noElement(); throw dart._internal::IterableElementError::noElement();
@ -143,7 +143,7 @@ library from "org-dartlang-test:///main.dart" as main {
} }
return value; return value;
} }
method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ fold<T extends dart.core::Object? = dynamic>(main::_WithListMixin&Object&ListMixin::fold::T% initialValue, (main::_WithListMixin&Object&ListMixin::fold::T%, dart.core::int*) → main::_WithListMixin&Object&ListMixin::fold::T% combine) → main::_WithListMixin&Object&ListMixin::fold::T% { method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk/lib/collection/list.dart */ fold<T extends dart.core::Object? = dynamic>(main::_WithListMixin&Object&ListMixin::fold::T% initialValue, (main::_WithListMixin&Object&ListMixin::fold::T%, dart.core::int*) → main::_WithListMixin&Object&ListMixin::fold::T% combine) → main::_WithListMixin&Object&ListMixin::fold::T% {
main::_WithListMixin&Object&ListMixin::fold::T% value = initialValue; main::_WithListMixin&Object&ListMixin::fold::T% value = initialValue;
dart.core::int length = this.{dart.core::List::length}; dart.core::int length = this.{dart.core::List::length};
for (dart.core::int i = 0; i.{dart.core::num::<}(length); i = i.{dart.core::num::+}(1)) { for (dart.core::int i = 0; i.{dart.core::num::<}(length); i = i.{dart.core::num::+}(1)) {
@ -154,17 +154,17 @@ library from "org-dartlang-test:///main.dart" as main {
} }
return value; return value;
} }
method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ skip(dart.core::int count) → dart.core::Iterable<dart.core::int*> method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk/lib/collection/list.dart */ skip(dart.core::int count) → dart.core::Iterable<dart.core::int*>
return new dart._internal::SubListIterable::•<dart.core::int*>(this, count, null); return new dart._internal::SubListIterable::•<dart.core::int*>(this, count, null);
method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ skipWhile((dart.core::int*) → dart.core::bool test) → dart.core::Iterable<dart.core::int*> { method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk/lib/collection/list.dart */ skipWhile((dart.core::int*) → dart.core::bool test) → dart.core::Iterable<dart.core::int*> {
return new dart._internal::SkipWhileIterable::•<dart.core::int*>(this, test); return new dart._internal::SkipWhileIterable::•<dart.core::int*>(this, test);
} }
method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ take(dart.core::int count) → dart.core::Iterable<dart.core::int*> method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk/lib/collection/list.dart */ take(dart.core::int count) → dart.core::Iterable<dart.core::int*>
return new dart._internal::SubListIterable::•<dart.core::int*>(this, 0, count); return new dart._internal::SubListIterable::•<dart.core::int*>(this, 0, count);
method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ takeWhile((dart.core::int*) → dart.core::bool test) → dart.core::Iterable<dart.core::int*> { method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk/lib/collection/list.dart */ takeWhile((dart.core::int*) → dart.core::bool test) → dart.core::Iterable<dart.core::int*> {
return new dart._internal::TakeWhileIterable::•<dart.core::int*>(this, test); return new dart._internal::TakeWhileIterable::•<dart.core::int*>(this, test);
} }
method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ toList({dart.core::bool growable = #C5}) → dart.core::List<dart.core::int*> { method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk/lib/collection/list.dart */ toList({dart.core::bool growable = #C5}) → dart.core::List<dart.core::int*> {
if(this.{dart.collection::ListMixin::isEmpty}) if(this.{dart.collection::ListMixin::isEmpty})
return dart.core::List::empty<dart.core::int*>(growable: growable); return dart.core::List::empty<dart.core::int*>(growable: growable);
dart.core::int* first = this.{dart.core::List::[]}(0); dart.core::int* first = this.{dart.core::List::[]}(0);
@ -174,14 +174,14 @@ library from "org-dartlang-test:///main.dart" as main {
} }
return result; return result;
} }
method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ toSet() → dart.core::Set<dart.core::int*> { method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk/lib/collection/list.dart */ toSet() → dart.core::Set<dart.core::int*> {
dart.core::Set<dart.core::int*> result = dart.collection::LinkedHashSet::•<dart.core::int*>(); dart.core::Set<dart.core::int*> result = dart.collection::LinkedHashSet::•<dart.core::int*>();
for (dart.core::int i = 0; i.{dart.core::num::<}(this.{dart.core::List::length}); i = i.{dart.core::num::+}(1)) { for (dart.core::int i = 0; i.{dart.core::num::<}(this.{dart.core::List::length}); i = i.{dart.core::num::+}(1)) {
result.{dart.core::Set::add}(this.{dart.core::List::[]}(i)); result.{dart.core::Set::add}(this.{dart.core::List::[]}(i));
} }
return result; return result;
} }
method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ addAll(generic-covariant-impl dart.core::Iterable<dart.core::int*> iterable) → void { method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk/lib/collection/list.dart */ addAll(generic-covariant-impl dart.core::Iterable<dart.core::int*> iterable) → void {
dart.core::int i = this.{dart.core::List::length}; dart.core::int i = this.{dart.core::List::length};
{ {
dart.core::Iterator<dart.core::int*> :sync-for-iterator = iterable.{dart.core::Iterable::iterator}; dart.core::Iterator<dart.core::int*> :sync-for-iterator = iterable.{dart.core::Iterable::iterator};
@ -195,7 +195,7 @@ library from "org-dartlang-test:///main.dart" as main {
} }
} }
} }
method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ remove(dart.core::Object? element) → dart.core::bool { method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk/lib/collection/list.dart */ remove(dart.core::Object? element) → dart.core::bool {
for (dart.core::int i = 0; i.{dart.core::num::<}(this.{dart.core::List::length}); i = i.{dart.core::num::+}(1)) { for (dart.core::int i = 0; i.{dart.core::num::<}(this.{dart.core::List::length}); i = i.{dart.core::num::+}(1)) {
if(this.{dart.core::List::[]}(i).{dart.core::Object::==}(element)) { if(this.{dart.core::List::[]}(i).{dart.core::Object::==}(element)) {
this.{dart.collection::ListMixin::_closeGap}(i, i.{dart.core::num::+}(1)); this.{dart.collection::ListMixin::_closeGap}(i, i.{dart.core::num::+}(1));
@ -204,7 +204,7 @@ library from "org-dartlang-test:///main.dart" as main {
} }
return false; return false;
} }
method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ _closeGap(dart.core::int start, dart.core::int end) → void { method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk/lib/collection/list.dart */ _closeGap(dart.core::int start, dart.core::int end) → void {
dart.core::int length = this.{dart.core::List::length}; dart.core::int length = this.{dart.core::List::length};
assert(0.{dart.core::num::<=}(start)); assert(0.{dart.core::num::<=}(start));
assert(start.{dart.core::num::<}(end)); assert(start.{dart.core::num::<}(end));
@ -215,13 +215,13 @@ library from "org-dartlang-test:///main.dart" as main {
} }
this.{dart.core::List::length} = length.{dart.core::num::-}(size); this.{dart.core::List::length} = length.{dart.core::num::-}(size);
} }
method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ removeWhere((dart.core::int*) → dart.core::bool test) → void { method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk/lib/collection/list.dart */ removeWhere((dart.core::int*) → dart.core::bool test) → void {
this.{dart.collection::ListMixin::_filter}(test, false); this.{dart.collection::ListMixin::_filter}(test, false);
} }
method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ retainWhere((dart.core::int*) → dart.core::bool test) → void { method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk/lib/collection/list.dart */ retainWhere((dart.core::int*) → dart.core::bool test) → void {
this.{dart.collection::ListMixin::_filter}(test, true); this.{dart.collection::ListMixin::_filter}(test, true);
} }
method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ _filter((dart.core::int*) → dart.core::bool test, dart.core::bool retainMatching) → void { method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk/lib/collection/list.dart */ _filter((dart.core::int*) → dart.core::bool test, dart.core::bool retainMatching) → void {
dart.core::List<dart.core::int*> retained = <dart.core::int*>[]; dart.core::List<dart.core::int*> retained = <dart.core::int*>[];
dart.core::int length = this.{dart.core::List::length}; dart.core::int length = this.{dart.core::List::length};
for (dart.core::int i = 0; i.{dart.core::num::<}(length); i = i.{dart.core::num::+}(1)) { for (dart.core::int i = 0; i.{dart.core::num::<}(length); i = i.{dart.core::num::+}(1)) {
@ -238,12 +238,12 @@ library from "org-dartlang-test:///main.dart" as main {
this.{dart.core::List::length} = retained.{dart.core::List::length}; this.{dart.core::List::length} = retained.{dart.core::List::length};
} }
} }
method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ cast<R extends dart.core::Object? = dynamic>() → dart.core::List<main::_WithListMixin&Object&ListMixin::cast::R%> method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk/lib/collection/list.dart */ cast<R extends dart.core::Object? = dynamic>() → dart.core::List<main::_WithListMixin&Object&ListMixin::cast::R%>
return dart.core::List::castFrom<dart.core::int*, main::_WithListMixin&Object&ListMixin::cast::R%>(this); return dart.core::List::castFrom<dart.core::int*, main::_WithListMixin&Object&ListMixin::cast::R%>(this);
method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ sort([(dart.core::int*, dart.core::int*) →? dart.core::int compare = #C2]) → void { method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk/lib/collection/list.dart */ sort([(dart.core::int*, dart.core::int*) →? dart.core::int compare = #C2]) → void {
dart._internal::Sort::sort<dart.core::int*>(this, let final (dart.core::int*, dart.core::int*) →? dart.core::int #t2 = compare in #t2.{dart.core::Object::==}(null) ?{(dart.core::int*, dart.core::int*) → dart.core::int} #C6 : #t2{(dart.core::int*, dart.core::int*) → dart.core::int}); dart._internal::Sort::sort<dart.core::int*>(this, let final (dart.core::int*, dart.core::int*) →? dart.core::int #t2 = compare in #t2.{dart.core::Object::==}(null) ?{(dart.core::int*, dart.core::int*) → dart.core::int} #C6 : #t2{(dart.core::int*, dart.core::int*) → dart.core::int});
} }
method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ shuffle([dart.math::Random? random = #C2]) → void { method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk/lib/collection/list.dart */ shuffle([dart.math::Random? random = #C2]) → void {
random.{dart.core::Object::==}(null) ?{dart.math::Random} random = dart.math::Random::•() : null; random.{dart.core::Object::==}(null) ?{dart.math::Random} random = dart.math::Random::•() : null;
if(random{dart.math::Random}.{dart.core::Object::==}(null)) if(random{dart.math::Random}.{dart.core::Object::==}(null))
throw "!"; throw "!";
@ -256,10 +256,10 @@ library from "org-dartlang-test:///main.dart" as main {
this.{dart.core::List::[]=}(pos, tmp); this.{dart.core::List::[]=}(pos, tmp);
} }
} }
method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ asMap() → dart.core::Map<dart.core::int, dart.core::int*> { method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk/lib/collection/list.dart */ asMap() → dart.core::Map<dart.core::int, dart.core::int*> {
return new dart._internal::ListMapView::•<dart.core::int*>(this); return new dart._internal::ListMapView::•<dart.core::int*>(this);
} }
operator /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ +(generic-covariant-impl dart.core::List<dart.core::int*> other) → dart.core::List<dart.core::int*> operator /*isNonNullableByDefault, from org-dartlang-sdk:///sdk/lib/collection/list.dart */ +(generic-covariant-impl dart.core::List<dart.core::int*> other) → dart.core::List<dart.core::int*>
return block { return block {
final dart.core::List<dart.core::int*> #t3 = <dart.core::int*>[]; final dart.core::List<dart.core::int*> #t3 = <dart.core::int*>[];
{ {
@ -277,7 +277,7 @@ library from "org-dartlang-test:///main.dart" as main {
} }
} }
} =>#t3; } =>#t3;
method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ sublist(dart.core::int start, [dart.core::int? end = #C2]) → dart.core::List<dart.core::int*> { method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk/lib/collection/list.dart */ sublist(dart.core::int start, [dart.core::int? end = #C2]) → dart.core::List<dart.core::int*> {
dart.core::int listLength = this.{dart.core::List::length}; dart.core::int listLength = this.{dart.core::List::length};
end.{dart.core::num::==}(null) ?{dart.core::int} end = listLength : null; end.{dart.core::num::==}(null) ?{dart.core::int} end = listLength : null;
if(end{dart.core::int}.{dart.core::num::==}(null)) if(end{dart.core::int}.{dart.core::num::==}(null))
@ -285,24 +285,24 @@ library from "org-dartlang-test:///main.dart" as main {
dart.core::RangeError::checkValidRange(start, end{dart.core::int}, listLength); dart.core::RangeError::checkValidRange(start, end{dart.core::int}, listLength);
return dart.core::List::from<dart.core::int*>(this.{dart.collection::ListMixin::getRange}(start, end{dart.core::int})); return dart.core::List::from<dart.core::int*>(this.{dart.collection::ListMixin::getRange}(start, end{dart.core::int}));
} }
method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ getRange(dart.core::int start, dart.core::int end) → dart.core::Iterable<dart.core::int*> { method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk/lib/collection/list.dart */ getRange(dart.core::int start, dart.core::int end) → dart.core::Iterable<dart.core::int*> {
dart.core::RangeError::checkValidRange(start, end, this.{dart.core::List::length}); dart.core::RangeError::checkValidRange(start, end, this.{dart.core::List::length});
return new dart._internal::SubListIterable::•<dart.core::int*>(this, start, end); return new dart._internal::SubListIterable::•<dart.core::int*>(this, start, end);
} }
method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ removeRange(dart.core::int start, dart.core::int end) → void { method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk/lib/collection/list.dart */ removeRange(dart.core::int start, dart.core::int end) → void {
dart.core::RangeError::checkValidRange(start, end, this.{dart.core::List::length}); dart.core::RangeError::checkValidRange(start, end, this.{dart.core::List::length});
if(end.{dart.core::num::>}(start)) { if(end.{dart.core::num::>}(start)) {
this.{dart.collection::ListMixin::_closeGap}(start, end); this.{dart.collection::ListMixin::_closeGap}(start, end);
} }
} }
method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ fillRange(dart.core::int start, dart.core::int end, [generic-covariant-impl dart.core::int? fill = #C2]) → void { method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk/lib/collection/list.dart */ fillRange(dart.core::int start, dart.core::int end, [generic-covariant-impl dart.core::int? fill = #C2]) → void {
dart.core::int* value = let dart.core::int? #t6 = fill in #t6.==(null) ?{dart.core::int*} #t6 : #t6{dart.core::int*}; dart.core::int* value = let dart.core::int? #t6 = fill in #t6.==(null) ?{dart.core::int*} #t6 : #t6{dart.core::int*};
dart.core::RangeError::checkValidRange(start, end, this.{dart.core::List::length}); dart.core::RangeError::checkValidRange(start, end, this.{dart.core::List::length});
for (dart.core::int i = start; i.{dart.core::num::<}(end); i = i.{dart.core::num::+}(1)) { for (dart.core::int i = start; i.{dart.core::num::<}(end); i = i.{dart.core::num::+}(1)) {
this.{dart.core::List::[]=}(i, value); this.{dart.core::List::[]=}(i, value);
} }
} }
method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ setRange(dart.core::int start, dart.core::int end, generic-covariant-impl dart.core::Iterable<dart.core::int*> iterable, [dart.core::int skipCount = #C7]) → void { method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk/lib/collection/list.dart */ setRange(dart.core::int start, dart.core::int end, generic-covariant-impl dart.core::Iterable<dart.core::int*> iterable, [dart.core::int skipCount = #C7]) → void {
dart.core::RangeError::checkValidRange(start, end, this.{dart.core::List::length}); dart.core::RangeError::checkValidRange(start, end, this.{dart.core::List::length});
dart.core::int length = end.{dart.core::num::-}(start); dart.core::int length = end.{dart.core::num::-}(start);
if(length.{dart.core::num::==}(0)) if(length.{dart.core::num::==}(0))
@ -332,7 +332,7 @@ library from "org-dartlang-test:///main.dart" as main {
} }
} }
} }
method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ replaceRange(dart.core::int start, dart.core::int end, generic-covariant-impl dart.core::Iterable<dart.core::int*> newContents) → void { method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk/lib/collection/list.dart */ replaceRange(dart.core::int start, dart.core::int end, generic-covariant-impl dart.core::Iterable<dart.core::int*> newContents) → void {
dart.core::RangeError::checkValidRange(start, end, this.{dart.core::List::length}); dart.core::RangeError::checkValidRange(start, end, this.{dart.core::List::length});
if(start.{dart.core::num::==}(this.{dart.core::List::length})) { if(start.{dart.core::num::==}(this.{dart.core::List::length})) {
this.{dart.collection::ListMixin::addAll}(newContents); this.{dart.collection::ListMixin::addAll}(newContents);
@ -382,7 +382,7 @@ library from "org-dartlang-test:///main.dart" as main {
this.{dart.collection::ListMixin::setRange}(start, insertEnd, newContents); this.{dart.collection::ListMixin::setRange}(start, insertEnd, newContents);
} }
} }
method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ indexOf(generic-covariant-impl dart.core::Object? element, [dart.core::int start = #C7]) → dart.core::int { method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk/lib/collection/list.dart */ indexOf(generic-covariant-impl dart.core::Object? element, [dart.core::int start = #C7]) → dart.core::int {
if(start.{dart.core::num::<}(0)) if(start.{dart.core::num::<}(0))
start = 0; start = 0;
for (dart.core::int i = start; i.{dart.core::num::<}(this.{dart.core::List::length}); i = i.{dart.core::num::+}(1)) { for (dart.core::int i = start; i.{dart.core::num::<}(this.{dart.core::List::length}); i = i.{dart.core::num::+}(1)) {
@ -391,7 +391,7 @@ library from "org-dartlang-test:///main.dart" as main {
} }
return 1.{dart.core::int::unary-}(); return 1.{dart.core::int::unary-}();
} }
method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ indexWhere((dart.core::int*) → dart.core::bool test, [dart.core::int start = #C7]) → dart.core::int { method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk/lib/collection/list.dart */ indexWhere((dart.core::int*) → dart.core::bool test, [dart.core::int start = #C7]) → dart.core::int {
if(start.{dart.core::num::<}(0)) if(start.{dart.core::num::<}(0))
start = 0; start = 0;
for (dart.core::int i = start; i.{dart.core::num::<}(this.{dart.core::List::length}); i = i.{dart.core::num::+}(1)) { for (dart.core::int i = start; i.{dart.core::num::<}(this.{dart.core::List::length}); i = i.{dart.core::num::+}(1)) {
@ -400,7 +400,7 @@ library from "org-dartlang-test:///main.dart" as main {
} }
return 1.{dart.core::int::unary-}(); return 1.{dart.core::int::unary-}();
} }
method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ lastIndexOf(generic-covariant-impl dart.core::Object? element, [dart.core::int? start = #C2]) → dart.core::int { method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk/lib/collection/list.dart */ lastIndexOf(generic-covariant-impl dart.core::Object? element, [dart.core::int? start = #C2]) → dart.core::int {
if(start.{dart.core::num::==}(null) || start{dart.core::int}.{dart.core::num::>=}(this.{dart.core::List::length})) if(start.{dart.core::num::==}(null) || start{dart.core::int}.{dart.core::num::>=}(this.{dart.core::List::length}))
start = this.{dart.core::List::length}.{dart.core::num::-}(1); start = this.{dart.core::List::length}.{dart.core::num::-}(1);
if(start{dart.core::int}.{dart.core::num::==}(null)) if(start{dart.core::int}.{dart.core::num::==}(null))
@ -411,7 +411,7 @@ library from "org-dartlang-test:///main.dart" as main {
} }
return 1.{dart.core::int::unary-}(); return 1.{dart.core::int::unary-}();
} }
method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ lastIndexWhere((dart.core::int*) → dart.core::bool test, [dart.core::int? start = #C2]) → dart.core::int { method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk/lib/collection/list.dart */ lastIndexWhere((dart.core::int*) → dart.core::bool test, [dart.core::int? start = #C2]) → dart.core::int {
if(start.{dart.core::num::==}(null) || start{dart.core::int}.{dart.core::num::>=}(this.{dart.core::List::length})) if(start.{dart.core::num::==}(null) || start{dart.core::int}.{dart.core::num::>=}(this.{dart.core::List::length}))
start = this.{dart.core::List::length}.{dart.core::num::-}(1); start = this.{dart.core::List::length}.{dart.core::num::-}(1);
if(start{dart.core::int}.{dart.core::num::==}(null)) if(start{dart.core::int}.{dart.core::num::==}(null))
@ -422,7 +422,7 @@ library from "org-dartlang-test:///main.dart" as main {
} }
return 1.{dart.core::int::unary-}(); return 1.{dart.core::int::unary-}();
} }
method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ insert(dart.core::int index, generic-covariant-impl dart.core::int* element) → void { method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk/lib/collection/list.dart */ insert(dart.core::int index, generic-covariant-impl dart.core::int* element) → void {
dart.core::ArgumentError::checkNotNull<dart.core::int>(index, "index"); dart.core::ArgumentError::checkNotNull<dart.core::int>(index, "index");
dart.core::RangeError::checkValueInInterval(index, 0, this.{dart.core::List::length}, "index"); dart.core::RangeError::checkValueInInterval(index, 0, this.{dart.core::List::length}, "index");
if(index.{dart.core::num::==}(this.{dart.core::List::length})) { if(index.{dart.core::num::==}(this.{dart.core::List::length})) {
@ -433,12 +433,12 @@ library from "org-dartlang-test:///main.dart" as main {
this.{dart.collection::ListMixin::setRange}(index.{dart.core::num::+}(1), this.{dart.core::List::length}, this, index); this.{dart.collection::ListMixin::setRange}(index.{dart.core::num::+}(1), this.{dart.core::List::length}, this, index);
this.{dart.core::List::[]=}(index, element); this.{dart.core::List::[]=}(index, element);
} }
method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ removeAt(dart.core::int index) → dart.core::int* { method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk/lib/collection/list.dart */ removeAt(dart.core::int index) → dart.core::int* {
dart.core::int* result = this.{dart.core::List::[]}(index); dart.core::int* result = this.{dart.core::List::[]}(index);
this.{dart.collection::ListMixin::_closeGap}(index, index.{dart.core::num::+}(1)); this.{dart.collection::ListMixin::_closeGap}(index, index.{dart.core::num::+}(1));
return result; return result;
} }
method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ insertAll(dart.core::int index, generic-covariant-impl dart.core::Iterable<dart.core::int*> iterable) → void { method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk/lib/collection/list.dart */ insertAll(dart.core::int index, generic-covariant-impl dart.core::Iterable<dart.core::int*> iterable) → void {
dart.core::RangeError::checkValueInInterval(index, 0, this.{dart.core::List::length}, "index"); dart.core::RangeError::checkValueInInterval(index, 0, this.{dart.core::List::length}, "index");
if(index.{dart.core::num::==}(this.{dart.core::List::length})) { if(index.{dart.core::num::==}(this.{dart.core::List::length})) {
this.{dart.collection::ListMixin::addAll}(iterable); this.{dart.collection::ListMixin::addAll}(iterable);
@ -465,7 +465,7 @@ library from "org-dartlang-test:///main.dart" as main {
} }
this.{dart.collection::ListMixin::setAll}(index, iterable); this.{dart.collection::ListMixin::setAll}(index, iterable);
} }
method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ setAll(dart.core::int index, generic-covariant-impl dart.core::Iterable<dart.core::int*> iterable) → void { method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk/lib/collection/list.dart */ setAll(dart.core::int index, generic-covariant-impl dart.core::Iterable<dart.core::int*> iterable) → void {
if(iterable is{ForNonNullableByDefault} dart.core::List<dynamic>) { if(iterable is{ForNonNullableByDefault} dart.core::List<dynamic>) {
this.{dart.collection::ListMixin::setRange}(index, index.{dart.core::num::+}(iterable.{dart.core::Iterable::length}), iterable); this.{dart.collection::ListMixin::setRange}(index, index.{dart.core::num::+}(iterable.{dart.core::Iterable::length}), iterable);
} }
@ -481,9 +481,9 @@ library from "org-dartlang-test:///main.dart" as main {
} }
} }
} }
get /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ reversed() → dart.core::Iterable<dart.core::int*> get /*isNonNullableByDefault, from org-dartlang-sdk:///sdk/lib/collection/list.dart */ reversed() → dart.core::Iterable<dart.core::int*>
return new dart._internal::ReversedListIterable::•<dart.core::int*>(this); return new dart._internal::ReversedListIterable::•<dart.core::int*>(this);
method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ toString() → dart.core::String method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk/lib/collection/list.dart */ toString() → dart.core::String
return dart.collection::IterableBase::iterableToFullString(this, "[", "]"); return dart.collection::IterableBase::iterableToFullString(this, "[", "]");
abstract member-signature get _identityHashCode() → dart.core::int*; abstract member-signature get _identityHashCode() → dart.core::int*;
abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → dart.core::bool*; abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → dart.core::bool*;
@ -495,40 +495,40 @@ library from "org-dartlang-test:///main.dart" as main {
abstract member-signature method noSuchMethod(dart.core::Invocation* invocation) → dynamic; abstract member-signature method noSuchMethod(dart.core::Invocation* invocation) → dynamic;
abstract member-signature get runtimeType() → dart.core::Type*; abstract member-signature get runtimeType() → dart.core::Type*;
abstract member-signature set length(dart.core::int* newLength) → void; abstract member-signature set length(dart.core::int* newLength) → void;
get /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ first() → dart.core::int* { get /*isNonNullableByDefault, from org-dartlang-sdk:///sdk/lib/collection/list.dart */ first() → dart.core::int* {
if(this.{dart.core::List::length}.{dart.core::num::==}(0)) if(this.{dart.core::List::length}.{dart.core::num::==}(0))
throw dart._internal::IterableElementError::noElement(); throw dart._internal::IterableElementError::noElement();
return this.{dart.core::List::[]}(0); return this.{dart.core::List::[]}(0);
} }
set /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ first(generic-covariant-impl dart.core::int* value) → void { set /*isNonNullableByDefault, from org-dartlang-sdk:///sdk/lib/collection/list.dart */ first(generic-covariant-impl dart.core::int* value) → void {
if(this.{dart.core::List::length}.{dart.core::num::==}(0)) if(this.{dart.core::List::length}.{dart.core::num::==}(0))
throw dart._internal::IterableElementError::noElement(); throw dart._internal::IterableElementError::noElement();
this.{dart.core::List::[]=}(0, value); this.{dart.core::List::[]=}(0, value);
} }
get /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ last() → dart.core::int* { get /*isNonNullableByDefault, from org-dartlang-sdk:///sdk/lib/collection/list.dart */ last() → dart.core::int* {
if(this.{dart.core::List::length}.{dart.core::num::==}(0)) if(this.{dart.core::List::length}.{dart.core::num::==}(0))
throw dart._internal::IterableElementError::noElement(); throw dart._internal::IterableElementError::noElement();
return this.{dart.core::List::[]}(this.{dart.core::List::length}.{dart.core::num::-}(1)); return this.{dart.core::List::[]}(this.{dart.core::List::length}.{dart.core::num::-}(1));
} }
set /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ last(generic-covariant-impl dart.core::int* value) → void { set /*isNonNullableByDefault, from org-dartlang-sdk:///sdk/lib/collection/list.dart */ last(generic-covariant-impl dart.core::int* value) → void {
if(this.{dart.core::List::length}.{dart.core::num::==}(0)) if(this.{dart.core::List::length}.{dart.core::num::==}(0))
throw dart._internal::IterableElementError::noElement(); throw dart._internal::IterableElementError::noElement();
this.{dart.core::List::[]=}(this.{dart.core::List::length}.{dart.core::num::-}(1), value); this.{dart.core::List::[]=}(this.{dart.core::List::length}.{dart.core::num::-}(1), value);
} }
get /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ single() → dart.core::int* { get /*isNonNullableByDefault, from org-dartlang-sdk:///sdk/lib/collection/list.dart */ single() → dart.core::int* {
if(this.{dart.core::List::length}.{dart.core::num::==}(0)) if(this.{dart.core::List::length}.{dart.core::num::==}(0))
throw dart._internal::IterableElementError::noElement(); throw dart._internal::IterableElementError::noElement();
if(this.{dart.core::List::length}.{dart.core::num::>}(1)) if(this.{dart.core::List::length}.{dart.core::num::>}(1))
throw dart._internal::IterableElementError::tooMany(); throw dart._internal::IterableElementError::tooMany();
return this.{dart.core::List::[]}(0); return this.{dart.core::List::[]}(0);
} }
method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ add(generic-covariant-impl dart.core::int* element) → void { method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk/lib/collection/list.dart */ add(generic-covariant-impl dart.core::int* element) → void {
this.{dart.core::List::[]=}(let final dart.core::int #t9 = this.{dart.core::List::length} in let final dart.core::int #t10 = this.{dart.core::List::length} = #t9.{dart.core::num::+}(1) in #t9, element); this.{dart.core::List::[]=}(let final dart.core::int #t9 = this.{dart.core::List::length} in let final dart.core::int #t10 = this.{dart.core::List::length} = #t9.{dart.core::num::+}(1) in #t9, element);
} }
method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ clear() → void { method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk/lib/collection/list.dart */ clear() → void {
this.{dart.core::List::length} = 0; this.{dart.core::List::length} = 0;
} }
method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ removeLast() → dart.core::int* { method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk/lib/collection/list.dart */ removeLast() → dart.core::int* {
if(this.{dart.core::List::length}.{dart.core::num::==}(0)) { if(this.{dart.core::List::length}.{dart.core::num::==}(0)) {
throw dart._internal::IterableElementError::noElement(); throw dart._internal::IterableElementError::noElement();
} }
@ -536,7 +536,7 @@ library from "org-dartlang-test:///main.dart" as main {
this.{dart.core::List::length} = this.{dart.core::List::length}.{dart.core::num::-}(1); this.{dart.core::List::length} = this.{dart.core::List::length}.{dart.core::num::-}(1);
return result; return result;
} }
static method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk_nnbd/lib/collection/list.dart */ _compareAny(dynamic a, dynamic b) → dart.core::int { static method /*isNonNullableByDefault, from org-dartlang-sdk:///sdk/lib/collection/list.dart */ _compareAny(dynamic a, dynamic b) → dart.core::int {
return dart.core::Comparable::compare(a as{ForNonNullableByDefault} dart.core::Comparable<dynamic>, b as{ForNonNullableByDefault} dart.core::Comparable<dynamic>); return dart.core::Comparable::compare(a as{ForNonNullableByDefault} dart.core::Comparable<dynamic>, b as{ForNonNullableByDefault} dart.core::Comparable<dynamic>);
} }
} }

View file

@ -37,7 +37,7 @@ Uri computeYamlFile() {
Uri computeAllowListFile() { Uri computeAllowListFile() {
return Platform.script return Platform.script
.resolve("../../../../sdk_nnbd/lib/_internal/allowed_experiments.json"); .resolve("../../../../sdk/lib/_internal/allowed_experiments.json");
} }
String generateKernelFile() { String generateKernelFile() {

View file

@ -204,8 +204,6 @@ Future<void> _addModulePerPackage(
Future<Module> _createSdkModule(Uri root) async { Future<Module> _createSdkModule(Uri root) async {
List<Uri> sources = [ List<Uri> sources = [
Uri.parse('sdk/lib/libraries.json'), Uri.parse('sdk/lib/libraries.json'),
// TODO(#38701) Cleanup after merging the forked SDK into mainline.
Uri.parse('sdk_nnbd/lib/libraries.json'),
]; ];
// Include all dart2js, ddc, vm library sources and patch files. // Include all dart2js, ddc, vm library sources and patch files.
@ -213,8 +211,6 @@ Future<Module> _createSdkModule(Uri root) async {
// it doesn't list files that are transitively imported. // it doesn't list files that are transitively imported.
var sdkLibrariesAndPatchesRoots = [ var sdkLibrariesAndPatchesRoots = [
'sdk/lib/', 'sdk/lib/',
// TODO(#38701) Cleanup after merging the forked SDK into mainline.
'sdk_nnbd/lib/',
'runtime/lib/', 'runtime/lib/',
'runtime/bin/', 'runtime/bin/',
]; ];

View file

@ -217,15 +217,4 @@ class Sdk {
Sdk(String sdkPath) { Sdk(String sdkPath) {
this.sdkPath = path.canonicalize(sdkPath); this.sdkPath = path.canonicalize(sdkPath);
} }
/// Returns true if the SDK was built with --nnbd.
///
/// May throw if [sdkPath] is invalid, or there is an error parsing
/// the libraries.json file.
bool get isNnbdSdk {
// TODO(jcollins-g): contact eng-prod for a more foolproof detection method
String libraries = path.join(sdkPath, 'lib', 'libraries.json');
var decodedJson = JsonDecoder().convert(File(libraries).readAsStringSync());
return ((decodedJson['comment:1'] as String).contains('sdk_nnbd'));
}
} }

View file

@ -27,7 +27,6 @@ main(List<String> args) async {
Sdk sdk = Sdk(parsedArgs['sdk'] as String); Sdk sdk = Sdk(parsedArgs['sdk'] as String);
warnOnNoAssertions(); warnOnNoAssertions();
warnOnNoSdkNnbd(sdk);
Playground playground = Playground playground =
Playground(defaultPlaygroundPath, parsedArgs['clean'] as bool); Playground(defaultPlaygroundPath, parsedArgs['clean'] as bool);
@ -218,17 +217,6 @@ void warnOnNoAssertions() {
printWarning("You didn't --enable-asserts!"); printWarning("You didn't --enable-asserts!");
} }
void warnOnNoSdkNnbd(Sdk sdk) {
try {
if (sdk.isNnbdSdk) return;
} catch (e) {
printWarning('Unable to determine whether this SDK supports NNBD');
return;
}
printWarning(
'SDK at ${sdk.sdkPath} not compiled with --nnbd, use --sdk option');
}
class ExceptionCategory { class ExceptionCategory {
final String topOfStack; final String topOfStack;
final List<MapEntry<String, int>> exceptionCountPerPackage; final List<MapEntry<String, int>> exceptionCountPerPackage;

View file

@ -367,9 +367,7 @@ class Dart2xCompilerConfiguration extends CompilerConfiguration {
: super._subclass(configuration); : super._subclass(configuration);
String computeCompilerPath() { String computeCompilerPath() {
var prefix = var prefix = 'sdk/bin';
// TODO(38701): Cleanup after merging the forked SDK into mainline.
_configuration.nnbdMode == NnbdMode.legacy ? 'sdk/bin' : 'sdk_nnbd/bin';
var suffix = shellScriptExtension; var suffix = shellScriptExtension;
if (_isHostChecked) { if (_isHostChecked) {
@ -461,9 +459,7 @@ class Dart2jsCompilerConfiguration extends Dart2xCompilerConfiguration {
CommandArtifact artifact) { CommandArtifact artifact) {
var sdk = _useSdk var sdk = _useSdk
? Uri.directory(_configuration.buildDirectory).resolve('dart-sdk/') ? Uri.directory(_configuration.buildDirectory).resolve('dart-sdk/')
: Uri.directory(Repository.dir.toNativePath()).resolve( : Uri.directory(Repository.dir.toNativePath()).resolve('sdk/');
// TODO(38701): Cleanup after merging the forked SDK into mainline.
_configuration.nnbdMode == NnbdMode.legacy ? 'sdk/' : 'sdk_nnbd/');
var preambleDir = sdk.resolve('lib/_internal/js_runtime/lib/preambles/'); var preambleDir = sdk.resolve('lib/_internal/js_runtime/lib/preambles/');
return runtimeConfiguration.dart2jsPreambles(preambleDir) return runtimeConfiguration.dart2jsPreambles(preambleDir)
..add(artifact.filename); ..add(artifact.filename);
@ -494,10 +490,7 @@ class DevCompilerConfiguration extends CompilerConfiguration {
bool get useKernel => _configuration.compiler == Compiler.dartdevk; bool get useKernel => _configuration.compiler == Compiler.dartdevk;
String computeCompilerPath() { String computeCompilerPath() {
var dir = _useSdk var dir = _useSdk ? "${_configuration.buildDirectory}/dart-sdk" : "sdk";
? "${_configuration.buildDirectory}/dart-sdk"
// TODO(38701): Cleanup after merging the forked SDK into mainline.
: _configuration.nnbdMode == NnbdMode.legacy ? "sdk" : "sdk_nnbd";
return "$dir/bin/dartdevc$shellScriptExtension"; return "$dir/bin/dartdevc$shellScriptExtension";
} }
@ -508,8 +501,7 @@ class DevCompilerConfiguration extends CompilerConfiguration {
..._configuration.sharedOptions, ..._configuration.sharedOptions,
..._experimentsArgument(_configuration, testFile), ..._experimentsArgument(_configuration, testFile),
...testFile.ddcOptions, ...testFile.ddcOptions,
if (_configuration.nnbdMode == NnbdMode.strong) if (_configuration.nnbdMode == NnbdMode.strong) '--sound-null-safety',
'--sound-null-safety',
// The file being compiled is the last argument. // The file being compiled is the last argument.
args.last args.last
]; ];
@ -712,14 +704,11 @@ class PrecompilerCompilerConfiguration extends CompilerConfiguration
"--snapshot-kind=app-aot-assembly", "--snapshot-kind=app-aot-assembly",
"--assembly=$tempDir/out.S" "--assembly=$tempDir/out.S"
], ],
if (_isAndroid && _isArm) if (_isAndroid && _isArm) '--no-sim-use-hardfp',
'--no-sim-use-hardfp', if (_configuration.isMinified) '--obfuscate',
if (_configuration.isMinified)
'--obfuscate',
// The SIMARM precompiler assumes support for integer division, but the // The SIMARM precompiler assumes support for integer division, but the
// Qemu arm cpus do not support integer division. // Qemu arm cpus do not support integer division.
if (_configuration.useQemu) if (_configuration.useQemu) '--no-use-integer-division',
'--no-use-integer-division',
..._replaceDartFiles(arguments, tempKernelFile(tempDir)), ..._replaceDartFiles(arguments, tempKernelFile(tempDir)),
]; ];
@ -936,9 +925,7 @@ class AnalyzerCompilerConfiguration extends CompilerConfiguration {
int get timeoutMultiplier => 4; int get timeoutMultiplier => 4;
String computeCompilerPath() { String computeCompilerPath() {
var prefix = var prefix = 'sdk/bin';
// TODO(38701): Cleanup after merging the forked SDK into mainline.
_configuration.nnbdMode == NnbdMode.legacy ? 'sdk/bin' : 'sdk_nnbd/bin';
if (_isHostChecked) { if (_isHostChecked) {
if (_useSdk) { if (_useSdk) {
throw "--host-checked and --use-sdk cannot be used together"; throw "--host-checked and --use-sdk cannot be used together";

View file

@ -69,8 +69,7 @@ class TestConfiguration {
this.reproducingArguments, this.reproducingArguments,
this.fastTestsOnly, this.fastTestsOnly,
this.printPassingStdout}) this.printPassingStdout})
: _packages = packages, : _packages = packages;
isPreNNBD = configuration.name.split('-').contains('prennbd');
final Map<String, RegExp> selectors; final Map<String, RegExp> selectors;
final Progress progress; final Progress progress;
@ -99,7 +98,6 @@ class TestConfiguration {
final bool writeResults; final bool writeResults;
final bool writeLogs; final bool writeLogs;
final bool printPassingStdout; final bool printPassingStdout;
final bool isPreNNBD;
Architecture get architecture => configuration.architecture; Architecture get architecture => configuration.architecture;
Compiler get compiler => configuration.compiler; Compiler get compiler => configuration.compiler;
@ -470,13 +468,6 @@ class TestConfiguration {
var normal = '$result$arch'; var normal = '$result$arch';
var cross = '${result}X$arch'; var cross = '${result}X$arch';
// TODO(sigmund): remove once all prennbd coverage is dropped. Currently
// only dart2js supports opting-out of using the nnbd sdk.
if (isPreNNBD) {
normal += 'Legacy';
cross += 'Legacy';
}
var outDir = system.outputDirectory; var outDir = system.outputDirectory;
var normalDir = Directory(Path('$outDir$normal').toNativePath()); var normalDir = Directory(Path('$outDir$normal').toNativePath());
var crossDir = Directory(Path('$outDir$cross').toNativePath()); var crossDir = Directory(Path('$outDir$cross').toNativePath());

View file

@ -528,14 +528,9 @@ gen_snapshot_action("generate_snapshot_bin") {
isolate_snapshot_data, isolate_snapshot_data,
isolate_snapshot_instructions, isolate_snapshot_instructions,
] ]
args = [] args = [
if (!dont_use_nnbd) { "--enable-experiment=non-nullable",
args += [ "--null-safety",
"--enable-experiment=non-nullable",
"--null-safety",
]
}
args += [
"--deterministic", "--deterministic",
"--snapshot_kind=" + dart_core_snapshot_kind, "--snapshot_kind=" + dart_core_snapshot_kind,
"--vm_snapshot_data=" + rebase_path(vm_snapshot_data, root_build_dir), "--vm_snapshot_data=" + rebase_path(vm_snapshot_data, root_build_dir),

View file

@ -155,12 +155,7 @@ template("gen_vm_platform") {
} }
single_root_scheme = "org-dartlang-sdk" single_root_scheme = "org-dartlang-sdk"
single_root_base = rebase_path("../../") single_root_base = rebase_path("../../")
if (!dont_use_nnbd) { libraries_specification_uri = "org-dartlang-sdk:///sdk/lib/libraries.json"
libraries_specification_uri =
"org-dartlang-sdk:///sdk_nnbd/lib/libraries.json"
} else {
libraries_specification_uri = "org-dartlang-sdk:///sdk/lib/libraries.json"
}
outputs = [ outputs = [
"$root_out_dir/vm_platform" + output_postfix + ".dill", "$root_out_dir/vm_platform" + output_postfix + ".dill",
"$root_out_dir/vm_outline" + output_postfix + ".dill", "$root_out_dir/vm_outline" + output_postfix + ".dill",
@ -172,11 +167,9 @@ template("gen_vm_platform") {
"-Ddart.vm.product=$is_product_flag", "-Ddart.vm.product=$is_product_flag",
"-Ddart.developer.causal_async_stacks=$allow_causal_async_stacks", "-Ddart.developer.causal_async_stacks=$allow_causal_async_stacks",
"-Ddart.isVM=true", "-Ddart.isVM=true",
"--enable-experiment=non-nullable",
"--nnbd-agnostic",
] ]
if (!dont_use_nnbd) {
args += [ "--enable-experiment=non-nullable" ]
args += [ "--nnbd-agnostic" ]
}
if (defined(invoker.exclude_source) && invoker.exclude_source) { if (defined(invoker.exclude_source) && invoker.exclude_source) {
args += [ "--exclude-source" ] args += [ "--exclude-source" ]
} }

View file

@ -618,11 +618,15 @@ copy("copy_dart2js_dill_files") {
visibility = [ ":create_full_sdk" ] visibility = [ ":create_full_sdk" ]
deps = [ deps = [
":copy_libraries", ":copy_libraries",
"../utils/compiler:compile_dart2js_nnbd_strong_platform",
"../utils/compiler:compile_dart2js_platform", "../utils/compiler:compile_dart2js_platform",
"../utils/compiler:compile_dart2js_server_nnbd_strong_platform",
"../utils/compiler:compile_dart2js_server_platform", "../utils/compiler:compile_dart2js_server_platform",
] ]
sources = [ sources = [
"$root_out_dir/dart2js_nnbd_strong_platform.dill",
"$root_out_dir/dart2js_platform.dill", "$root_out_dir/dart2js_platform.dill",
"$root_out_dir/dart2js_server_nnbd_strong_platform.dill",
"$root_out_dir/dart2js_server_platform.dill", "$root_out_dir/dart2js_server_platform.dill",
] ]
outputs = [ "$root_out_dir/dart-sdk/lib/_internal/{{source_file_part}}" ] outputs = [ "$root_out_dir/dart-sdk/lib/_internal/{{source_file_part}}" ]
@ -636,9 +640,22 @@ copy("copy_dev_compiler_outline") {
"../utils/dartdevc:dartdevc_platform", "../utils/dartdevc:dartdevc_platform",
] ]
sources = [ "$root_out_dir/ddc_outline.dill" ] sources = [ "$root_out_dir/ddc_outline.dill" ]
# TODO(nshahan) Fix the name here to be consistent and merge with below.
outputs = [ "$root_out_dir/dart-sdk/lib/_internal/ddc_sdk.dill" ] outputs = [ "$root_out_dir/dart-sdk/lib/_internal/ddc_sdk.dill" ]
} }
# Copies DDC's SDK outline .dill with sound null safety to lib/_internal
copy("copy_dev_compiler_outline_sound") {
visibility = [ "../utils/dartdevc:dartdevc_test" ]
deps = [
":copy_libraries",
"../utils/dartdevc:dartdevc_platform_sound",
]
sources = [ "$root_out_dir/ddc_outline_sound.dill" ]
outputs = [ "$root_out_dir/dart-sdk/lib/_internal/{{source_file_part}}" ]
}
# This rule copies DDK's JS SDK and require.js to lib/dev_compiler/kernel/amd. # This rule copies DDK's JS SDK and require.js to lib/dev_compiler/kernel/amd.
copy("copy_dev_compiler_js_amd_kernel") { copy("copy_dev_compiler_js_amd_kernel") {
visibility = [ ":copy_dev_compiler_js" ] visibility = [ ":copy_dev_compiler_js" ]

View file

@ -52,4 +52,4 @@ DART_ROOT="$(cd "${SDK_DIR}/.." ; pwd -P)"
DART2JS="package:compiler/src/dart2js.dart" DART2JS="package:compiler/src/dart2js.dart"
exec "$DART" "--packages=$DART_ROOT/.packages" "${EXTRA_VM_OPTIONS[@]}" "$DART2JS" "${EXTRA_OPTIONS[@]}" "$@" exec "$DART" "--packages=$DART_ROOT/.packages" --enable-experiment=non-nullable "${EXTRA_VM_OPTIONS[@]}" "$DART2JS" "${EXTRA_OPTIONS[@]}" "$@"

View file

@ -55,4 +55,4 @@ if [[ $DART_VM_OPTIONS ]]; then
EXTRA_VM_OPTIONS+=("${OPTIONS[@]}") EXTRA_VM_OPTIONS+=("${OPTIONS[@]}")
fi fi
exec "$DART" "${EXTRA_VM_OPTIONS[@]}" "$SNAPSHOT" "${EXTRA_OPTIONS[@]}" "$@" exec "$DART" --enable-experiment=non-nullable "${EXTRA_VM_OPTIONS[@]}" "$SNAPSHOT" "${EXTRA_OPTIONS[@]}" "$@"

View file

@ -28,6 +28,7 @@ DART="$BIN_DIR/dart"
unset EXTRA_VM_OPTIONS unset EXTRA_VM_OPTIONS
declare -a EXTRA_VM_OPTIONS declare -a EXTRA_VM_OPTIONS
EXTRA_VM_OPTIONS+=("--enable_experiment=non-nullable")
case $0 in case $0 in
*_developer) *_developer)

View file

@ -28,4 +28,4 @@ SNAPSHOT="$BIN_DIR/snapshots/dartanalyzer.dart.snapshot"
# We are running the snapshot in the built SDK. # We are running the snapshot in the built SDK.
DART="$BIN_DIR/dart" DART="$BIN_DIR/dart"
exec "$DART" "$SNAPSHOT" "$SDK_ARG" "$@" exec "$DART" --enable_experiment=non-nullable "$SNAPSHOT" "$SDK_ARG" "$@"

View file

@ -45,4 +45,4 @@ DART_ROOT="$(cd "${SDK_DIR}/.." ; pwd -P)"
DEV_COMPILER="$DART_ROOT/pkg/dev_compiler/bin/dartdevc.dart" DEV_COMPILER="$DART_ROOT/pkg/dev_compiler/bin/dartdevc.dart"
exec "$DART" "--packages=$DART_ROOT/.packages" "${EXTRA_VM_OPTIONS[@]}" "$DEV_COMPILER" "$SDK_ARG" "$@" exec "$DART" "--packages=$DART_ROOT/.packages" --enable_experiment=non-nullable "${EXTRA_VM_OPTIONS[@]}" "$DEV_COMPILER" "$SDK_ARG" "$@"

View file

@ -35,4 +35,4 @@ if [[ $DART_VM_OPTIONS ]]; then
EXTRA_VM_OPTIONS+=("${OPTIONS[@]}") EXTRA_VM_OPTIONS+=("${OPTIONS[@]}")
fi fi
exec "$DART" "${EXTRA_VM_OPTIONS[@]}" "$SNAPSHOT" "$@" exec "$DART" --enable_experiment=non-nullable "${EXTRA_VM_OPTIONS[@]}" "$SNAPSHOT" "$@"

View file

@ -2,8 +2,6 @@
// for details. All rights reserved. Use of this source code is governed by a // for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file. // BSD-style license that can be found in the LICENSE file.
// @dart = 2.6
part of dart._http; part of dart._http;
class _CryptoUtils { class _CryptoUtils {
@ -68,7 +66,7 @@ class _CryptoUtils {
} }
final String lookup = urlSafe ? _encodeTableUrlSafe : _encodeTable; final String lookup = urlSafe ? _encodeTableUrlSafe : _encodeTable;
// Size of 24 bit chunks. // Size of 24 bit chunks.
final int remainderLength = len.remainder(3); final int remainderLength = len.remainder(3) as int;
final int chunkLength = len - remainderLength; final int chunkLength = len - remainderLength;
// Size of base output. // Size of base output.
int outputLen = ((len ~/ 3) * 4) + ((remainderLength > 0) ? 4 : 0); int outputLen = ((len ~/ 3) * 4) + ((remainderLength > 0) ? 4 : 0);
@ -76,7 +74,7 @@ class _CryptoUtils {
if (addLineSeparator) { if (addLineSeparator) {
outputLen += ((outputLen - 1) ~/ LINE_LENGTH) << 1; outputLen += ((outputLen - 1) ~/ LINE_LENGTH) << 1;
} }
List<int> out = new List<int>(outputLen); List<int> out = new List<int>.filled(outputLen, 0);
// Encode 24 bit chunks. // Encode 24 bit chunks.
int j = 0, i = 0, c = 0; int j = 0, i = 0, c = 0;
@ -120,7 +118,7 @@ class _CryptoUtils {
[bool ignoreInvalidCharacters = true]) { [bool ignoreInvalidCharacters = true]) {
int len = input.length; int len = input.length;
if (len == 0) { if (len == 0) {
return new List<int>(0); return new List<int>.empty();
} }
// Count '\r', '\n' and illegal characters, For illegal characters, // Count '\r', '\n' and illegal characters, For illegal characters,
@ -149,7 +147,7 @@ class _CryptoUtils {
if (currentCodeUnit == PAD) padLength++; if (currentCodeUnit == PAD) padLength++;
} }
int outputLen = (((len - extrasLen) * 6) >> 3) - padLength; int outputLen = (((len - extrasLen) * 6) >> 3) - padLength;
List<int> out = new List<int>(outputLen); List<int> out = new List<int>.filled(outputLen, 0);
for (int i = 0, o = 0; o < outputLen;) { for (int i = 0, o = 0; o < outputLen;) {
// Accumulate 4 valid 6 bit Base 64 characters into an int. // Accumulate 4 valid 6 bit Base 64 characters into an int.
@ -182,7 +180,6 @@ const _BYTES_PER_WORD = 4;
abstract class _HashBase { abstract class _HashBase {
// Hasher state. // Hasher state.
final int _chunkSizeInWords; final int _chunkSizeInWords;
final int _digestSizeInWords;
final bool _bigEndianWords; final bool _bigEndianWords;
int _lengthInBytes = 0; int _lengthInBytes = 0;
List<int> _pendingData; List<int> _pendingData;
@ -190,12 +187,10 @@ abstract class _HashBase {
List<int> _h; List<int> _h;
bool _digestCalled = false; bool _digestCalled = false;
_HashBase( _HashBase(this._chunkSizeInWords, int digestSizeInWords, this._bigEndianWords)
this._chunkSizeInWords, this._digestSizeInWords, this._bigEndianWords) : _pendingData = [],
: _pendingData = [] { _currentChunk = new List.filled(_chunkSizeInWords, 0),
_currentChunk = new List(_chunkSizeInWords); _h = new List.filled(digestSizeInWords, 0);
_h = new List(_digestSizeInWords);
}
// Update the hasher with more data. // Update the hasher with more data.
add(List<int> data) { add(List<int> data) {
@ -271,7 +266,7 @@ abstract class _HashBase {
// Convert a 32-bit word to four bytes. // Convert a 32-bit word to four bytes.
List<int> _wordToBytes(int word) { List<int> _wordToBytes(int word) {
List<int> bytes = new List(_BYTES_PER_WORD); List<int> bytes = new List.filled(_BYTES_PER_WORD, 0);
bytes[0] = (word >> (_bigEndianWords ? 24 : 0)) & _MASK_8; bytes[0] = (word >> (_bigEndianWords ? 24 : 0)) & _MASK_8;
bytes[1] = (word >> (_bigEndianWords ? 16 : 8)) & _MASK_8; bytes[1] = (word >> (_bigEndianWords ? 16 : 8)) & _MASK_8;
bytes[2] = (word >> (_bigEndianWords ? 8 : 16)) & _MASK_8; bytes[2] = (word >> (_bigEndianWords ? 8 : 16)) & _MASK_8;
@ -397,9 +392,11 @@ class _MD5 extends _HashBase {
// The SHA1 hasher is used to compute an SHA1 message digest. // The SHA1 hasher is used to compute an SHA1 message digest.
class _SHA1 extends _HashBase { class _SHA1 extends _HashBase {
List<int> _w;
// Construct a SHA1 hasher object. // Construct a SHA1 hasher object.
_SHA1() _SHA1()
: _w = new List(80), : _w = List<int>.filled(80, 0),
super(16, 5, true) { super(16, 5, true) {
_h[0] = 0x67452301; _h[0] = 0x67452301;
_h[1] = 0xEFCDAB89; _h[1] = 0xEFCDAB89;
@ -455,6 +452,4 @@ class _SHA1 extends _HashBase {
_h[3] = _add32(d, _h[3]); _h[3] = _add32(d, _h[3]);
_h[4] = _add32(e, _h[4]); _h[4] = _add32(e, _h[4]);
} }
List<int> _w;
} }

View file

@ -2,8 +2,6 @@
// for details. All rights reserved. Use of this source code is governed by a // for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file. // BSD-style license that can be found in the LICENSE file.
// @dart = 2.6
part of dart._http; part of dart._http;
/// Embedder-specific `dart:_http` configuration. /// Embedder-specific `dart:_http` configuration.

View file

@ -2,8 +2,6 @@
// for details. All rights reserved. Use of this source code is governed by a // for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file. // BSD-style license that can be found in the LICENSE file.
// @dart = 2.6
library dart._http; library dart._http;
import 'dart:async'; import 'dart:async';
@ -18,7 +16,8 @@ import 'dart:collection'
UnmodifiableMapView; UnmodifiableMapView;
import 'dart:convert'; import 'dart:convert';
import 'dart:developer' hide log; import 'dart:developer' hide log;
import 'dart:_internal' show Since, HttpStatus; import 'dart:_internal'
show Since, valueOfNonNullableParamWithDefault, HttpStatus;
import 'dart:math'; import 'dart:math';
import 'dart:io'; import 'dart:io';
import 'dart:typed_data'; import 'dart:typed_data';
@ -144,7 +143,7 @@ abstract class HttpServer implements Stream<HttpRequest> {
* *
* The default value is `null`. * The default value is `null`.
*/ */
String serverHeader; String? serverHeader;
/** /**
* Default set of headers added to all response objects. * Default set of headers added to all response objects.
@ -171,7 +170,7 @@ abstract class HttpServer implements Stream<HttpRequest> {
* The default value is `false` (compression disabled). * The default value is `false` (compression disabled).
* To enable, set `autoCompress` to `true`. * To enable, set `autoCompress` to `true`.
*/ */
bool autoCompress; bool autoCompress = false;
/** /**
* Gets or sets the timeout used for idle keep-alive connections. If no * Gets or sets the timeout used for idle keep-alive connections. If no
@ -185,7 +184,7 @@ abstract class HttpServer implements Stream<HttpRequest> {
* *
* To disable, set [idleTimeout] to `null`. * To disable, set [idleTimeout] to `null`.
*/ */
Duration idleTimeout; Duration? idleTimeout = const Duration(seconds: 120);
/** /**
* Starts listening for HTTP requests on the specified [address] and * Starts listening for HTTP requests on the specified [address] and
@ -209,13 +208,13 @@ abstract class HttpServer implements Stream<HttpRequest> {
* [InternetAddress.loopbackIPv6], only IP version 6 (IPv6) connections * [InternetAddress.loopbackIPv6], only IP version 6 (IPv6) connections
* will be accepted. * will be accepted.
* *
* If [port] has the value [:0:] an ephemeral port will be chosen by * If [port] has the value 0 an ephemeral port will be chosen by
* the system. The actual port used can be retrieved using the * the system. The actual port used can be retrieved using the
* [port] getter. * [port] getter.
* *
* The optional argument [backlog] can be used to specify the listen * The optional argument [backlog] can be used to specify the listen
* backlog for the underlying OS listen setup. If [backlog] has the * backlog for the underlying OS listen setup. If [backlog] has the
* value of [:0:] (the default) a reasonable value will be chosen by * value of 0 (the default) a reasonable value will be chosen by
* the system. * the system.
* *
* The optional argument [shared] specifies whether additional HttpServer * The optional argument [shared] specifies whether additional HttpServer
@ -226,7 +225,7 @@ abstract class HttpServer implements Stream<HttpRequest> {
* distributed over multiple isolates this way. * distributed over multiple isolates this way.
*/ */
static Future<HttpServer> bind(address, int port, static Future<HttpServer> bind(address, int port,
{int backlog: 0, bool v6Only: false, bool shared: false}) => {int backlog = 0, bool v6Only = false, bool shared = false}) =>
_HttpServer.bind(address, port, backlog, v6Only, shared); _HttpServer.bind(address, port, backlog, v6Only, shared);
/** /**
@ -246,13 +245,13 @@ abstract class HttpServer implements Stream<HttpRequest> {
* restrict this to version 6 (IPv6) only, use [v6Only] to set * restrict this to version 6 (IPv6) only, use [v6Only] to set
* version 6 only. * version 6 only.
* *
* If [port] has the value [:0:] an ephemeral port will be chosen by * If [port] has the value 0 an ephemeral port will be chosen by
* the system. The actual port used can be retrieved using the * the system. The actual port used can be retrieved using the
* [port] getter. * [port] getter.
* *
* The optional argument [backlog] can be used to specify the listen * The optional argument [backlog] can be used to specify the listen
* backlog for the underlying OS listen setup. If [backlog] has the * backlog for the underlying OS listen setup. If [backlog] has the
* value of [:0:] (the default) a reasonable value will be chosen by * value of 0 (the default) a reasonable value will be chosen by
* the system. * the system.
* *
* If [requestClientCertificate] is true, the server will * If [requestClientCertificate] is true, the server will
@ -271,10 +270,10 @@ abstract class HttpServer implements Stream<HttpRequest> {
static Future<HttpServer> bindSecure( static Future<HttpServer> bindSecure(
address, int port, SecurityContext context, address, int port, SecurityContext context,
{int backlog: 0, {int backlog = 0,
bool v6Only: false, bool v6Only = false,
bool requestClientCertificate: false, bool requestClientCertificate = false,
bool shared: false}) => bool shared = false}) =>
_HttpServer.bindSecure(address, port, context, backlog, v6Only, _HttpServer.bindSecure(address, port, context, backlog, v6Only,
requestClientCertificate, shared); requestClientCertificate, shared);
@ -295,30 +294,33 @@ abstract class HttpServer implements Stream<HttpRequest> {
* *
* If [force] is `true`, active connections will be closed immediately. * If [force] is `true`, active connections will be closed immediately.
*/ */
Future close({bool force: false}); Future close({bool force = false});
/** /**
* Returns the port that the server is listening on. This can be * The port that the server is listening on.
* used to get the actual port used when a value of 0 for [:port:] is *
* This is the actual port used when a port of zero is
* specified in the [bind] or [bindSecure] call. * specified in the [bind] or [bindSecure] call.
*/ */
int get port; int get port;
/** /**
* Returns the address that the server is listening on. This can be * The address that the server is listening on.
* used to get the actual address used, when the address is fetched by *
* a lookup from a hostname. * This is the actual address used when the original address
* was specified as a hostname.
*/ */
InternetAddress get address; InternetAddress get address;
/** /**
* Sets the timeout, in seconds, for sessions of this [HttpServer]. * Sets the timeout, in seconds, for sessions of this [HttpServer].
*
* The default timeout is 20 minutes. * The default timeout is 20 minutes.
*/ */
set sessionTimeout(int timeout); set sessionTimeout(int timeout);
/** /**
* Returns an [HttpConnectionsInfo] object summarizing the number of * A [HttpConnectionsInfo] object summarizing the number of
* current connections handled by the server. * current connections handled by the server.
*/ */
HttpConnectionsInfo connectionsInfo(); HttpConnectionsInfo connectionsInfo();
@ -345,8 +347,9 @@ class HttpConnectionsInfo {
int idle = 0; int idle = 0;
/** /**
* Number of connections which are preparing to close. Note: These * Number of connections which are preparing to close.
* connections are also part of the [:active:] count as they might *
* Note: These connections are also part of the [active] count as they might
* still be sending data to the client before finally closing. * still be sending data to the client before finally closing.
*/ */
int closing = 0; int closing = 0;
@ -357,9 +360,9 @@ class HttpConnectionsInfo {
* *
* In some situations, headers are immutable: * In some situations, headers are immutable:
* *
* * HttpRequest and HttpClientResponse always have immutable headers. * * [HttpRequest] and [HttpClientResponse] always have immutable headers.
* *
* * HttpResponse and HttpClientRequest have immutable headers * * [HttpResponse] and [HttpClientRequest] have immutable headers
* from the moment the body is written to. * from the moment the body is written to.
* *
* In these situations, the mutating methods throw exceptions. * In these situations, the mutating methods throw exceptions.
@ -376,7 +379,7 @@ class HttpConnectionsInfo {
* *
* print(request.headers.value(HttpHeaders.userAgentHeader)); * print(request.headers.value(HttpHeaders.userAgentHeader));
* *
* An HttpHeaders object holds a list of values for each name * An `HttpHeaders` object holds a list of values for each name
* as the standard allows. In most cases a name holds only a single value, * as the standard allows. In most cases a name holds only a single value,
* The most common mode of operation is to use `set()` for setting a value, * The most common mode of operation is to use `set()` for setting a value,
* and `value()` for retrieving a value. * and `value()` for retrieving a value.
@ -534,6 +537,7 @@ abstract class HttpHeaders {
@Deprecated("Use setCookieHeader instead") @Deprecated("Use setCookieHeader instead")
static const SET_COOKIE = setCookieHeader; static const SET_COOKIE = setCookieHeader;
// TODO(39783): Document this.
static const generalHeaders = const [ static const generalHeaders = const [
cacheControlHeader, cacheControlHeader,
connectionHeader, connectionHeader,
@ -606,71 +610,71 @@ abstract class HttpHeaders {
static const REQUEST_HEADERS = requestHeaders; static const REQUEST_HEADERS = requestHeaders;
/** /**
* Gets and sets the date. The value of this property will * The date specified by the [dateHeader] header, if any.
* reflect the 'date' header.
*/ */
DateTime date; DateTime? date;
/** /**
* Gets and sets the expiry date. The value of this property will * The date and time specified by the [expiresHeader] header, if any.
* reflect the 'expires' header.
*/ */
DateTime expires; DateTime? expires;
/** /**
* Gets and sets the "if-modified-since" date. The value of this property will * The date and time specified by the [ifModifiedSinceHeader] header, if any.
* reflect the "if-modified-since" header.
*/ */
DateTime ifModifiedSince; DateTime? ifModifiedSince;
/** /**
* Gets and sets the host part of the 'host' header for the * The value of the [hostHeader] header, if any.
* connection.
*/ */
String host; String? host;
/** /**
* Gets and sets the port part of the 'host' header for the * The value of the port part of the [hostHeader] header, if any.
* connection.
*/ */
int port; int? port;
/** /**
* Gets and sets the content type. Note that the content type in the * The [ContentType] of the [contentTypeHeader] header, if any.
* header will only be updated if this field is set
* directly. Mutating the returned current value will have no
* effect.
*/ */
ContentType contentType; ContentType? contentType;
/** /**
* Gets and sets the content length header value. * The value of the [contentLengthHeader] header, if any.
*
* The value is negative if there is no content length set.
*/ */
int contentLength; int contentLength = -1;
/** /**
* Gets and sets the persistent connection header value. * Whether the connection is persistent (keep-alive).
*/ */
bool persistentConnection; late bool persistentConnection;
/** /**
* Gets and sets the chunked transfer encoding header value. * Whether the connection uses chunked transfer encoding.
*
* Reflects and modifies the value of the [transferEncodingHeader] header.
*/ */
bool chunkedTransferEncoding; late bool chunkedTransferEncoding;
/** /**
* Returns the list of values for the header named [name]. If there * The values for the header named [name].
* is no header with the provided name, [:null:] will be returned. *
* Returns null if there is no header with the provided name,
* otherwise returns a new list containing the current values.
* Not that modifying the list does not change the header.
*/ */
List<String> operator [](String name); List<String>? operator [](String name);
/** /**
* Convenience method for the value for a single valued header. If * Convenience method for the value for a single valued header.
* there is no header with the provided name, [:null:] will be *
* returned. If the header has more than one value an exception is * The value must not have more than one value.
* thrown. *
* Returns `null` if there is no header with the provided name.
*/ */
String value(String name); String? value(String name);
/** /**
* Adds a header value. * Adds a header value.
@ -705,17 +709,24 @@ abstract class HttpHeaders {
{@Since("2.8") bool preserveHeaderCase = false}); {@Since("2.8") bool preserveHeaderCase = false});
/** /**
* Removes a specific value for a header name. Some headers have * Removes a specific value for a header name.
* system supplied values and for these the system supplied values *
* will still be added to the collection of values for the header. * Some headers have system supplied values which cannot be removed.
* For all other headers and values, the [value] is converted to a string
* in the same way as for [add], then that string value is removed from the
* current values of [name].
* If there are no remaining values for [name], the header is no longer
* considered present.
*/ */
void remove(String name, Object value); void remove(String name, Object value);
/** /**
* Removes all values for the specified header name. Some headers * Removes all values for the specified header name.
* have system supplied values and for these the system supplied *
* values will still be added to the collection of values for the * Some headers have system supplied values which cannot be removed.
* header. * All other values for [name] are removed.
* If there are no remaining values for [name], the header is no longer
* considered present.
*/ */
void removeAll(String name); void removeAll(String name);
@ -731,25 +742,30 @@ abstract class HttpHeaders {
void forEach(void action(String name, List<String> values)); void forEach(void action(String name, List<String> values));
/** /**
* Disables folding for the header named [name] when sending the HTTP * Disables folding for the header named [name] when sending the HTTP header.
* header. By default, multiple header values are folded into a *
* single header line by separating the values with commas. The * By default, multiple header values are folded into a
* 'set-cookie' header has folding disabled by default. * single header line by separating the values with commas.
*
* The 'set-cookie' header has folding disabled by default.
*/ */
void noFolding(String name); void noFolding(String name);
/** /**
* Remove all headers. Some headers have system supplied values and * Removes all headers.
* for these the system supplied values will still be added to the *
* collection of values for the header. * Some headers have system supplied values which cannot be removed.
* All other header values are removed, and header names with not
* remaining values are no longer considered present.
*/ */
void clear(); void clear();
} }
/** /**
* Representation of a header value in the form: * Representation of a header value in the form:
* * ```dart
* [:value; parameter1=value1; parameter2=value2:] * value; parameter1=value1; parameter2=value2
* ```
* *
* [HeaderValue] can be used to conveniently build and parse header * [HeaderValue] can be used to conveniently build and parse header
* values on this form. * values on this form.
@ -759,7 +775,7 @@ abstract class HttpHeaders {
* token characters and backslash sequences can be used to represent the double * token characters and backslash sequences can be used to represent the double
* quote and backslash characters themselves. * quote and backslash characters themselves.
* *
* To build an [:accepts:] header with the value * To build an "accepts" header with the value
* *
* text/plain; q=0.3, text/html * text/plain; q=0.3, text/html
* *
@ -770,7 +786,7 @@ abstract class HttpHeaders {
* request.headers.add(HttpHeaders.acceptHeader, v); * request.headers.add(HttpHeaders.acceptHeader, v);
* request.headers.add(HttpHeaders.acceptHeader, "text/html"); * request.headers.add(HttpHeaders.acceptHeader, "text/html");
* *
* To parse the header values use the [:parse:] static method. * To parse the header values use the [parse] static method.
* *
* HttpRequest request = ...; * HttpRequest request = ...;
* List<String> values = request.headers[HttpHeaders.acceptHeader]; * List<String> values = request.headers[HttpHeaders.acceptHeader];
@ -786,7 +802,7 @@ abstract class HeaderValue {
* Creates a new header value object setting the value and parameters. * Creates a new header value object setting the value and parameters.
*/ */
factory HeaderValue( factory HeaderValue(
[String value = "", Map<String, String> parameters = const {}]) { [String value = "", Map<String, String?> parameters = const {}]) {
return new _HeaderValue(value, parameters); return new _HeaderValue(value, parameters);
} }
@ -795,9 +811,9 @@ abstract class HeaderValue {
* string with both value and optional parameters. * string with both value and optional parameters.
*/ */
static HeaderValue parse(String value, static HeaderValue parse(String value,
{String parameterSeparator: ";", {String parameterSeparator = ";",
String valueSeparator: null, String? valueSeparator,
bool preserveBackslash: false}) { bool preserveBackslash = false}) {
return _HeaderValue.parse(value, return _HeaderValue.parse(value,
parameterSeparator: parameterSeparator, parameterSeparator: parameterSeparator,
valueSeparator: valueSeparator, valueSeparator: valueSeparator,
@ -805,52 +821,57 @@ abstract class HeaderValue {
} }
/** /**
* Gets the header value. * The value of the header.
*/ */
String get value; String get value;
/** /**
* Gets the map of parameters. * A map of parameters.
* *
* This map cannot be modified. Invoking any operation which would * This map cannot be modified.
* modify the map will throw [UnsupportedError].
*/ */
Map<String, String> get parameters; Map<String, String?> get parameters;
/** /**
* Returns the formatted string representation in the form: * Returns the formatted string representation in the form:
* * ```
* value; parameter1=value1; parameter2=value2 * value; parameter1=value1; parameter2=value2
* ```
*/ */
String toString(); String toString();
} }
abstract class HttpSession implements Map { abstract class HttpSession implements Map {
/** /**
* Gets the id for the current session. * The id of the current session.
*/ */
String get id; String get id;
/** /**
* Destroys the session. This will terminate the session and any further * Destroys the session.
*
* This terminates the session and any further
* connections with this id will be given a new id and session. * connections with this id will be given a new id and session.
*/ */
void destroy(); void destroy();
/** /**
* Sets a callback that will be called when the session is timed out. * Sets a callback that will be called when the session is timed out.
*
* Calling this again will overwrite the previous value.
*/ */
void set onTimeout(void callback()); void set onTimeout(void callback());
/** /**
* Is true if the session has not been sent to the client yet. * Whether the session has not yet been sent to the client.
*/ */
bool get isNew; bool get isNew;
} }
/** /**
* Representation of a content type. An instance of [ContentType] is * A MIME/IANA media type used as the value of the [contentTypeHeader] header.
* immutable. *
* A [ContentType] is immutable.
*/ */
abstract class ContentType implements HeaderValue { abstract class ContentType implements HeaderValue {
/** /**
@ -899,7 +920,7 @@ abstract class ContentType implements HeaderValue {
* or in `parameters`, will have its value converted to lower-case. * or in `parameters`, will have its value converted to lower-case.
*/ */
factory ContentType(String primaryType, String subType, factory ContentType(String primaryType, String subType,
{String charset, Map<String, String> parameters = const {}}) { {String? charset, Map<String, String?> parameters = const {}}) {
return new _ContentType(primaryType, subType, charset, parameters); return new _ContentType(primaryType, subType, charset, parameters);
} }
@ -911,32 +932,47 @@ abstract class ContentType implements HeaderValue {
* *
* text/html; charset=utf-8 * text/html; charset=utf-8
* *
* will create a content type object with primary type [:text:], sub * will create a content type object with primary type "text",
* type [:html:] and parameter [:charset:] with value [:utf-8:]. * subtype "html" and parameter "charset" with value "utf-8".
* There may be more parameters supplied, but they are not recognized
* by this class.
*/ */
static ContentType parse(String value) { static ContentType parse(String value) {
return _ContentType.parse(value); return _ContentType.parse(value);
} }
/** /**
* Gets the mime-type, without any parameters. * Gets the MIME type and subtype, without any parameters.
*
* For the full content type `text/html;charset=utf-8`,
* the [mimeType] value is the string `text/html`.
*/ */
String get mimeType; String get mimeType;
/** /**
* Gets the primary type. * Gets the primary type.
*
* For the full content type `text/html;charset=utf-8`,
* the [primaryType] value is the string `text`.
*/ */
String get primaryType; String get primaryType;
/** /**
* Gets the sub type. * Gets the subtype.
*
* For the full content type `text/html;charset=utf-8`,
* the [subType] value is the string `html`.
* May be the empty string.
*/ */
String get subType; String get subType;
/** /**
* Gets the character set. * Gets the character set, if any.
*
* For the full content type `text/html;charset=utf-8`,
* the [charset] value is the string `utf-8`.
*/ */
String get charset; String? get charset;
} }
/** /**
@ -956,7 +992,7 @@ abstract class Cookie {
* `(`, `)`, `<`, `>`, `@`, `,`, `;`, `:`, `\`, `"`, `/`, `[`, `]`, `?`, `=`, * `(`, `)`, `<`, `>`, `@`, `,`, `;`, `:`, `\`, `"`, `/`, `[`, `]`, `?`, `=`,
* `{`, and `}`. * `{`, and `}`.
*/ */
String name; late String name;
/** /**
* The value of the cookie. * The value of the cookie.
@ -969,39 +1005,39 @@ abstract class Cookie {
* Cookie values may be wrapped in a single pair of double quotes * Cookie values may be wrapped in a single pair of double quotes
* (U+0022, `"`). * (U+0022, `"`).
*/ */
String value; late String value;
/** /**
* The time at which the cookie expires. * The time at which the cookie expires.
*/ */
DateTime expires; DateTime? expires;
/** /**
* The number of seconds until the cookie expires. A zero or negative value * The number of seconds until the cookie expires. A zero or negative value
* means the cookie has expired. * means the cookie has expired.
*/ */
int maxAge; int? maxAge;
/** /**
* The domain the cookie applies to. * The domain that the cookie applies to.
*/ */
String domain; String? domain;
/** /**
* The path within the [domain] the cookie applies to. * The path within the [domain] that the cookie applies to.
*/ */
String path; String? path;
/** /**
* Whether to only send this cookie on secure connections. * Whether to only send this cookie on secure connections.
*/ */
bool secure; bool secure = false;
/** /**
* Whether the cookie is only sent in the HTTP request and is not made * Whether the cookie is only sent in the HTTP request and is not made
* available to client side scripts. * available to client side scripts.
*/ */
bool httpOnly; bool httpOnly = false;
/** /**
* Creates a new cookie setting the name and value. * Creates a new cookie setting the name and value.
@ -1123,7 +1159,7 @@ abstract class HttpRequest implements Stream<Uint8List> {
HttpHeaders get headers; HttpHeaders get headers;
/** /**
* The cookies in the request, from the Cookie headers. * The cookies in the request, from the "Cookie" headers.
*/ */
List<Cookie> get cookies; List<Cookie> get cookies;
@ -1139,14 +1175,13 @@ abstract class HttpRequest implements Stream<Uint8List> {
* or if the server does not request a client certificate, or if the client * or if the server does not request a client certificate, or if the client
* does not provide one. * does not provide one.
*/ */
X509Certificate get certificate; X509Certificate? get certificate;
/** /**
* The session for the given request. * The session for the given request.
* *
* If the session is * If the session is being initialized by this call,
* being initialized by this call, [:isNew:] is true for the returned * [HttpSession.isNew] is true for the returned session.
* session.
* See [HttpServer.sessionTimeout] on how to change default timeout. * See [HttpServer.sessionTimeout] on how to change default timeout.
*/ */
HttpSession get session; HttpSession get session;
@ -1160,9 +1195,9 @@ abstract class HttpRequest implements Stream<Uint8List> {
/** /**
* Information about the client connection. * Information about the client connection.
* *
* Returns [:null:] if the socket is not available. * Returns `null` if the socket is not available.
*/ */
HttpConnectionInfo get connectionInfo; HttpConnectionInfo? get connectionInfo;
/** /**
* The [HttpResponse] object, used for sending back the response to the * The [HttpResponse] object, used for sending back the response to the
@ -1231,10 +1266,12 @@ abstract class HttpResponse implements IOSink {
* the response is not known in advance set the content length to * the response is not known in advance set the content length to
* -1, which is also the default if not set. * -1, which is also the default if not set.
*/ */
int contentLength; int contentLength = -1;
/** /**
* Gets and sets the status code. Any integer value is accepted. For * The status code of the response.
*
* Any integer value is accepted. For
* the official HTTP status codes use the fields from * the official HTTP status codes use the fields from
* [HttpStatus]. If no status code is explicitly set the default * [HttpStatus]. If no status code is explicitly set the default
* value [HttpStatus.ok] is used. * value [HttpStatus.ok] is used.
@ -1243,24 +1280,25 @@ abstract class HttpResponse implements IOSink {
* to. Setting the status code after writing to the response body or * to. Setting the status code after writing to the response body or
* closing the response will throw a `StateError`. * closing the response will throw a `StateError`.
*/ */
int statusCode; int statusCode = HttpStatus.ok;
/** /**
* Gets and sets the reason phrase. If no reason phrase is explicitly * The reason phrase for the response.
* set a default reason phrase is provided. *
* If no reason phrase is explicitly set, a default reason phrase is provided.
* *
* The reason phrase must be set before the body is written * The reason phrase must be set before the body is written
* to. Setting the reason phrase after writing to the response body * to. Setting the reason phrase after writing to the response body
* or closing the response will throw a `StateError`. * or closing the response will throw a [StateError].
*/ */
String reasonPhrase; late String reasonPhrase;
/** /**
* Gets and sets the persistent connection state. The initial value * Gets and sets the persistent connection state. The initial value
* of this property is the persistent connection state from the * of this property is the persistent connection state from the
* request. * request.
*/ */
bool persistentConnection; late bool persistentConnection;
/** /**
* Set and get the [deadline] for the response. The deadline is timed from the * Set and get the [deadline] for the response. The deadline is timed from the
@ -1272,7 +1310,7 @@ abstract class HttpResponse implements IOSink {
* *
* The [deadline] is `null` by default. * The [deadline] is `null` by default.
*/ */
Duration deadline; Duration? deadline;
/** /**
* Gets or sets if the [HttpResponse] should buffer output. * Gets or sets if the [HttpResponse] should buffer output.
@ -1282,7 +1320,7 @@ abstract class HttpResponse implements IOSink {
* __Note__: Disabling buffering of the output can result in very poor * __Note__: Disabling buffering of the output can result in very poor
* performance, when writing many small chunks. * performance, when writing many small chunks.
*/ */
bool bufferOutput; bool bufferOutput = true;
/** /**
* Returns the response headers. * Returns the response headers.
@ -1310,7 +1348,7 @@ abstract class HttpResponse implements IOSink {
* This method will also call `close`, and the returned future is * This method will also call `close`, and the returned future is
* the future returned by `close`. * the future returned by `close`.
*/ */
Future redirect(Uri location, {int status: HttpStatus.movedTemporarily}); Future redirect(Uri location, {int status = HttpStatus.movedTemporarily});
/** /**
* Detaches the underlying socket from the HTTP server. When the * Detaches the underlying socket from the HTTP server. When the
@ -1324,13 +1362,13 @@ abstract class HttpResponse implements IOSink {
* to the socket before it's detached. If `false`, the socket is detached * to the socket before it's detached. If `false`, the socket is detached
* immediately, without any data written to the socket. Default is `true`. * immediately, without any data written to the socket. Default is `true`.
*/ */
Future<Socket> detachSocket({bool writeHeaders: true}); Future<Socket> detachSocket({bool writeHeaders = true});
/** /**
* Gets information about the client connection. Returns [:null:] if the * Gets information about the client connection. Returns `null` if the
* socket is not available. * socket is not available.
*/ */
HttpConnectionInfo get connectionInfo; HttpConnectionInfo? get connectionInfo;
} }
/** /**
@ -1416,7 +1454,7 @@ abstract class HttpResponse implements IOSink {
* By default the HttpClient uses the proxy configuration available * By default the HttpClient uses the proxy configuration available
* from the environment, see [findProxyFromEnvironment]. To turn off * from the environment, see [findProxyFromEnvironment]. To turn off
* the use of proxies set the [findProxy] property to * the use of proxies set the [findProxy] property to
* [:null:]. * `null`.
* *
* HttpClient client = new HttpClient(); * HttpClient client = new HttpClient();
* client.findProxy = null; * client.findProxy = null;
@ -1435,7 +1473,8 @@ abstract class HttpClient {
/// ///
/// Default is `false`. /// Default is `false`.
static set enableTimelineLogging(bool value) { static set enableTimelineLogging(bool value) {
_enableTimelineLogging = value ?? false; _enableTimelineLogging =
valueOfNonNullableParamWithDefault<bool>(value, false);
} }
/// Current state of HTTP request logging from all [HttpClient]s to the /// Current state of HTTP request logging from all [HttpClient]s to the
@ -1450,7 +1489,7 @@ abstract class HttpClient {
/// connections. /// connections.
/// ///
/// The default value is 15 seconds. /// The default value is 15 seconds.
Duration idleTimeout; Duration idleTimeout = const Duration(seconds: 15);
/// Gets and sets the connection timeout. /// Gets and sets the connection timeout.
/// ///
@ -1460,7 +1499,7 @@ abstract class HttpClient {
/// ///
/// When this is `null`, the OS default timeout is used. The default is /// When this is `null`, the OS default timeout is used. The default is
/// `null`. /// `null`.
Duration connectionTimeout; Duration? connectionTimeout;
/** /**
* Gets and sets the maximum number of live connections, to a single host. * Gets and sets the maximum number of live connections, to a single host.
@ -1472,7 +1511,7 @@ abstract class HttpClient {
* *
* Default is `null`. * Default is `null`.
*/ */
int maxConnectionsPerHost; int? maxConnectionsPerHost;
/** /**
* Gets and sets whether the body of a response will be automatically * Gets and sets whether the body of a response will be automatically
@ -1500,7 +1539,7 @@ abstract class HttpClient {
* *
* Default is `true`. * Default is `true`.
*/ */
bool autoUncompress; bool autoUncompress = true;
/// Gets and sets the default value of the `User-Agent` header for all requests /// Gets and sets the default value of the `User-Agent` header for all requests
/// generated by this [HttpClient]. /// generated by this [HttpClient].
@ -1509,10 +1548,10 @@ abstract class HttpClient {
/// ///
/// If the userAgent is set to `null`, no default `User-Agent` header will be /// If the userAgent is set to `null`, no default `User-Agent` header will be
/// added to each request. /// added to each request.
String userAgent; String? userAgent;
factory HttpClient({SecurityContext context}) { factory HttpClient({SecurityContext? context}) {
HttpOverrides overrides = HttpOverrides.current; HttpOverrides? overrides = HttpOverrides.current;
if (overrides == null) { if (overrides == null) {
return new _HttpClient(context); return new _HttpClient(context);
} }
@ -1679,12 +1718,12 @@ abstract class HttpClient {
* *
* The function returns a [Future] which should complete when the * The function returns a [Future] which should complete when the
* authentication has been resolved. If credentials cannot be * authentication has been resolved. If credentials cannot be
* provided the [Future] should complete with [:false:]. If * provided the [Future] should complete with `false`. If
* credentials are available the function should add these using * credentials are available the function should add these using
* [addCredentials] before completing the [Future] with the value * [addCredentials] before completing the [Future] with the value
* [:true:]. * `true`.
* *
* If the [Future] completes with [:true:] the request will be retried * If the [Future] completes with `true` the request will be retried
* using the updated credentials, however, the retried request will not * using the updated credentials, however, the retried request will not
* carry the original request payload. Otherwise response processing will * carry the original request payload. Otherwise response processing will
* continue normally. * continue normally.
@ -1695,7 +1734,7 @@ abstract class HttpClient {
* of a failed request, or issues due to missing request payload on retried * of a failed request, or issues due to missing request payload on retried
* request. * request.
*/ */
set authenticate(Future<bool> f(Uri url, String scheme, String realm)); void set authenticate(Future<bool> f(Uri url, String scheme, String realm)?);
/** /**
* Add credentials to be used for authorizing HTTP requests. * Add credentials to be used for authorizing HTTP requests.
@ -1716,7 +1755,7 @@ abstract class HttpClient {
* *
* "PROXY host:port" * "PROXY host:port"
* *
* for using the proxy server [:host:] on port [:port:]. * for using the proxy server `host` on port `port`.
* *
* A configuration can contain several configuration elements * A configuration can contain several configuration elements
* separated by semicolons, e.g. * separated by semicolons, e.g.
@ -1727,7 +1766,7 @@ abstract class HttpClient {
* be used to implement proxy server resolving based on environment * be used to implement proxy server resolving based on environment
* variables. * variables.
*/ */
set findProxy(String f(Uri url)); void set findProxy(String f(Uri url)?);
/** /**
* Function for resolving the proxy server to be used for a HTTP * Function for resolving the proxy server to be used for a HTTP
@ -1781,8 +1820,8 @@ abstract class HttpClient {
* to set credentials for proxies which require authentication. * to set credentials for proxies which require authentication.
*/ */
static String findProxyFromEnvironment(Uri url, static String findProxyFromEnvironment(Uri url,
{Map<String, String> environment}) { {Map<String, String>? environment}) {
HttpOverrides overrides = HttpOverrides.current; HttpOverrides? overrides = HttpOverrides.current;
if (overrides == null) { if (overrides == null) {
return _HttpClient._findProxyFromEnvironment(url, environment); return _HttpClient._findProxyFromEnvironment(url, environment);
} }
@ -1797,17 +1836,17 @@ abstract class HttpClient {
* *
* The function returns a [Future] which should complete when the * The function returns a [Future] which should complete when the
* authentication has been resolved. If credentials cannot be * authentication has been resolved. If credentials cannot be
* provided the [Future] should complete with [:false:]. If * provided the [Future] should complete with `false`. If
* credentials are available the function should add these using * credentials are available the function should add these using
* [addProxyCredentials] before completing the [Future] with the value * [addProxyCredentials] before completing the [Future] with the value
* [:true:]. * `true`.
* *
* If the [Future] completes with [:true:] the request will be retried * If the [Future] completes with `true` the request will be retried
* using the updated credentials. Otherwise response processing will * using the updated credentials. Otherwise response processing will
* continue normally. * continue normally.
*/ */
set authenticateProxy( void set authenticateProxy(
Future<bool> f(String host, int port, String scheme, String realm)); Future<bool> f(String host, int port, String scheme, String realm)?);
/** /**
* Add credentials to be used for authorizing HTTP proxies. * Add credentials to be used for authorizing HTTP proxies.
@ -1824,8 +1863,8 @@ abstract class HttpClient {
* server returns a server certificate that cannot be authenticated, the * server returns a server certificate that cannot be authenticated, the
* callback is called asynchronously with the [X509Certificate] object and * callback is called asynchronously with the [X509Certificate] object and
* the server's hostname and port. If the value of [badCertificateCallback] * the server's hostname and port. If the value of [badCertificateCallback]
* is [:null:], the bad certificate is rejected, as if the callback * is `null`, the bad certificate is rejected, as if the callback
* returned [:false:] * returned `false`
* *
* If the callback returns true, the secure connection is accepted and the * If the callback returns true, the secure connection is accepted and the
* [:Future<HttpClientRequest>:] that was returned from the call making the * [:Future<HttpClientRequest>:] that was returned from the call making the
@ -1837,8 +1876,8 @@ abstract class HttpClient {
* the request is made, even if the value of badCertificateCallback * the request is made, even if the value of badCertificateCallback
* has changed since then. * has changed since then.
*/ */
set badCertificateCallback( void set badCertificateCallback(
bool callback(X509Certificate cert, String host, int port)); bool callback(X509Certificate cert, String host, int port)?);
/// Shuts down the HTTP client. /// Shuts down the HTTP client.
/// ///
@ -1848,7 +1887,7 @@ abstract class HttpClient {
/// closed connections will receive an error event to indicate that the client /// closed connections will receive an error event to indicate that the client
/// was shut down. In both cases trying to establish a new connection after /// was shut down. In both cases trying to establish a new connection after
/// calling [close] will throw an exception. /// calling [close] will throw an exception.
void close({bool force: false}); void close({bool force = false});
} }
/** /**
@ -1883,23 +1922,25 @@ abstract class HttpClient {
*/ */
abstract class HttpClientRequest implements IOSink { abstract class HttpClientRequest implements IOSink {
/** /**
* Gets and sets the requested persistent connection state. * The requested persistent connection state.
* *
* The default value is [:true:]. * The default value is `true`.
*/ */
bool persistentConnection; bool persistentConnection = true;
/** /**
* Set this property to [:true:] if this request should * Whether to follow redirects automatically.
* automatically follow redirects. The default is [:true:]. *
* Set this property to `false` if this request should not
* automatically follow redirects. The default is `true`.
* *
* Automatic redirect will only happen for "GET" and "HEAD" requests * Automatic redirect will only happen for "GET" and "HEAD" requests
* and only for the status codes [:HttpStatus.movedPermanently:] * and only for the status codes [HttpStatus.movedPermanently]
* (301), [:HttpStatus.found:] (302), * (301), [HttpStatus.found] (302),
* [:HttpStatus.movedTemporarily:] (302, alias for * [HttpStatus.movedTemporarily] (302, alias for
* [:HttpStatus.found:]), [:HttpStatus.seeOther:] (303) and * [HttpStatus.found]), [HttpStatus.seeOther] (303) and
* [:HttpStatus.temporaryRedirect:] (307). For * [HttpStatus.temporaryRedirect] (307). For
* [:HttpStatus.seeOther:] (303) automatic redirect will also happen * [HttpStatus.seeOther] (303) automatic redirect will also happen
* for "POST" requests with the method changed to "GET" when * for "POST" requests with the method changed to "GET" when
* following the redirect. * following the redirect.
* *
@ -1907,7 +1948,7 @@ abstract class HttpClientRequest implements IOSink {
* request(s). However, any body send with the request will not be * request(s). However, any body send with the request will not be
* part of the redirection request(s). * part of the redirection request(s).
*/ */
bool followRedirects; bool followRedirects = true;
/** /**
* Set this property to the maximum number of redirects to follow * Set this property to the maximum number of redirects to follow
@ -1916,7 +1957,7 @@ abstract class HttpClientRequest implements IOSink {
* *
* The default value is 5. * The default value is 5.
*/ */
int maxRedirects; int maxRedirects = 5;
/** /**
* The method of the request. * The method of the request.
@ -1932,7 +1973,7 @@ abstract class HttpClientRequest implements IOSink {
/// ///
/// If the size of the request is not known in advance set content length to /// If the size of the request is not known in advance set content length to
/// -1, which is also the default. /// -1, which is also the default.
int contentLength; int contentLength = -1;
/** /**
* Gets or sets if the [HttpClientRequest] should buffer output. * Gets or sets if the [HttpClientRequest] should buffer output.
@ -1942,7 +1983,7 @@ abstract class HttpClientRequest implements IOSink {
* __Note__: Disabling buffering of the output can result in very poor * __Note__: Disabling buffering of the output can result in very poor
* performance, when writing many small chunks. * performance, when writing many small chunks.
*/ */
bool bufferOutput; bool bufferOutput = true;
/** /**
* Returns the client request headers. * Returns the client request headers.
@ -1972,8 +2013,8 @@ abstract class HttpClientRequest implements IOSink {
/// Gets information about the client connection. /// Gets information about the client connection.
/// ///
/// Returns [:null:] if the socket is not available. /// Returns `null` if the socket is not available.
HttpConnectionInfo get connectionInfo; HttpConnectionInfo? get connectionInfo;
} }
/** /**
@ -2063,14 +2104,14 @@ abstract class HttpClientResponse implements Stream<List<int>> {
* request. However, any body sent with the request will not be * request. However, any body sent with the request will not be
* part of the redirection request. * part of the redirection request.
* *
* If [followLoops] is set to [:true:], redirect will follow the redirect, * If [followLoops] is set to `true`, redirect will follow the redirect,
* even if the URL was already visited. The default value is [:false:]. * even if the URL was already visited. The default value is `false`.
* *
* The method will ignore [HttpClientRequest.maxRedirects] * The method will ignore [HttpClientRequest.maxRedirects]
* and will always perform the redirect. * and will always perform the redirect.
*/ */
Future<HttpClientResponse> redirect( Future<HttpClientResponse> redirect(
[String method, Uri url, bool followLoops]); [String? method, Uri? url, bool? followLoops]);
/** /**
* Returns the client response headers. * Returns the client response headers.
@ -2098,13 +2139,13 @@ abstract class HttpClientResponse implements Stream<List<int>> {
* Returns the certificate of the HTTPS server providing the response. * Returns the certificate of the HTTPS server providing the response.
* Returns null if the connection is not a secure TLS or SSL connection. * Returns null if the connection is not a secure TLS or SSL connection.
*/ */
X509Certificate get certificate; X509Certificate? get certificate;
/** /**
* Gets information about the client connection. Returns [:null:] if the socket * Gets information about the client connection. Returns `null` if the socket
* is not available. * is not available.
*/ */
HttpConnectionInfo get connectionInfo; HttpConnectionInfo? get connectionInfo;
} }
/// Enum that specifies the compression state of the byte stream of an /// Enum that specifies the compression state of the byte stream of an
@ -2215,12 +2256,13 @@ abstract class DetachedSocket {
class HttpException implements IOException { class HttpException implements IOException {
final String message; final String message;
final Uri uri; final Uri? uri;
const HttpException(this.message, {this.uri}); const HttpException(this.message, {this.uri});
String toString() { String toString() {
var b = new StringBuffer()..write('HttpException: ')..write(message); var b = new StringBuffer()..write('HttpException: ')..write(message);
var uri = this.uri;
if (uri != null) { if (uri != null) {
b.write(', uri = $uri'); b.write(', uri = $uri');
} }

View file

@ -2,8 +2,6 @@
// for details. All rights reserved. Use of this source code is governed by a // for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file. // BSD-style license that can be found in the LICENSE file.
// @dart = 2.6
part of dart._http; part of dart._http;
/** /**
@ -123,7 +121,6 @@ class HttpDate {
int index = 0; int index = 0;
String tmp; String tmp;
int format;
void expect(String s) { void expect(String s) {
if (date.length - index < s.length) { if (date.length - index < s.length) {
@ -147,21 +144,18 @@ class HttpDate {
index = pos + 1; index = pos + 1;
weekday = wkdays.indexOf(tmp); weekday = wkdays.indexOf(tmp);
if (weekday != -1) { if (weekday != -1) {
format = formatAsctime; return formatAsctime;
return weekday;
} }
} else { } else {
tmp = date.substring(index, pos); tmp = date.substring(index, pos);
index = pos + 1; index = pos + 1;
weekday = wkdays.indexOf(tmp); weekday = wkdays.indexOf(tmp);
if (weekday != -1) { if (weekday != -1) {
format = formatRfc1123; return formatRfc1123;
return weekday;
} }
weekday = weekdays.indexOf(tmp); weekday = weekdays.indexOf(tmp);
if (weekday != -1) { if (weekday != -1) {
format = formatRfc850; return formatRfc850;
return weekday;
} }
} }
throw new HttpException("Invalid HTTP date $date"); throw new HttpException("Invalid HTTP date $date");
@ -200,10 +194,10 @@ class HttpDate {
} }
} }
int weekday = expectWeekday(); int format = expectWeekday();
int day;
int month;
int year; int year;
int month;
int day;
int hours; int hours;
int minutes; int minutes;
int seconds; int seconds;
@ -248,7 +242,7 @@ class HttpDate {
int position = 0; int position = 0;
void error() { Never error() {
throw new HttpException("Invalid cookie date $date"); throw new HttpException("Invalid cookie date $date");
} }
@ -302,10 +296,10 @@ class HttpDate {
while (!isEnd() && isDelimiter(date[position])) position++; while (!isEnd() && isDelimiter(date[position])) position++;
} }
String timeStr; String? timeStr;
String dayOfMonthStr; String? dayOfMonthStr;
String monthStr; String? monthStr;
String yearStr; String? yearStr;
for (var token in tokens) { for (var token in tokens) {
if (token.length < 1) continue; if (token.length < 1) continue;

View file

@ -2,30 +2,28 @@
// for details. All rights reserved. Use of this source code is governed by a // for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file. // BSD-style license that can be found in the LICENSE file.
// @dart = 2.6
part of dart._http; part of dart._http;
class _HttpHeaders implements HttpHeaders { class _HttpHeaders implements HttpHeaders {
final Map<String, List<String>> _headers; final Map<String, List<String>> _headers;
// The original header names keyed by the lowercase header names. // The original header names keyed by the lowercase header names.
Map<String, String> _originalHeaderNames; Map<String, String>? _originalHeaderNames;
final String protocolVersion; final String protocolVersion;
bool _mutable = true; // Are the headers currently mutable? bool _mutable = true; // Are the headers currently mutable?
List<String> _noFoldingHeaders; List<String>? _noFoldingHeaders;
int _contentLength = -1; int _contentLength = -1;
bool _persistentConnection = true; bool _persistentConnection = true;
bool _chunkedTransferEncoding = false; bool _chunkedTransferEncoding = false;
String _host; String? _host;
int _port; int? _port;
final int _defaultPortForScheme; final int _defaultPortForScheme;
_HttpHeaders(this.protocolVersion, _HttpHeaders(this.protocolVersion,
{int defaultPortForScheme: HttpClient.defaultHttpPort, {int defaultPortForScheme = HttpClient.defaultHttpPort,
_HttpHeaders initialHeaders}) _HttpHeaders? initialHeaders})
: _headers = new HashMap<String, List<String>>(), : _headers = new HashMap<String, List<String>>(),
_defaultPortForScheme = defaultPortForScheme { _defaultPortForScheme = defaultPortForScheme {
if (initialHeaders != null) { if (initialHeaders != null) {
@ -42,12 +40,13 @@ class _HttpHeaders implements HttpHeaders {
} }
} }
List<String> operator [](String name) => _headers[_validateField(name)]; List<String>? operator [](String name) => _headers[_validateField(name)];
String value(String name) { String? value(String name) {
name = _validateField(name); name = _validateField(name);
List<String> values = _headers[name]; List<String>? values = _headers[name];
if (values == null) return null; if (values == null) return null;
assert(values.isNotEmpty);
if (values.length > 1) { if (values.length > 1) {
throw new HttpException("More than one value for header $name"); throw new HttpException("More than one value for header $name");
} }
@ -86,8 +85,6 @@ class _HttpHeaders implements HttpHeaders {
} }
if (preserveHeaderCase && name != lowercaseName) { if (preserveHeaderCase && name != lowercaseName) {
(_originalHeaderNames ??= {})[lowercaseName] = name; (_originalHeaderNames ??= {})[lowercaseName] = name;
} else {
_originalHeaderNames?.remove(lowercaseName);
} }
_addAll(lowercaseName, value); _addAll(lowercaseName, value);
} }
@ -96,12 +93,9 @@ class _HttpHeaders implements HttpHeaders {
_checkMutable(); _checkMutable();
name = _validateField(name); name = _validateField(name);
value = _validateValue(value); value = _validateValue(value);
List<String> values = _headers[name]; List<String>? values = _headers[name];
if (values != null) { if (values != null) {
int index = values.indexOf(value); values.remove(_valueToString(value));
if (index != -1) {
values.removeRange(index, index + 1);
}
if (values.length == 0) { if (values.length == 0) {
_headers.remove(name); _headers.remove(name);
_originalHeaderNames?.remove(name); _originalHeaderNames?.remove(name);
@ -128,8 +122,7 @@ class _HttpHeaders implements HttpHeaders {
void noFolding(String name) { void noFolding(String name) {
name = _validateField(name); name = _validateField(name);
if (_noFoldingHeaders == null) _noFoldingHeaders = new List<String>(); (_noFoldingHeaders ??= <String>[]).add(name);
_noFoldingHeaders.add(name);
} }
bool get persistentConnection => _persistentConnection; bool get persistentConnection => _persistentConnection;
@ -142,7 +135,7 @@ class _HttpHeaders implements HttpHeaders {
if (protocolVersion == "1.1") { if (protocolVersion == "1.1") {
remove(HttpHeaders.connectionHeader, "close"); remove(HttpHeaders.connectionHeader, "close");
} else { } else {
if (_contentLength == -1) { if (_contentLength < 0) {
throw new HttpException( throw new HttpException(
"Trying to set 'Connection: Keep-Alive' on HTTP 1.0 headers with " "Trying to set 'Connection: Keep-Alive' on HTTP 1.0 headers with "
"no ContentLength"); "no ContentLength");
@ -176,7 +169,7 @@ class _HttpHeaders implements HttpHeaders {
if (chunkedTransferEncoding) chunkedTransferEncoding = false; if (chunkedTransferEncoding) chunkedTransferEncoding = false;
_set(HttpHeaders.contentLengthHeader, contentLength.toString()); _set(HttpHeaders.contentLengthHeader, contentLength.toString());
} else { } else {
removeAll(HttpHeaders.contentLengthHeader); _headers.remove(HttpHeaders.contentLengthHeader);
if (protocolVersion == "1.1") { if (protocolVersion == "1.1") {
chunkedTransferEncoding = true; chunkedTransferEncoding = true;
} }
@ -193,8 +186,8 @@ class _HttpHeaders implements HttpHeaders {
} }
if (chunkedTransferEncoding == _chunkedTransferEncoding) return; if (chunkedTransferEncoding == _chunkedTransferEncoding) return;
if (chunkedTransferEncoding) { if (chunkedTransferEncoding) {
List<String> values = _headers[HttpHeaders.transferEncodingHeader]; List<String>? values = _headers[HttpHeaders.transferEncodingHeader];
if ((values == null || !values.contains("chunked"))) { if (values == null || !values.contains("chunked")) {
// Headers does not specify chunked encoding - add it if set. // Headers does not specify chunked encoding - add it if set.
_addValue(HttpHeaders.transferEncodingHeader, "chunked"); _addValue(HttpHeaders.transferEncodingHeader, "chunked");
} }
@ -206,25 +199,26 @@ class _HttpHeaders implements HttpHeaders {
_chunkedTransferEncoding = chunkedTransferEncoding; _chunkedTransferEncoding = chunkedTransferEncoding;
} }
String get host => _host; String? get host => _host;
void set host(String host) { void set host(String? host) {
_checkMutable(); _checkMutable();
_host = host; _host = host;
_updateHostHeader(); _updateHostHeader();
} }
int get port => _port; int? get port => _port;
void set port(int port) { void set port(int? port) {
_checkMutable(); _checkMutable();
_port = port; _port = port;
_updateHostHeader(); _updateHostHeader();
} }
DateTime get ifModifiedSince { DateTime? get ifModifiedSince {
List<String> values = _headers[HttpHeaders.ifModifiedSinceHeader]; List<String>? values = _headers[HttpHeaders.ifModifiedSinceHeader];
if (values != null) { if (values != null) {
assert(values.isNotEmpty);
try { try {
return HttpDate.parse(values[0]); return HttpDate.parse(values[0]);
} on Exception { } on Exception {
@ -234,16 +228,21 @@ class _HttpHeaders implements HttpHeaders {
return null; return null;
} }
void set ifModifiedSince(DateTime ifModifiedSince) { void set ifModifiedSince(DateTime? ifModifiedSince) {
_checkMutable(); _checkMutable();
// Format "ifModifiedSince" header with date in Greenwich Mean Time (GMT). if (ifModifiedSince == null) {
String formatted = HttpDate.format(ifModifiedSince.toUtc()); _headers.remove(HttpHeaders.ifModifiedSinceHeader);
_set(HttpHeaders.ifModifiedSinceHeader, formatted); } else {
// Format "ifModifiedSince" header with date in Greenwich Mean Time (GMT).
String formatted = HttpDate.format(ifModifiedSince.toUtc());
_set(HttpHeaders.ifModifiedSinceHeader, formatted);
}
} }
DateTime get date { DateTime? get date {
List<String> values = _headers[HttpHeaders.dateHeader]; List<String>? values = _headers[HttpHeaders.dateHeader];
if (values != null) { if (values != null) {
assert(values.isNotEmpty);
try { try {
return HttpDate.parse(values[0]); return HttpDate.parse(values[0]);
} on Exception { } on Exception {
@ -253,16 +252,21 @@ class _HttpHeaders implements HttpHeaders {
return null; return null;
} }
void set date(DateTime date) { void set date(DateTime? date) {
_checkMutable(); _checkMutable();
// Format "DateTime" header with date in Greenwich Mean Time (GMT). if (date == null) {
String formatted = HttpDate.format(date.toUtc()); _headers.remove(HttpHeaders.dateHeader);
_set("date", formatted); } else {
// Format "DateTime" header with date in Greenwich Mean Time (GMT).
String formatted = HttpDate.format(date.toUtc());
_set(HttpHeaders.dateHeader, formatted);
}
} }
DateTime get expires { DateTime? get expires {
List<String> values = _headers[HttpHeaders.expiresHeader]; List<String>? values = _headers[HttpHeaders.expiresHeader];
if (values != null) { if (values != null) {
assert(values.isNotEmpty);
try { try {
return HttpDate.parse(values[0]); return HttpDate.parse(values[0]);
} on Exception { } on Exception {
@ -272,14 +276,18 @@ class _HttpHeaders implements HttpHeaders {
return null; return null;
} }
void set expires(DateTime expires) { void set expires(DateTime? expires) {
_checkMutable(); _checkMutable();
// Format "Expires" header with date in Greenwich Mean Time (GMT). if (expires == null) {
String formatted = HttpDate.format(expires.toUtc()); _headers.remove(HttpHeaders.expiresHeader);
_set(HttpHeaders.expiresHeader, formatted); } else {
// Format "Expires" header with date in Greenwich Mean Time (GMT).
String formatted = HttpDate.format(expires.toUtc());
_set(HttpHeaders.expiresHeader, formatted);
}
} }
ContentType get contentType { ContentType? get contentType {
var values = _headers[HttpHeaders.contentTypeHeader]; var values = _headers[HttpHeaders.contentTypeHeader];
if (values != null) { if (values != null) {
return ContentType.parse(values[0]); return ContentType.parse(values[0]);
@ -288,9 +296,13 @@ class _HttpHeaders implements HttpHeaders {
} }
} }
void set contentType(ContentType contentType) { void set contentType(ContentType? contentType) {
_checkMutable(); _checkMutable();
_set(HttpHeaders.contentTypeHeader, contentType.toString()); if (contentType == null) {
_headers.remove(HttpHeaders.contentTypeHeader);
} else {
_set(HttpHeaders.contentTypeHeader, contentType.toString());
}
} }
void clear() { void clear() {
@ -447,42 +459,41 @@ class _HttpHeaders implements HttpHeaders {
} }
void _addValue(String name, Object value) { void _addValue(String name, Object value) {
List<String> values = _headers[name]; List<String> values = (_headers[name] ??= <String>[]);
if (values == null) { values.add(_valueToString(value));
values = new List<String>(); }
_headers[name] = values;
} String _valueToString(Object value) {
if (value is DateTime) { if (value is DateTime) {
values.add(HttpDate.format(value)); return HttpDate.format(value);
} else if (value is String) { } else if (value is String) {
values.add(value); return value; // TODO(39784): no _validateValue?
} else { } else {
values.add(_validateValue(value.toString())); return _validateValue(value.toString()) as String;
} }
} }
void _set(String name, String value) { void _set(String name, String value) {
assert(name == _validateField(name)); assert(name == _validateField(name));
List<String> values = new List<String>(); _headers[name] = <String>[value];
_headers[name] = values;
values.add(value);
} }
_checkMutable() { void _checkMutable() {
if (!_mutable) throw new HttpException("HTTP headers are not mutable"); if (!_mutable) throw new HttpException("HTTP headers are not mutable");
} }
_updateHostHeader() { void _updateHostHeader() {
bool defaultPort = _port == null || _port == _defaultPortForScheme; var host = _host;
_set("host", defaultPort ? host : "$host:$_port"); if (host != null) {
bool defaultPort = _port == null || _port == _defaultPortForScheme;
_set("host", defaultPort ? host : "$host:$_port");
}
} }
_foldHeader(String name) { bool _foldHeader(String name) {
if (name == HttpHeaders.setCookieHeader || if (name == HttpHeaders.setCookieHeader) return false;
(_noFoldingHeaders != null && _noFoldingHeaders.indexOf(name) != -1)) { var noFoldingHeaders = _noFoldingHeaders;
return false; return noFoldingHeaders == null || !noFoldingHeaders.contains(name);
}
return true;
} }
void _finalize() { void _finalize() {
@ -540,7 +551,7 @@ class _HttpHeaders implements HttpHeaders {
List<Cookie> _parseCookies() { List<Cookie> _parseCookies() {
// Parse a Cookie header value according to the rules in RFC 6265. // Parse a Cookie header value according to the rules in RFC 6265.
var cookies = new List<Cookie>(); var cookies = <Cookie>[];
void parseCookieString(String s) { void parseCookieString(String s) {
int index = 0; int index = 0;
@ -603,7 +614,7 @@ class _HttpHeaders implements HttpHeaders {
} }
} }
List<String> values = _headers[HttpHeaders.cookieHeader]; List<String>? values = _headers[HttpHeaders.cookieHeader];
if (values != null) { if (values != null) {
values.forEach((headerValue) => parseCookieString(headerValue)); values.forEach((headerValue) => parseCookieString(headerValue));
} }
@ -632,26 +643,28 @@ class _HttpHeaders implements HttpHeaders {
} }
String _originalHeaderName(String name) { String _originalHeaderName(String name) {
return (_originalHeaderNames == null ? null : _originalHeaderNames[name]) ?? // TODO: Update syntax to_originalHeaderNames?[name].
name; return _originalHeaderNames?.[name] ?? name;
} }
} }
class _HeaderValue implements HeaderValue { class _HeaderValue implements HeaderValue {
String _value; String _value;
Map<String, String> _parameters; Map<String, String?>? _parameters;
Map<String, String> _unmodifiableParameters; Map<String, String?>? _unmodifiableParameters;
_HeaderValue([this._value = "", Map<String, String> parameters = const {}]) { _HeaderValue([this._value = "", Map<String, String?> parameters = const {}]) {
if (parameters != null && parameters.isNotEmpty) { // TODO(40614): Remove once non-nullability is sound.
_parameters = new HashMap<String, String>.from(parameters); Map<String, String?>? nullableParameters = parameters;
if (nullableParameters != null && nullableParameters.isNotEmpty) {
_parameters = new HashMap<String, String?>.from(nullableParameters);
} }
} }
static _HeaderValue parse(String value, static _HeaderValue parse(String value,
{parameterSeparator: ";", {String parameterSeparator = ";",
valueSeparator: null, String? valueSeparator,
preserveBackslash: false}) { bool preserveBackslash = false}) {
// Parse the string. // Parse the string.
var result = new _HeaderValue(); var result = new _HeaderValue();
result._parse(value, parameterSeparator, valueSeparator, preserveBackslash); result._parse(value, parameterSeparator, valueSeparator, preserveBackslash);
@ -660,9 +673,10 @@ class _HeaderValue implements HeaderValue {
String get value => _value; String get value => _value;
Map<String, String> _ensureParameters() => _parameters ??= <String, String>{}; Map<String, String?> _ensureParameters() =>
_parameters ??= <String, String?>{};
Map<String, String> get parameters => Map<String, String?> get parameters =>
_unmodifiableParameters ??= UnmodifiableMapView(_ensureParameters()); _unmodifiableParameters ??= UnmodifiableMapView(_ensureParameters());
static bool _isToken(String token) { static bool _isToken(String token) {
@ -684,8 +698,9 @@ class _HeaderValue implements HeaderValue {
String toString() { String toString() {
StringBuffer sb = new StringBuffer(); StringBuffer sb = new StringBuffer();
sb.write(_value); sb.write(_value);
var parameters = this._parameters;
if (parameters != null && parameters.length > 0) { if (parameters != null && parameters.length > 0) {
_parameters.forEach((String name, String value) { parameters.forEach((String name, String? value) {
sb..write("; ")..write(name); sb..write("; ")..write(name);
if (value != null) { if (value != null) {
sb.write("="); sb.write("=");
@ -712,7 +727,7 @@ class _HeaderValue implements HeaderValue {
return sb.toString(); return sb.toString();
} }
void _parse(String s, String parameterSeparator, String valueSeparator, void _parse(String s, String parameterSeparator, String? valueSeparator,
bool preserveBackslash) { bool preserveBackslash) {
int index = 0; int index = 0;
@ -728,10 +743,11 @@ class _HeaderValue implements HeaderValue {
String parseValue() { String parseValue() {
int start = index; int start = index;
while (!done()) { while (!done()) {
if (s[index] == " " || var char = s[index];
s[index] == "\t" || if (char == " " ||
s[index] == valueSeparator || char == "\t" ||
s[index] == parameterSeparator) break; char == valueSeparator ||
char == parameterSeparator) break;
index++; index++;
} }
return s.substring(start, index); return s.substring(start, index);
@ -753,17 +769,17 @@ class _HeaderValue implements HeaderValue {
} }
void parseParameters() { void parseParameters() {
var parameters = new HashMap<String, String>(); var parameters = _ensureParameters();
_parameters = new UnmodifiableMapView(parameters);
String parseParameterName() { String parseParameterName() {
int start = index; int start = index;
while (!done()) { while (!done()) {
if (s[index] == " " || var char = s[index];
s[index] == "\t" || if (char == " " ||
s[index] == "=" || char == "\t" ||
s[index] == parameterSeparator || char == "=" ||
s[index] == valueSeparator) break; char == parameterSeparator ||
char == valueSeparator) break;
index++; index++;
} }
return s.substring(start, index).toLowerCase(); return s.substring(start, index).toLowerCase();
@ -775,19 +791,21 @@ class _HeaderValue implements HeaderValue {
StringBuffer sb = new StringBuffer(); StringBuffer sb = new StringBuffer();
index++; index++;
while (!done()) { while (!done()) {
if (s[index] == "\\") { var char = s[index];
if (char == "\\") {
if (index + 1 == s.length) { if (index + 1 == s.length) {
throw new HttpException("Failed to parse header value"); throw new HttpException("Failed to parse header value");
} }
if (preserveBackslash && s[index + 1] != "\"") { if (preserveBackslash && s[index + 1] != "\"") {
sb.write(s[index]); sb.write(char);
} }
index++; index++;
} else if (s[index] == "\"") { } else if (char == "\"") {
index++; index++;
return sb.toString(); return sb.toString();
} }
sb.write(s[index]); char = s[index];
sb.write(char);
index++; index++;
} }
throw new HttpException("Failed to parse header value"); throw new HttpException("Failed to parse header value");
@ -835,27 +853,30 @@ class _ContentType extends _HeaderValue implements ContentType {
String _primaryType = ""; String _primaryType = "";
String _subType = ""; String _subType = "";
_ContentType(String primaryType, String subType, String charset, _ContentType(String primaryType, String subType, String? charset,
Map<String, String> parameters) Map<String, String?> parameters)
: _primaryType = primaryType, : _primaryType = primaryType,
_subType = subType, _subType = subType,
super("") { super("") {
if (_primaryType == null) _primaryType = ""; // TODO(40614): Remove once non-nullability is sound.
if (_subType == null) _subType = ""; String emptyIfNull(String? string) => string ?? "";
_primaryType = emptyIfNull(_primaryType);
_subType = emptyIfNull(_subType);
_value = "$_primaryType/$_subType"; _value = "$_primaryType/$_subType";
if (parameters != null) { // TODO(40614): Remove once non-nullability is sound.
_ensureParameters(); Map<String, String?>? nullableParameters = parameters;
parameters.forEach((String key, String value) { if (nullableParameters != null) {
var parameterMap = _ensureParameters();
nullableParameters.forEach((String key, String? value) {
String lowerCaseKey = key.toLowerCase(); String lowerCaseKey = key.toLowerCase();
if (lowerCaseKey == "charset") { if (lowerCaseKey == "charset") {
value = value?.toLowerCase(); value = value?.toLowerCase();
} }
this._parameters[lowerCaseKey] = value; parameterMap[lowerCaseKey] = value;
}); });
} }
if (charset != null) { if (charset != null) {
_ensureParameters(); _ensureParameters()["charset"] = charset.toLowerCase();
this._parameters["charset"] = charset.toLowerCase();
} }
} }
@ -867,7 +888,6 @@ class _ContentType extends _HeaderValue implements ContentType {
int index = result._value.indexOf("/"); int index = result._value.indexOf("/");
if (index == -1 || index == (result._value.length - 1)) { if (index == -1 || index == (result._value.length - 1)) {
result._primaryType = result._value.trim().toLowerCase(); result._primaryType = result._value.trim().toLowerCase();
result._subType = "";
} else { } else {
result._primaryType = result._primaryType =
result._value.substring(0, index).trim().toLowerCase(); result._value.substring(0, index).trim().toLowerCase();
@ -882,16 +902,16 @@ class _ContentType extends _HeaderValue implements ContentType {
String get subType => _subType; String get subType => _subType;
String get charset => parameters["charset"]; String? get charset => parameters["charset"];
} }
class _Cookie implements Cookie { class _Cookie implements Cookie {
String _name; String _name;
String _value; String _value;
DateTime expires; DateTime? expires;
int maxAge; int? maxAge;
String domain; String? domain;
String path; String? path;
bool httpOnly = false; bool httpOnly = false;
bool secure = false; bool secure = false;
@ -913,7 +933,9 @@ class _Cookie implements Cookie {
_value = newValue; _value = newValue;
} }
_Cookie.fromSetCookieValue(String value) { _Cookie.fromSetCookieValue(String value)
: _name = "",
_value = "" {
// Parse the 'set-cookie' header value. // Parse the 'set-cookie' header value.
_parseSetCookieValue(value); _parseSetCookieValue(value);
} }
@ -999,6 +1021,7 @@ class _Cookie implements Cookie {
String toString() { String toString() {
StringBuffer sb = new StringBuffer(); StringBuffer sb = new StringBuffer();
sb..write(_name)..write("=")..write(_value); sb..write(_name)..write("=")..write(_value);
var expires = this.expires;
if (expires != null) { if (expires != null) {
sb..write("; Expires=")..write(HttpDate.format(expires)); sb..write("; Expires=")..write(HttpDate.format(expires));
} }
@ -1038,7 +1061,7 @@ class _Cookie implements Cookie {
]; ];
if (newName == null) throw new ArgumentError.notNull("name"); if (newName == null) throw new ArgumentError.notNull("name");
for (int i = 0; i < newName.length; i++) { for (int i = 0; i < newName.length; i++) {
int codeUnit = newName.codeUnits[i]; int codeUnit = newName.codeUnitAt(i);
if (codeUnit <= 32 || if (codeUnit <= 32 ||
codeUnit >= 127 || codeUnit >= 127 ||
separators.indexOf(newName[i]) >= 0) { separators.indexOf(newName[i]) >= 0) {

File diff suppressed because it is too large Load diff

View file

@ -2,8 +2,6 @@
// for details. All rights reserved. Use of this source code is governed by a // for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file. // BSD-style license that can be found in the LICENSE file.
// @dart = 2.6
part of dart._http; part of dart._http;
// Global constants. // Global constants.
@ -112,19 +110,19 @@ class _MessageType {
*/ */
class _HttpDetachedStreamSubscription implements StreamSubscription<Uint8List> { class _HttpDetachedStreamSubscription implements StreamSubscription<Uint8List> {
StreamSubscription<Uint8List> _subscription; StreamSubscription<Uint8List> _subscription;
Uint8List _injectData; Uint8List? _injectData;
Function? _userOnData;
bool _isCanceled = false; bool _isCanceled = false;
int _pauseCount = 1;
Function _userOnData;
bool _scheduled = false; bool _scheduled = false;
int _pauseCount = 1;
_HttpDetachedStreamSubscription( _HttpDetachedStreamSubscription(
this._subscription, this._injectData, this._userOnData); this._subscription, this._injectData, this._userOnData);
bool get isPaused => _subscription.isPaused; bool get isPaused => _subscription.isPaused;
Future<T> asFuture<T>([T futureValue]) => Future<T> asFuture<T>([T? futureValue]) =>
_subscription.asFuture<T>(futureValue); _subscription.asFuture<T>(futureValue as T);
Future cancel() { Future cancel() {
_isCanceled = true; _isCanceled = true;
@ -132,20 +130,20 @@ class _HttpDetachedStreamSubscription implements StreamSubscription<Uint8List> {
return _subscription.cancel(); return _subscription.cancel();
} }
void onData(void handleData(Uint8List data)) { void onData(void handleData(Uint8List data)?) {
_userOnData = handleData; _userOnData = handleData;
_subscription.onData(handleData); _subscription.onData(handleData);
} }
void onDone(void handleDone()) { void onDone(void handleDone()?) {
_subscription.onDone(handleDone); _subscription.onDone(handleDone);
} }
void onError(Function handleError) { void onError(Function? handleError) {
_subscription.onError(handleError); _subscription.onError(handleError);
} }
void pause([Future resumeSignal]) { void pause([Future? resumeSignal]) {
if (_injectData == null) { if (_injectData == null) {
_subscription.pause(resumeSignal); _subscription.pause(resumeSignal);
} else { } else {
@ -177,21 +175,20 @@ class _HttpDetachedStreamSubscription implements StreamSubscription<Uint8List> {
// To ensure that 'subscription.isPaused' is false, we resume the // To ensure that 'subscription.isPaused' is false, we resume the
// subscription here. This is fine as potential events are delayed. // subscription here. This is fine as potential events are delayed.
_subscription.resume(); _subscription.resume();
if (_userOnData != null) { _userOnData?.call(data);
_userOnData(data);
}
}); });
} }
} }
class _HttpDetachedIncoming extends Stream<Uint8List> { class _HttpDetachedIncoming extends Stream<Uint8List> {
final StreamSubscription<Uint8List> subscription; final StreamSubscription<Uint8List>? subscription;
final Uint8List bufferedData; final Uint8List? bufferedData;
_HttpDetachedIncoming(this.subscription, this.bufferedData); _HttpDetachedIncoming(this.subscription, this.bufferedData);
StreamSubscription<Uint8List> listen(void onData(Uint8List event), StreamSubscription<Uint8List> listen(void onData(Uint8List event)?,
{Function onError, void onDone(), bool cancelOnError}) { {Function? onError, void onDone()?, bool? cancelOnError}) {
var subscription = this.subscription;
if (subscription != null) { if (subscription != null) {
subscription subscription
..onData(onData) ..onData(onData)
@ -205,7 +202,7 @@ class _HttpDetachedIncoming extends Stream<Uint8List> {
..resume(); ..resume();
} else { } else {
// TODO(26379): add test for this branch. // TODO(26379): add test for this branch.
return new Stream<Uint8List>.fromIterable([bufferedData]).listen(onData, return new Stream<Uint8List>.fromIterable([bufferedData!]).listen(onData,
onError: onError, onDone: onDone, cancelOnError: cancelOnError); onError: onError, onDone: onDone, cancelOnError: cancelOnError);
} }
} }
@ -236,13 +233,13 @@ class _HttpParser extends Stream<_HttpIncoming> {
bool _parserCalled = false; bool _parserCalled = false;
// The data that is currently being parsed. // The data that is currently being parsed.
Uint8List _buffer; Uint8List? _buffer;
int _index; int _index = -1;
final bool _requestParser; final bool _requestParser;
int _state; int _state = _State.START;
int _httpVersionIndex; int? _httpVersionIndex;
int _messageType; int _messageType = _MessageType.UNDETERMINED;
int _statusCode = 0; int _statusCode = 0;
int _statusCodeLength = 0; int _statusCodeLength = 0;
final List<int> _method = []; final List<int> _method = [];
@ -252,11 +249,11 @@ class _HttpParser extends Stream<_HttpIncoming> {
// The limit for method, uriOrReasonPhrase, header field and value // The limit for method, uriOrReasonPhrase, header field and value
int _headerSizeLimit = 8 * 1024; int _headerSizeLimit = 8 * 1024;
int _httpVersion; int _httpVersion = _HttpVersion.UNDETERMINED;
int _transferLength = -1; int _transferLength = -1;
bool _persistentConnection; bool _persistentConnection = false;
bool _connectionUpgrade; bool _connectionUpgrade = false;
bool _chunked; bool _chunked = false;
bool _noMessageBody = false; bool _noMessageBody = false;
int _remainingContent = -1; int _remainingContent = -1;
@ -264,18 +261,18 @@ class _HttpParser extends Stream<_HttpIncoming> {
bool _transferEncoding = false; bool _transferEncoding = false;
bool connectMethod = false; bool connectMethod = false;
_HttpHeaders _headers; _HttpHeaders? _headers;
// The limit for parsing chunk size // The limit for parsing chunk size
int _chunkSizeLimit = 0x7FFFFFFF; int _chunkSizeLimit = 0x7FFFFFFF;
// The current incoming connection. // The current incoming connection.
_HttpIncoming _incoming; _HttpIncoming? _incoming;
StreamSubscription<Uint8List> _socketSubscription; StreamSubscription<Uint8List>? _socketSubscription;
bool _paused = true; bool _paused = true;
bool _bodyPaused = false; bool _bodyPaused = false;
StreamController<_HttpIncoming> _controller; final StreamController<_HttpIncoming> _controller;
StreamController<Uint8List> _bodyController; StreamController<Uint8List>? _bodyController;
factory _HttpParser.requestParser() { factory _HttpParser.requestParser() {
return new _HttpParser._(true); return new _HttpParser._(true);
@ -285,30 +282,28 @@ class _HttpParser extends Stream<_HttpIncoming> {
return new _HttpParser._(false); return new _HttpParser._(false);
} }
_HttpParser._(this._requestParser) { _HttpParser._(this._requestParser)
_controller = new StreamController<_HttpIncoming>( : _controller = new StreamController<_HttpIncoming>(sync: true) {
sync: true, _controller
onListen: () { ..onListen = () {
_paused = false; _paused = false;
}, }
onPause: () { ..onPause = () {
_paused = true; _paused = true;
_pauseStateChanged(); _pauseStateChanged();
}, }
onResume: () { ..onResume = () {
_paused = false; _paused = false;
_pauseStateChanged(); _pauseStateChanged();
}, }
onCancel: () { ..onCancel = () {
if (_socketSubscription != null) { _socketSubscription?.cancel();
_socketSubscription.cancel(); };
}
});
_reset(); _reset();
} }
StreamSubscription<_HttpIncoming> listen(void onData(_HttpIncoming event), StreamSubscription<_HttpIncoming> listen(void onData(_HttpIncoming event)?,
{Function onError, void onDone(), bool cancelOnError}) { {Function? onError, void onDone()?, bool? cancelOnError}) {
return _controller.stream.listen(onData, return _controller.stream.listen(onData,
onError: onError, onDone: onDone, cancelOnError: cancelOnError); onError: onError, onDone: onDone, cancelOnError: cancelOnError);
} }
@ -341,6 +336,7 @@ class _HttpParser extends Stream<_HttpIncoming> {
// parsing and return. This will be in case of either an upgrade // parsing and return. This will be in case of either an upgrade
// request or a request or response with an empty body. // request or a request or response with an empty body.
bool _headersEnd() { bool _headersEnd() {
var headers = _headers!;
// If method is CONNECT, response parser should ignore any Content-Length or // If method is CONNECT, response parser should ignore any Content-Length or
// Transfer-Encoding header fields in a successful response. // Transfer-Encoding header fields in a successful response.
// [RFC 7231](https://tools.ietf.org/html/rfc7231#section-4.3.6) // [RFC 7231](https://tools.ietf.org/html/rfc7231#section-4.3.6)
@ -349,14 +345,14 @@ class _HttpParser extends Stream<_HttpIncoming> {
_statusCode < 300 && _statusCode < 300 &&
connectMethod) { connectMethod) {
_transferLength = -1; _transferLength = -1;
_headers.chunkedTransferEncoding = false; headers.chunkedTransferEncoding = false;
_chunked = false; _chunked = false;
_headers.removeAll(HttpHeaders.contentLengthHeader); headers.removeAll(HttpHeaders.contentLengthHeader);
_headers.removeAll(HttpHeaders.transferEncodingHeader); headers.removeAll(HttpHeaders.transferEncodingHeader);
} }
_headers._mutable = false; headers._mutable = false;
_transferLength = _headers.contentLength; _transferLength = headers.contentLength;
// Ignore the Content-Length header if Transfer-Encoding // Ignore the Content-Length header if Transfer-Encoding
// is chunked (RFC 2616 section 4.4) // is chunked (RFC 2616 section 4.4)
if (_chunked) _transferLength = -1; if (_chunked) _transferLength = -1;
@ -373,30 +369,28 @@ class _HttpParser extends Stream<_HttpIncoming> {
_state = _State.UPGRADED; _state = _State.UPGRADED;
_transferLength = 0; _transferLength = 0;
} }
_createIncoming(_transferLength); var incoming = _createIncoming(_transferLength);
if (_requestParser) { if (_requestParser) {
_incoming.method = new String.fromCharCodes(_method); incoming.method = new String.fromCharCodes(_method);
_incoming.uri = Uri.parse(new String.fromCharCodes(_uriOrReasonPhrase)); incoming.uri = Uri.parse(new String.fromCharCodes(_uriOrReasonPhrase));
} else { } else {
_incoming.statusCode = _statusCode; incoming.statusCode = _statusCode;
_incoming.reasonPhrase = new String.fromCharCodes(_uriOrReasonPhrase); incoming.reasonPhrase = new String.fromCharCodes(_uriOrReasonPhrase);
} }
_method.clear(); _method.clear();
_uriOrReasonPhrase.clear(); _uriOrReasonPhrase.clear();
if (_connectionUpgrade) { if (_connectionUpgrade) {
_incoming.upgraded = true; incoming.upgraded = true;
_parserCalled = false; _parserCalled = false;
var tmp = _incoming;
_closeIncoming(); _closeIncoming();
_controller.add(tmp); _controller.add(incoming);
return true; return true;
} }
if (_transferLength == 0 || if (_transferLength == 0 ||
(_messageType == _MessageType.RESPONSE && _noMessageBody)) { (_messageType == _MessageType.RESPONSE && _noMessageBody)) {
_reset(); _reset();
var tmp = _incoming;
_closeIncoming(); _closeIncoming();
_controller.add(tmp); _controller.add(incoming);
return false; return false;
} else if (_chunked) { } else if (_chunked) {
_state = _State.CHUNK_SIZE; _state = _State.CHUNK_SIZE;
@ -410,7 +404,7 @@ class _HttpParser extends Stream<_HttpIncoming> {
_state = _State.BODY; _state = _State.BODY;
} }
_parserCalled = false; _parserCalled = false;
_controller.add(_incoming); _controller.add(incoming);
return true; return true;
} }
@ -433,7 +427,7 @@ class _HttpParser extends Stream<_HttpIncoming> {
throw HttpException("Data on failed connection"); throw HttpException("Data on failed connection");
} }
while (_buffer != null && while (_buffer != null &&
_index < _buffer.length && _index < _buffer!.length &&
_state != _State.FAILURE && _state != _State.FAILURE &&
_state != _State.UPGRADED) { _state != _State.UPGRADED) {
// Depending on _incoming, we either break on _bodyPaused or _paused. // Depending on _incoming, we either break on _bodyPaused or _paused.
@ -442,7 +436,9 @@ class _HttpParser extends Stream<_HttpIncoming> {
_parserCalled = false; _parserCalled = false;
return; return;
} }
int byte = _buffer[_index++]; int index = _index;
int byte = _buffer![index];
_index = index + 1;
switch (_state) { switch (_state) {
case _State.START: case _State.START:
if (byte == _Const.HTTP[0]) { if (byte == _Const.HTTP[0]) {
@ -463,22 +459,23 @@ class _HttpParser extends Stream<_HttpIncoming> {
break; break;
case _State.METHOD_OR_RESPONSE_HTTP_VERSION: case _State.METHOD_OR_RESPONSE_HTTP_VERSION:
if (_httpVersionIndex < _Const.HTTP.length && var httpVersionIndex = _httpVersionIndex!;
byte == _Const.HTTP[_httpVersionIndex]) { if (httpVersionIndex < _Const.HTTP.length &&
byte == _Const.HTTP[httpVersionIndex]) {
// Continue parsing HTTP version. // Continue parsing HTTP version.
_httpVersionIndex++; _httpVersionIndex = httpVersionIndex + 1;
} else if (_httpVersionIndex == _Const.HTTP.length && } else if (httpVersionIndex == _Const.HTTP.length &&
byte == _CharCode.SLASH) { byte == _CharCode.SLASH) {
// HTTP/ parsed. As method is a token this cannot be a // HTTP/ parsed. As method is a token this cannot be a
// method anymore. // method anymore.
_httpVersionIndex++; _httpVersionIndex = httpVersionIndex + 1;
if (_requestParser) { if (_requestParser) {
throw HttpException("Invalid request line"); throw HttpException("Invalid request line");
} }
_state = _State.RESPONSE_HTTP_VERSION; _state = _State.RESPONSE_HTTP_VERSION;
} else { } else {
// Did not parse HTTP version. Expect method instead. // Did not parse HTTP version. Expect method instead.
for (int i = 0; i < _httpVersionIndex; i++) { for (int i = 0; i < httpVersionIndex; i++) {
_addWithValidation(_method, _Const.HTTP[i]); _addWithValidation(_method, _Const.HTTP[i]);
} }
if (byte == _CharCode.SP) { if (byte == _CharCode.SP) {
@ -495,23 +492,24 @@ class _HttpParser extends Stream<_HttpIncoming> {
break; break;
case _State.RESPONSE_HTTP_VERSION: case _State.RESPONSE_HTTP_VERSION:
if (_httpVersionIndex < _Const.HTTP1DOT.length) { var httpVersionIndex = _httpVersionIndex!;
if (httpVersionIndex < _Const.HTTP1DOT.length) {
// Continue parsing HTTP version. // Continue parsing HTTP version.
_expect(byte, _Const.HTTP1DOT[_httpVersionIndex]); _expect(byte, _Const.HTTP1DOT[httpVersionIndex]);
_httpVersionIndex++; _httpVersionIndex = httpVersionIndex + 1;
} else if (_httpVersionIndex == _Const.HTTP1DOT.length && } else if (httpVersionIndex == _Const.HTTP1DOT.length &&
byte == _CharCode.ONE) { byte == _CharCode.ONE) {
// HTTP/1.1 parsed. // HTTP/1.1 parsed.
_httpVersion = _HttpVersion.HTTP11; _httpVersion = _HttpVersion.HTTP11;
_persistentConnection = true; _persistentConnection = true;
_httpVersionIndex++; _httpVersionIndex = httpVersionIndex + 1;
} else if (_httpVersionIndex == _Const.HTTP1DOT.length && } else if (httpVersionIndex == _Const.HTTP1DOT.length &&
byte == _CharCode.ZERO) { byte == _CharCode.ZERO) {
// HTTP/1.0 parsed. // HTTP/1.0 parsed.
_httpVersion = _HttpVersion.HTTP10; _httpVersion = _HttpVersion.HTTP10;
_persistentConnection = false; _persistentConnection = false;
_httpVersionIndex++; _httpVersionIndex = httpVersionIndex + 1;
} else if (_httpVersionIndex == _Const.HTTP1DOT.length + 1) { } else if (httpVersionIndex == _Const.HTTP1DOT.length + 1) {
_expect(byte, _CharCode.SP); _expect(byte, _CharCode.SP);
// HTTP version parsed. // HTTP version parsed.
_state = _State.RESPONSE_LINE_STATUS_CODE; _state = _State.RESPONSE_LINE_STATUS_CODE;
@ -550,20 +548,21 @@ class _HttpParser extends Stream<_HttpIncoming> {
break; break;
case _State.REQUEST_LINE_HTTP_VERSION: case _State.REQUEST_LINE_HTTP_VERSION:
if (_httpVersionIndex < _Const.HTTP1DOT.length) { var httpVersionIndex = _httpVersionIndex!;
_expect(byte, _Const.HTTP11[_httpVersionIndex]); if (httpVersionIndex < _Const.HTTP1DOT.length) {
_httpVersionIndex++; _expect(byte, _Const.HTTP11[httpVersionIndex]);
_httpVersionIndex = httpVersionIndex + 1;
} else if (_httpVersionIndex == _Const.HTTP1DOT.length) { } else if (_httpVersionIndex == _Const.HTTP1DOT.length) {
if (byte == _CharCode.ONE) { if (byte == _CharCode.ONE) {
// HTTP/1.1 parsed. // HTTP/1.1 parsed.
_httpVersion = _HttpVersion.HTTP11; _httpVersion = _HttpVersion.HTTP11;
_persistentConnection = true; _persistentConnection = true;
_httpVersionIndex++; _httpVersionIndex = httpVersionIndex + 1;
} else if (byte == _CharCode.ZERO) { } else if (byte == _CharCode.ZERO) {
// HTTP/1.0 parsed. // HTTP/1.0 parsed.
_httpVersion = _HttpVersion.HTTP10; _httpVersion = _HttpVersion.HTTP10;
_persistentConnection = false; _persistentConnection = false;
_httpVersionIndex++; _httpVersionIndex = httpVersionIndex + 1;
} else { } else {
throw HttpException("Invalid response, invalid HTTP version"); throw HttpException("Invalid response, invalid HTTP version");
} }
@ -627,12 +626,12 @@ class _HttpParser extends Stream<_HttpIncoming> {
break; break;
case _State.HEADER_START: case _State.HEADER_START:
_headers = new _HttpHeaders(version); _headers = new _HttpHeaders(version!);
if (byte == _CharCode.CR) { if (byte == _CharCode.CR) {
_state = _State.HEADER_ENDING; _state = _State.HEADER_ENDING;
} else if (byte == _CharCode.LF) { } else if (byte == _CharCode.LF) {
_state = _State.HEADER_ENDING; _state = _State.HEADER_ENDING;
_index--; // Make the new state see the LF again. _index = _index - 1; // Make the new state see the LF again.
} else { } else {
// Start of new header field. // Start of new header field.
_addWithValidation(_headerField, _toLowerCaseByte(byte)); _addWithValidation(_headerField, _toLowerCaseByte(byte));
@ -700,6 +699,7 @@ class _HttpParser extends Stream<_HttpIncoming> {
_statusCode = HttpStatus.badRequest; _statusCode = HttpStatus.badRequest;
} }
} }
var headers = _headers!;
if (headerField == HttpHeaders.connectionHeader) { if (headerField == HttpHeaders.connectionHeader) {
List<String> tokens = _tokenizeFieldValue(headerValue); List<String> tokens = _tokenizeFieldValue(headerValue);
final bool isResponse = _messageType == _MessageType.RESPONSE; final bool isResponse = _messageType == _MessageType.RESPONSE;
@ -713,10 +713,10 @@ class _HttpParser extends Stream<_HttpIncoming> {
(isUpgrade && isResponse && isUpgradeCode)) { (isUpgrade && isResponse && isUpgradeCode)) {
_connectionUpgrade = true; _connectionUpgrade = true;
} }
_headers._add(headerField, tokens[i]); headers._add(headerField, tokens[i]);
} }
} else { } else {
_headers._add(headerField, headerValue); headers._add(headerField, headerValue);
} }
_headerField.clear(); _headerField.clear();
_headerValue.clear(); _headerValue.clear();
@ -725,7 +725,7 @@ class _HttpParser extends Stream<_HttpIncoming> {
_state = _State.HEADER_ENDING; _state = _State.HEADER_ENDING;
} else if (byte == _CharCode.LF) { } else if (byte == _CharCode.LF) {
_state = _State.HEADER_ENDING; _state = _State.HEADER_ENDING;
_index--; // Make the new state see the LF again. _index = _index - 1; // Make the new state see the LF again.
} else { } else {
// Start of new header field. // Start of new header field.
_state = _State.HEADER_FIELD; _state = _State.HEADER_FIELD;
@ -794,8 +794,9 @@ class _HttpParser extends Stream<_HttpIncoming> {
case _State.BODY: case _State.BODY:
// The body is not handled one byte at a time but in blocks. // The body is not handled one byte at a time but in blocks.
_index--; _index = _index - 1;
int dataAvailable = _buffer.length - _index; var buffer = _buffer!;
int dataAvailable = buffer.length - _index;
if (_remainingContent >= 0 && dataAvailable > _remainingContent) { if (_remainingContent >= 0 && dataAvailable > _remainingContent) {
dataAvailable = _remainingContent; dataAvailable = _remainingContent;
} }
@ -803,12 +804,12 @@ class _HttpParser extends Stream<_HttpIncoming> {
// cases like this, and the user will not experience different data // cases like this, and the user will not experience different data
// typed (which could lead to polymorphic user code). // typed (which could lead to polymorphic user code).
Uint8List data = new Uint8List.view( Uint8List data = new Uint8List.view(
_buffer.buffer, _buffer.offsetInBytes + _index, dataAvailable); buffer.buffer, buffer.offsetInBytes + _index, dataAvailable);
_bodyController.add(data); _bodyController!.add(data);
if (_remainingContent != -1) { if (_remainingContent != -1) {
_remainingContent -= data.length; _remainingContent -= data.length;
} }
_index += data.length; _index = _index + data.length;
if (_remainingContent == 0) { if (_remainingContent == 0) {
if (!_chunked) { if (!_chunked) {
_reset(); _reset();
@ -832,18 +833,19 @@ class _HttpParser extends Stream<_HttpIncoming> {
} }
_parserCalled = false; _parserCalled = false;
if (_buffer != null && _index == _buffer.length) { var buffer = _buffer;
if (buffer != null && _index == buffer.length) {
// If all data is parsed release the buffer and resume receiving // If all data is parsed release the buffer and resume receiving
// data. // data.
_releaseBuffer(); _releaseBuffer();
if (_state != _State.UPGRADED && _state != _State.FAILURE) { if (_state != _State.UPGRADED && _state != _State.FAILURE) {
_socketSubscription.resume(); _socketSubscription!.resume();
} }
} }
} }
void _onData(Uint8List buffer) { void _onData(Uint8List buffer) {
_socketSubscription.pause(); _socketSubscription!.pause();
assert(_buffer == null); assert(_buffer == null);
_buffer = buffer; _buffer = buffer;
_index = 0; _index = 0;
@ -903,7 +905,7 @@ class _HttpParser extends Stream<_HttpIncoming> {
_controller.close(); _controller.close();
} }
String get version { String? get version {
switch (_httpVersion) { switch (_httpVersion) {
case _HttpVersion.HTTP10: case _HttpVersion.HTTP10:
return "1.0"; return "1.0";
@ -918,7 +920,9 @@ class _HttpParser extends Stream<_HttpIncoming> {
bool get upgrade => _connectionUpgrade && _state == _State.UPGRADED; bool get upgrade => _connectionUpgrade && _state == _State.UPGRADED;
bool get persistentConnection => _persistentConnection; bool get persistentConnection => _persistentConnection;
void set isHead(bool value) => _noMessageBody = value ?? false; void set isHead(bool value) {
_noMessageBody = valueOfNonNullableParamWithDefault<bool>(value, false);
}
_HttpDetachedIncoming detachIncoming() { _HttpDetachedIncoming detachIncoming() {
// Simulate detached by marking as upgraded. // Simulate detached by marking as upgraded.
@ -926,10 +930,12 @@ class _HttpParser extends Stream<_HttpIncoming> {
return new _HttpDetachedIncoming(_socketSubscription, readUnparsedData()); return new _HttpDetachedIncoming(_socketSubscription, readUnparsedData());
} }
Uint8List readUnparsedData() { Uint8List? readUnparsedData() {
if (_buffer == null) return null; var buffer = _buffer;
if (_index == _buffer.length) return null; if (buffer == null) return null;
var result = _buffer.sublist(_index); var index = _index;
if (index == buffer.length) return null;
var result = buffer.sublist(index);
_releaseBuffer(); _releaseBuffer();
return result; return result;
} }
@ -963,7 +969,7 @@ class _HttpParser extends Stream<_HttpIncoming> {
void _releaseBuffer() { void _releaseBuffer() {
_buffer = null; _buffer = null;
_index = null; _index = -1;
} }
static bool _isTokenChar(int byte) { static bool _isTokenChar(int byte) {
@ -977,7 +983,7 @@ class _HttpParser extends Stream<_HttpIncoming> {
} }
static List<String> _tokenizeFieldValue(String headerValue) { static List<String> _tokenizeFieldValue(String headerValue) {
List<String> tokens = new List<String>(); List<String> tokens = <String>[];
int start = 0; int start = 0;
int index = 0; int index = 0;
while (index < headerValue.length) { while (index < headerValue.length) {
@ -1072,53 +1078,53 @@ class _HttpParser extends Stream<_HttpIncoming> {
throw HttpException("$method exceeds the $_headerSizeLimit size limit"); throw HttpException("$method exceeds the $_headerSizeLimit size limit");
} }
void _createIncoming(int transferLength) { _HttpIncoming _createIncoming(int transferLength) {
assert(_incoming == null); assert(_incoming == null);
assert(_bodyController == null); assert(_bodyController == null);
assert(!_bodyPaused); assert(!_bodyPaused);
var incoming; var controller =
_bodyController = new StreamController<Uint8List>( _bodyController = new StreamController<Uint8List>(sync: true);
sync: true, var incoming = _incoming =
onListen: () { new _HttpIncoming(_headers!, transferLength, controller.stream);
if (incoming != _incoming) return; controller
assert(_bodyPaused); ..onListen = () {
_bodyPaused = false; if (incoming != _incoming) return;
_pauseStateChanged(); assert(_bodyPaused);
}, _bodyPaused = false;
onPause: () { _pauseStateChanged();
if (incoming != _incoming) return; }
assert(!_bodyPaused); ..onPause = () {
_bodyPaused = true; if (incoming != _incoming) return;
_pauseStateChanged(); assert(!_bodyPaused);
}, _bodyPaused = true;
onResume: () { _pauseStateChanged();
if (incoming != _incoming) return; }
assert(_bodyPaused); ..onResume = () {
_bodyPaused = false; if (incoming != _incoming) return;
_pauseStateChanged(); assert(_bodyPaused);
}, _bodyPaused = false;
onCancel: () { _pauseStateChanged();
if (incoming != _incoming) return; }
if (_socketSubscription != null) { ..onCancel = () {
_socketSubscription.cancel(); if (incoming != _incoming) return;
} _socketSubscription?.cancel();
_closeIncoming(true); _closeIncoming(true);
_controller.close(); _controller.close();
}); };
incoming = _incoming =
new _HttpIncoming(_headers, transferLength, _bodyController.stream);
_bodyPaused = true; _bodyPaused = true;
_pauseStateChanged(); _pauseStateChanged();
return incoming;
} }
void _closeIncoming([bool closing = false]) { void _closeIncoming([bool closing = false]) {
// Ignore multiple close (can happen in re-entrance). // Ignore multiple close (can happen in re-entrance).
if (_incoming == null) return;
var tmp = _incoming; var tmp = _incoming;
if (tmp == null) return;
tmp.close(closing); tmp.close(closing);
_incoming = null; _incoming = null;
if (_bodyController != null) { var controller = _bodyController;
_bodyController.close(); if (controller != null) {
controller.close();
_bodyController = null; _bodyController = null;
} }
_bodyPaused = false; _bodyPaused = false;
@ -1138,19 +1144,17 @@ class _HttpParser extends Stream<_HttpIncoming> {
} }
void _reportHttpError(error, [stackTrace]) { void _reportHttpError(error, [stackTrace]) {
if (_socketSubscription != null) _socketSubscription.cancel(); _socketSubscription?.cancel();
_state = _State.FAILURE; _state = _State.FAILURE;
_controller.addError(error, stackTrace); _controller.addError(error, stackTrace);
_controller.close(); _controller.close();
} }
void _reportBodyError(error, [stackTrace]) { void _reportBodyError(error, [stackTrace]) {
if (_socketSubscription != null) _socketSubscription.cancel(); _socketSubscription?.cancel();
_state = _State.FAILURE; _state = _State.FAILURE;
_bodyController.addError(error, stackTrace); _bodyController?.addError(error, stackTrace);
// In case of drain(), error event will close the stream. // In case of drain(), error event will close the stream.
if (_bodyController != null) { _bodyController?.close();
_bodyController.close();
}
} }
} }

View file

@ -2,8 +2,6 @@
// for details. All rights reserved. Use of this source code is governed by a // for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file. // BSD-style license that can be found in the LICENSE file.
// @dart = 2.6
part of dart._http; part of dart._http;
const String _DART_SESSION_ID = "DARTSESSID"; const String _DART_SESSION_ID = "DARTSESSID";
@ -15,11 +13,11 @@ class _HttpSession implements HttpSession {
bool _destroyed = false; bool _destroyed = false;
bool _isNew = true; bool _isNew = true;
DateTime _lastSeen; DateTime _lastSeen;
Function _timeoutCallback; Function? _timeoutCallback;
_HttpSessionManager _sessionManager; _HttpSessionManager _sessionManager;
// Pointers in timeout queue. // Pointers in timeout queue.
_HttpSession _prev; _HttpSession? _prev;
_HttpSession _next; _HttpSession? _next;
final String id; final String id;
final Map _data = new HashMap(); final Map _data = new HashMap();
@ -27,6 +25,7 @@ class _HttpSession implements HttpSession {
_HttpSession(this._sessionManager, this.id) : _lastSeen = new DateTime.now(); _HttpSession(this._sessionManager, this.id) : _lastSeen = new DateTime.now();
void destroy() { void destroy() {
assert(!_destroyed);
_destroyed = true; _destroyed = true;
_sessionManager._removeFromTimeoutQueue(this); _sessionManager._removeFromTimeoutQueue(this);
_sessionManager._sessions.remove(id); _sessionManager._sessions.remove(id);
@ -43,7 +42,7 @@ class _HttpSession implements HttpSession {
bool get isNew => _isNew; bool get isNew => _isNew;
void set onTimeout(void callback()) { void set onTimeout(void callback()?) {
_timeoutCallback = callback; _timeoutCallback = callback;
} }
@ -80,7 +79,7 @@ class _HttpSession implements HttpSession {
} }
Map<K, V> cast<K, V>() => _data.cast<K, V>(); Map<K, V> cast<K, V>() => _data.cast<K, V>();
update(key, update(value), {ifAbsent()}) => update(key, update(value), {ifAbsent()?}) =>
_data.update(key, update, ifAbsent: ifAbsent); _data.update(key, update, ifAbsent: ifAbsent);
void updateAll(update(key, value)) { void updateAll(update(key, value)) {
@ -104,9 +103,9 @@ class _HttpSession implements HttpSession {
class _HttpSessionManager { class _HttpSessionManager {
Map<String, _HttpSession> _sessions; Map<String, _HttpSession> _sessions;
int _sessionTimeout = 20 * 60; // 20 mins. int _sessionTimeout = 20 * 60; // 20 mins.
_HttpSession _head; _HttpSession? _head;
_HttpSession _tail; _HttpSession? _tail;
Timer _timer; Timer? _timer;
_HttpSessionManager() : _sessions = {}; _HttpSessionManager() : _sessions = {};
@ -116,7 +115,7 @@ class _HttpSessionManager {
return _CryptoUtils.bytesToHex(data); return _CryptoUtils.bytesToHex(data);
} }
_HttpSession getSession(String id) => _sessions[id]; _HttpSession? getSession(String id) => _sessions[id];
_HttpSession createSession() { _HttpSession createSession() {
var id = createSessionId(); var id = createSessionId();
@ -152,55 +151,52 @@ class _HttpSessionManager {
_startTimer(); _startTimer();
} else { } else {
assert(_timer != null); assert(_timer != null);
assert(_tail != null); var tail = _tail!;
// Add to end. // Add to end.
_tail._next = session; tail._next = session;
session._prev = _tail; session._prev = tail;
_tail = session; _tail = session;
} }
} }
void _removeFromTimeoutQueue(_HttpSession session) { void _removeFromTimeoutQueue(_HttpSession session) {
if (session._next != null) { var next = session._next;
session._next._prev = session._prev; var prev = session._prev;
} session._next = session._prev = null;
if (session._prev != null) { next?._prev = prev;
session._prev._next = session._next; prev?._next = next;
if (_tail == session) {
_tail = prev;
} }
if (_head == session) { if (_head == session) {
_head = next;
// We removed the head element, start new timer. // We removed the head element, start new timer.
_head = session._next;
_stopTimer(); _stopTimer();
_startTimer(); _startTimer();
} }
if (_tail == session) {
_tail = session._prev;
}
session._next = session._prev = null;
} }
void _timerTimeout() { void _timerTimeout() {
_stopTimer(); // Clear timer. _stopTimer(); // Clear timer.
assert(_head != null); var session = _head!;
var session = _head;
session.destroy(); // Will remove the session from timeout queue and map. session.destroy(); // Will remove the session from timeout queue and map.
if (session._timeoutCallback != null) { session._timeoutCallback?.call();
session._timeoutCallback();
}
} }
void _startTimer() { void _startTimer() {
assert(_timer == null); assert(_timer == null);
if (_head != null) { var head = _head;
int seconds = new DateTime.now().difference(_head.lastSeen).inSeconds; if (head != null) {
int seconds = new DateTime.now().difference(head.lastSeen).inSeconds;
_timer = new Timer( _timer = new Timer(
new Duration(seconds: _sessionTimeout - seconds), _timerTimeout); new Duration(seconds: _sessionTimeout - seconds), _timerTimeout);
} }
} }
void _stopTimer() { void _stopTimer() {
if (_timer != null) { var timer = _timer;
_timer.cancel(); if (timer != null) {
timer.cancel();
_timer = null; _timer = null;
} }
} }

View file

@ -2,8 +2,6 @@
// for details. All rights reserved. Use of this source code is governed by a // for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file. // BSD-style license that can be found in the LICENSE file.
// @dart = 2.6
part of dart._http; part of dart._http;
final _httpOverridesToken = new Object(); final _httpOverridesToken = new Object();
@ -32,9 +30,9 @@ const _asyncRunZoned = runZoned;
/// } /// }
/// ``` /// ```
abstract class HttpOverrides { abstract class HttpOverrides {
static HttpOverrides _global; static HttpOverrides? _global;
static HttpOverrides get current { static HttpOverrides? get current {
return Zone.current[_httpOverridesToken] ?? _global; return Zone.current[_httpOverridesToken] ?? _global;
} }
@ -43,14 +41,14 @@ abstract class HttpOverrides {
/// These are the [HttpOverrides] that will be used in the root Zone, and in /// These are the [HttpOverrides] that will be used in the root Zone, and in
/// Zone's that do not set [HttpOverrides] and whose ancestors up to the root /// Zone's that do not set [HttpOverrides] and whose ancestors up to the root
/// Zone do not set [HttpOverrides]. /// Zone do not set [HttpOverrides].
static set global(HttpOverrides overrides) { static set global(HttpOverrides? overrides) {
_global = overrides; _global = overrides;
} }
/// Runs [body] in a fresh [Zone] using the provided overrides. /// Runs [body] in a fresh [Zone] using the provided overrides.
static R runZoned<R>(R body(), static R runZoned<R>(R body(),
{HttpClient Function(SecurityContext) createHttpClient, {HttpClient Function(SecurityContext?)? createHttpClient,
String Function(Uri uri, Map<String, String> environment) String Function(Uri uri, Map<String, String>? environment)?
findProxyFromEnvironment}) { findProxyFromEnvironment}) {
HttpOverrides overrides = HttpOverrides overrides =
new _HttpOverridesScope(createHttpClient, findProxyFromEnvironment); new _HttpOverridesScope(createHttpClient, findProxyFromEnvironment);
@ -71,7 +69,7 @@ abstract class HttpOverrides {
/// ///
/// When this override is installed, this function overrides the behavior of /// When this override is installed, this function overrides the behavior of
/// `new HttpClient`. /// `new HttpClient`.
HttpClient createHttpClient(SecurityContext context) { HttpClient createHttpClient(SecurityContext? context) {
return new _HttpClient(context); return new _HttpClient(context);
} }
@ -79,34 +77,37 @@ abstract class HttpOverrides {
/// ///
/// When this override is installed, this function overrides the behavior of /// When this override is installed, this function overrides the behavior of
/// `HttpClient.findProxyFromEnvironment`. /// `HttpClient.findProxyFromEnvironment`.
String findProxyFromEnvironment(Uri url, Map<String, String> environment) { String findProxyFromEnvironment(Uri url, Map<String, String>? environment) {
return _HttpClient._findProxyFromEnvironment(url, environment); return _HttpClient._findProxyFromEnvironment(url, environment);
} }
} }
class _HttpOverridesScope extends HttpOverrides { class _HttpOverridesScope extends HttpOverrides {
final HttpOverrides _previous = HttpOverrides.current; final HttpOverrides? _previous = HttpOverrides.current;
final HttpClient Function(SecurityContext?)? _createHttpClient;
final HttpClient Function(SecurityContext) _createHttpClient; final String Function(Uri uri, Map<String, String>? environment)?
final String Function(Uri uri, Map<String, String> environment)
_findProxyFromEnvironment; _findProxyFromEnvironment;
_HttpOverridesScope(this._createHttpClient, this._findProxyFromEnvironment); _HttpOverridesScope(this._createHttpClient, this._findProxyFromEnvironment);
@override @override
HttpClient createHttpClient(SecurityContext context) { HttpClient createHttpClient(SecurityContext? context) {
if (_createHttpClient != null) return _createHttpClient(context); var createHttpClient = _createHttpClient;
if (_previous != null) return _previous.createHttpClient(context); if (createHttpClient != null) return createHttpClient(context);
var previous = _previous;
if (previous != null) return previous.createHttpClient(context);
return super.createHttpClient(context); return super.createHttpClient(context);
} }
@override @override
String findProxyFromEnvironment(Uri url, Map<String, String> environment) { String findProxyFromEnvironment(Uri url, Map<String, String>? environment) {
if (_findProxyFromEnvironment != null) { var findProxyFromEnvironment = _findProxyFromEnvironment;
return _findProxyFromEnvironment(url, environment); if (findProxyFromEnvironment != null) {
return findProxyFromEnvironment(url, environment);
} }
if (_previous != null) { var previous = _previous;
return _previous.findProxyFromEnvironment(url, environment); if (previous != null) {
return previous.findProxyFromEnvironment(url, environment);
} }
return super.findProxyFromEnvironment(url, environment); return super.findProxyFromEnvironment(url, environment);
} }

View file

@ -2,8 +2,6 @@
// for details. All rights reserved. Use of this source code is governed by a // for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file. // BSD-style license that can be found in the LICENSE file.
// @dart = 2.6
part of dart._http; part of dart._http;
/** /**
@ -99,7 +97,7 @@ class CompressionOptions {
/// If set to `null`, the client has no preference, and the compression can /// If set to `null`, the client has no preference, and the compression can
/// use up to its default maximum window size of 15 bits depending on the /// use up to its default maximum window size of 15 bits depending on the
/// server's preference. /// server's preference.
final int clientMaxWindowBits; final int? clientMaxWindowBits;
/// The maximal window size bit count requested by the server. /// The maximal window size bit count requested by the server.
/// ///
@ -109,7 +107,7 @@ class CompressionOptions {
/// If set to `null`, the server has no preference, and the compression can /// If set to `null`, the server has no preference, and the compression can
/// use up to its default maximum window size of 15 bits depending on the /// use up to its default maximum window size of 15 bits depending on the
/// client's preference. /// client's preference.
final int serverMaxWindowBits; final int? serverMaxWindowBits;
/// Whether WebSocket compression is enabled. /// Whether WebSocket compression is enabled.
/// ///
@ -132,21 +130,18 @@ class CompressionOptions {
/// value from headers. Defaults to [WebSocket.DEFAULT_WINDOW_BITS]. Returns a /// value from headers. Defaults to [WebSocket.DEFAULT_WINDOW_BITS]. Returns a
/// [_CompressionMaxWindowBits] object which contains the response headers and /// [_CompressionMaxWindowBits] object which contains the response headers and
/// negotiated max window bits. /// negotiated max window bits.
_CompressionMaxWindowBits _createServerResponseHeader(HeaderValue requested) { _CompressionMaxWindowBits _createServerResponseHeader(
var info = new _CompressionMaxWindowBits(); HeaderValue? requested) {
var info = new _CompressionMaxWindowBits("", 0);
int mwb; String? part = requested?.parameters[_serverMaxWindowBits];
String part;
if (requested?.parameters != null) {
part = requested.parameters[_serverMaxWindowBits];
}
if (part != null) { if (part != null) {
if (part.length >= 2 && part.startsWith('0')) { if (part.length >= 2 && part.startsWith('0')) {
throw new ArgumentError("Illegal 0 padding on value."); throw new ArgumentError("Illegal 0 padding on value.");
} else { } else {
mwb = serverMaxWindowBits == null int mwb = serverMaxWindowBits ??
? int.tryParse(part) ?? _WebSocketImpl.DEFAULT_WINDOW_BITS int.tryParse(part) ??
: serverMaxWindowBits; _WebSocketImpl.DEFAULT_WINDOW_BITS;
info.headerValue = "; server_max_window_bits=${mwb}"; info.headerValue = "; server_max_window_bits=${mwb}";
info.maxWindowBits = mwb; info.maxWindowBits = mwb;
} }
@ -158,7 +153,7 @@ class CompressionOptions {
} }
/// Returns default values for client compression request headers. /// Returns default values for client compression request headers.
String _createClientRequestHeader(HeaderValue requested, int size) { String _createClientRequestHeader(HeaderValue? requested, int size) {
var info = ""; var info = "";
// If responding to a valid request, specify size // If responding to a valid request, specify size
@ -189,7 +184,7 @@ class CompressionOptions {
/// `server_max_window_bits` value. This method returns a /// `server_max_window_bits` value. This method returns a
/// [_CompressionMaxWindowBits] object with the response headers and /// [_CompressionMaxWindowBits] object with the response headers and
/// negotiated `maxWindowBits` value. /// negotiated `maxWindowBits` value.
_CompressionMaxWindowBits _createHeader([HeaderValue requested]) { _CompressionMaxWindowBits _createHeader([HeaderValue? requested]) {
var info = new _CompressionMaxWindowBits("", 0); var info = new _CompressionMaxWindowBits("", 0);
if (!enabled) { if (!enabled) {
return info; return info;
@ -266,8 +261,8 @@ abstract class WebSocketTransformer
* then the [WebSocket] will be created with the default [CompressionOptions]. * then the [WebSocket] will be created with the default [CompressionOptions].
*/ */
factory WebSocketTransformer( factory WebSocketTransformer(
{/*String|Future<String>*/ protocolSelector(List<String> protocols), {/*String|Future<String>*/ protocolSelector(List<String> protocols)?,
CompressionOptions compression: CompressionOptions.compressionDefault}) { CompressionOptions compression = CompressionOptions.compressionDefault}) {
return new _WebSocketTransformerImpl(protocolSelector, compression); return new _WebSocketTransformerImpl(protocolSelector, compression);
} }
@ -289,8 +284,8 @@ abstract class WebSocketTransformer
* then the [WebSocket] will be created with the default [CompressionOptions]. * then the [WebSocket] will be created with the default [CompressionOptions].
*/ */
static Future<WebSocket> upgrade(HttpRequest request, static Future<WebSocket> upgrade(HttpRequest request,
{protocolSelector(List<String> protocols), {protocolSelector(List<String> protocols)?,
CompressionOptions compression: CompressionOptions.compressionDefault}) { CompressionOptions compression = CompressionOptions.compressionDefault}) {
return _WebSocketTransformerImpl._upgrade( return _WebSocketTransformerImpl._upgrade(
request, protocolSelector, compression); request, protocolSelector, compression);
} }
@ -347,7 +342,7 @@ abstract class WebSocket
* *
* The default value is `null`. * The default value is `null`.
*/ */
Duration pingInterval; Duration? pingInterval;
/** /**
* Create a new WebSocket connection. The URL supplied in [url] * Create a new WebSocket connection. The URL supplied in [url]
@ -377,9 +372,9 @@ abstract class WebSocket
* authentication when setting up the connection. * authentication when setting up the connection.
*/ */
static Future<WebSocket> connect(String url, static Future<WebSocket> connect(String url,
{Iterable<String> protocols, {Iterable<String>? protocols,
Map<String, dynamic> headers, Map<String, dynamic>? headers,
CompressionOptions compression: CompressionOptions compression =
CompressionOptions.compressionDefault}) => CompressionOptions.compressionDefault}) =>
_WebSocketImpl.connect(url, protocols, headers, compression: compression); _WebSocketImpl.connect(url, protocols, headers, compression: compression);
@ -407,9 +402,9 @@ abstract class WebSocket
* then the [WebSocket] will be created with the default [CompressionOptions]. * then the [WebSocket] will be created with the default [CompressionOptions].
*/ */
factory WebSocket.fromUpgradedSocket(Socket socket, factory WebSocket.fromUpgradedSocket(Socket socket,
{String protocol, {String? protocol,
bool serverSide, bool? serverSide,
CompressionOptions compression: CompressionOptions.compressionDefault}) { CompressionOptions compression = CompressionOptions.compressionDefault}) {
if (serverSide == null) { if (serverSide == null) {
throw new ArgumentError("The serverSide argument must be passed " throw new ArgumentError("The serverSide argument must be passed "
"explicitly to WebSocket.fromUpgradedSocket."); "explicitly to WebSocket.fromUpgradedSocket.");
@ -436,19 +431,19 @@ abstract class WebSocket
* selected by the server. If no subprotocol is negotiated the * selected by the server. If no subprotocol is negotiated the
* value will remain [:null:]. * value will remain [:null:].
*/ */
String get protocol; String? get protocol;
/** /**
* The close code set when the WebSocket connection is closed. If * The close code set when the WebSocket connection is closed. If
* there is no close code available this property will be [:null:] * there is no close code available this property will be [:null:]
*/ */
int get closeCode; int? get closeCode;
/** /**
* The close reason set when the WebSocket connection is closed. If * The close reason set when the WebSocket connection is closed. If
* there is no close reason available this property will be [:null:] * there is no close reason available this property will be [:null:]
*/ */
String get closeReason; String? get closeReason;
/** /**
* Closes the WebSocket connection. Set the optional [code] and [reason] * Closes the WebSocket connection. Set the optional [code] and [reason]
@ -456,7 +451,7 @@ abstract class WebSocket
* omitted, the peer will see [WebSocketStatus.noStatusReceived] code * omitted, the peer will see [WebSocketStatus.noStatusReceived] code
* with no reason. * with no reason.
*/ */
Future close([int code, String reason]); Future close([int? code, String? reason]);
/** /**
* Sends data on the WebSocket connection. The data in [data] must * Sends data on the WebSocket connection. The data in [data] must
@ -482,12 +477,12 @@ abstract class WebSocket
/** /**
* Gets the user agent used for WebSocket connections. * Gets the user agent used for WebSocket connections.
*/ */
static String get userAgent => _WebSocketImpl.userAgent; static String? get userAgent => _WebSocketImpl.userAgent;
/** /**
* Sets the user agent to use for WebSocket connections. * Sets the user agent to use for WebSocket connections.
*/ */
static set userAgent(String userAgent) { static set userAgent(String? userAgent) {
_WebSocketImpl.userAgent = userAgent; _WebSocketImpl.userAgent = userAgent;
} }
} }

View file

@ -2,8 +2,6 @@
// for details. All rights reserved. Use of this source code is governed by a // for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file. // BSD-style license that can be found in the LICENSE file.
// @dart = 2.6
part of dart._http; part of dart._http;
const String _webSocketGUID = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"; const String _webSocketGUID = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11";
@ -51,7 +49,7 @@ class _EncodedString {
class _CompressionMaxWindowBits { class _CompressionMaxWindowBits {
String headerValue; String headerValue;
int maxWindowBits; int maxWindowBits;
_CompressionMaxWindowBits([this.headerValue, this.maxWindowBits]); _CompressionMaxWindowBits(this.headerValue, this.maxWindowBits);
String toString() => headerValue; String toString() => headerValue;
} }
@ -91,16 +89,16 @@ class _WebSocketProtocolTransformer extends StreamTransformerBase<List<int>,
int _remainingPayloadBytes = -1; int _remainingPayloadBytes = -1;
int _unmaskingIndex = 0; int _unmaskingIndex = 0;
int _currentMessageType = _WebSocketMessageType.NONE; int _currentMessageType = _WebSocketMessageType.NONE;
int closeCode = WebSocketStatus.noStatusReceived; int closeCode = WebSocketStatus.NO_STATUS_RECEIVED;
String closeReason = ""; String closeReason = "";
EventSink<dynamic /*List<int>|_WebSocketPing|_WebSocketPong*/ > _eventSink; EventSink<dynamic /*List<int>|_WebSocketPing|_WebSocketPong*/ >? _eventSink;
final bool _serverSide; final bool _serverSide;
final List _maskingBytes = new List(4); final Uint8List _maskingBytes = Uint8List(4);
final BytesBuilder _payload = new BytesBuilder(copy: false); final BytesBuilder _payload = new BytesBuilder(copy: false);
_WebSocketPerMessageDeflate _deflate; _WebSocketPerMessageDeflate? _deflate;
_WebSocketProtocolTransformer([this._serverSide = false, this._deflate]); _WebSocketProtocolTransformer([this._serverSide = false, this._deflate]);
Stream<dynamic /*List<int>|_WebSocketPing|_WebSocketPong*/ > bind( Stream<dynamic /*List<int>|_WebSocketPing|_WebSocketPong*/ > bind(
@ -114,13 +112,14 @@ class _WebSocketProtocolTransformer extends StreamTransformerBase<List<int>,
}); });
} }
void addError(Object error, [StackTrace stackTrace]) { void addError(Object error, [StackTrace? stackTrace]) {
// TODO(40614): Remove once non-nullability is sound.
ArgumentError.checkNotNull(error, "error"); ArgumentError.checkNotNull(error, "error");
_eventSink.addError(error, stackTrace); _eventSink!.addError(error, stackTrace);
} }
void close() { void close() {
_eventSink.close(); _eventSink!.close();
} }
/** /**
@ -308,13 +307,13 @@ class _WebSocketProtocolTransformer extends StreamTransformerBase<List<int>,
switch (_opcode) { switch (_opcode) {
case _WebSocketOpcode.CLOSE: case _WebSocketOpcode.CLOSE:
_state = CLOSED; _state = CLOSED;
_eventSink.close(); _eventSink!.close();
break; break;
case _WebSocketOpcode.PING: case _WebSocketOpcode.PING:
_eventSink.add(new _WebSocketPing()); _eventSink!.add(new _WebSocketPing());
break; break;
case _WebSocketOpcode.PONG: case _WebSocketOpcode.PONG:
_eventSink.add(new _WebSocketPong()); _eventSink!.add(new _WebSocketPong());
break; break;
} }
_prepareForNextFrame(); _prepareForNextFrame();
@ -329,16 +328,17 @@ class _WebSocketProtocolTransformer extends StreamTransformerBase<List<int>,
void _messageFrameEnd() { void _messageFrameEnd() {
if (_fin) { if (_fin) {
var bytes = _payload.takeBytes(); var bytes = _payload.takeBytes();
if (_deflate != null && _compressed) { var deflate = _deflate;
bytes = _deflate.processIncomingMessage(bytes); if (deflate != null && _compressed) {
bytes = deflate.processIncomingMessage(bytes);
} }
switch (_currentMessageType) { switch (_currentMessageType) {
case _WebSocketMessageType.TEXT: case _WebSocketMessageType.TEXT:
_eventSink.add(utf8.decode(bytes)); _eventSink!.add(utf8.decode(bytes));
break; break;
case _WebSocketMessageType.BINARY: case _WebSocketMessageType.BINARY:
_eventSink.add(bytes); _eventSink!.add(bytes);
break; break;
} }
_currentMessageType = _WebSocketMessageType.NONE; _currentMessageType = _WebSocketMessageType.NONE;
@ -364,15 +364,15 @@ class _WebSocketProtocolTransformer extends StreamTransformerBase<List<int>,
} }
} }
_state = CLOSED; _state = CLOSED;
_eventSink.close(); _eventSink!.close();
break; break;
case _WebSocketOpcode.PING: case _WebSocketOpcode.PING:
_eventSink.add(new _WebSocketPing(_payload.takeBytes())); _eventSink!.add(new _WebSocketPing(_payload.takeBytes()));
break; break;
case _WebSocketOpcode.PONG: case _WebSocketOpcode.PONG:
_eventSink.add(new _WebSocketPong(_payload.takeBytes())); _eventSink!.add(new _WebSocketPong(_payload.takeBytes()));
break; break;
} }
_prepareForNextFrame(); _prepareForNextFrame();
@ -397,12 +397,12 @@ class _WebSocketProtocolTransformer extends StreamTransformerBase<List<int>,
} }
class _WebSocketPing { class _WebSocketPing {
final List<int> payload; final List<int>? payload;
_WebSocketPing([this.payload = null]); _WebSocketPing([this.payload = null]);
} }
class _WebSocketPong { class _WebSocketPong {
final List<int> payload; final List<int>? payload;
_WebSocketPong([this.payload = null]); _WebSocketPong([this.payload = null]);
} }
@ -413,7 +413,7 @@ class _WebSocketTransformerImpl
implements WebSocketTransformer { implements WebSocketTransformer {
final StreamController<WebSocket> _controller = final StreamController<WebSocket> _controller =
new StreamController<WebSocket>(sync: true); new StreamController<WebSocket>(sync: true);
final _ProtocolSelector _protocolSelector; final _ProtocolSelector? _protocolSelector;
final CompressionOptions _compression; final CompressionOptions _compression;
_WebSocketTransformerImpl(this._protocolSelector, this._compression); _WebSocketTransformerImpl(this._protocolSelector, this._compression);
@ -431,7 +431,7 @@ class _WebSocketTransformerImpl
} }
static List<String> _tokenizeFieldValue(String headerValue) { static List<String> _tokenizeFieldValue(String headerValue) {
List<String> tokens = new List<String>(); List<String> tokens = <String>[];
int start = 0; int start = 0;
int index = 0; int index = 0;
while (index < headerValue.length) { while (index < headerValue.length) {
@ -448,7 +448,7 @@ class _WebSocketTransformerImpl
} }
static Future<WebSocket> _upgrade(HttpRequest request, static Future<WebSocket> _upgrade(HttpRequest request,
_ProtocolSelector _protocolSelector, CompressionOptions compression) { _ProtocolSelector? protocolSelector, CompressionOptions compression) {
var response = request.response; var response = request.response;
if (!_isUpgradeRequest(request)) { if (!_isUpgradeRequest(request)) {
// Send error response. // Send error response.
@ -459,13 +459,13 @@ class _WebSocketTransformerImpl
new WebSocketException("Invalid WebSocket upgrade request")); new WebSocketException("Invalid WebSocket upgrade request"));
} }
Future<WebSocket> upgrade(String protocol) { Future<WebSocket> upgrade(String? protocol) {
// Send the upgrade response. // Send the upgrade response.
response response
..statusCode = HttpStatus.switchingProtocols ..statusCode = HttpStatus.switchingProtocols
..headers.add(HttpHeaders.connectionHeader, "Upgrade") ..headers.add(HttpHeaders.connectionHeader, "Upgrade")
..headers.add(HttpHeaders.upgradeHeader, "websocket"); ..headers.add(HttpHeaders.upgradeHeader, "websocket");
String key = request.headers.value("Sec-WebSocket-Key"); String key = request.headers.value("Sec-WebSocket-Key")!;
_SHA1 sha1 = new _SHA1(); _SHA1 sha1 = new _SHA1();
sha1.add("$key$_webSocketGUID".codeUnits); sha1.add("$key$_webSocketGUID".codeUnits);
String accept = _CryptoUtils.bytesToBase64(sha1.close()); String accept = _CryptoUtils.bytesToBase64(sha1.close());
@ -483,14 +483,14 @@ class _WebSocketTransformerImpl
} }
var protocols = request.headers['Sec-WebSocket-Protocol']; var protocols = request.headers['Sec-WebSocket-Protocol'];
if (protocols != null && _protocolSelector != null) { if (protocols != null && protocolSelector != null) {
// The suggested protocols can be spread over multiple lines, each // The suggested protocols can be spread over multiple lines, each
// consisting of multiple protocols. To unify all of them, first join // consisting of multiple protocols. To unify all of them, first join
// the lists with ', ' and then tokenize. // the lists with ', ' and then tokenize.
protocols = _tokenizeFieldValue(protocols.join(', ')); var tokenizedProtocols = _tokenizeFieldValue(protocols.join(', '));
return new Future<String>(() => _protocolSelector(protocols)) return new Future<String>(() => protocolSelector(tokenizedProtocols))
.then<String>((protocol) { .then<String>((protocol) {
if (protocols.indexOf(protocol) < 0) { if (tokenizedProtocols.indexOf(protocol) < 0) {
throw new WebSocketException( throw new WebSocketException(
"Selected protocol is not in the list of available protocols"); "Selected protocol is not in the list of available protocols");
} }
@ -506,7 +506,7 @@ class _WebSocketTransformerImpl
} }
} }
static _WebSocketPerMessageDeflate _negotiateCompression(HttpRequest request, static _WebSocketPerMessageDeflate? _negotiateCompression(HttpRequest request,
HttpResponse response, CompressionOptions compression) { HttpResponse response, CompressionOptions compression) {
var extensionHeader = request.headers.value("Sec-WebSocket-Extensions"); var extensionHeader = request.headers.value("Sec-WebSocket-Extensions");
@ -540,23 +540,27 @@ class _WebSocketTransformerImpl
if (request.method != "GET") { if (request.method != "GET") {
return false; return false;
} }
if (request.headers[HttpHeaders.connectionHeader] == null) { var connectionHeader = request.headers[HttpHeaders.connectionHeader];
if (connectionHeader == null) {
return false; return false;
} }
bool isUpgrade = false; bool isUpgrade = false;
request.headers[HttpHeaders.connectionHeader].forEach((String value) { for (var value in connectionHeader) {
if (value.toLowerCase() == "upgrade") isUpgrade = true; if (value.toLowerCase() == "upgrade") {
}); isUpgrade = true;
break;
}
}
if (!isUpgrade) return false; if (!isUpgrade) return false;
String upgrade = request.headers.value(HttpHeaders.upgradeHeader); String? upgrade = request.headers.value(HttpHeaders.upgradeHeader);
if (upgrade == null || upgrade.toLowerCase() != "websocket") { if (upgrade == null || upgrade.toLowerCase() != "websocket") {
return false; return false;
} }
String version = request.headers.value("Sec-WebSocket-Version"); String? version = request.headers.value("Sec-WebSocket-Version");
if (version == null || version != "13") { if (version == null || version != "13") {
return false; return false;
} }
String key = request.headers.value("Sec-WebSocket-Key"); String? key = request.headers.value("Sec-WebSocket-Key");
if (key == null) { if (key == null) {
return false; return false;
} }
@ -571,34 +575,26 @@ class _WebSocketPerMessageDeflate {
int serverMaxWindowBits; int serverMaxWindowBits;
bool serverSide; bool serverSide;
RawZLibFilter decoder; RawZLibFilter? decoder;
RawZLibFilter encoder; RawZLibFilter? encoder;
_WebSocketPerMessageDeflate( _WebSocketPerMessageDeflate(
{this.clientMaxWindowBits: _WebSocketImpl.DEFAULT_WINDOW_BITS, {this.clientMaxWindowBits = _WebSocketImpl.DEFAULT_WINDOW_BITS,
this.serverMaxWindowBits: _WebSocketImpl.DEFAULT_WINDOW_BITS, this.serverMaxWindowBits = _WebSocketImpl.DEFAULT_WINDOW_BITS,
this.serverNoContextTakeover: false, this.serverNoContextTakeover = false,
this.clientNoContextTakeover: false, this.clientNoContextTakeover = false,
this.serverSide: false}); this.serverSide = false});
void _ensureDecoder() { RawZLibFilter _ensureDecoder() => decoder ??= new RawZLibFilter.inflateFilter(
if (decoder == null) { windowBits: serverSide ? clientMaxWindowBits : serverMaxWindowBits,
decoder = new RawZLibFilter.inflateFilter( raw: true);
windowBits: serverSide ? clientMaxWindowBits : serverMaxWindowBits,
raw: true);
}
}
void _ensureEncoder() { RawZLibFilter _ensureEncoder() => encoder ??= new RawZLibFilter.deflateFilter(
if (encoder == null) { windowBits: serverSide ? serverMaxWindowBits : clientMaxWindowBits,
encoder = new RawZLibFilter.deflateFilter( raw: true);
windowBits: serverSide ? serverMaxWindowBits : clientMaxWindowBits,
raw: true);
}
}
Uint8List processIncomingMessage(List<int> msg) { Uint8List processIncomingMessage(List<int> msg) {
_ensureDecoder(); var decoder = _ensureDecoder();
var data = <int>[]; var data = <int>[];
data.addAll(msg); data.addAll(msg);
@ -608,20 +604,22 @@ class _WebSocketPerMessageDeflate {
final result = new BytesBuilder(); final result = new BytesBuilder();
List<int> out; List<int> out;
while ((out = decoder.processed()) != null) { while (true) {
final out = decoder.processed();
if (out == null) break;
result.add(out); result.add(out);
} }
if ((serverSide && clientNoContextTakeover) || if ((serverSide && clientNoContextTakeover) ||
(!serverSide && serverNoContextTakeover)) { (!serverSide && serverNoContextTakeover)) {
decoder = null; this.decoder = null;
} }
return result.takeBytes(); return result.takeBytes();
} }
List<int> processOutgoingMessage(List<int> msg) { List<int> processOutgoingMessage(List<int> msg) {
_ensureEncoder(); var encoder = _ensureEncoder();
var result = <int>[]; var result = <int>[];
Uint8List buffer; Uint8List buffer;
@ -639,14 +637,15 @@ class _WebSocketPerMessageDeflate {
encoder.process(buffer, 0, buffer.length); encoder.process(buffer, 0, buffer.length);
List<int> out; while (true) {
while ((out = encoder.processed()) != null) { final out = encoder.processed();
if (out == null) break;
result.addAll(out); result.addAll(out);
} }
if ((!serverSide && clientNoContextTakeover) || if ((!serverSide && clientNoContextTakeover) ||
(serverSide && serverNoContextTakeover)) { (serverSide && serverNoContextTakeover)) {
encoder = null; this.encoder = null;
} }
if (result.length > 4) { if (result.length > 4) {
@ -670,13 +669,12 @@ class _WebSocketPerMessageDeflate {
class _WebSocketOutgoingTransformer class _WebSocketOutgoingTransformer
extends StreamTransformerBase<dynamic, List<int>> implements EventSink { extends StreamTransformerBase<dynamic, List<int>> implements EventSink {
final _WebSocketImpl webSocket; final _WebSocketImpl webSocket;
EventSink<List<int>> _eventSink; EventSink<List<int>>? _eventSink;
_WebSocketPerMessageDeflate _deflateHelper; _WebSocketPerMessageDeflate? _deflateHelper;
_WebSocketOutgoingTransformer(this.webSocket) { _WebSocketOutgoingTransformer(this.webSocket)
_deflateHelper = webSocket._deflate; : _deflateHelper = webSocket._deflate;
}
Stream<List<int>> bind(Stream stream) { Stream<List<int>> bind(Stream stream) {
return new Stream<List<int>>.eventTransformed(stream, return new Stream<List<int>>.eventTransformed(stream,
@ -698,53 +696,55 @@ class _WebSocketOutgoingTransformer
addFrame(_WebSocketOpcode.PING, message.payload); addFrame(_WebSocketOpcode.PING, message.payload);
return; return;
} }
List<int> data; List<int>? data;
int opcode; int opcode;
if (message != null) { if (message != null) {
List<int> messageData;
if (message is String) { if (message is String) {
opcode = _WebSocketOpcode.TEXT; opcode = _WebSocketOpcode.TEXT;
data = utf8.encode(message); messageData = utf8.encode(message);
} else if (message is List<int>) { } else if (message is List<int>) {
opcode = _WebSocketOpcode.BINARY; opcode = _WebSocketOpcode.BINARY;
data = message; messageData = message;
} else if (message is _EncodedString) { } else if (message is _EncodedString) {
opcode = _WebSocketOpcode.TEXT; opcode = _WebSocketOpcode.TEXT;
data = message.bytes; messageData = message.bytes;
} else { } else {
throw new ArgumentError(message); throw new ArgumentError(message);
} }
var deflateHelper = _deflateHelper;
if (_deflateHelper != null) { if (deflateHelper != null) {
data = _deflateHelper.processOutgoingMessage(data); messageData = deflateHelper.processOutgoingMessage(messageData);
} }
data = messageData;
} else { } else {
opcode = _WebSocketOpcode.TEXT; opcode = _WebSocketOpcode.TEXT;
} }
addFrame(opcode, data); addFrame(opcode, data);
} }
void addError(Object error, [StackTrace stackTrace]) { void addError(Object error, [StackTrace? stackTrace]) {
// TODO(40614): Remove once non-nullability is sound.
ArgumentError.checkNotNull(error, "error"); ArgumentError.checkNotNull(error, "error");
_eventSink.addError(error, stackTrace); _eventSink!.addError(error, stackTrace);
} }
void close() { void close() {
int code = webSocket._outCloseCode; int? code = webSocket._outCloseCode;
String reason = webSocket._outCloseReason; String? reason = webSocket._outCloseReason;
List<int> data; List<int>? data;
if (code != null) { if (code != null) {
data = new List<int>(); data = [
data.add((code >> 8) & 0xFF); (code >> 8) & 0xFF,
data.add(code & 0xFF); code & 0xFF,
if (reason != null) { if (reason != null) ...utf8.encode(reason)
data.addAll(utf8.encode(reason)); ];
}
} }
addFrame(_WebSocketOpcode.CLOSE, data); addFrame(_WebSocketOpcode.CLOSE, data);
_eventSink.close(); _eventSink!.close();
} }
void addFrame(int opcode, List<int> data) { void addFrame(int opcode, List<int>? data) {
createFrame( createFrame(
opcode, opcode,
data, data,
@ -753,12 +753,12 @@ class _WebSocketOutgoingTransformer
(opcode == _WebSocketOpcode.TEXT || (opcode == _WebSocketOpcode.TEXT ||
opcode == _WebSocketOpcode.BINARY)) opcode == _WebSocketOpcode.BINARY))
.forEach((e) { .forEach((e) {
_eventSink.add(e); _eventSink!.add(e);
}); });
} }
static Iterable<List<int>> createFrame( static Iterable<List<int>> createFrame(
int opcode, List<int> data, bool serverSide, bool compressed) { int opcode, List<int>? data, bool serverSide, bool compressed) {
bool mask = !serverSide; // Masking not implemented for server. bool mask = !serverSide; // Masking not implemented for server.
int dataLength = data == null ? 0 : data.length; int dataLength = data == null ? 0 : data.length;
// Determine the header size. // Determine the header size.
@ -849,58 +849,59 @@ class _WebSocketOutgoingTransformer
class _WebSocketConsumer implements StreamConsumer { class _WebSocketConsumer implements StreamConsumer {
final _WebSocketImpl webSocket; final _WebSocketImpl webSocket;
final Socket socket; final Socket socket;
StreamController _controller; StreamController? _controller;
StreamSubscription _subscription; StreamSubscription? _subscription;
bool _issuedPause = false; bool _issuedPause = false;
bool _closed = false; bool _closed = false;
Completer _closeCompleter = new Completer<WebSocket>(); Completer _closeCompleter = new Completer<WebSocket>();
Completer _completer; Completer? _completer;
_WebSocketConsumer(this.webSocket, this.socket); _WebSocketConsumer(this.webSocket, this.socket);
void _onListen() { void _onListen() {
if (_subscription != null) { _subscription?.cancel();
_subscription.cancel();
}
} }
void _onPause() { void _onPause() {
if (_subscription != null) { var subscription = _subscription;
_subscription.pause(); if (subscription != null) {
subscription.pause();
} else { } else {
_issuedPause = true; _issuedPause = true;
} }
} }
void _onResume() { void _onResume() {
if (_subscription != null) { var subscription = _subscription;
_subscription.resume(); if (subscription != null) {
subscription.resume();
} else { } else {
_issuedPause = false; _issuedPause = false;
} }
} }
void _cancel() { void _cancel() {
if (_subscription != null) { var subscription = _subscription;
var subscription = _subscription; if (subscription != null) {
_subscription = null; _subscription = null;
subscription.cancel(); subscription.cancel();
} }
} }
_ensureController() { StreamController _ensureController() {
if (_controller != null) return; var controller = _controller;
_controller = new StreamController( if (controller != null) return controller;
controller = _controller = new StreamController(
sync: true, sync: true,
onPause: _onPause, onPause: _onPause,
onResume: _onResume, onResume: _onResume,
onCancel: _onListen); onCancel: _onListen);
var stream = _controller.stream var stream = controller.stream
.transform(new _WebSocketOutgoingTransformer(webSocket)); .transform(new _WebSocketOutgoingTransformer(webSocket));
socket.addStream(stream).then((_) { socket.addStream(stream).then((_) {
_done(); _done();
_closeCompleter.complete(webSocket); _closeCompleter.complete(webSocket);
}, onError: (error, StackTrace stackTrace) { }, onError: (Object error, StackTrace stackTrace) {
_closed = true; _closed = true;
_cancel(); _cancel();
if (error is ArgumentError) { if (error is ArgumentError) {
@ -912,53 +913,52 @@ class _WebSocketConsumer implements StreamConsumer {
_closeCompleter.complete(webSocket); _closeCompleter.complete(webSocket);
} }
}); });
return controller;
} }
bool _done([error, StackTrace stackTrace]) { bool _done([Object? error, StackTrace? stackTrace]) {
if (_completer == null) return false; var completer = _completer;
if (completer == null) return false;
if (error != null) { if (error != null) {
_completer.completeError(error, stackTrace); completer.completeError(error, stackTrace);
} else { } else {
_completer.complete(webSocket); completer.complete(webSocket);
} }
_completer = null; _completer = null;
return true; return true;
} }
Future addStream(var stream) { Future addStream(Stream stream) {
if (_closed) { if (_closed) {
stream.listen(null).cancel(); stream.listen(null).cancel();
return new Future.value(webSocket); return new Future.value(webSocket);
} }
_ensureController(); _ensureController();
_completer = new Completer(); var completer = _completer = new Completer();
_subscription = stream.listen((data) { var subscription = _subscription = stream.listen((data) {
_controller.add(data); _controller!.add(data);
}, onDone: _done, onError: _done, cancelOnError: true); }, onDone: _done, onError: _done, cancelOnError: true);
if (_issuedPause) { if (_issuedPause) {
_subscription.pause(); subscription.pause();
_issuedPause = false; _issuedPause = false;
} }
return _completer.future; return completer.future;
} }
Future close() { Future close() {
_ensureController(); _ensureController().close();
Future closeSocket() {
return socket.close().catchError((_) {}).then((_) => webSocket);
}
_controller.close(); return _closeCompleter.future
return _closeCompleter.future.then((_) => closeSocket()); .then((_) => socket.close().catchError((_) {}).then((_) => webSocket));
} }
void add(data) { void add(data) {
if (_closed) return; if (_closed) return;
_ensureController(); var controller = _ensureController();
// Stop sending message if _controller has been closed. // Stop sending message if _controller has been closed.
// https://github.com/dart-lang/sdk/issues/37441 // https://github.com/dart-lang/sdk/issues/37441
if (_controller.isClosed) return; if (controller.isClosed) return;
_controller.add(data); controller.add(data);
} }
void closeSocket() { void closeSocket() {
@ -974,32 +974,33 @@ class _WebSocketImpl extends Stream with _ServiceObject implements WebSocket {
static const int DEFAULT_WINDOW_BITS = 15; static const int DEFAULT_WINDOW_BITS = 15;
static const String PER_MESSAGE_DEFLATE = "permessage-deflate"; static const String PER_MESSAGE_DEFLATE = "permessage-deflate";
final String protocol; final String? protocol;
StreamController _controller; final StreamController _controller;
StreamSubscription _subscription; StreamSubscription? _subscription;
StreamSink _sink; late StreamSink _sink;
final _socket; final Socket _socket;
final bool _serverSide; final bool _serverSide;
int _readyState = WebSocket.connecting; int _readyState = WebSocket.connecting;
bool _writeClosed = false; bool _writeClosed = false;
int _closeCode; int? _closeCode;
String _closeReason; String? _closeReason;
Duration _pingInterval; Duration? _pingInterval;
Timer _pingTimer; Timer? _pingTimer;
_WebSocketConsumer _consumer; late _WebSocketConsumer _consumer;
int _outCloseCode; int? _outCloseCode;
String _outCloseReason; String? _outCloseReason;
Timer _closeTimer; Timer? _closeTimer;
_WebSocketPerMessageDeflate _deflate; _WebSocketPerMessageDeflate? _deflate;
static final HttpClient _httpClient = new HttpClient(); static final HttpClient _httpClient = new HttpClient();
static Future<WebSocket> connect( static Future<WebSocket> connect(
String url, Iterable<String> protocols, Map<String, dynamic> headers, String url, Iterable<String>? protocols, Map<String, dynamic>? headers,
{CompressionOptions compression: CompressionOptions.compressionDefault}) { {CompressionOptions compression =
CompressionOptions.compressionDefault}) {
Uri uri = Uri.parse(url); Uri uri = Uri.parse(url);
if (uri.scheme != "ws" && uri.scheme != "wss") { if (uri.scheme != "ws" && uri.scheme != "wss") {
throw new WebSocketException("Unsupported URL scheme '${uri.scheme}'"); throw new WebSocketException("Unsupported URL scheme '${uri.scheme}'");
@ -1049,7 +1050,7 @@ class _WebSocketImpl extends Stream with _ServiceObject implements WebSocket {
return request.close(); return request.close();
}).then((response) { }).then((response) {
void error(String message) { Never error(String message) {
// Flush data. // Flush data.
response.detachSocket().then((socket) { response.detachSocket().then((socket) {
socket.destroy(); socket.destroy();
@ -1057,15 +1058,15 @@ class _WebSocketImpl extends Stream with _ServiceObject implements WebSocket {
throw new WebSocketException(message); throw new WebSocketException(message);
} }
var connectionHeader = response.headers[HttpHeaders.connectionHeader];
if (response.statusCode != HttpStatus.switchingProtocols || if (response.statusCode != HttpStatus.switchingProtocols ||
response.headers[HttpHeaders.connectionHeader] == null || connectionHeader == null ||
!response.headers[HttpHeaders.connectionHeader] !connectionHeader.any((value) => value.toLowerCase() == "upgrade") ||
.any((value) => value.toLowerCase() == "upgrade") || response.headers.value(HttpHeaders.upgradeHeader)!.toLowerCase() !=
response.headers.value(HttpHeaders.upgradeHeader).toLowerCase() !=
"websocket") { "websocket") {
error("Connection to '$uri' was not upgraded to websocket"); error("Connection to '$uri' was not upgraded to websocket");
} }
String accept = response.headers.value("Sec-WebSocket-Accept"); String? accept = response.headers.value("Sec-WebSocket-Accept");
if (accept == null) { if (accept == null) {
error("Response did not contain a 'Sec-WebSocket-Accept' header"); error("Response did not contain a 'Sec-WebSocket-Accept' header");
} }
@ -1083,7 +1084,7 @@ class _WebSocketImpl extends Stream with _ServiceObject implements WebSocket {
} }
var protocol = response.headers.value('Sec-WebSocket-Protocol'); var protocol = response.headers.value('Sec-WebSocket-Protocol');
_WebSocketPerMessageDeflate deflate = _WebSocketPerMessageDeflate? deflate =
negotiateClientCompression(response, compression); negotiateClientCompression(response, compression);
return response.detachSocket().then<WebSocket>((socket) => return response.detachSocket().then<WebSocket>((socket) =>
@ -1092,13 +1093,10 @@ class _WebSocketImpl extends Stream with _ServiceObject implements WebSocket {
}); });
} }
static _WebSocketPerMessageDeflate negotiateClientCompression( static _WebSocketPerMessageDeflate? negotiateClientCompression(
HttpClientResponse response, CompressionOptions compression) { HttpClientResponse response, CompressionOptions compression) {
String extensionHeader = response.headers.value('Sec-WebSocket-Extensions'); String extensionHeader =
response.headers.value('Sec-WebSocket-Extensions') ?? "";
if (extensionHeader == null) {
extensionHeader = "";
}
var hv = HeaderValue.parse(extensionHeader, valueSeparator: ','); var hv = HeaderValue.parse(extensionHeader, valueSeparator: ',');
@ -1129,14 +1127,15 @@ class _WebSocketImpl extends Stream with _ServiceObject implements WebSocket {
_WebSocketImpl._fromSocket( _WebSocketImpl._fromSocket(
this._socket, this.protocol, CompressionOptions compression, this._socket, this.protocol, CompressionOptions compression,
[this._serverSide = false, _WebSocketPerMessageDeflate deflate]) { [this._serverSide = false, _WebSocketPerMessageDeflate? deflate])
: _controller = new StreamController(sync: true) {
_consumer = new _WebSocketConsumer(this, _socket); _consumer = new _WebSocketConsumer(this, _socket);
_sink = new _StreamSinkImpl(_consumer); _sink = new _StreamSinkImpl(_consumer);
_readyState = WebSocket.open; _readyState = WebSocket.open;
_deflate = deflate; _deflate = deflate;
var transformer = new _WebSocketProtocolTransformer(_serverSide, _deflate); var transformer = new _WebSocketProtocolTransformer(_serverSide, deflate);
_subscription = transformer.bind(_socket).listen((data) { var subscription = _subscription = transformer.bind(_socket).listen((data) {
if (data is _WebSocketPing) { if (data is _WebSocketPing) {
if (!_writeClosed) _consumer.add(new _WebSocketPong(data.payload)); if (!_writeClosed) _consumer.add(new _WebSocketPong(data.payload));
} else if (data is _WebSocketPong) { } else if (data is _WebSocketPong) {
@ -1145,8 +1144,8 @@ class _WebSocketImpl extends Stream with _ServiceObject implements WebSocket {
} else { } else {
_controller.add(data); _controller.add(data);
} }
}, onError: (error, stackTrace) { }, onError: (Object error, StackTrace stackTrace) {
if (_closeTimer != null) _closeTimer.cancel(); _closeTimer?.cancel();
if (error is FormatException) { if (error is FormatException) {
_close(WebSocketStatus.invalidFramePayloadData); _close(WebSocketStatus.invalidFramePayloadData);
} else { } else {
@ -1157,7 +1156,7 @@ class _WebSocketImpl extends Stream with _ServiceObject implements WebSocket {
_closeReason = _outCloseReason; _closeReason = _outCloseReason;
_controller.close(); _controller.close();
}, onDone: () { }, onDone: () {
if (_closeTimer != null) _closeTimer.cancel(); _closeTimer?.cancel();
if (_readyState == WebSocket.open) { if (_readyState == WebSocket.open) {
_readyState = WebSocket.closing; _readyState = WebSocket.closing;
if (!_isReservedStatusCode(transformer.closeCode)) { if (!_isReservedStatusCode(transformer.closeCode)) {
@ -1172,39 +1171,38 @@ class _WebSocketImpl extends Stream with _ServiceObject implements WebSocket {
_closeReason = transformer.closeReason; _closeReason = transformer.closeReason;
_controller.close(); _controller.close();
}, cancelOnError: true); }, cancelOnError: true);
_subscription.pause(); subscription.pause();
_controller = new StreamController( _controller
sync: true, ..onListen = subscription.resume
onListen: _subscription.resume, ..onCancel = () {
onCancel: () { _subscription!.cancel();
_subscription.cancel(); _subscription = null;
_subscription = null; }
}, ..onPause = subscription.pause
onPause: _subscription.pause, ..onResume = subscription.resume;
onResume: _subscription.resume);
_webSockets[_serviceId] = this; _webSockets[_serviceId] = this;
} }
StreamSubscription listen(void onData(message), StreamSubscription listen(void onData(message)?,
{Function onError, void onDone(), bool cancelOnError}) { {Function? onError, void onDone()?, bool? cancelOnError}) {
return _controller.stream.listen(onData, return _controller.stream.listen(onData,
onError: onError, onDone: onDone, cancelOnError: cancelOnError); onError: onError, onDone: onDone, cancelOnError: cancelOnError);
} }
Duration get pingInterval => _pingInterval; Duration? get pingInterval => _pingInterval;
void set pingInterval(Duration interval) { void set pingInterval(Duration? interval) {
if (_writeClosed) return; if (_writeClosed) return;
if (_pingTimer != null) _pingTimer.cancel(); _pingTimer?.cancel();
_pingInterval = interval; _pingInterval = interval;
if (_pingInterval == null) return; if (interval == null) return;
_pingTimer = new Timer(_pingInterval, () { _pingTimer = new Timer(interval, () {
if (_writeClosed) return; if (_writeClosed) return;
_consumer.add(new _WebSocketPing()); _consumer.add(new _WebSocketPing());
_pingTimer = new Timer(_pingInterval, () { _pingTimer = new Timer(interval, () {
_closeTimer?.cancel(); _closeTimer?.cancel();
// No pong received. // No pong received.
_close(WebSocketStatus.goingAway); _close(WebSocketStatus.goingAway);
@ -1217,27 +1215,28 @@ class _WebSocketImpl extends Stream with _ServiceObject implements WebSocket {
int get readyState => _readyState; int get readyState => _readyState;
String get extensions => null; String get extensions => "";
int get closeCode => _closeCode; int? get closeCode => _closeCode;
String get closeReason => _closeReason; String? get closeReason => _closeReason;
void add(data) { void add(data) {
_sink.add(data); _sink.add(data);
} }
void addUtf8Text(List<int> bytes) { void addUtf8Text(List<int> bytes) {
// TODO(40614): Remove once non-nullability is sound.
ArgumentError.checkNotNull(bytes, "bytes"); ArgumentError.checkNotNull(bytes, "bytes");
_sink.add(new _EncodedString(bytes)); _sink.add(new _EncodedString(bytes));
} }
void addError(error, [StackTrace stackTrace]) { void addError(Object error, [StackTrace? stackTrace]) {
_sink.addError(error, stackTrace); _sink.addError(error, stackTrace);
} }
Future addStream(Stream stream) => _sink.addStream(stream); Future addStream(Stream stream) => _sink.addStream(stream);
Future get done => _sink.done; Future get done => _sink.done;
Future close([int code, String reason]) { Future close([int? code, String? reason]) {
if (_isReservedStatusCode(code)) { if (_isReservedStatusCode(code)) {
throw new WebSocketException("Reserved status code $code"); throw new WebSocketException("Reserved status code $code");
} }
@ -1260,7 +1259,7 @@ class _WebSocketImpl extends Stream with _ServiceObject implements WebSocket {
// Reuse code and reason from the local close. // Reuse code and reason from the local close.
_closeCode = _outCloseCode; _closeCode = _outCloseCode;
_closeReason = _outCloseReason; _closeReason = _outCloseReason;
if (_subscription != null) _subscription.cancel(); _subscription?.cancel();
_controller.close(); _controller.close();
_webSockets.remove(_serviceId); _webSockets.remove(_serviceId);
}); });
@ -1269,13 +1268,13 @@ class _WebSocketImpl extends Stream with _ServiceObject implements WebSocket {
return _sink.close(); return _sink.close();
} }
static String get userAgent => _httpClient.userAgent; static String? get userAgent => _httpClient.userAgent;
static set userAgent(String userAgent) { static set userAgent(String? userAgent) {
_httpClient.userAgent = userAgent; _httpClient.userAgent = userAgent;
} }
void _close([int code, String reason]) { void _close([int? code, String? reason]) {
if (_writeClosed) return; if (_writeClosed) return;
if (_outCloseCode == null) { if (_outCloseCode == null) {
_outCloseCode = code; _outCloseCode = code;
@ -1301,7 +1300,7 @@ class _WebSocketImpl extends Stream with _ServiceObject implements WebSocket {
return r; return r;
} }
try { try {
r['socket'] = _socket._toJSON(true); r['socket'] = (_socket as dynamic)._toJSON(true);
} catch (_) { } catch (_) {
r['socket'] = { r['socket'] = {
'id': _servicePath, 'id': _servicePath,
@ -1313,7 +1312,7 @@ class _WebSocketImpl extends Stream with _ServiceObject implements WebSocket {
return r; return r;
} }
static bool _isReservedStatusCode(int code) { static bool _isReservedStatusCode(int? code) {
return code != null && return code != null &&
(code < WebSocketStatus.normalClosure || (code < WebSocketStatus.normalClosure ||
code == WebSocketStatus.reserved1004 || code == WebSocketStatus.reserved1004 ||

View file

@ -1,313 +0,0 @@
// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
// @dart = 2.6
library libraries;
/**
* A bit flag used by [LibraryInfo] indicating that a library is used by dart2js
*/
const int DART2JS_PLATFORM = 1;
/**
* A bit flag used by [LibraryInfo] indicating that a library is used by the VM
*/
const int VM_PLATFORM = 2;
/// The contexts that a library can be used from.
enum Category {
/// Indicates that a library can be used in a browser context.
client,
/// Indicates that a library can be used in a command line context.
server,
/// Indicates that a library can be used from embedded devices.
embedded
}
Category parseCategory(String name) {
switch (name) {
case "Client":
return Category.client;
case "Server":
return Category.server;
case "Embedded":
return Category.embedded;
}
return null;
}
/// Mapping of "dart:" library name (e.g. "core") to information about that
/// library.
const Map<String, LibraryInfo> libraries = const {
"async": const LibraryInfo("async/async.dart",
categories: "Client,Server",
maturity: Maturity.STABLE,
dart2jsPatchPath: "_internal/js_runtime/lib/async_patch.dart"),
"collection": const LibraryInfo("collection/collection.dart",
categories: "Client,Server,Embedded",
maturity: Maturity.STABLE,
dart2jsPatchPath: "_internal/js_runtime/lib/collection_patch.dart"),
"convert": const LibraryInfo("convert/convert.dart",
categories: "Client,Server",
maturity: Maturity.STABLE,
dart2jsPatchPath: "_internal/js_runtime/lib/convert_patch.dart"),
"core": const LibraryInfo("core/core.dart",
categories: "Client,Server,Embedded",
maturity: Maturity.STABLE,
dart2jsPatchPath: "_internal/js_runtime/lib/core_patch.dart"),
"developer": const LibraryInfo("developer/developer.dart",
categories: "Client,Server,Embedded",
maturity: Maturity.UNSTABLE,
dart2jsPatchPath: "_internal/js_runtime/lib/developer_patch.dart"),
"html": const LibraryInfo("html/dart2js/html_dart2js.dart",
categories: "Client",
maturity: Maturity.WEB_STABLE,
platforms: DART2JS_PLATFORM),
"html_common": const LibraryInfo("html/html_common/html_common.dart",
categories: "Client",
maturity: Maturity.WEB_STABLE,
dart2jsPath: "html/html_common/html_common_dart2js.dart",
documented: false,
implementation: true),
"indexed_db": const LibraryInfo("indexed_db/dart2js/indexed_db_dart2js.dart",
categories: "Client",
maturity: Maturity.WEB_STABLE,
platforms: DART2JS_PLATFORM),
"_http":
const LibraryInfo("_http/http.dart", categories: "", documented: false),
"io": const LibraryInfo("io/io.dart",
categories: "Server",
dart2jsPatchPath: "_internal/js_runtime/lib/io_patch.dart"),
"isolate": const LibraryInfo("isolate/isolate.dart",
categories: "Client,Server",
maturity: Maturity.STABLE,
dart2jsPatchPath: "_internal/js_runtime/lib/isolate_patch.dart"),
"js": const LibraryInfo("js/js.dart",
categories: "Client",
maturity: Maturity.STABLE,
platforms: DART2JS_PLATFORM,
dart2jsPatchPath: "_internal/js_runtime/lib/js_patch.dart"),
"js_util": const LibraryInfo("js_util/js_util.dart",
categories: "Client",
maturity: Maturity.STABLE,
platforms: DART2JS_PLATFORM),
"math": const LibraryInfo("math/math.dart",
categories: "Client,Server,Embedded",
maturity: Maturity.STABLE,
dart2jsPatchPath: "_internal/js_runtime/lib/math_patch.dart"),
"mirrors": const LibraryInfo("mirrors/mirrors.dart",
categories: "Client,Server",
maturity: Maturity.UNSTABLE,
dart2jsPatchPath: "_internal/js_runtime/lib/mirrors_patch.dart"),
"nativewrappers": const LibraryInfo("html/dartium/nativewrappers.dart",
categories: "Client",
implementation: true,
documented: false,
platforms: DART2JS_PLATFORM),
"typed_data": const LibraryInfo("typed_data/typed_data.dart",
categories: "Client,Server,Embedded",
maturity: Maturity.STABLE,
dart2jsPatchPath: "_internal/js_runtime/lib/typed_data_patch.dart"),
"_native_typed_data": const LibraryInfo(
"_internal/js_runtime/lib/native_typed_data.dart",
categories: "",
implementation: true,
documented: false,
platforms: DART2JS_PLATFORM),
"cli": const LibraryInfo("cli/cli.dart",
categories: "Server",
dart2jsPatchPath: "_internal/js_runtime/lib/cli_patch.dart"),
"svg": const LibraryInfo("svg/dart2js/svg_dart2js.dart",
categories: "Client",
maturity: Maturity.WEB_STABLE,
platforms: DART2JS_PLATFORM),
"web_audio": const LibraryInfo("web_audio/dart2js/web_audio_dart2js.dart",
categories: "Client",
maturity: Maturity.WEB_STABLE,
platforms: DART2JS_PLATFORM),
"web_gl": const LibraryInfo("web_gl/dart2js/web_gl_dart2js.dart",
categories: "Client",
maturity: Maturity.WEB_STABLE,
platforms: DART2JS_PLATFORM),
"web_sql": const LibraryInfo("web_sql/dart2js/web_sql_dart2js.dart",
categories: "Client",
maturity: Maturity.WEB_STABLE,
platforms: DART2JS_PLATFORM),
"_internal": const LibraryInfo("internal/internal.dart",
categories: "",
documented: false,
dart2jsPatchPath: "_internal/js_runtime/lib/internal_patch.dart"),
"_js_helper": const LibraryInfo("_internal/js_runtime/lib/js_helper.dart",
categories: "", documented: false, platforms: DART2JS_PLATFORM),
"_interceptors": const LibraryInfo(
"_internal/js_runtime/lib/interceptors.dart",
categories: "",
documented: false,
platforms: DART2JS_PLATFORM),
"_foreign_helper": const LibraryInfo(
"_internal/js_runtime/lib/foreign_helper.dart",
categories: "",
documented: false,
platforms: DART2JS_PLATFORM),
"_isolate_helper": const LibraryInfo(
"_internal/js_runtime/lib/isolate_helper.dart",
categories: "",
documented: false,
platforms: DART2JS_PLATFORM),
"_js_mirrors": const LibraryInfo("_internal/js_runtime/lib/js_mirrors.dart",
categories: "", documented: false, platforms: DART2JS_PLATFORM),
"_js_primitives": const LibraryInfo(
"_internal/js_runtime/lib/js_primitives.dart",
categories: "",
documented: false,
platforms: DART2JS_PLATFORM),
"_metadata": const LibraryInfo("html/html_common/metadata.dart",
categories: "", documented: false, platforms: DART2JS_PLATFORM),
"_debugger": const LibraryInfo("_internal/js_runtime/lib/debugger.dart",
category: "", documented: false, platforms: DART2JS_PLATFORM),
"_runtime": const LibraryInfo(
"_internal/js_runtime/lib/ddc_runtime/runtime.dart",
category: "",
documented: false,
platforms: DART2JS_PLATFORM),
};
/**
* Information about a "dart:" library.
*/
class LibraryInfo {
/**
* Path to the library's *.dart file relative to this file.
*/
final String path;
/**
* The categories in which the library can be used encoded as a
* comma-separated String.
*/
final String _categories;
/**
* Path to the dart2js library's *.dart file relative to this file
* or null if dart2js uses the common library path defined above.
* Access using the [#getDart2JsPath()] method.
*/
final String dart2jsPath;
/**
* Path to the dart2js library's patch file relative to this file
* or null if no dart2js patch file associated with this library.
* Access using the [#getDart2JsPatchPath()] method.
*/
final String dart2jsPatchPath;
/**
* True if this library is documented and should be shown to the user.
*/
final bool documented;
/**
* Bit flags indicating which platforms consume this library.
* See [DART2JS_LIBRARY] and [VM_LIBRARY].
*/
final int platforms;
/**
* True if the library contains implementation details for another library.
* The implication is that these libraries are less commonly used
* and that tools like Dart Editor should not show these libraries
* in a list of all libraries unless the user specifically asks the tool to
* do so.
*/
final bool implementation;
/**
* States the current maturity of this library.
*/
final Maturity maturity;
const LibraryInfo(this.path,
{String categories: "",
this.dart2jsPath,
this.dart2jsPatchPath,
this.implementation: false,
this.documented: true,
this.maturity: Maturity.UNSPECIFIED,
this.platforms: DART2JS_PLATFORM | VM_PLATFORM})
: _categories = categories;
bool get isDart2jsLibrary => (platforms & DART2JS_PLATFORM) != 0;
bool get isVmLibrary => (platforms & VM_PLATFORM) != 0;
/**
* The categories in which the library can be used.
*
* If no categories are specified, the library is internal and can not be
* loaded by user code.
*/
List<Category> get categories {
// `"".split(,)` returns [""] not [], so we handle that case separately.
if (_categories == "") return const <Category>[];
return _categories.split(",").map(parseCategory).toList();
}
bool get isInternal => categories.isEmpty;
/// The original "categories" String that was passed to the constructor.
///
/// Can be used to construct a slightly modified copy of this LibraryInfo.
String get categoriesString {
return _categories;
}
}
/**
* Abstraction to capture the maturity of a library.
*/
class Maturity {
final int level;
final String name;
final String description;
const Maturity(this.level, this.name, this.description);
String toString() => "$name: $level\n$description\n";
static const Maturity DEPRECATED = const Maturity(0, "Deprecated",
"This library will be remove before next major release.");
static const Maturity EXPERIMENTAL = const Maturity(
1,
"Experimental",
"This library is experimental and will likely change or be removed\n"
"in future versions.");
static const Maturity UNSTABLE = const Maturity(
2,
"Unstable",
"This library is in still changing and have not yet endured\n"
"sufficient real-world testing.\n"
"Backwards-compatibility is NOT guaranteed.");
static const Maturity WEB_STABLE = const Maturity(
3,
"Web Stable",
"This library is tracking the DOM evolution as defined by WC3.\n"
"Backwards-compatibility is NOT guaranteed.");
static const Maturity STABLE = const Maturity(
4,
"Stable",
"The library is stable. API backwards-compatibility is guaranteed.\n"
"However implementation details might change.");
static const Maturity LOCKED = const Maturity(5, "Locked",
"This library will not change except when serious bugs are encountered.");
static const Maturity UNSPECIFIED = const Maturity(-1, "Unspecified",
"The maturity for this library has not been specified.");
}

View file

@ -2,8 +2,6 @@
// for details. All rights reserved. Use of this source code is governed by a // for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file. // BSD-style license that can be found in the LICENSE file.
// @dart = 2.6
// Patch file for the dart:async library. // Patch file for the dart:async library.
import 'dart:_js_helper' show notNull, patch, ReifyFunctionTypes; import 'dart:_js_helper' show notNull, patch, ReifyFunctionTypes;
@ -26,11 +24,11 @@ import 'dart:_runtime' as dart;
@ReifyFunctionTypes(false) @ReifyFunctionTypes(false)
_async<T>(Function() initGenerator) { _async<T>(Function() initGenerator) {
var iter; var iter;
Object Function(Object) onValue; late Object? Function(Object?) onValue;
Object Function(Object, StackTrace) onError; late Object Function(Object, StackTrace?) onError;
onAwait(Object value) { onAwait(Object? value) {
_Future f; _Future<Object?> f;
if (value is _Future) { if (value is _Future) {
f = value; f = value;
} else if (value is Future) { } else if (value is Future) {
@ -161,7 +159,7 @@ class _AsyncRun {
} }
@ReifyFunctionTypes(false) @ReifyFunctionTypes(false)
static Object _scheduleImmediateWithPromise(void Function() callback) { static void _scheduleImmediateWithPromise(void Function() callback) {
dart.addAsyncCallback(); dart.addAsyncCallback();
JS('', '#.Promise.resolve(null).then(#)', dart.global_, () { JS('', '#.Promise.resolve(null).then(#)', dart.global_, () {
dart.removeAsyncCallback(); dart.removeAsyncCallback();
@ -182,7 +180,7 @@ class DeferredLibrary {
@patch @patch
class Timer { class Timer {
@patch @patch
static Timer _createTimer(Duration duration, void callback()) { static Timer _createTimer(Duration duration, void Function() callback) {
int milliseconds = duration.inMilliseconds; int milliseconds = duration.inMilliseconds;
if (milliseconds < 0) milliseconds = 0; if (milliseconds < 0) milliseconds = 0;
return TimerImpl(milliseconds, callback); return TimerImpl(milliseconds, callback);
@ -228,7 +226,7 @@ void _rethrow(Object error, StackTrace stackTrace) {
/// } /// }
/// ///
class _AsyncStarImpl<T> { class _AsyncStarImpl<T> {
StreamController<T> controller; late StreamController<T> controller;
Object Function(_AsyncStarImpl<T>) initGenerator; Object Function(_AsyncStarImpl<T>) initGenerator;
@notNull @notNull
bool isSuspendedAtYieldStar = false; bool isSuspendedAtYieldStar = false;
@ -243,11 +241,11 @@ class _AsyncStarImpl<T> {
@notNull @notNull
bool isSuspendedAtAwait = false; bool isSuspendedAtAwait = false;
Completer cancellationCompleter; Completer? cancellationCompleter;
Object jsIterator; late Object jsIterator;
Null Function(Object, StackTrace) _handleErrorCallback; Null Function(Object, StackTrace)? _handleErrorCallback;
void Function([Object]) _runBodyCallback; void Function([Object?])? _runBodyCallback;
_AsyncStarImpl(this.initGenerator) { _AsyncStarImpl(this.initGenerator) {
controller = StreamController( controller = StreamController(
@ -293,10 +291,10 @@ class _AsyncStarImpl<T> {
}; };
var zone = Zone.current; var zone = Zone.current;
if (!identical(zone, Zone.root)) { if (!identical(zone, Zone.root)) {
_handleErrorCallback = zone.bindBinaryCallback(_handleErrorCallback); _handleErrorCallback = zone.bindBinaryCallback(_handleErrorCallback!);
} }
} }
return _handleErrorCallback; return _handleErrorCallback!;
} }
void scheduleGenerator() { void scheduleGenerator() {
@ -315,11 +313,11 @@ class _AsyncStarImpl<T> {
if (_runBodyCallback == null) { if (_runBodyCallback == null) {
_runBodyCallback = JS('!', '#.bind(this)', runBody); _runBodyCallback = JS('!', '#.bind(this)', runBody);
if (!identical(zone, Zone.root)) { if (!identical(zone, Zone.root)) {
var registered = zone.registerUnaryCallback(_runBodyCallback); var registered = zone.registerUnaryCallback(_runBodyCallback!);
_runBodyCallback = ([arg]) => zone.runUnaryGuarded(registered, arg); _runBodyCallback = ([arg]) => zone.runUnaryGuarded(registered, arg);
} }
} }
zone.scheduleMicrotask(_runBodyCallback); zone.scheduleMicrotask(_runBodyCallback!);
} }
void runBody(awaitValue) { void runBody(awaitValue) {
@ -332,16 +330,16 @@ class _AsyncStarImpl<T> {
iterResult = JS('', '#.next(#)', jsIterator, awaitValue); iterResult = JS('', '#.next(#)', jsIterator, awaitValue);
} catch (e, s) { } catch (e, s) {
addError(e, s); addError(e, s);
return null; return;
} }
if (JS('!', '#.done', iterResult)) { if (JS('!', '#.done', iterResult)) {
close(); close();
return null; return;
} }
// If we're suspended at a yield/yield*, we're done for now. // If we're suspended at a yield/yield*, we're done for now.
if (isSuspendedAtYield || isSuspendedAtYieldStar) return null; if (isSuspendedAtYield || isSuspendedAtYieldStar) return;
// Handle `await`: if we get a value passed to `yield` it means we are // Handle `await`: if we get a value passed to `yield` it means we are
// waiting on this Future. Make sure to prevent scheduling, and pass the // waiting on this Future. Make sure to prevent scheduling, and pass the
@ -350,10 +348,10 @@ class _AsyncStarImpl<T> {
// TODO(jmesserly): is the timing here correct? The assumption here is // TODO(jmesserly): is the timing here correct? The assumption here is
// that we should schedule `await` in `async*` the same as in `async`. // that we should schedule `await` in `async*` the same as in `async`.
isSuspendedAtAwait = true; isSuspendedAtAwait = true;
FutureOr<Object> value = JS('', '#.value', iterResult); FutureOr<Object?> value = JS('', '#.value', iterResult);
// TODO(jmesserly): this logic was copied from `async` function impl. // TODO(jmesserly): this logic was copied from `async` function impl.
_Future f; _Future<Object?> f;
if (value is _Future) { if (value is _Future) {
f = value; f = value;
} else if (value is Future) { } else if (value is Future) {
@ -362,7 +360,7 @@ class _AsyncStarImpl<T> {
} else { } else {
f = _Future.value(value); f = _Future.value(value);
} }
f._thenAwait(_runBodyCallback, handleError); f._thenAwait(_runBodyCallback!, handleError);
} }
/// Adds element to [stream] and returns true if the caller should terminate /// Adds element to [stream] and returns true if the caller should terminate
@ -417,10 +415,11 @@ class _AsyncStarImpl<T> {
void addError(Object error, StackTrace stackTrace) { void addError(Object error, StackTrace stackTrace) {
ArgumentError.checkNotNull(error, "error"); ArgumentError.checkNotNull(error, "error");
if (cancellationCompleter != null && !cancellationCompleter.isCompleted) { var completer = cancellationCompleter;
if (completer != null && !completer.isCompleted) {
// If the stream has been cancelled, complete the cancellation future // If the stream has been cancelled, complete the cancellation future
// with the error. // with the error.
cancellationCompleter.completeError(error, stackTrace); completer.completeError(error, stackTrace);
} else if (controller.hasListener) { } else if (controller.hasListener) {
controller.addError(error, stackTrace); controller.addError(error, stackTrace);
} }
@ -432,10 +431,11 @@ class _AsyncStarImpl<T> {
} }
void close() { void close() {
if (cancellationCompleter != null && !cancellationCompleter.isCompleted) { var completer = cancellationCompleter;
if (completer != null && !completer.isCompleted) {
// If the stream has been cancelled, complete the cancellation future // If the stream has been cancelled, complete the cancellation future
// with the error. // with the error.
cancellationCompleter.complete(); completer.complete();
} }
controller.close(); controller.close();
} }
@ -465,7 +465,7 @@ class _AsyncStarImpl<T> {
scheduleGenerator(); scheduleGenerator();
} }
} }
return cancellationCompleter.future; return cancellationCompleter!.future;
} }
_fatal(String message) => throw StateError(message); _fatal(String message) => throw StateError(message);

View file

@ -2,8 +2,6 @@
// for details. All rights reserved. Use of this source code is governed by a // for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file. // BSD-style license that can be found in the LICENSE file.
// @dart = 2.6
// Patch file for dart:collection classes. // Patch file for dart:collection classes.
import 'dart:_foreign_helper' show JS, JSExportName; import 'dart:_foreign_helper' show JS, JSExportName;
import 'dart:_runtime' as dart; import 'dart:_runtime' as dart;
@ -26,9 +24,9 @@ import 'dart:_js_helper'
class HashMap<K, V> { class HashMap<K, V> {
@patch @patch
factory HashMap( factory HashMap(
{bool equals(K key1, K key2), {bool Function(K, K)? equals,
int hashCode(K key), int Function(K)? hashCode,
bool isValidKey(Object potentialKey)}) { bool Function(dynamic)? isValidKey}) {
if (isValidKey == null) { if (isValidKey == null) {
if (hashCode == null) { if (hashCode == null) {
if (equals == null) { if (equals == null) {
@ -56,9 +54,9 @@ class HashMap<K, V> {
class LinkedHashMap<K, V> { class LinkedHashMap<K, V> {
@patch @patch
factory LinkedHashMap( factory LinkedHashMap(
{bool equals(K key1, K key2), {bool Function(K, K)? equals,
int hashCode(K key), int Function(K)? hashCode,
bool isValidKey(Object potentialKey)}) { bool Function(dynamic)? isValidKey}) {
if (isValidKey == null) { if (isValidKey == null) {
if (hashCode == null) { if (hashCode == null) {
if (equals == null) { if (equals == null) {
@ -86,9 +84,9 @@ class LinkedHashMap<K, V> {
class HashSet<E> { class HashSet<E> {
@patch @patch
factory HashSet( factory HashSet(
{bool equals(E e1, E e2), {bool Function(E, E)? equals,
int hashCode(E e), int Function(E)? hashCode,
bool isValidKey(Object potentialKey)}) { bool Function(dynamic)? isValidKey}) {
if (isValidKey == null) { if (isValidKey == null) {
if (hashCode == null) { if (hashCode == null) {
if (equals == null) { if (equals == null) {
@ -97,7 +95,6 @@ class HashSet<E> {
} }
return _HashSet<E>(); return _HashSet<E>();
} }
hashCode = dart.hashCode;
} else if (identical(identityHashCode, hashCode) && } else if (identical(identityHashCode, hashCode) &&
identical(identical, equals)) { identical(identical, equals)) {
return _IdentityHashSet<E>(); return _IdentityHashSet<E>();
@ -117,9 +114,9 @@ class HashSet<E> {
class LinkedHashSet<E> { class LinkedHashSet<E> {
@patch @patch
factory LinkedHashSet( factory LinkedHashSet(
{bool equals(E e1, E e2), {bool Function(E, E)? equals,
int hashCode(E e), int Function(E)? hashCode,
bool isValidKey(Object potentialKey)}) { bool Function(dynamic)? isValidKey}) {
if (isValidKey == null) { if (isValidKey == null) {
if (hashCode == null) { if (hashCode == null) {
if (equals == null) { if (equals == null) {
@ -133,8 +130,7 @@ class LinkedHashSet<E> {
identical(identical, equals)) { identical(identical, equals)) {
return _IdentityHashSet<E>(); return _IdentityHashSet<E>();
} }
return _CustomHashSet<E>( return _CustomHashSet<E>(equals ?? dart.equals, hashCode);
equals ?? dart.equals, hashCode ?? dart.hashCode);
} }
return _CustomKeyHashSet<E>( return _CustomKeyHashSet<E>(
equals ?? dart.equals, hashCode ?? dart.hashCode, isValidKey); equals ?? dart.equals, hashCode ?? dart.hashCode, isValidKey);
@ -180,13 +176,14 @@ class _HashSet<E> extends _InternalSet<E>
Set<R> _newSimilarSet<R>() => _HashSet<R>(); Set<R> _newSimilarSet<R>() => _HashSet<R>();
bool contains(Object key) { bool contains(Object? key) {
if (key == null) { if (key == null) {
// Convert undefined to null, if needed.
key = null; key = null;
} else if (JS<bool>('!', '#[#] !== #', key, dart.extensionSymbol('_equals'), } else if (JS<bool>('!', '#[#] !== #', key, dart.extensionSymbol('_equals'),
dart.identityEquals)) { dart.identityEquals)) {
@notNull @notNull
var k = key; Object? k = key;
var buckets = JS('', '#.get(# & 0x3ffffff)', _keyMap, k.hashCode); var buckets = JS('', '#.get(# & 0x3ffffff)', _keyMap, k.hashCode);
if (buckets != null) { if (buckets != null) {
for (int i = 0, n = JS('!', '#.length', buckets); i < n; i++) { for (int i = 0, n = JS('!', '#.length', buckets); i < n; i++) {
@ -199,12 +196,12 @@ class _HashSet<E> extends _InternalSet<E>
return JS<bool>('!', '#.has(#)', _map, key); return JS<bool>('!', '#.has(#)', _map, key);
} }
E lookup(Object key) { E? lookup(Object? key) {
if (key == null) return null; if (key == null) return null;
if (JS<bool>('!', '#[#] !== #', key, dart.extensionSymbol('_equals'), if (JS<bool>('!', '#[#] !== #', key, dart.extensionSymbol('_equals'),
dart.identityEquals)) { dart.identityEquals)) {
@notNull @notNull
var k = key; Object? k = key;
var buckets = JS('', '#.get(# & 0x3ffffff)', _keyMap, k.hashCode); var buckets = JS('', '#.get(# & 0x3ffffff)', _keyMap, k.hashCode);
if (buckets != null) { if (buckets != null) {
for (int i = 0, n = JS('!', '#.length', buckets); i < n; i++) { for (int i = 0, n = JS('!', '#.length', buckets); i < n; i++) {
@ -221,7 +218,8 @@ class _HashSet<E> extends _InternalSet<E>
var map = _map; var map = _map;
if (key == null) { if (key == null) {
if (JS('', '#.has(null)', map)) return false; if (JS('', '#.has(null)', map)) return false;
key = null; // Convert undefined to null, if needed.
JS('', '# = null', key);
} else if (JS<bool>('!', '#[#] !== #', key, dart.extensionSymbol('_equals'), } else if (JS<bool>('!', '#[#] !== #', key, dart.extensionSymbol('_equals'),
dart.identityEquals)) { dart.identityEquals)) {
var keyMap = _keyMap; var keyMap = _keyMap;
@ -251,7 +249,8 @@ class _HashSet<E> extends _InternalSet<E>
int length = JS('', '#.size', map); int length = JS('', '#.size', map);
for (E key in objects) { for (E key in objects) {
if (key == null) { if (key == null) {
key = null; // converts undefined to null, if needed. // Convert undefined to null, if needed.
JS('', '# = null', key);
} else if (JS<bool>('!', '#[#] !== #', key, } else if (JS<bool>('!', '#[#] !== #', key,
dart.extensionSymbol('_equals'), dart.identityEquals)) { dart.extensionSymbol('_equals'), dart.identityEquals)) {
key = putLinkedMapKey(key, _keyMap); key = putLinkedMapKey(key, _keyMap);
@ -263,13 +262,14 @@ class _HashSet<E> extends _InternalSet<E>
} }
} }
bool remove(Object key) { bool remove(Object? key) {
if (key == null) { if (key == null) {
// Convert undefined to null, if needed.
key = null; key = null;
} else if (JS<bool>('!', '#[#] !== #', key, dart.extensionSymbol('_equals'), } else if (JS<bool>('!', '#[#] !== #', key, dart.extensionSymbol('_equals'),
dart.identityEquals)) { dart.identityEquals)) {
@notNull @notNull
var k = key; Object? k = key;
int hash = JS('!', '# & 0x3ffffff', k.hashCode); int hash = JS('!', '# & 0x3ffffff', k.hashCode);
var buckets = JS('', '#.get(#)', _keyMap, hash); var buckets = JS('', '#.get(#)', _keyMap, hash);
if (buckets == null) return false; // not found if (buckets == null) return false; // not found
@ -311,7 +311,8 @@ class _ImmutableSet<E> extends _HashSet<E> {
var map = _map; var map = _map;
for (Object key in entries) { for (Object key in entries) {
if (key == null) { if (key == null) {
key = null; // converts undefined to null, if needed. // Convert undefined to null, if needed.
JS('', '# = null', key);
} else if (JS<bool>('!', '#[#] !== #', key, } else if (JS<bool>('!', '#[#] !== #', key,
dart.extensionSymbol('_equals'), dart.identityEquals)) { dart.extensionSymbol('_equals'), dart.identityEquals)) {
key = putLinkedMapKey(key, _keyMap); key = putLinkedMapKey(key, _keyMap);
@ -320,10 +321,10 @@ class _ImmutableSet<E> extends _HashSet<E> {
} }
} }
bool add(Object other) => throw _unsupported(); bool add(E value) => throw _unsupported();
void addAll(Object other) => throw _unsupported(); void addAll(Iterable<E> elements) => throw _unsupported();
void clear() => throw _unsupported(); void clear() => throw _unsupported();
bool remove(Object key) => throw _unsupported(); bool remove(Object? value) => throw _unsupported();
static Error _unsupported() => static Error _unsupported() =>
UnsupportedError("Cannot modify unmodifiable set"); UnsupportedError("Cannot modify unmodifiable set");
@ -344,12 +345,14 @@ class _IdentityHashSet<E> extends _InternalSet<E>
Set<R> _newSimilarSet<R>() => _IdentityHashSet<R>(); Set<R> _newSimilarSet<R>() => _IdentityHashSet<R>();
bool contains(Object element) { bool contains(Object? element) {
return JS('', '#.has(#)', _map, element); return JS<bool>('!', '#.has(#)', _map, element);
} }
E lookup(Object element) { E? lookup(Object? element) {
return JS('', '#.has(#)', _map, element) ? element : null; return element is E && JS<bool>('!', '#.has(#)', _map, element)
? element
: null;
} }
bool add(E element) { bool add(E element) {
@ -371,7 +374,7 @@ class _IdentityHashSet<E> extends _InternalSet<E>
} }
} }
bool remove(Object element) { bool remove(Object? element) {
if (JS<bool>('!', '#.delete(#)', _map, element)) { if (JS<bool>('!', '#.delete(#)', _map, element)) {
_modifications = (_modifications + 1) & 0x3ffffff; _modifications = (_modifications + 1) & 0x3ffffff;
return true; return true;
@ -389,7 +392,7 @@ class _IdentityHashSet<E> extends _InternalSet<E>
} }
class _CustomKeyHashSet<E> extends _CustomHashSet<E> { class _CustomKeyHashSet<E> extends _CustomHashSet<E> {
_Predicate<Object> _validKey; _Predicate<Object?> _validKey;
_CustomKeyHashSet(_Equality<E> equals, _Hasher<E> hashCode, this._validKey) _CustomKeyHashSet(_Equality<E> equals, _Hasher<E> hashCode, this._validKey)
: super(equals, hashCode); : super(equals, hashCode);
@ -397,7 +400,7 @@ class _CustomKeyHashSet<E> extends _CustomHashSet<E> {
Set<R> _newSimilarSet<R>() => _HashSet<R>(); Set<R> _newSimilarSet<R>() => _HashSet<R>();
bool contains(Object element) { bool contains(Object? element) {
// TODO(jmesserly): there is a subtle difference here compared to Dart 1. // TODO(jmesserly): there is a subtle difference here compared to Dart 1.
// See the comment on CustomKeyHashMap.containsKey for more information. // See the comment on CustomKeyHashMap.containsKey for more information.
// Treatment of `null` is different due to strong mode's requirement to // Treatment of `null` is different due to strong mode's requirement to
@ -406,12 +409,12 @@ class _CustomKeyHashSet<E> extends _CustomHashSet<E> {
return super.contains(element); return super.contains(element);
} }
E lookup(Object element) { E? lookup(Object? element) {
if (!_validKey(element)) return null; if (!_validKey(element)) return null;
return super.lookup(element); return super.lookup(element);
} }
bool remove(Object element) { bool remove(Object? element) {
if (!_validKey(element)) return false; if (!_validKey(element)) return false;
return super.remove(element); return super.remove(element);
} }
@ -447,7 +450,7 @@ class _CustomHashSet<E> extends _InternalSet<E>
Set<E> _newSet() => _CustomHashSet<E>(_equals, _hashCode); Set<E> _newSet() => _CustomHashSet<E>(_equals, _hashCode);
Set<R> _newSimilarSet<R>() => _HashSet<R>(); Set<R> _newSimilarSet<R>() => _HashSet<R>();
bool contains(Object key) { bool contains(Object? key) {
if (key is E) { if (key is E) {
var buckets = JS('', '#.get(# & 0x3ffffff)', _keyMap, _hashCode(key)); var buckets = JS('', '#.get(# & 0x3ffffff)', _keyMap, _hashCode(key));
if (buckets != null) { if (buckets != null) {
@ -461,7 +464,7 @@ class _CustomHashSet<E> extends _InternalSet<E>
return false; return false;
} }
E lookup(Object key) { E? lookup(Object? key) {
if (key is E) { if (key is E) {
var buckets = JS('', '#.get(# & 0x3ffffff)', _keyMap, _hashCode(key)); var buckets = JS('', '#.get(# & 0x3ffffff)', _keyMap, _hashCode(key));
if (buckets != null) { if (buckets != null) {
@ -499,7 +502,7 @@ class _CustomHashSet<E> extends _InternalSet<E>
for (E element in objects) add(element); for (E element in objects) add(element);
} }
bool remove(Object key) { bool remove(Object? key) {
if (key is E) { if (key is E) {
var hash = JS<int>('!', '# & 0x3ffffff', _hashCode(key)); var hash = JS<int>('!', '# & 0x3ffffff', _hashCode(key));
var keyMap = _keyMap; var keyMap = _keyMap;
@ -575,30 +578,3 @@ abstract class _InternalSet<E> extends _SetBase<E> {
iterator); iterator);
} }
} }
@patch
abstract class _SplayTree<K, Node extends _SplayTreeNode<K>> {
@patch
Node _splayMin(Node node) {
Node current = node;
while (current.left != null) {
Node left = current.left;
current.left = left.right;
left.right = current;
current = left;
}
return current;
}
@patch
Node _splayMax(Node node) {
Node current = node;
while (current.right != null) {
Node right = current.right;
current.right = right.left;
right.left = current;
current = right;
}
return current;
}
}

View file

@ -2,15 +2,13 @@
// for details. All rights reserved. Use of this source code is governed by a // for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file. // BSD-style license that can be found in the LICENSE file.
// @dart = 2.6
// Patch file for dart:convert library. // Patch file for dart:convert library.
import 'dart:_js_helper' show argumentErrorValue, patch; import 'dart:_js_helper' show argumentErrorValue, patch;
import 'dart:_foreign_helper' show JS; import 'dart:_foreign_helper' show JS;
import 'dart:_interceptors' show JSExtendableArray; import 'dart:_interceptors' show JSExtendableArray;
import 'dart:_internal' show MappedIterable, ListIterable; import 'dart:_internal' show MappedIterable, ListIterable;
import 'dart:collection' show Maps, LinkedHashMap, MapBase; import 'dart:collection' show LinkedHashMap, MapBase;
import 'dart:_native_typed_data' show NativeUint8List; import 'dart:_native_typed_data' show NativeUint8List;
/** /**
@ -30,7 +28,7 @@ import 'dart:_native_typed_data' show NativeUint8List;
* Throws [FormatException] if the input is not valid JSON text. * Throws [FormatException] if the input is not valid JSON text.
*/ */
@patch @patch
_parseJson(String source, reviver(Object key, Object value)) { _parseJson(String source, reviver(key, value)?) {
if (source is! String) throw argumentErrorValue(source); if (source is! String) throw argumentErrorValue(source);
var parsed; var parsed;
@ -53,8 +51,7 @@ _parseJson(String source, reviver(Object key, Object value)) {
* Maps. [json] is expected to be freshly allocated so elements can be replaced * Maps. [json] is expected to be freshly allocated so elements can be replaced
* in-place. * in-place.
*/ */
_convertJsonToDart(json, reviver(Object key, Object value)) { _convertJsonToDart(json, reviver(Object? key, Object? value)) {
assert(reviver != null);
walk(e) { walk(e) {
// JavaScript null, string, number, bool are in the correct representation. // JavaScript null, string, number, bool are in the correct representation.
if (JS<bool>('!', '# == null', e) || if (JS<bool>('!', '# == null', e) ||
@ -214,7 +211,7 @@ class _JsonMap extends MapBase<String, dynamic> {
return value; return value;
} }
remove(Object key) { remove(Object? key) {
if (!_isUpgraded && !containsKey(key)) return null; if (!_isUpgraded && !containsKey(key)) return null;
return _upgrade().remove(key); return _upgrade().remove(key);
} }
@ -275,7 +272,7 @@ class _JsonMap extends MapBase<String, dynamic> {
List<String> _computeKeys() { List<String> _computeKeys() {
assert(!_isUpgraded); assert(!_isUpgraded);
List keys = _data; List? keys = _data;
if (keys == null) { if (keys == null) {
keys = _data = _getPropertyNames(_original); keys = _data = _getPropertyNames(_original);
} }
@ -298,7 +295,7 @@ class _JsonMap extends MapBase<String, dynamic> {
// safely force a concurrent modification error in case // safely force a concurrent modification error in case
// someone is iterating over the map here. // someone is iterating over the map here.
if (keys.isEmpty) { if (keys.isEmpty) {
keys.add(null); keys.add("");
} else { } else {
keys.clear(); keys.clear();
} }
@ -357,13 +354,13 @@ class _JsonMapKeyIterable extends ListIterable<String> {
/// Delegate to [parent.containsKey] to ensure the performance expected /// Delegate to [parent.containsKey] to ensure the performance expected
/// from [Map.keys.containsKey]. /// from [Map.keys.containsKey].
bool contains(Object key) => _parent.containsKey(key); bool contains(Object? key) => _parent.containsKey(key);
} }
@patch @patch
class JsonDecoder { class JsonDecoder {
@patch @patch
StringConversionSink startChunkedConversion(Sink<Object> sink) { StringConversionSink startChunkedConversion(Sink<Object?> sink) {
return _JsonDecoderSink(_reviver, sink); return _JsonDecoderSink(_reviver, sink);
} }
} }
@ -375,18 +372,17 @@ class JsonDecoder {
* The sink only creates one object, but its input can be chunked. * The sink only creates one object, but its input can be chunked.
*/ */
// TODO(floitsch): don't accumulate everything before starting to decode. // TODO(floitsch): don't accumulate everything before starting to decode.
class _JsonDecoderSink extends _StringSinkConversionSink { class _JsonDecoderSink extends _StringSinkConversionSink<StringBuffer> {
final Function(Object key, Object value) _reviver; final Object? Function(Object? key, Object? value)? _reviver;
final Sink<Object> _sink; final Sink<Object?> _sink;
_JsonDecoderSink(this._reviver, this._sink) : super(StringBuffer('')); _JsonDecoderSink(this._reviver, this._sink) : super(StringBuffer(''));
void close() { void close() {
super.close(); super.close();
StringBuffer buffer = _stringSink; String accumulated = _stringSink.toString();
String accumulated = buffer.toString(); _stringSink.clear();
buffer.clear(); Object? decoded = _parseJson(accumulated, _reviver);
Object decoded = _parseJson(accumulated, _reviver);
_sink.add(decoded); _sink.add(decoded);
_sink.close(); _sink.close();
} }
@ -405,8 +401,8 @@ class Utf8Decoder {
// Currently not intercepting UTF8 decoding. // Currently not intercepting UTF8 decoding.
@patch @patch
static String _convertIntercepted( static String? _convertIntercepted(
bool allowMalformed, List<int> codeUnits, int start, int end) { bool allowMalformed, List<int> codeUnits, int start, int? end) {
// Test `codeUnits is NativeUint8List`. Dart's NativeUint8List is // Test `codeUnits is NativeUint8List`. Dart's NativeUint8List is
// implemented by JavaScript's Uint8Array. // implemented by JavaScript's Uint8Array.
if (JS<bool>('!', '# instanceof Uint8Array', codeUnits)) { if (JS<bool>('!', '# instanceof Uint8Array', codeUnits)) {
@ -417,7 +413,7 @@ class Utf8Decoder {
if (end - start < _shortInputThreshold) { if (end - start < _shortInputThreshold) {
return null; return null;
} }
String result = String? result =
_convertInterceptedUint8List(allowMalformed, casted, start, end); _convertInterceptedUint8List(allowMalformed, casted, start, end);
if (result != null && allowMalformed) { if (result != null && allowMalformed) {
// In principle, TextDecoder should have provided the correct result // In principle, TextDecoder should have provided the correct result
@ -433,7 +429,7 @@ class Utf8Decoder {
return null; // This call was not intercepted. return null; // This call was not intercepted.
} }
static String _convertInterceptedUint8List( static String? _convertInterceptedUint8List(
bool allowMalformed, NativeUint8List codeUnits, int start, int end) { bool allowMalformed, NativeUint8List codeUnits, int start, int end) {
final decoder = allowMalformed ? _decoderNonfatal : _decoder; final decoder = allowMalformed ? _decoderNonfatal : _decoder;
if (decoder == null) return null; if (decoder == null) return null;
@ -448,7 +444,7 @@ class Utf8Decoder {
JS<NativeUint8List>('!', '#.subarray(#, #)', codeUnits, start, end)); JS<NativeUint8List>('!', '#.subarray(#, #)', codeUnits, start, end));
} }
static String _useTextDecoder(decoder, NativeUint8List codeUnits) { static String? _useTextDecoder(decoder, NativeUint8List codeUnits) {
// If the input is malformed, catch the exception and return `null` to fall // If the input is malformed, catch the exception and return `null` to fall
// back on unintercepted decoder. The fallback will either succeed in // back on unintercepted decoder. The fallback will either succeed in
// decoding, or report the problem better than TextDecoder. // decoding, or report the problem better than TextDecoder.
@ -480,12 +476,12 @@ class _Utf8Decoder {
_Utf8Decoder(this.allowMalformed) : _state = beforeBom; _Utf8Decoder(this.allowMalformed) : _state = beforeBom;
@patch @patch
String convertSingle(List<int> codeUnits, int start, int maybeEnd) { String convertSingle(List<int> codeUnits, int start, int? maybeEnd) {
return convertGeneral(codeUnits, start, maybeEnd, true); return convertGeneral(codeUnits, start, maybeEnd, true);
} }
@patch @patch
String convertChunked(List<int> codeUnits, int start, int maybeEnd) { String convertChunked(List<int> codeUnits, int start, int? maybeEnd) {
return convertGeneral(codeUnits, start, maybeEnd, false); return convertGeneral(codeUnits, start, maybeEnd, false);
} }
} }

View file

@ -2,8 +2,6 @@
// for details. All rights reserved. Use of this source code is governed by a // for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file. // BSD-style license that can be found in the LICENSE file.
// @dart = 2.6
// Patch file for dart:core classes. // Patch file for dart:core classes.
import "dart:_internal" as _symbol_dev; import "dart:_internal" as _symbol_dev;
import 'dart:_interceptors'; import 'dart:_interceptors';
@ -30,14 +28,14 @@ import 'dart:typed_data' show Endian, Uint8List, Uint16List;
String _symbolToString(Symbol symbol) => symbol is PrivateSymbol String _symbolToString(Symbol symbol) => symbol is PrivateSymbol
? PrivateSymbol.getName(symbol) ? PrivateSymbol.getName(symbol)
: _symbol_dev.Symbol.getName(symbol); : _symbol_dev.Symbol.getName(symbol as _symbol_dev.Symbol);
@patch @patch
int identityHashCode(Object object) { int identityHashCode(Object? object) {
if (object == null) return 0; if (object == null) return 0;
// Note: this works for primitives because we define the `identityHashCode` // Note: this works for primitives because we define the `identityHashCode`
// for them to be equivalent to their computed hashCode function. // for them to be equivalent to their computed hashCode function.
int hash = JS('int|Null', r'#[#]', object, dart.identityHashCode_); int? hash = JS<int?>('int|Null', r'#[#]', object, dart.identityHashCode_);
if (hash == null) { if (hash == null) {
hash = JS<int>('!', '(Math.random() * 0x3fffffff) | 0'); hash = JS<int>('!', '(Math.random() * 0x3fffffff) | 0');
JS('void', r'#[#] = #', object, dart.identityHashCode_, hash); JS('void', r'#[#] = #', object, dart.identityHashCode_, hash);
@ -49,7 +47,7 @@ int identityHashCode(Object object) {
@patch @patch
class Object { class Object {
@patch @patch
bool operator ==(other) => identical(this, other); bool operator ==(Object other) => identical(this, other);
@patch @patch
int get hashCode => identityHashCode(this); int get hashCode => identityHashCode(this);
@ -59,7 +57,7 @@ class Object {
"Instance of '${dart.typeName(dart.getReifiedType(this))}'"; "Instance of '${dart.typeName(dart.getReifiedType(this))}'";
@patch @patch
noSuchMethod(Invocation invocation) { dynamic noSuchMethod(Invocation invocation) {
return dart.defaultNoSuchMethod(this, invocation); return dart.defaultNoSuchMethod(this, invocation);
} }
@ -68,10 +66,11 @@ class Object {
// Everything is an Object. // Everything is an Object.
@JSExportName('is') @JSExportName('is')
static bool _is_Object(Object o) => true; static bool _is_Object(Object? o) => o != null;
@JSExportName('as') @JSExportName('as')
static Object _as_Object(Object o) => o; static Object? _as_Object(Object? o) =>
o == null ? dart.cast(o, dart.unwrapType(Object)) : o;
} }
@patch @patch
@ -80,10 +79,10 @@ class Null {
int get hashCode => super.hashCode; int get hashCode => super.hashCode;
@JSExportName('is') @JSExportName('is')
static bool _is_Null(Object o) => o == null; static bool _is_Null(Object? o) => o == null;
@JSExportName('as') @JSExportName('as')
static Object _as_Null(Object o) { static Object? _as_Null(Object? o) {
// Avoid extra function call to core.Null.is() by manually inlining. // Avoid extra function call to core.Null.is() by manually inlining.
if (o == null) return o; if (o == null) return o;
return dart.cast(o, dart.unwrapType(Null)); return dart.cast(o, dart.unwrapType(Null));
@ -94,8 +93,8 @@ class Null {
@patch @patch
class Function { class Function {
@patch @patch
static apply(Function f, List positionalArguments, static apply(Function function, List<dynamic>? positionalArguments,
[Map<Symbol, dynamic> namedArguments]) { [Map<Symbol, dynamic>? namedArguments]) {
positionalArguments ??= []; positionalArguments ??= [];
// dcall expects the namedArguments as a JS map in the last slot. // dcall expects the namedArguments as a JS map in the last slot.
if (namedArguments != null && namedArguments.isNotEmpty) { if (namedArguments != null && namedArguments.isNotEmpty) {
@ -103,9 +102,9 @@ class Function {
namedArguments.forEach((symbol, arg) { namedArguments.forEach((symbol, arg) {
JS('', '#[#] = #', map, _symbolToString(symbol), arg); JS('', '#[#] = #', map, _symbolToString(symbol), arg);
}); });
return dart.dcall(f, positionalArguments, map); return dart.dcall(function, positionalArguments, map);
} }
return dart.dcall(f, positionalArguments); return dart.dcall(function, positionalArguments);
} }
static Map<String, dynamic> _toMangledNames( static Map<String, dynamic> _toMangledNames(
@ -118,13 +117,13 @@ class Function {
} }
@JSExportName('is') @JSExportName('is')
static bool _is_Function(Object o) => static bool _is_Function(Object? o) =>
JS<bool>('!', 'typeof $o == "function"'); JS<bool>('!', 'typeof $o == "function"');
@JSExportName('as') @JSExportName('as')
static Object _as_Function(Object o) { static Object? _as_Function(Object? o) {
// Avoid extra function call to core.Function.is() by manually inlining. // Avoid extra function call to core.Function.is() by manually inlining.
if (JS<Object>('!', 'typeof $o == "function"') || o == null) return o; if (JS<bool>('!', 'typeof $o == "function"')) return o;
return dart.cast(o, dart.unwrapType(Function)); return dart.cast(o, dart.unwrapType(Function));
} }
} }
@ -132,18 +131,20 @@ class Function {
// TODO(jmesserly): switch to WeakMap // TODO(jmesserly): switch to WeakMap
// Patch for Expando implementation. // Patch for Expando implementation.
@patch @patch
class Expando<T> { class Expando<T extends Object> {
@patch @patch
Expando([String name]) : this.name = name; Expando([String? name]) : this.name = name;
@patch @patch
T operator [](Object object) { T? operator [](Object object) {
var values = Primitives.getProperty(object, _EXPANDO_PROPERTY_NAME); var values = Primitives.getProperty(object, _EXPANDO_PROPERTY_NAME);
return (values == null) ? null : Primitives.getProperty(values, _getKey()); return (values == null)
? null
: Primitives.getProperty(values, _getKey()) as T?;
} }
@patch @patch
void operator []=(Object object, T value) { void operator []=(Object object, T? value) {
var values = Primitives.getProperty(object, _EXPANDO_PROPERTY_NAME); var values = Primitives.getProperty(object, _EXPANDO_PROPERTY_NAME);
if (values == null) { if (values == null) {
values = Object(); values = Object();
@ -153,7 +154,7 @@ class Expando<T> {
} }
String _getKey() { String _getKey() {
String key = Primitives.getProperty(this, _KEY_PROPERTY_NAME); var key = Primitives.getProperty(this, _KEY_PROPERTY_NAME) as String?;
if (key == null) { if (key == null) {
key = "expando\$key\$${_keyCount++}"; key = "expando\$key\$${_keyCount++}";
Primitives.setProperty(this, _KEY_PROPERTY_NAME, key); Primitives.setProperty(this, _KEY_PROPERTY_NAME, key);
@ -170,7 +171,7 @@ class Expando<T> {
class int { class int {
@patch @patch
static int parse(String source, static int parse(String source,
{int radix, @deprecated int onError(String source)}) { {int? radix, @deprecated int onError(String source)?}) {
var value = tryParse(source, radix: radix); var value = tryParse(source, radix: radix);
if (value != null) return value; if (value != null) return value;
if (onError != null) return onError(source); if (onError != null) return onError(source);
@ -178,7 +179,7 @@ class int {
} }
@patch @patch
static int tryParse(String source, {int radix}) { static int? tryParse(String source, {int? radix}) {
return Primitives.parseInt(source, radix); return Primitives.parseInt(source, radix);
} }
@ -190,15 +191,14 @@ class int {
} }
@JSExportName('is') @JSExportName('is')
static bool _is_int(Object o) { static bool _is_int(Object? o) {
return JS<bool>('!', 'typeof $o == "number" && Math.floor($o) == $o'); return JS<bool>('!', 'typeof $o == "number" && Math.floor($o) == $o');
} }
@JSExportName('as') @JSExportName('as')
static Object _as_int(Object o) { static Object? _as_int(Object? o) {
// Avoid extra function call to core.int.is() by manually inlining. // Avoid extra function call to core.int.is() by manually inlining.
if (JS<bool>('!', '(typeof $o == "number" && Math.floor($o) == $o)') || if (JS<bool>('!', '(typeof $o == "number" && Math.floor($o) == $o)')) {
o == null) {
return o; return o;
} }
return dart.cast(o, dart.unwrapType(int)); return dart.cast(o, dart.unwrapType(int));
@ -209,7 +209,7 @@ class int {
class double { class double {
@patch @patch
static double parse(String source, static double parse(String source,
[@deprecated double onError(String source)]) { [@deprecated double onError(String source)?]) {
var value = tryParse(source); var value = tryParse(source);
if (value != null) return value; if (value != null) return value;
if (onError != null) return onError(source); if (onError != null) return onError(source);
@ -217,19 +217,19 @@ class double {
} }
@patch @patch
static double tryParse(String source) { static double? tryParse(String source) {
return Primitives.parseDouble(source); return Primitives.parseDouble(source);
} }
@JSExportName('is') @JSExportName('is')
static bool _is_double(o) { static bool _is_double(Object? o) {
return JS<bool>('!', 'typeof $o == "number"'); return JS<bool>('!', 'typeof $o == "number"');
} }
@JSExportName('as') @JSExportName('as')
static Object _as_double(o) { static Object? _as_double(Object? o) {
// Avoid extra function call to core.double.is() by manually inlining. // Avoid extra function call to core.double.is() by manually inlining.
if (JS<bool>('!', 'typeof $o == "number"') || o == null) return o; if (JS<bool>('!', 'typeof $o == "number"')) return o;
return dart.cast(o, dart.unwrapType(double)); return dart.cast(o, dart.unwrapType(double));
} }
} }
@ -237,14 +237,14 @@ class double {
@patch @patch
abstract class num implements Comparable<num> { abstract class num implements Comparable<num> {
@JSExportName('is') @JSExportName('is')
static bool _is_num(o) { static bool _is_num(Object? o) {
return JS<bool>('!', 'typeof $o == "number"'); return JS<bool>('!', 'typeof $o == "number"');
} }
@JSExportName('as') @JSExportName('as')
static Object _as_num(o) { static Object? _as_num(Object? o) {
// Avoid extra function call to core.num.is() by manually inlining. // Avoid extra function call to core.num.is() by manually inlining.
if (JS<bool>('!', 'typeof $o == "number"') || o == null) return o; if (JS<bool>('!', 'typeof $o == "number"')) return o;
return dart.cast(o, dart.unwrapType(num)); return dart.cast(o, dart.unwrapType(num));
} }
} }
@ -259,11 +259,11 @@ class BigInt implements Comparable<BigInt> {
static BigInt get two => _BigIntImpl.two; static BigInt get two => _BigIntImpl.two;
@patch @patch
static BigInt parse(String source, {int radix}) => static BigInt parse(String source, {int? radix}) =>
_BigIntImpl.parse(source, radix: radix); _BigIntImpl.parse(source, radix: radix);
@patch @patch
static BigInt tryParse(String source, {int radix}) => static BigInt? tryParse(String source, {int? radix}) =>
_BigIntImpl._tryParse(source, radix: radix); _BigIntImpl._tryParse(source, radix: radix);
@patch @patch
@ -283,7 +283,7 @@ class Error {
} }
@patch @patch
StackTrace get stackTrace => dart.stackTraceForError(this); StackTrace? get stackTrace => dart.stackTraceForError(this);
} }
@patch @patch
@ -319,10 +319,7 @@ class DateTime {
@patch @patch
DateTime._internal(int year, int month, int day, int hour, int minute, DateTime._internal(int year, int month, int day, int hour, int minute,
int second, int millisecond, int microsecond, bool isUtc) int second, int millisecond, int microsecond, bool isUtc)
// checkBool is manually inlined here because dart2js doesn't inline it : isUtc = isUtc,
// and [isUtc] is usually a constant.
: this.isUtc =
isUtc is bool ? isUtc : throw ArgumentError.value(isUtc, 'isUtc'),
_value = checkInt(Primitives.valueFromDecomposedDate( _value = checkInt(Primitives.valueFromDecomposedDate(
year, year,
month, month,
@ -346,7 +343,7 @@ class DateTime {
} }
@patch @patch
static int _brokenDownDateToValue(int year, int month, int day, int hour, static int? _brokenDownDateToValue(int year, int month, int day, int hour,
int minute, int second, int millisecond, int microsecond, bool isUtc) { int minute, int second, int millisecond, int microsecond, bool isUtc) {
return Primitives.valueFromDecomposedDate( return Primitives.valueFromDecomposedDate(
year, year,
@ -367,7 +364,7 @@ class DateTime {
@patch @patch
Duration get timeZoneOffset { Duration get timeZoneOffset {
if (isUtc) return Duration(); if (isUtc) return Duration.zero;
return Duration(minutes: Primitives.getTimeZoneOffsetInMinutes(this)); return Duration(minutes: Primitives.getTimeZoneOffsetInMinutes(this));
} }
@ -420,7 +417,7 @@ class DateTime {
int get weekday => Primitives.getWeekday(this); int get weekday => Primitives.getWeekday(this);
@patch @patch
bool operator ==(dynamic other) => bool operator ==(Object other) =>
other is DateTime && other is DateTime &&
_value == other.millisecondsSinceEpoch && _value == other.millisecondsSinceEpoch &&
isUtc == other.isUtc; isUtc == other.isUtc;
@ -444,9 +441,9 @@ class DateTime {
@patch @patch
class Stopwatch { class Stopwatch {
@patch @patch
static void _initTicker() { static int _initTicker() {
Primitives.initTicker(); Primitives.initTicker();
_frequency = Primitives.timerFrequency; return Primitives.timerFrequency;
} }
@patch @patch
@ -473,22 +470,29 @@ class Stopwatch {
@patch @patch
class List<E> { class List<E> {
@patch @patch
factory List([@undefined int _length]) { factory List([@undefined int? length]) {
dynamic list; dynamic list;
if (JS<bool>('!', '# === void 0', _length)) { if (JS<bool>('!', '# === void 0', length)) {
list = JS('', '[]'); list = JS('', '[]');
} else { } else {
int length = JS('!', '#', _length); int _length = JS('!', '#', length);
if (_length == null || length < 0) { if (length == null || _length < 0) {
throw ArgumentError("Length must be a non-negative integer: $_length"); throw ArgumentError("Length must be a non-negative integer: $_length");
} }
list = JS('', 'new Array(#)', length); list = JS('', 'new Array(#)', _length);
JS('', '#.fill(null)', list); JS('', '#.fill(null)', list);
JSArray.markFixedList(list); JSArray.markFixedList(list);
} }
return JSArray<E>.of(list); return JSArray<E>.of(list);
} }
@patch
factory List.empty({bool growable = false}) {
var list = JSArray<E>.of(JS('', 'new Array()'));
if (!growable) JSArray.markFixedList(list);
return list;
}
@patch @patch
factory List.filled(@nullCheck int length, E fill, {bool growable = false}) { factory List.filled(@nullCheck int length, E fill, {bool growable = false}) {
var list = JSArray<E>.of(JS('', 'new Array(#)', length)); var list = JSArray<E>.of(JS('', 'new Array(#)', length));
@ -521,6 +525,17 @@ class List<E> {
return List.from(elements, growable: growable); return List.from(elements, growable: growable);
} }
@patch
factory List.generate(int length, E generator(int index),
{bool growable = true}) {
final result = JSArray<E>.of(JS('', 'new Array(#)', length));
if (!growable) JSArray.markFixedList(result);
for (int i = 0; i < length; i++) {
result[i] = generator(i);
}
return result;
}
@patch @patch
factory List.unmodifiable(Iterable elements) { factory List.unmodifiable(Iterable elements) {
var list = List<E>.from(elements); var list = List<E>.from(elements);
@ -532,7 +547,7 @@ class List<E> {
@patch @patch
class Map<K, V> { class Map<K, V> {
@patch @patch
factory Map.unmodifiable(Map other) { factory Map.unmodifiable(Map<dynamic, dynamic> other) {
return UnmodifiableMapView<K, V>(Map<K, V>.from(other)); return UnmodifiableMapView<K, V>(Map<K, V>.from(other));
} }
@ -544,7 +559,7 @@ class Map<K, V> {
class String { class String {
@patch @patch
factory String.fromCharCodes(Iterable<int> charCodes, factory String.fromCharCodes(Iterable<int> charCodes,
[int start = 0, int end]) { [int start = 0, int? end]) {
if (charCodes is JSArray) { if (charCodes is JSArray) {
return _stringFromJSArray(charCodes, start, end); return _stringFromJSArray(charCodes, start, end);
} }
@ -569,7 +584,7 @@ class String {
static String _stringFromJSArray( static String _stringFromJSArray(
/*=JSArray<int>*/ list, /*=JSArray<int>*/ list,
int start, int start,
int endOrNull) { int? endOrNull) {
int len = list.length; int len = list.length;
int end = RangeError.checkValidRange(start, endOrNull, len); int end = RangeError.checkValidRange(start, endOrNull, len);
if (start > 0 || end < len) { if (start > 0 || end < len) {
@ -579,14 +594,14 @@ class String {
} }
static String _stringFromUint8List( static String _stringFromUint8List(
NativeUint8List charCodes, int start, int endOrNull) { NativeUint8List charCodes, int start, int? endOrNull) {
int len = charCodes.length; int len = charCodes.length;
int end = RangeError.checkValidRange(start, endOrNull, len); int end = RangeError.checkValidRange(start, endOrNull, len);
return Primitives.stringFromNativeUint8List(charCodes, start, end); return Primitives.stringFromNativeUint8List(charCodes, start, end);
} }
static String _stringFromIterable( static String _stringFromIterable(
Iterable<int> charCodes, int start, int end) { Iterable<int> charCodes, int start, int? end) {
if (start < 0) throw RangeError.range(start, 0, charCodes.length); if (start < 0) throw RangeError.range(start, 0, charCodes.length);
if (end != null && end < start) { if (end != null && end < start) {
throw RangeError.range(end, start, charCodes.length); throw RangeError.range(end, start, charCodes.length);
@ -597,7 +612,7 @@ class String {
throw RangeError.range(start, 0, i); throw RangeError.range(start, 0, i);
} }
} }
var list = <int>[]; var list = JSArray<int>.of(JS('', 'new Array()'));
if (end == null) { if (end == null) {
while (it.moveNext()) list.add(it.current); while (it.moveNext()) list.add(it.current);
} else { } else {
@ -612,14 +627,14 @@ class String {
} }
@JSExportName('is') @JSExportName('is')
static bool _is_String(Object o) { static bool _is_String(Object? o) {
return JS<bool>('!', 'typeof $o == "string"'); return JS<bool>('!', 'typeof $o == "string"');
} }
@JSExportName('as') @JSExportName('as')
static Object _as_String(Object o) { static Object? _as_String(Object? o) {
// Avoid extra function call to core.String.is() by manually inlining. // Avoid extra function call to core.String.is() by manually inlining.
if (JS<bool>('!', 'typeof $o == "string"') || o == null) return o; if (JS<bool>('!', 'typeof $o == "string"')) return o;
return dart.cast(o, dart.unwrapType(String)); return dart.cast(o, dart.unwrapType(String));
} }
} }
@ -644,13 +659,13 @@ class bool {
int get hashCode => super.hashCode; int get hashCode => super.hashCode;
@JSExportName('is') @JSExportName('is')
static bool _is_bool(Object o) => static bool _is_bool(Object? o) =>
JS<bool>('!', '$o === true || $o === false'); JS<bool>('!', '$o === true || $o === false');
@JSExportName('as') @JSExportName('as')
static Object _as_bool(Object o) { static Object? _as_bool(Object? o) {
// Avoid extra function call to core.bool.is() by manually inlining. // Avoid extra function call to core.bool.is() by manually inlining.
if (JS<bool>("!", '$o === true || $o === false') || o == null) return o; if (JS<bool>("!", '$o === true || $o === false')) return o;
return dart.cast(o, dart.unwrapType(bool)); return dart.cast(o, dart.unwrapType(bool));
} }
} }
@ -675,7 +690,7 @@ class RegExp {
// Patch for 'identical' function. // Patch for 'identical' function.
@patch @patch
bool identical(Object a, Object b) { bool identical(Object? a, Object? b) {
return JS<bool>('!', '(# == null ? # == null : # === #)', a, b, a, b); return JS<bool>('!', '(# == null ? # == null : # === #)', a, b, a, b);
} }
@ -690,7 +705,7 @@ class StringBuffer {
int get length => _contents.length; int get length => _contents.length;
@patch @patch
void write(Object obj) { void write(Object? obj) {
_writeString('$obj'); _writeString('$obj');
} }
@ -700,12 +715,12 @@ class StringBuffer {
} }
@patch @patch
void writeAll(Iterable objects, [String separator = ""]) { void writeAll(Iterable<dynamic> objects, [String separator = ""]) {
_contents = _writeAll(_contents, objects, separator); _contents = _writeAll(_contents, objects, separator);
} }
@patch @patch
void writeln([Object obj = ""]) { void writeln([Object? obj = ""]) {
_writeString('$obj\n'); _writeString('$obj\n');
} }
@ -717,7 +732,7 @@ class StringBuffer {
@patch @patch
String toString() => Primitives.flattenString(_contents); String toString() => Primitives.flattenString(_contents);
void _writeString(str) { void _writeString(String str) {
_contents = Primitives.stringConcatUnchecked(_contents, str); _contents = Primitives.stringConcatUnchecked(_contents, str);
} }
@ -738,7 +753,7 @@ class StringBuffer {
return string; return string;
} }
static String _writeOne(String string, Object obj) { static String _writeOne(String string, Object? obj) {
return Primitives.stringConcatUnchecked(string, '$obj'); return Primitives.stringConcatUnchecked(string, '$obj');
} }
} }
@ -752,46 +767,44 @@ class _CompileTimeError extends Error {
@patch @patch
class NoSuchMethodError { class NoSuchMethodError {
final Object _receiver; final Object? _receiver;
final Symbol _memberName; final Symbol _memberName;
final List _arguments; final List? _arguments;
final Map<Symbol, dynamic> _namedArguments; final Map<Symbol, dynamic>? _namedArguments;
final List _existingArgumentNames; final Invocation? _invocation;
final Invocation _invocation;
@patch @patch
NoSuchMethodError(Object receiver, Symbol memberName, NoSuchMethodError(Object? receiver, Symbol memberName,
List positionalArguments, Map<Symbol, dynamic> namedArguments, List? positionalArguments, Map<Symbol, dynamic>? namedArguments)
[List existingArgumentNames = null])
: _receiver = receiver, : _receiver = receiver,
_memberName = memberName, _memberName = memberName,
_arguments = positionalArguments, _arguments = positionalArguments,
_namedArguments = namedArguments, _namedArguments = namedArguments,
_existingArgumentNames = existingArgumentNames,
_invocation = null; _invocation = null;
@patch @patch
NoSuchMethodError.withInvocation(Object receiver, Invocation invocation) NoSuchMethodError.withInvocation(Object? receiver, Invocation invocation)
: _receiver = receiver, : _receiver = receiver,
_memberName = invocation.memberName, _memberName = invocation.memberName,
_arguments = invocation.positionalArguments, _arguments = invocation.positionalArguments,
_namedArguments = invocation.namedArguments, _namedArguments = invocation.namedArguments,
_existingArgumentNames = null,
_invocation = invocation; _invocation = invocation;
@patch @patch
String toString() { String toString() {
StringBuffer sb = StringBuffer(''); StringBuffer sb = StringBuffer('');
String comma = ''; String comma = '';
if (_arguments != null) { var arguments = _arguments;
for (var argument in _arguments) { if (arguments != null) {
for (var argument in arguments) {
sb.write(comma); sb.write(comma);
sb.write(Error.safeToString(argument)); sb.write(Error.safeToString(argument));
comma = ', '; comma = ', ';
} }
} }
if (_namedArguments != null) { var namedArguments = _namedArguments;
_namedArguments.forEach((Symbol key, var value) { if (namedArguments != null) {
namedArguments.forEach((Symbol key, var value) {
sb.write(comma); sb.write(comma);
sb.write(_symbolToString(key)); sb.write(_symbolToString(key));
sb.write(": "); sb.write(": ");
@ -802,22 +815,14 @@ class NoSuchMethodError {
String memberName = _symbolToString(_memberName); String memberName = _symbolToString(_memberName);
String receiverText = Error.safeToString(_receiver); String receiverText = Error.safeToString(_receiver);
String actualParameters = '$sb'; String actualParameters = '$sb';
var failureMessage = (_invocation is dart.InvocationImpl) var invocation = _invocation;
? (_invocation as dart.InvocationImpl).failureMessage var failureMessage = (invocation is dart.InvocationImpl)
? invocation.failureMessage
: 'method not found'; : 'method not found';
if (_existingArgumentNames == null) { return "NoSuchMethodError: '$memberName'\n"
return "NoSuchMethodError: '$memberName'\n" "$failureMessage\n"
"$failureMessage\n" "Receiver: ${receiverText}\n"
"Receiver: ${receiverText}\n" "Arguments: [$actualParameters]";
"Arguments: [$actualParameters]";
} else {
String formalParameters = _existingArgumentNames.join(', ');
return "NoSuchMethodError: incorrect number of arguments passed to "
"method named '$memberName'\n"
"Receiver: ${receiverText}\n"
"Tried calling: $memberName($actualParameters)\n"
"Found: $memberName($formalParameters)";
}
} }
} }
@ -973,14 +978,14 @@ class _BigIntImpl implements BigInt {
// Result cache for last _divRem call. // Result cache for last _divRem call.
// Result cache for last _divRem call. // Result cache for last _divRem call.
static Uint16List _lastDividendDigits; static Uint16List? _lastDividendDigits;
static int _lastDividendUsed; static int? _lastDividendUsed;
static Uint16List _lastDivisorDigits; static Uint16List? _lastDivisorDigits;
static int _lastDivisorUsed; static int? _lastDivisorUsed;
static Uint16List _lastQuoRemDigits; static Uint16List? _lastQuoRemDigits;
static int _lastQuoRemUsed; static int? _lastQuoRemUsed;
static int _lastRemUsed; static int? _lastRemUsed;
static int _lastRem_nsh; static int? _lastRem_nsh;
/// Whether this bigint is negative. /// Whether this bigint is negative.
final bool _isNegative; final bool _isNegative;
@ -1021,7 +1026,7 @@ class _BigIntImpl implements BigInt {
* Throws a [FormatException] if the [source] is not a valid integer literal, * Throws a [FormatException] if the [source] is not a valid integer literal,
* optionally prefixed by a sign. * optionally prefixed by a sign.
*/ */
static _BigIntImpl parse(String source, {int radix}) { static _BigIntImpl parse(String source, {int? radix}) {
var result = _tryParse(source, radix: radix); var result = _tryParse(source, radix: radix);
if (result == null) { if (result == null) {
throw FormatException("Could not parse BigInt", source); throw FormatException("Could not parse BigInt", source);
@ -1040,7 +1045,7 @@ class _BigIntImpl implements BigInt {
// Read in the source 4 digits at a time. // Read in the source 4 digits at a time.
// The first part may have a few leading virtual '0's to make the remaining // The first part may have a few leading virtual '0's to make the remaining
// parts all have exactly 4 digits. // parts all have exactly 4 digits.
int digitInPartCount = 4 - source.length.remainder(4); var digitInPartCount = 4 - source.length.remainder(4);
if (digitInPartCount == 4) digitInPartCount = 0; if (digitInPartCount == 4) digitInPartCount = 0;
for (int i = 0; i < source.length; i++) { for (int i = 0; i < source.length; i++) {
part = part * 10 + source.codeUnitAt(i) - _0; part = part * 10 + source.codeUnitAt(i) - _0;
@ -1082,7 +1087,7 @@ class _BigIntImpl implements BigInt {
/// If [isNegative] is true, negates the result before returning it. /// If [isNegative] is true, negates the result before returning it.
/// ///
/// The [source] (substring) must be a valid hex literal. /// The [source] (substring) must be a valid hex literal.
static _BigIntImpl _parseHex(String source, int startPos, bool isNegative) { static _BigIntImpl? _parseHex(String source, int startPos, bool isNegative) {
int hexDigitsPerChunk = _digitBits ~/ 4; int hexDigitsPerChunk = _digitBits ~/ 4;
int sourceLength = source.length - startPos; int sourceLength = source.length - startPos;
int chunkCount = (sourceLength / hexDigitsPerChunk).ceil(); int chunkCount = (sourceLength / hexDigitsPerChunk).ceil();
@ -1116,7 +1121,7 @@ class _BigIntImpl implements BigInt {
/// ///
/// The [source] will be checked for invalid characters. If it is invalid, /// The [source] will be checked for invalid characters. If it is invalid,
/// this function returns `null`. /// this function returns `null`.
static _BigIntImpl _parseRadix(String source, int radix, bool isNegative) { static _BigIntImpl? _parseRadix(String source, int radix, bool isNegative) {
var result = zero; var result = zero;
var base = _BigIntImpl._fromInt(radix); var base = _BigIntImpl._fromInt(radix);
for (int i = 0; i < source.length; i++) { for (int i = 0; i < source.length; i++) {
@ -1133,7 +1138,7 @@ class _BigIntImpl implements BigInt {
/// Returns the parsed big integer, or `null` if it failed. /// Returns the parsed big integer, or `null` if it failed.
/// ///
/// If the [radix] is `null` accepts decimal literals or `0x` hex literals. /// If the [radix] is `null` accepts decimal literals or `0x` hex literals.
static _BigIntImpl _tryParse(String source, {int radix}) { static _BigIntImpl? _tryParse(String source, {int? radix}) {
if (source == "") return null; if (source == "") return null;
var match = _parseRE.firstMatch(source); var match = _parseRE.firstMatch(source);
@ -1145,9 +1150,9 @@ class _BigIntImpl implements BigInt {
bool isNegative = match[signIndex] == "-"; bool isNegative = match[signIndex] == "-";
String decimalMatch = match[decimalIndex]; String? decimalMatch = match[decimalIndex];
String hexMatch = match[hexIndex]; String? hexMatch = match[hexIndex];
String nonDecimalMatch = match[nonDecimalHexIndex]; String? nonDecimalMatch = match[nonDecimalHexIndex];
if (radix == null) { if (radix == null) {
if (decimalMatch != null) { if (decimalMatch != null) {
@ -1168,11 +1173,11 @@ class _BigIntImpl implements BigInt {
return _parseDecimal(decimalMatch, isNegative); return _parseDecimal(decimalMatch, isNegative);
} }
if (radix == 16 && (decimalMatch != null || nonDecimalMatch != null)) { if (radix == 16 && (decimalMatch != null || nonDecimalMatch != null)) {
return _parseHex(decimalMatch ?? nonDecimalMatch, 0, isNegative); return _parseHex(decimalMatch ?? nonDecimalMatch!, 0, isNegative);
} }
return _parseRadix( return _parseRadix(
decimalMatch ?? nonDecimalMatch ?? hexMatch, radix, isNegative); decimalMatch ?? nonDecimalMatch ?? hexMatch!, radix, isNegative);
} }
static RegExp _parseRE = RegExp( static RegExp _parseRE = RegExp(
@ -1220,7 +1225,7 @@ class _BigIntImpl implements BigInt {
// then use the bit-manipulating `_fromDouble` for all other values. // then use the bit-manipulating `_fromDouble` for all other values.
if (value.abs() < 0x100000000) return _BigIntImpl._fromInt(value.toInt()); if (value.abs() < 0x100000000) return _BigIntImpl._fromInt(value.toInt());
if (value is double) return _BigIntImpl._fromDouble(value); if (value is double) return _BigIntImpl._fromDouble(value);
return _BigIntImpl._fromInt(value); return _BigIntImpl._fromInt(value as int);
} }
factory _BigIntImpl._fromInt(int value) { factory _BigIntImpl._fromInt(int value) {
@ -1984,9 +1989,9 @@ class _BigIntImpl implements BigInt {
_divRem(other); _divRem(other);
// Return quotient, i.e. // Return quotient, i.e.
// _lastQuoRem_digits[_lastRem_used.._lastQuoRem_used-1] with proper sign. // _lastQuoRem_digits[_lastRem_used.._lastQuoRem_used-1] with proper sign.
var lastQuo_used = _lastQuoRemUsed - _lastRemUsed; var lastQuo_used = _lastQuoRemUsed! - _lastRemUsed!;
var quo_digits = _cloneDigits( var quo_digits = _cloneDigits(
_lastQuoRemDigits, _lastRemUsed, _lastQuoRemUsed, lastQuo_used); _lastQuoRemDigits!, _lastRemUsed!, _lastQuoRemUsed!, lastQuo_used);
var quo = _BigIntImpl._(false, lastQuo_used, quo_digits); var quo = _BigIntImpl._(false, lastQuo_used, quo_digits);
if ((_isNegative != other._isNegative) && (quo._used > 0)) { if ((_isNegative != other._isNegative) && (quo._used > 0)) {
quo = -quo; quo = -quo;
@ -2004,10 +2009,10 @@ class _BigIntImpl implements BigInt {
// Return remainder, i.e. // Return remainder, i.e.
// denormalized _lastQuoRem_digits[0.._lastRem_used-1] with proper sign. // denormalized _lastQuoRem_digits[0.._lastRem_used-1] with proper sign.
var remDigits = var remDigits =
_cloneDigits(_lastQuoRemDigits, 0, _lastRemUsed, _lastRemUsed); _cloneDigits(_lastQuoRemDigits!, 0, _lastRemUsed!, _lastRemUsed!);
var rem = _BigIntImpl._(false, _lastRemUsed, remDigits); var rem = _BigIntImpl._(false, _lastRemUsed!, remDigits);
if (_lastRem_nsh > 0) { if (_lastRem_nsh! > 0) {
rem = rem >> _lastRem_nsh; // Denormalize remainder. rem = rem >> _lastRem_nsh!; // Denormalize remainder.
} }
if (_isNegative && (rem._used > 0)) { if (_isNegative && (rem._used > 0)) {
rem = -rem; rem = -rem;

View file

@ -2,8 +2,6 @@
// for details. All rights reserved. Use of this source code is governed by a // for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file. // BSD-style license that can be found in the LICENSE file.
// @dart = 2.6
// Patch file for dart:developer library. // Patch file for dart:developer library.
import 'dart:_js_helper' show patch, ForceInline, ReifyFunctionTypes; import 'dart:_js_helper' show patch, ForceInline, ReifyFunctionTypes;
@ -15,7 +13,7 @@ import 'dart:isolate';
@patch @patch
@ForceInline() @ForceInline()
bool debugger({bool when = true, String message}) { bool debugger({bool when = true, String? message}) {
if (when) { if (when) {
JS('', 'debugger'); JS('', 'debugger');
} }
@ -23,7 +21,7 @@ bool debugger({bool when = true, String message}) {
} }
@patch @patch
Object inspect(Object object) { Object? inspect(Object? object) {
// Note: this log level does not show up by default in Chrome. // Note: this log level does not show up by default in Chrome.
// This is used for communication with the debugger service. // This is used for communication with the debugger service.
JS('', 'console.debug("dart.developer.inspect", #)', object); JS('', 'console.debug("dart.developer.inspect", #)', object);
@ -32,13 +30,13 @@ Object inspect(Object object) {
@patch @patch
void log(String message, void log(String message,
{DateTime time, {DateTime? time,
int sequenceNumber, int? sequenceNumber,
int level = 0, int level = 0,
String name = '', String name = '',
Zone zone, Zone? zone,
Object error, Object? error,
StackTrace stackTrace}) { StackTrace? stackTrace}) {
Object items = Object items =
JS('!', '{ message: #, name: #, level: # }', message, name, level); JS('!', '{ message: #, name: #, level: # }', message, name, level);
if (time != null) JS('', '#.time = #', items, time); if (time != null) JS('', '#.time = #', items, time);
@ -52,10 +50,10 @@ void log(String message,
JS('', 'console.debug("dart.developer.log", #)', items); JS('', 'console.debug("dart.developer.log", #)', items);
} }
final _extensions = Map<String, ServiceExtensionHandler>(); final _extensions = <String, ServiceExtensionHandler>{};
@patch @patch
ServiceExtensionHandler _lookupExtension(String method) { ServiceExtensionHandler? _lookupExtension(String method) {
return _extensions[method]; return _extensions[method];
} }
@ -81,7 +79,7 @@ _invokeExtension(String methodName, String encodedJson) {
return JS('', 'new #.Promise(#)', dart.global_, return JS('', 'new #.Promise(#)', dart.global_,
(Function(Object) resolve, Function(Object) reject) async { (Function(Object) resolve, Function(Object) reject) async {
try { try {
var method = _lookupExtension(methodName); var method = _lookupExtension(methodName)!;
var parameters = (json.decode(encodedJson) as Map).cast<String, String>(); var parameters = (json.decode(encodedJson) as Map).cast<String, String>();
var result = await method(methodName, parameters); var result = await method(methodName, parameters);
resolve(result._toString()); resolve(result._toString());
@ -154,7 +152,7 @@ void _webServerControl(SendPort sendPort, bool enable) {
} }
@patch @patch
String _getIsolateIDFromSendPort(SendPort sendPort) { String? _getIsolateIDFromSendPort(SendPort sendPort) {
return null; return null;
} }
@ -168,7 +166,7 @@ class UserTag {
} }
class _FakeUserTag implements UserTag { class _FakeUserTag implements UserTag {
static Map _instances = {}; static final _instances = <String, _FakeUserTag>{};
_FakeUserTag.real(this.label); _FakeUserTag.real(this.label);
@ -183,10 +181,7 @@ class _FakeUserTag implements UserTag {
throw UnsupportedError( throw UnsupportedError(
'UserTag instance limit (${UserTag.MAX_USER_TAGS}) reached.'); 'UserTag instance limit (${UserTag.MAX_USER_TAGS}) reached.');
} }
// Create a new instance and add it to the instance map. return _instances[label] = _FakeUserTag.real(label);
var instance = _FakeUserTag.real(label);
_instances[label] = instance;
return instance;
} }
final String label; final String label;

View file

@ -2,8 +2,6 @@
// for details. All rights reserved. Use of this source code is governed by a // for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file. // BSD-style license that can be found in the LICENSE file.
// @dart = 2.6
import 'dart:core' hide Symbol; import 'dart:core' hide Symbol;
import 'dart:core' as core show Symbol; import 'dart:core' as core show Symbol;
import 'dart:_js_primitives' show printString; import 'dart:_js_primitives' show printString;
@ -12,6 +10,9 @@ import 'dart:_interceptors' show JSArray;
import 'dart:_foreign_helper' show JS; import 'dart:_foreign_helper' show JS;
import 'dart:_runtime' as dart; import 'dart:_runtime' as dart;
@patch
bool typeAcceptsNull<T>() => !dart.strictNullSafety || null is T;
@patch @patch
class Symbol implements core.Symbol { class Symbol implements core.Symbol {
@patch @patch
@ -19,7 +20,7 @@ class Symbol implements core.Symbol {
@patch @patch
int get hashCode { int get hashCode {
int hash = JS('int|Null', '#._hashCode', this); int? hash = JS('int|Null', '#._hashCode', this);
if (hash != null) return hash; if (hash != null) return hash;
const arbitraryPrime = 664597; const arbitraryPrime = 664597;
hash = 0x1fffffff & (arbitraryPrime * _name.hashCode); hash = 0x1fffffff & (arbitraryPrime * _name.hashCode);
@ -40,17 +41,17 @@ void printToConsole(String line) {
} }
@patch @patch
List<E> makeListFixedLength<E>(List<E> growableList) { List<T> makeListFixedLength<T>(List<T> growableList) {
JSArray.markFixedList(growableList); JSArray.markFixedList(growableList);
return growableList; return growableList;
} }
@patch @patch
List<E> makeFixedListUnmodifiable<E>(List<E> fixedLengthList) { List<T> makeFixedListUnmodifiable<T>(List<T> fixedLengthList) {
JSArray.markUnmodifiableList(fixedLengthList); JSArray.markUnmodifiableList(fixedLengthList);
return fixedLengthList; return fixedLengthList;
} }
@patch @patch
Object extractTypeArguments<T>(T instance, Function extract) => Object? extractTypeArguments<T>(T instance, Function extract) =>
dart.extractTypeArguments<T>(instance, extract); dart.extractTypeArguments<T>(instance, extract);

View file

@ -2,8 +2,6 @@
// for details. All rights reserved. Use of this source code is governed by a // for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file. // BSD-style license that can be found in the LICENSE file.
// @dart = 2.6
import 'dart:_js_helper' show patch; import 'dart:_js_helper' show patch;
import 'dart:async'; import 'dart:async';
import 'dart:convert'; import 'dart:convert';
@ -75,7 +73,7 @@ class _AsyncDirectoryListerOps {
@patch @patch
class _EventHandler { class _EventHandler {
@patch @patch
static void _sendData(Object sender, SendPort sendPort, int data) { static void _sendData(Object? sender, SendPort sendPort, int data) {
throw UnsupportedError("EventHandler._sendData"); throw UnsupportedError("EventHandler._sendData");
} }
} }
@ -305,7 +303,7 @@ class _Platform {
@patch @patch
class _ProcessUtils { class _ProcessUtils {
@patch @patch
static void _exit(int status) { static Never _exit(int status) {
throw UnsupportedError("ProcessUtils._exit"); throw UnsupportedError("ProcessUtils._exit");
} }
@ -325,7 +323,7 @@ class _ProcessUtils {
} }
@patch @patch
static int _pid(Process process) { static int _pid(Process? process) {
throw UnsupportedError("ProcessUtils._pid"); throw UnsupportedError("ProcessUtils._pid");
} }
@ -352,8 +350,8 @@ class ProcessInfo {
class Process { class Process {
@patch @patch
static Future<Process> start(String executable, List<String> arguments, static Future<Process> start(String executable, List<String> arguments,
{String workingDirectory, {String? workingDirectory,
Map<String, String> environment, Map<String, String>? environment,
bool includeParentEnvironment = true, bool includeParentEnvironment = true,
bool runInShell = false, bool runInShell = false,
ProcessStartMode mode = ProcessStartMode.normal}) { ProcessStartMode mode = ProcessStartMode.normal}) {
@ -362,8 +360,8 @@ class Process {
@patch @patch
static Future<ProcessResult> run(String executable, List<String> arguments, static Future<ProcessResult> run(String executable, List<String> arguments,
{String workingDirectory, {String? workingDirectory,
Map<String, String> environment, Map<String, String>? environment,
bool includeParentEnvironment = true, bool includeParentEnvironment = true,
bool runInShell = false, bool runInShell = false,
Encoding stdoutEncoding = systemEncoding, Encoding stdoutEncoding = systemEncoding,
@ -373,8 +371,8 @@ class Process {
@patch @patch
static ProcessResult runSync(String executable, List<String> arguments, static ProcessResult runSync(String executable, List<String> arguments,
{String workingDirectory, {String? workingDirectory,
Map<String, String> environment, Map<String, String>? environment,
bool includeParentEnvironment = true, bool includeParentEnvironment = true,
bool runInShell = false, bool runInShell = false,
Encoding stdoutEncoding = systemEncoding, Encoding stdoutEncoding = systemEncoding,
@ -411,13 +409,13 @@ class InternetAddress {
} }
@patch @patch
factory InternetAddress(String address, {InternetAddressType type}) { factory InternetAddress(String address, {InternetAddressType? type}) {
throw UnsupportedError("InternetAddress"); throw UnsupportedError("InternetAddress");
} }
@patch @patch
factory InternetAddress.fromRawAddress(Uint8List rawAddress, factory InternetAddress.fromRawAddress(Uint8List rawAddress,
{InternetAddressType type}) { {InternetAddressType? type}) {
throw new UnsupportedError("InternetAddress.fromRawAddress"); throw new UnsupportedError("InternetAddress.fromRawAddress");
} }
@ -434,7 +432,7 @@ class InternetAddress {
} }
@patch @patch
static InternetAddress tryParse(String address) { static InternetAddress? tryParse(String address) {
throw UnsupportedError("InternetAddress.tryParse"); throw UnsupportedError("InternetAddress.tryParse");
} }
} }
@ -476,14 +474,14 @@ class ServerSocket {
@patch @patch
class RawSocket { class RawSocket {
@patch @patch
static Future<RawSocket> connect(host, int port, static Future<RawSocket> connect(dynamic host, int port,
{sourceAddress, Duration timeout}) { {dynamic sourceAddress, Duration? timeout}) {
throw UnsupportedError("RawSocket constructor"); throw UnsupportedError("RawSocket constructor");
} }
@patch @patch
static Future<ConnectionTask<RawSocket>> startConnect(host, int port, static Future<ConnectionTask<RawSocket>> startConnect(dynamic host, int port,
{sourceAddress}) { {dynamic sourceAddress}) {
throw UnsupportedError("RawSocket constructor"); throw UnsupportedError("RawSocket constructor");
} }
} }
@ -491,14 +489,14 @@ class RawSocket {
@patch @patch
class Socket { class Socket {
@patch @patch
static Future<Socket> _connect(host, int port, static Future<Socket> _connect(dynamic host, int port,
{sourceAddress, Duration timeout}) { {dynamic sourceAddress, Duration? timeout}) {
throw UnsupportedError("Socket constructor"); throw UnsupportedError("Socket constructor");
} }
@patch @patch
static Future<ConnectionTask<Socket>> _startConnect(host, int port, static Future<ConnectionTask<Socket>> _startConnect(dynamic host, int port,
{sourceAddress}) { {dynamic sourceAddress}) {
throw UnsupportedError("Socket constructor"); throw UnsupportedError("Socket constructor");
} }
} }
@ -514,7 +512,7 @@ class SecureSocket {
@patch @patch
class RawSynchronousSocket { class RawSynchronousSocket {
@patch @patch
static RawSynchronousSocket connectSync(host, int port) { static RawSynchronousSocket connectSync(dynamic host, int port) {
throw UnsupportedError("RawSynchronousSocket.connectSync"); throw UnsupportedError("RawSynchronousSocket.connectSync");
} }
} }
@ -556,7 +554,7 @@ class X509Certificate {
@patch @patch
class RawDatagramSocket { class RawDatagramSocket {
@patch @patch
static Future<RawDatagramSocket> bind(host, int port, static Future<RawDatagramSocket> bind(dynamic host, int port,
{bool reuseAddress = true, bool reusePort = false, int ttl = 1}) { {bool reuseAddress = true, bool reusePort = false, int ttl = 1}) {
throw UnsupportedError("RawDatagramSocket.bind"); throw UnsupportedError("RawDatagramSocket.bind");
} }
@ -618,14 +616,14 @@ class RawZLibFilter {
int windowBits, int windowBits,
int memLevel, int memLevel,
int strategy, int strategy,
List<int> dictionary, List<int>? dictionary,
bool raw) { bool raw) {
throw UnsupportedError("_newZLibDeflateFilter"); throw UnsupportedError("_newZLibDeflateFilter");
} }
@patch @patch
static RawZLibFilter _makeZLibInflateFilter( static RawZLibFilter _makeZLibInflateFilter(
int windowBits, List<int> dictionary, bool raw) { int windowBits, List<int>? dictionary, bool raw) {
throw UnsupportedError("_newZLibInflateFilter"); throw UnsupportedError("_newZLibInflateFilter");
} }
} }

View file

@ -2,8 +2,6 @@
// for details. All rights reserved. Use of this source code is governed by a // for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file. // BSD-style license that can be found in the LICENSE file.
// @dart = 2.6
// Patch file for the dart:isolate library. // Patch file for the dart:isolate library.
import 'dart:_js_helper' show patch, NoReifyGeneric; import 'dart:_js_helper' show patch, NoReifyGeneric;
@ -18,36 +16,37 @@ class Isolate {
static Isolate get current => _unsupported(); static Isolate get current => _unsupported();
@patch @patch
String get debugName => _unsupported(); String? get debugName => _unsupported();
@patch @patch
static Future<Uri> get packageRoot => _unsupported(); static Future<Uri?> get packageRoot => _unsupported();
@patch @patch
static Future<Uri> get packageConfig => _unsupported(); static Future<Uri?> get packageConfig => _unsupported();
@patch @patch
static Future<Uri> resolvePackageUri(Uri packageUri) => _unsupported(); static Future<Uri?> resolvePackageUri(Uri packageUri) => _unsupported();
@patch @patch
static Future<Isolate> spawn<T>(void entryPoint(T message), T message, static Future<Isolate> spawn<T>(void entryPoint(T message), T message,
{bool paused = false, {bool paused = false,
bool errorsAreFatal, bool errorsAreFatal = true,
SendPort onExit, SendPort? onExit,
SendPort onError}) => SendPort? onError}) =>
_unsupported(); _unsupported();
@patch @patch
static Future<Isolate> spawnUri(Uri uri, List<String> args, var message, static Future<Isolate> spawnUri(Uri uri, List<String> args, var message,
{bool paused = false, {bool paused = false,
SendPort onExit, SendPort? onExit,
SendPort onError, SendPort? onError,
bool errorsAreFatal, bool errorsAreFatal = true,
bool checked, bool? checked,
Map<String, String> environment, Map<String, String>? environment,
Uri packageRoot, Uri? packageRoot,
Uri packageConfig, Uri? packageConfig,
bool automaticPackageResolution = false}) => bool automaticPackageResolution = false,
String? debugName}) =>
_unsupported(); _unsupported();
@patch @patch
@ -57,7 +56,7 @@ class Isolate {
void resume(Capability resumeCapability) => _unsupported(); void resume(Capability resumeCapability) => _unsupported();
@patch @patch
void addOnExitListener(SendPort responsePort, {Object response}) => void addOnExitListener(SendPort responsePort, {Object? response}) =>
_unsupported(); _unsupported();
@patch @patch
@ -70,7 +69,7 @@ class Isolate {
void kill({int priority = beforeNextEvent}) => _unsupported(); void kill({int priority = beforeNextEvent}) => _unsupported();
@patch @patch
void ping(SendPort responsePort, void ping(SendPort responsePort,
{Object response, int priority = immediate}) => {Object? response, int priority = immediate}) =>
_unsupported(); _unsupported();
@patch @patch
@ -99,13 +98,17 @@ class _ReceivePort extends Stream implements ReceivePort {
get sendPort => _unsupported(); get sendPort => _unsupported();
listen(onData, {onError, onDone, cancelOnError}) => _unsupported(); StreamSubscription listen(void Function(dynamic)? onData,
{Function? onError,
void Function()? onDone,
bool? cancelOnError = true}) =>
_unsupported();
} }
@patch @patch
class RawReceivePort { class RawReceivePort {
@patch @patch
factory RawReceivePort([void handler(event)]) => _unsupported(); factory RawReceivePort([Function? handler]) => _unsupported();
} }
@patch @patch

View file

@ -2,14 +2,12 @@
// for details. All rights reserved. Use of this source code is governed by a // for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file. // BSD-style license that can be found in the LICENSE file.
// @dart = 2.6
// Patch file for dart:js library. // Patch file for dart:js library.
library dart.js; library dart.js;
import 'dart:collection' show HashMap, ListMixin; import 'dart:collection' show HashMap, ListMixin;
import 'dart:_js_helper' show patch, Primitives; import 'dart:_js_helper' show patch, NoReifyGeneric, Primitives;
import 'dart:_foreign_helper' show JS; import 'dart:_foreign_helper' show JS;
import 'dart:_runtime' as dart; import 'dart:_runtime' as dart;
@ -21,7 +19,7 @@ final JsObject _context = _wrapToDart(dart.global_);
@patch @patch
class JsObject { class JsObject {
// The wrapped JS object. // The wrapped JS object.
final dynamic _jsObject; final Object _jsObject;
// This should only be called from _wrapToDart // This should only be called from _wrapToDart
JsObject._fromJs(this._jsObject) { JsObject._fromJs(this._jsObject) {
@ -29,7 +27,7 @@ class JsObject {
} }
@patch @patch
factory JsObject(JsFunction constructor, [List arguments]) { factory JsObject(JsFunction constructor, [List? arguments]) {
var ctor = constructor._jsObject; var ctor = constructor._jsObject;
if (arguments == null) { if (arguments == null) {
return _wrapToDart(JS('', 'new #()', ctor)); return _wrapToDart(JS('', 'new #()', ctor));
@ -39,25 +37,25 @@ class JsObject {
} }
@patch @patch
factory JsObject.fromBrowserObject(object) { factory JsObject.fromBrowserObject(Object object) {
if (object is num || object is String || object is bool || object == null) { if (object is num || object is String || object is bool || object == null) {
throw ArgumentError("object cannot be a num, string, bool, or null"); throw ArgumentError("object cannot be a num, string, bool, or null");
} }
return _wrapToDart(_convertToJS(object)); return _wrapToDart(_convertToJS(object)!);
} }
@patch @patch
factory JsObject.jsify(object) { factory JsObject.jsify(Object object) {
if ((object is! Map) && (object is! Iterable)) { if ((object is! Map) && (object is! Iterable)) {
throw ArgumentError("object must be a Map or Iterable"); throw ArgumentError("object must be a Map or Iterable");
} }
return _wrapToDart(_convertDataTree(object)); return _wrapToDart(_convertDataTree(object));
} }
static _convertDataTree(data) { static _convertDataTree(Object data) {
var _convertedObjects = HashMap.identity(); var _convertedObjects = HashMap.identity();
_convert(o) { _convert(Object? o) {
if (_convertedObjects.containsKey(o)) { if (_convertedObjects.containsKey(o)) {
return _convertedObjects[o]; return _convertedObjects[o];
} }
@ -90,7 +88,7 @@ class JsObject {
} }
@patch @patch
void operator []=(Object property, value) { void operator []=(Object property, Object? value) {
if (property is! String && property is! num) { if (property is! String && property is! num) {
throw ArgumentError("property is not a String or num"); throw ArgumentError("property is not a String or num");
} }
@ -98,11 +96,11 @@ class JsObject {
} }
@patch @patch
bool operator ==(other) => bool operator ==(Object other) =>
other is JsObject && JS<bool>('!', '# === #', _jsObject, other._jsObject); other is JsObject && JS<bool>('!', '# === #', _jsObject, other._jsObject);
@patch @patch
bool hasProperty(property) { bool hasProperty(Object property) {
if (property is! String && property is! num) { if (property is! String && property is! num) {
throw ArgumentError("property is not a String or num"); throw ArgumentError("property is not a String or num");
} }
@ -110,7 +108,7 @@ class JsObject {
} }
@patch @patch
void deleteProperty(property) { void deleteProperty(Object property) {
if (property is! String && property is! num) { if (property is! String && property is! num) {
throw ArgumentError("property is not a String or num"); throw ArgumentError("property is not a String or num");
} }
@ -132,14 +130,14 @@ class JsObject {
} }
@patch @patch
dynamic callMethod(method, [List args]) { dynamic callMethod(Object method, [List? args]) {
if (method is! String && method is! num) { if (method is! String && method is! num) {
throw ArgumentError("method is not a String or num"); throw ArgumentError("method is not a String or num");
} }
if (args != null) args = List.from(args.map(_convertToJS)); if (args != null) args = List.from(args.map(_convertToJS));
var fn = JS('', '#[#]', _jsObject, method); var fn = JS('', '#[#]', _jsObject, method);
if (JS<bool>('!', 'typeof(#) !== "function"', fn)) { if (JS<bool>('!', 'typeof(#) !== "function"', fn)) {
throw NoSuchMethodError(_jsObject, Symbol(method), args, {}); throw NoSuchMethodError(_jsObject, Symbol('$method'), args, {});
} }
return _convertToDart(JS('', '#.apply(#, #)', fn, _jsObject, args)); return _convertToDart(JS('', '#.apply(#, #)', fn, _jsObject, args));
} }
@ -164,7 +162,7 @@ class JsFunction extends JsObject {
f)); f));
} }
JsFunction._fromJs(jsObject) : super._fromJs(jsObject); JsFunction._fromJs(Object jsObject) : super._fromJs(jsObject);
@patch @patch
dynamic apply(List args, {thisArg}) => _convertToDart(JS( dynamic apply(List args, {thisArg}) => _convertToDart(JS(
@ -185,16 +183,16 @@ class JsArray<E> extends JsObject with ListMixin<E> {
factory JsArray.from(Iterable<E> other) => factory JsArray.from(Iterable<E> other) =>
JsArray<E>._fromJs([]..addAll(other.map(_convertToJS))); JsArray<E>._fromJs([]..addAll(other.map(_convertToJS)));
JsArray._fromJs(jsObject) : super._fromJs(jsObject); JsArray._fromJs(Object jsObject) : super._fromJs(jsObject);
_checkIndex(int index) { _checkIndex(int index) {
if (index is int && (index < 0 || index >= length)) { if (index < 0 || index >= length) {
throw RangeError.range(index, 0, length); throw RangeError.range(index, 0, length);
} }
} }
_checkInsertIndex(int index) { _checkInsertIndex(int index) {
if (index is int && (index < 0 || index >= length + 1)) { if (index < 0 || index >= length + 1) {
throw RangeError.range(index, 0, length); throw RangeError.range(index, 0, length);
} }
} }
@ -210,9 +208,7 @@ class JsArray<E> extends JsObject with ListMixin<E> {
@patch @patch
E operator [](Object index) { E operator [](Object index) {
// TODO(justinfagnani): fix the semantics for non-ints if (index is int) {
// dartbug.com/14605
if (index is num && index == index.toInt()) {
_checkIndex(index); _checkIndex(index);
} }
return super[index] as E; return super[index] as E;
@ -220,9 +216,7 @@ class JsArray<E> extends JsObject with ListMixin<E> {
@patch @patch
void operator []=(Object index, value) { void operator []=(Object index, value) {
// TODO(justinfagnani): fix the semantics for non-ints if (index is int) {
// dartbug.com/14605
if (index is num && index == index.toInt()) {
_checkIndex(index); _checkIndex(index);
} }
super[index] = value; super[index] = value;
@ -253,7 +247,7 @@ class JsArray<E> extends JsObject with ListMixin<E> {
@patch @patch
void addAll(Iterable<E> iterable) { void addAll(Iterable<E> iterable) {
var list = (JS<bool>('!', '# instanceof Array', iterable)) var list = (JS<bool>('!', '# instanceof Array', iterable))
? iterable ? JS<List>('', '#', iterable)
: List.from(iterable); : List.from(iterable);
callMethod('push', list); callMethod('push', list);
} }
@ -288,13 +282,13 @@ class JsArray<E> extends JsObject with ListMixin<E> {
int length = end - start; int length = end - start;
if (length == 0) return; if (length == 0) return;
if (skipCount < 0) throw ArgumentError(skipCount); if (skipCount < 0) throw ArgumentError(skipCount);
var args = <Object>[start, length] var args = <Object?>[start, length]
..addAll(iterable.skip(skipCount).take(length)); ..addAll(iterable.skip(skipCount).take(length));
callMethod('splice', args); callMethod('splice', args);
} }
@patch @patch
void sort([int compare(E a, E b)]) { void sort([int compare(E a, E b)?]) {
// Note: arr.sort(null) is a type error in FF // Note: arr.sort(null) is a type error in FF
callMethod('sort', compare == null ? [] : [compare]); callMethod('sort', compare == null ? [] : [compare]);
} }
@ -304,7 +298,7 @@ class JsArray<E> extends JsObject with ListMixin<E> {
// We include the instanceof Object test to filter out cross frame objects // We include the instanceof Object test to filter out cross frame objects
// on FireFox. Surprisingly on FireFox the instanceof Window test succeeds for // on FireFox. Surprisingly on FireFox the instanceof Window test succeeds for
// cross frame windows while the instanceof Object test fails. // cross frame windows while the instanceof Object test fails.
bool _isBrowserType(o) => JS( bool _isBrowserType(Object o) => JS(
'bool', 'bool',
'# instanceof Object && (' '# instanceof Object && ('
'# instanceof Blob || ' '# instanceof Blob || '
@ -329,11 +323,11 @@ bool _isBrowserType(o) => JS(
o); o);
class _DartObject { class _DartObject {
final _dartObj; final Object _dartObj;
_DartObject(this._dartObj); _DartObject(this._dartObj);
} }
dynamic _convertToJS(dynamic o) { Object? _convertToJS(Object? o) {
if (o == null || o is String || o is num || o is bool || _isBrowserType(o)) { if (o == null || o is String || o is num || o is bool || _isBrowserType(o)) {
return o; return o;
} else if (o is DateTime) { } else if (o is DateTime) {
@ -349,8 +343,8 @@ dynamic _convertToJS(dynamic o) {
} }
} }
dynamic _wrapDartFunction(f) { Object _wrapDartFunction(Object f) {
var wrapper = JS( var wrapper = JS<Object>(
'', '',
'function(/*...arguments*/) {' 'function(/*...arguments*/) {'
' let args = Array.prototype.map.call(arguments, #);' ' let args = Array.prototype.map.call(arguments, #);'
@ -366,11 +360,11 @@ dynamic _wrapDartFunction(f) {
// converts a Dart object to a reference to a native JS object // converts a Dart object to a reference to a native JS object
// which might be a DartObject JS->Dart proxy // which might be a DartObject JS->Dart proxy
Object _convertToDart(o) { Object? _convertToDart(Object? o) {
if (o == null || o is String || o is num || o is bool || _isBrowserType(o)) { if (o == null || o is String || o is num || o is bool || _isBrowserType(o)) {
return o; return o;
} else if (JS('!', '# instanceof Date', o)) { } else if (JS('!', '# instanceof Date', o)) {
num ms = JS('!', '#.getTime()', o); int ms = JS('!', '#.getTime()', o);
return DateTime.fromMillisecondsSinceEpoch(ms); return DateTime.fromMillisecondsSinceEpoch(ms);
} else if (o is _DartObject && } else if (o is _DartObject &&
!identical(dart.getReifiedType(o), dart.jsobject)) { !identical(dart.getReifiedType(o), dart.jsobject)) {
@ -380,9 +374,10 @@ Object _convertToDart(o) {
} }
} }
Object _wrapToDart(o) => _putIfAbsent(_dartProxies, o, _wrapToDartHelper); JsObject _wrapToDart(Object o) =>
_putIfAbsent(_dartProxies, o, _wrapToDartHelper);
Object _wrapToDartHelper(o) { JsObject _wrapToDartHelper(Object o) {
if (JS<bool>('!', 'typeof # == "function"', o)) { if (JS<bool>('!', 'typeof # == "function"', o)) {
return JsFunction._fromJs(o); return JsFunction._fromJs(o);
} }
@ -392,16 +387,18 @@ Object _wrapToDartHelper(o) {
return JsObject._fromJs(o); return JsObject._fromJs(o);
} }
final _dartProxies = JS('', 'new WeakMap()'); final Object _dartProxies = JS('', 'new WeakMap()');
final _jsProxies = JS('', 'new WeakMap()'); final Object _jsProxies = JS('', 'new WeakMap()');
Object _putIfAbsent(weakMap, o, getValue(o)) { @NoReifyGeneric()
var value = JS('', '#.get(#)', weakMap, o); T _putIfAbsent<T>(Object weakMap, Object o, T getValue(Object o)) {
T? value = JS('', '#.get(#)', weakMap, o);
if (value == null) { if (value == null) {
value = getValue(o); value = getValue(o);
JS('', '#.set(#, #)', weakMap, o, value); JS('', '#.set(#, #)', weakMap, o, value);
} }
return value; // TODO(vsm): Static cast. Unnecessary?
return JS('', '#', value);
} }
Expando<Function> _interopExpando = Expando<Function>(); Expando<Function> _interopExpando = Expando<Function>();
@ -409,9 +406,9 @@ Expando<Function> _interopExpando = Expando<Function>();
@patch @patch
F allowInterop<F extends Function>(F f) { F allowInterop<F extends Function>(F f) {
if (!dart.isDartFunction(f)) return f; if (!dart.isDartFunction(f)) return f;
var ret = _interopExpando[f]; var ret = _interopExpando[f] as F?;
if (ret == null) { if (ret == null) {
ret = JS( ret = JS<F>(
'', '',
'function (...args) {' 'function (...args) {'
' return #(#, args);' ' return #(#, args);'
@ -430,7 +427,7 @@ Function allowInteropCaptureThis(Function f) {
if (!dart.isDartFunction(f)) return f; if (!dart.isDartFunction(f)) return f;
var ret = _interopCaptureThisExpando[f]; var ret = _interopCaptureThisExpando[f];
if (ret == null) { if (ret == null) {
ret = JS( ret = JS<Function>(
'', '',
'function(...arguments) {' 'function(...arguments) {'
' let args = [this];' ' let args = [this];'

View file

@ -2,8 +2,6 @@
// for details. All rights reserved. Use of this source code is governed by a // for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file. // BSD-style license that can be found in the LICENSE file.
// @dart = 2.6
// Patch file for dart:math library. // Patch file for dart:math library.
import 'dart:_foreign_helper' show JS; import 'dart:_foreign_helper' show JS;
import 'dart:_js_helper' show patch, nullCheck, notNull; import 'dart:_js_helper' show patch, nullCheck, notNull;
@ -12,53 +10,53 @@ import 'dart:typed_data' show ByteData;
@patch @patch
@notNull @notNull
T min<T extends num>(@nullCheck T a, @nullCheck T b) => T min<T extends num>(@nullCheck T a, @nullCheck T b) =>
JS('-dynamic', r'Math.min(#, #)', a, b); JS<T>('-dynamic', r'Math.min(#, #)', a, b);
@patch @patch
@notNull @notNull
T max<T extends num>(@nullCheck T a, @nullCheck T b) => T max<T extends num>(@nullCheck T a, @nullCheck T b) =>
JS('-dynamic', r'Math.max(#, #)', a, b); JS<T>('-dynamic', r'Math.max(#, #)', a, b);
@patch @patch
@notNull @notNull
double sqrt(@nullCheck num x) => JS<num>('!', r'Math.sqrt(#)', x); double sqrt(@nullCheck num x) => JS<double>('!', r'Math.sqrt(#)', x);
@patch @patch
@notNull @notNull
double sin(@nullCheck num radians) => JS<num>('!', r'Math.sin(#)', radians); double sin(@nullCheck num radians) => JS<double>('!', r'Math.sin(#)', radians);
@patch @patch
@notNull @notNull
double cos(@nullCheck num radians) => JS<num>('!', r'Math.cos(#)', radians); double cos(@nullCheck num radians) => JS<double>('!', r'Math.cos(#)', radians);
@patch @patch
@notNull @notNull
double tan(@nullCheck num radians) => JS<num>('!', r'Math.tan(#)', radians); double tan(@nullCheck num radians) => JS<double>('!', r'Math.tan(#)', radians);
@patch @patch
@notNull @notNull
double acos(@nullCheck num x) => JS<num>('!', r'Math.acos(#)', x); double acos(@nullCheck num x) => JS<double>('!', r'Math.acos(#)', x);
@patch @patch
@notNull @notNull
double asin(@nullCheck num x) => JS<num>('!', r'Math.asin(#)', x); double asin(@nullCheck num x) => JS<double>('!', r'Math.asin(#)', x);
@patch @patch
@notNull @notNull
double atan(@nullCheck num x) => JS<num>('!', r'Math.atan(#)', x); double atan(@nullCheck num x) => JS<double>('!', r'Math.atan(#)', x);
@patch @patch
@notNull @notNull
double atan2(@nullCheck num a, @nullCheck num b) => double atan2(@nullCheck num a, @nullCheck num b) =>
JS<num>('!', r'Math.atan2(#, #)', a, b); JS<double>('!', r'Math.atan2(#, #)', a, b);
@patch @patch
@notNull @notNull
double exp(@nullCheck num x) => JS<num>('!', r'Math.exp(#)', x); double exp(@nullCheck num x) => JS<double>('!', r'Math.exp(#)', x);
@patch @patch
@notNull @notNull
double log(@nullCheck num x) => JS<num>('!', r'Math.log(#)', x); double log(@nullCheck num x) => JS<double>('!', r'Math.log(#)', x);
@patch @patch
@notNull @notNull
@ -69,10 +67,10 @@ const int _POW2_32 = 0x100000000;
@patch @patch
class Random { class Random {
static Random _secureRandom; static Random? _secureRandom;
@patch @patch
factory Random([int seed]) => factory Random([int? seed]) =>
(seed == null) ? const _JSRandom() : _Random(seed); (seed == null) ? const _JSRandom() : _Random(seed);
@patch @patch
@ -88,7 +86,7 @@ class _JSRandom implements Random {
if (max <= 0 || max > _POW2_32) { if (max <= 0 || max > _POW2_32) {
throw RangeError("max must be in range 0 < max ≤ 2^32, was $max"); throw RangeError("max must be in range 0 < max ≤ 2^32, was $max");
} }
return JS("int", "(Math.random() * #) >>> 0", max); return JS<int>("int", "(Math.random() * #) >>> 0", max);
} }
/** /**
@ -96,13 +94,13 @@ class _JSRandom implements Random {
* the range from 0.0, inclusive, to 1.0, exclusive. * the range from 0.0, inclusive, to 1.0, exclusive.
*/ */
@notNull @notNull
double nextDouble() => JS("double", "Math.random()"); double nextDouble() => JS<double>("double", "Math.random()");
/** /**
* Generates a random boolean value. * Generates a random boolean value.
*/ */
@notNull @notNull
bool nextBool() => JS("bool", "Math.random() < 0.5"); bool nextBool() => JS<bool>("bool", "Math.random() < 0.5");
} }
class _Random implements Random { class _Random implements Random {
@ -240,7 +238,7 @@ class _Random implements Random {
do { do {
_nextState(); _nextState();
rnd32 = _lo; rnd32 = _lo;
result = rnd32.remainder(max); // % max; result = rnd32.remainder(max).toInt(); // % max;
} while ((rnd32 - result + max) >= _POW2_32); } while ((rnd32 - result + max) >= _POW2_32);
return result; return result;
} }
@ -327,7 +325,7 @@ class _JSSecureRandom implements Random {
} }
_buffer.setUint32(0, 0); _buffer.setUint32(0, 0);
int start = 4 - byteCount; int start = 4 - byteCount;
int randomLimit = pow(256, byteCount); int randomLimit = pow(256, byteCount).toInt();
while (true) { while (true) {
_getRandomBytes(start, byteCount); _getRandomBytes(start, byteCount);
// The getUint32 method is big-endian as default. // The getUint32 method is big-endian as default.
@ -336,7 +334,7 @@ class _JSSecureRandom implements Random {
// Max is power of 2. // Max is power of 2.
return random & (max - 1); return random & (max - 1);
} }
int result = random.remainder(max); int result = random.remainder(max).toInt();
// Ensure results have equal probability by rejecting values in the // Ensure results have equal probability by rejecting values in the
// last range of k*max .. 256**byteCount. // last range of k*max .. 256**byteCount.
// TODO: Consider picking a higher byte count if the last range is a // TODO: Consider picking a higher byte count if the last range is a

View file

@ -2,8 +2,6 @@
// for details. All rights reserved. Use of this source code is governed by a // for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file. // BSD-style license that can be found in the LICENSE file.
// @dart = 2.6
import 'dart:_js_helper' show patch; import 'dart:_js_helper' show patch;
import 'dart:_native_typed_data'; import 'dart:_native_typed_data';

View file

@ -2,8 +2,6 @@
// for details. All rights reserved. Use of this source code is governed by a // for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file. // BSD-style license that can be found in the LICENSE file.
// @dart = 2.6
part of dart._js_helper; part of dart._js_helper;
/// Tells the optimizing compiler to always inline the annotated method. /// Tells the optimizing compiler to always inline the annotated method.
@ -83,7 +81,7 @@ class JsPeerInterface {
/// Used for classes where Dart subclasses should be callable from JavaScript /// Used for classes where Dart subclasses should be callable from JavaScript
/// matching the JavaScript calling conventions. /// matching the JavaScript calling conventions.
final String name; final String name;
const JsPeerInterface({this.name}); const JsPeerInterface({required this.name});
} }
/// A Dart interface may only be implemented by a native JavaScript object /// A Dart interface may only be implemented by a native JavaScript object

View file

@ -2,30 +2,28 @@
// for details. All rights reserved. Use of this source code is governed by a // for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file. // BSD-style license that can be found in the LICENSE file.
// @dart = 2.6
part of dart._js_helper; part of dart._js_helper;
class CustomKeyHashMap<K, V> extends CustomHashMap<K, V> { class CustomKeyHashMap<K, V> extends CustomHashMap<K, V> {
final _Predicate<Object> _validKey; final _Predicate<Object?> _validKey;
CustomKeyHashMap(_Equality<K> equals, _Hasher<K> hashCode, this._validKey) CustomKeyHashMap(_Equality<K> equals, _Hasher<K> hashCode, this._validKey)
: super(equals, hashCode); : super(equals, hashCode);
@override @override
@notNull @notNull
bool containsKey(Object key) { bool containsKey(Object? key) {
if (!_validKey(key)) return false; if (!_validKey(key)) return false;
return super.containsKey(key); return super.containsKey(key);
} }
@override @override
V operator [](Object key) { V? operator [](Object? key) {
if (!_validKey(key)) return null; if (!_validKey(key)) return null;
return super[key]; return super[key];
} }
@override @override
V remove(Object key) { V? remove(Object? key) {
if (!_validKey(key)) return null; if (!_validKey(key)) return null;
return super.remove(key); return super.remove(key);
} }
@ -69,7 +67,7 @@ class CustomHashMap<K, V> extends InternalMap<K, V> {
Iterable<V> get values => _JSMapIterable<V>(this, false); Iterable<V> get values => _JSMapIterable<V>(this, false);
@notNull @notNull
bool containsKey(Object key) { bool containsKey(Object? key) {
if (key is K) { if (key is K) {
var buckets = JS('', '#.get(# & 0x3ffffff)', _keyMap, _hashCode(key)); var buckets = JS('', '#.get(# & 0x3ffffff)', _keyMap, _hashCode(key));
if (buckets != null) { if (buckets != null) {
@ -83,7 +81,7 @@ class CustomHashMap<K, V> extends InternalMap<K, V> {
return false; return false;
} }
bool containsValue(Object value) { bool containsValue(Object? value) {
for (var v in JS('', '#.values()', _map)) { for (var v in JS('', '#.values()', _map)) {
if (value == v) return true; if (value == v) return true;
} }
@ -96,7 +94,7 @@ class CustomHashMap<K, V> extends InternalMap<K, V> {
}); });
} }
V operator [](Object key) { V? operator [](Object? key) {
if (key is K) { if (key is K) {
var buckets = JS('', '#.get(# & 0x3ffffff)', _keyMap, _hashCode(key)); var buckets = JS('', '#.get(# & 0x3ffffff)', _keyMap, _hashCode(key));
if (buckets != null) { if (buckets != null) {
@ -152,13 +150,13 @@ class CustomHashMap<K, V> extends InternalMap<K, V> {
JS('', '#.push(#)', buckets, key); JS('', '#.push(#)', buckets, key);
} }
V value = ifAbsent(); V value = ifAbsent();
if (value == null) value = null; // coerce undefined to null. if (value == null) JS('', '# = null', value); // coerce undefined to null.
JS('', '#.set(#, #)', _map, key, value); JS('', '#.set(#, #)', _map, key, value);
_modifications = (_modifications + 1) & 0x3ffffff; _modifications = (_modifications + 1) & 0x3ffffff;
return value; return value;
} }
V remove(Object key) { V? remove(Object? key) {
if (key is K) { if (key is K) {
int hash = JS('!', '# & 0x3ffffff', _hashCode(key)); int hash = JS('!', '# & 0x3ffffff', _hashCode(key));
var keyMap = _keyMap; var keyMap = _keyMap;

View file

@ -2,8 +2,6 @@
// for details. All rights reserved. Use of this source code is governed by a // for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file. // BSD-style license that can be found in the LICENSE file.
// @dart = 2.6
/// This library defines the operations that define and manipulate Dart /// This library defines the operations that define and manipulate Dart
/// classes. Included in this are: /// classes. Included in this are:
/// - Generics /// - Generics
@ -109,7 +107,7 @@ final mixinOn = JS('', 'Symbol("mixinOn")');
@JSExportName('implements') @JSExportName('implements')
final implements_ = JS('', 'Symbol("implements")'); final implements_ = JS('', 'Symbol("implements")');
List Function() getImplements(clazz) => JS( List? Function() getImplements(clazz) => JS(
'', '',
'Object.hasOwnProperty.call(#, #) ? #[#] : null', 'Object.hasOwnProperty.call(#, #) ? #[#] : null',
clazz, clazz,
@ -229,11 +227,11 @@ getGenericClass(type) => safeGetOwnProperty(type, _originalDeclaration);
// TODO(markzipan): Make this non-nullable if we can ensure this returns // TODO(markzipan): Make this non-nullable if we can ensure this returns
// an empty list or if null and the empty list are semantically the same. // an empty list or if null and the empty list are semantically the same.
List getGenericArgs(type) => List? getGenericArgs(type) =>
JS<List>('', '#', safeGetOwnProperty(type, _typeArguments)); JS<List>('', '#', safeGetOwnProperty(type, _typeArguments));
List getGenericArgVariances(type) => List? getGenericArgVariances(type) =>
JS<List>('', '#', safeGetOwnProperty(type, _variances)); JS<List?>('', '#', safeGetOwnProperty(type, _variances));
void setGenericArgVariances(f, variances) => void setGenericArgVariances(f, variances) =>
JS('', '#[#] = #', f, _variances, variances); JS('', '#[#] = #', f, _variances, variances);

View file

@ -2,8 +2,6 @@
// for details. All rights reserved. Use of this source code is governed by a // for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file. // BSD-style license that can be found in the LICENSE file.
// @dart = 2.6
part of dart._runtime; part of dart._runtime;
// We need to set these properties while the sdk is only partially initialized // We need to set these properties while the sdk is only partially initialized
@ -21,15 +19,15 @@ throwUnimplementedError(String message) {
// TODO(nshahan) Cleanup embeded strings and extract file location at runtime // TODO(nshahan) Cleanup embeded strings and extract file location at runtime
// from the stacktrace. // from the stacktrace.
assertFailed(String message, assertFailed(String? message,
[String fileUri, int line, int column, String conditionSource]) { [String? fileUri, int? line, int? column, String? conditionSource]) {
throw AssertionErrorImpl(message, fileUri, line, column, conditionSource); throw AssertionErrorImpl(message, fileUri, line, column, conditionSource);
} }
final _nullFailedSet = JS('!', 'new Set()'); final _nullFailedSet = JS('!', 'new Set()');
// Run-time null safety assertion per: // Run-time null safety assertion per:
// https://github.com/dart-lang/language/blob/master/accepted/future-releases/nnbd/feature-specification.md#automatic-debug-assertion-insertion // https://github.com/dart-lang/language/blob/master/accepted/future-releases/nnbd/feature-specification.md#automatic-debug-assertion-insertion
nullFailed(String fileUri, int line, int column, String variable) { nullFailed(String? fileUri, int? line, int? column, String? variable) {
if (strictNullSafety) { if (strictNullSafety) {
throw AssertionErrorImpl( throw AssertionErrorImpl(
'A null value was passed into a non-nullable parameter $variable', 'A null value was passed into a non-nullable parameter $variable',
@ -47,7 +45,7 @@ nullFailed(String fileUri, int line, int column, String variable) {
} }
} }
throwCyclicInitializationError([String field]) { throwCyclicInitializationError([String? field]) {
throw CyclicInitializationError(field); throw CyclicInitializationError(field);
} }
@ -101,7 +99,7 @@ final Object _jsError = JS('', 'Symbol("_jsError")');
/// ///
/// If the throw originated in JavaScript, then there is not a corresponding /// If the throw originated in JavaScript, then there is not a corresponding
/// Dart value, so we just return the error object. /// Dart value, so we just return the error object.
Object getThrown(Object error) { Object? getThrown(Object? error) {
if (error != null) { if (error != null) {
// Get the Dart thrown value, if any. // Get the Dart thrown value, if any.
var value = JS('', '#[#]', error, _thrownValue); var value = JS('', '#[#]', error, _thrownValue);
@ -123,7 +121,7 @@ final _stackTrace = JS('', 'Symbol("_stackTrace")');
/// the corresponding stack trace the same way we do for Dart throws. If the /// the corresponding stack trace the same way we do for Dart throws. If the
/// throw object was not an Error, then we don't have a JS trace, so we create /// throw object was not an Error, then we don't have a JS trace, so we create
/// one here. /// one here.
StackTrace stackTrace(Object error) { StackTrace stackTrace(Object? error) {
if (JS<bool>('!', '!(# instanceof Error)', error)) { if (JS<bool>('!', '!(# instanceof Error)', error)) {
// We caught something that isn't a JS Error. // We caught something that isn't a JS Error.
// //
@ -133,7 +131,7 @@ StackTrace stackTrace(Object error) {
} }
// If we've already created the Dart stack trace object, return it. // If we've already created the Dart stack trace object, return it.
StackTrace trace = JS('', '#[#]', error, _stackTrace); StackTrace? trace = JS('', '#[#]', error, _stackTrace);
if (trace != null) return trace; if (trace != null) return trace;
// Otherwise create the Dart stack trace (by parsing the JS stack), and // Otherwise create the Dart stack trace (by parsing the JS stack), and
@ -210,7 +208,7 @@ final Object RethrownDartError = JS(
/// Implements `throw` of [exception], allowing for throw in an expression /// Implements `throw` of [exception], allowing for throw in an expression
/// context, and capturing the current stack trace. /// context, and capturing the current stack trace.
@JSExportName('throw') @JSExportName('throw')
void throw_(Object exception) { void throw_(Object? exception) {
/// Wrap the object so we capture a new stack trace, and so it will print /// Wrap the object so we capture a new stack trace, and so it will print
/// nicely from JS, as if it were a normal JS error. /// nicely from JS, as if it were a normal JS error.
JS('', 'throw new #(#)', DartError, exception); JS('', 'throw new #(#)', DartError, exception);
@ -233,7 +231,7 @@ void throw_(Object exception) {
/// If the stack trace is null, this will preserve the original stack trace /// If the stack trace is null, this will preserve the original stack trace
/// on the exception, if available, otherwise it will capture the current stack /// on the exception, if available, otherwise it will capture the current stack
/// trace. /// trace.
Object createErrorWithStack(Object exception, StackTrace trace) { Object? createErrorWithStack(Object exception, StackTrace? trace) {
if (trace == null) { if (trace == null) {
var error = JS('', '#[#]', exception, _jsError); var error = JS('', '#[#]', exception, _jsError);
return error != null ? error : JS('', 'new #(#)', DartError, exception); return error != null ? error : JS('', 'new #(#)', DartError, exception);
@ -257,18 +255,18 @@ void stackPrint(Object error) {
} }
class _StackTrace implements StackTrace { class _StackTrace implements StackTrace {
final Object _jsError; final Object? _jsError;
final Object _jsObjectMissingTrace; final Object? _jsObjectMissingTrace;
String _trace; String? _trace;
_StackTrace(this._jsError) : _jsObjectMissingTrace = null; _StackTrace(this._jsError) : _jsObjectMissingTrace = null;
_StackTrace.missing(Object caughtObj) _StackTrace.missing(Object? caughtObj)
: _jsObjectMissingTrace = caughtObj != null ? caughtObj : 'null', : _jsObjectMissingTrace = caughtObj != null ? caughtObj : 'null',
_jsError = JS('', 'Error()'); _jsError = JS('', 'Error()');
String toString() { String toString() {
if (_trace != null) return _trace; if (_trace != null) return _trace!;
var e = _jsError; var e = _jsError;
String trace = ''; String trace = '';

View file

@ -2,8 +2,6 @@
// for details. All rights reserved. Use of this source code is governed by a // for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file. // BSD-style license that can be found in the LICENSE file.
// @dart = 2.6
/// This library defines runtime operations on objects used by the code /// This library defines runtime operations on objects used by the code
/// generator. /// generator.
part of dart._runtime; part of dart._runtime;
@ -19,7 +17,7 @@ class InvocationImpl extends Invocation {
final bool isSetter; final bool isSetter;
final String failureMessage; final String failureMessage;
InvocationImpl(memberName, List<Object> positionalArguments, InvocationImpl(memberName, List<Object?> positionalArguments,
{namedArguments, {namedArguments,
List typeArguments = const [], List typeArguments = const [],
this.isMethod = false, this.isMethod = false,
@ -146,7 +144,7 @@ dput(obj, field, value) {
/// [actuals] and [namedActuals]. /// [actuals] and [namedActuals].
/// ///
/// Returns `null` if all checks pass. /// Returns `null` if all checks pass.
String _argumentErrors(FunctionType type, List actuals, namedActuals) { String? _argumentErrors(FunctionType type, List actuals, namedActuals) {
// Check for too few required arguments. // Check for too few required arguments.
int actualsCount = JS('!', '#.length', actuals); int actualsCount = JS('!', '#.length', actuals);
var required = type.args; var required = type.args;
@ -165,7 +163,7 @@ String _argumentErrors(FunctionType type, List actuals, namedActuals) {
} }
// Check if we have invalid named arguments. // Check if we have invalid named arguments.
Iterable names; Iterable? names;
var named = type.named; var named = type.named;
var requiredNamed = type.requiredNamed; var requiredNamed = type.requiredNamed;
if (namedActuals != null) { if (namedActuals != null) {
@ -444,7 +442,7 @@ cast(obj, type) {
return castError(obj, type); return castError(obj, type);
} }
bool test(bool obj) { bool test(bool? obj) {
if (obj == null) throw BooleanConversionAssertionError(); if (obj == null) throw BooleanConversionAssertionError();
return obj; return obj;
} }
@ -513,11 +511,11 @@ final constantMaps = JS<Object>('!', 'new Map()');
// Keeping the paths is probably expensive. It would probably // Keeping the paths is probably expensive. It would probably
// be more space efficient to just use a direct hash table with // be more space efficient to just use a direct hash table with
// an appropriately defined structural equality function. // an appropriately defined structural equality function.
Object _lookupNonTerminal(Object map, Object key) { Object _lookupNonTerminal(Object map, Object? key) {
var result = JS('', '#.get(#)', map, key); var result = JS('', '#.get(#)', map, key);
if (result != null) return result; if (result != null) return result;
JS('', '#.set(#, # = new Map())', map, key, result); JS('', '#.set(#, # = new Map())', map, key, result);
return result; return result!;
} }
Map<K, V> constMap<K, V>(JSArray elements) { Map<K, V> constMap<K, V>(JSArray elements) {
@ -527,7 +525,7 @@ Map<K, V> constMap<K, V>(JSArray elements) {
map = _lookupNonTerminal(map, JS('', '#[#]', elements, i)); map = _lookupNonTerminal(map, JS('', '#[#]', elements, i));
} }
map = _lookupNonTerminal(map, K); map = _lookupNonTerminal(map, K);
Map<K, V> result = JS('', '#.get(#)', map, V); Map<K, V>? result = JS('', '#.get(#)', map, V);
if (result != null) return result; if (result != null) return result;
result = ImmutableMap<K, V>.from(elements); result = ImmutableMap<K, V>.from(elements);
JS('', '#.set(#, #)', map, V, result); JS('', '#.set(#, #)', map, V, result);
@ -550,7 +548,7 @@ Set<E> constSet<E>(JSArray<E> elements) {
for (var i = 0; i < count; i++) { for (var i = 0; i < count; i++) {
map = _lookupNonTerminal(map, JS('', '#[#]', elements, i)); map = _lookupNonTerminal(map, JS('', '#[#]', elements, i));
} }
Set<E> result = JS('', '#.get(#)', map, E); Set<E>? result = JS('', '#.get(#)', map, E);
if (result != null) return result; if (result != null) return result;
result = _createImmutableSet<E>(elements); result = _createImmutableSet<E>(elements);
JS('', '#.set(#, #)', map, E, result); JS('', '#.set(#, #)', map, E, result);

View file

@ -2,8 +2,6 @@
// for details. All rights reserved. Use of this source code is governed by a // for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file. // BSD-style license that can be found in the LICENSE file.
// @dart = 2.6
/// This library defines the association between runtime objects and /// This library defines the association between runtime objects and
/// runtime types. /// runtime types.
part of dart._runtime; part of dart._runtime;
@ -116,7 +114,7 @@ getReifiedType(obj) {
} }
/// Return the module name for a raw library object. /// Return the module name for a raw library object.
String getModuleName(Object module) => JS('', '#[#]', module, _moduleName); String? getModuleName(Object module) => JS('', '#[#]', module, _moduleName);
final _loadedModules = JS('', 'new Map()'); final _loadedModules = JS('', 'new Map()');
final _loadedPartMaps = JS('', 'new Map()'); final _loadedPartMaps = JS('', 'new Map()');
@ -126,7 +124,7 @@ List<String> getModuleNames() {
return JS<List<String>>('', 'Array.from(#.keys())', _loadedModules); return JS<List<String>>('', 'Array.from(#.keys())', _loadedModules);
} }
String getSourceMap(String moduleName) { String? getSourceMap(String moduleName) {
return JS('!', '#.get(#)', _loadedSourceMaps, moduleName); return JS('!', '#.get(#)', _loadedSourceMaps, moduleName);
} }
@ -143,7 +141,7 @@ getModulePartMap(String name) => JS('', '#.get(#)', _loadedPartMaps, name);
/// Track all libraries /// Track all libraries
void trackLibraries( void trackLibraries(
String moduleName, Object libraries, Object parts, String sourceMap) { String moduleName, Object libraries, Object parts, String? sourceMap) {
if (parts is String) { if (parts is String) {
// Added for backwards compatibility. // Added for backwards compatibility.
// package:build_web_compilers currently invokes this without [parts] // package:build_web_compilers currently invokes this without [parts]
@ -159,9 +157,9 @@ void trackLibraries(
_parts = null; _parts = null;
} }
List<String> _libraries; List<String>? _libraries;
Map<String, Object> _libraryObjects; Map<String, Object?>? _libraryObjects;
Map<String, List<String>> _parts; Map<String, List<String>?>? _parts;
_computeLibraryMetadata() { _computeLibraryMetadata() {
_libraries = []; _libraries = [];
@ -174,16 +172,16 @@ _computeLibraryMetadata() {
// TODO(nshahan) Can we optimize this cast and the one below to use // TODO(nshahan) Can we optimize this cast and the one below to use
// JsArray.of() to be more efficient? // JsArray.of() to be more efficient?
var libraries = getOwnPropertyNames(module).cast<String>(); var libraries = getOwnPropertyNames(module).cast<String>();
_libraries.addAll(libraries); _libraries!.addAll(libraries);
for (var library in libraries) { for (var library in libraries) {
_libraryObjects[library] = JS('', '#.#', module, library); _libraryObjects![library] = JS('', '#.#', module, library);
} }
// Add parts from each module. // Add parts from each module.
var partMap = getModulePartMap(name); var partMap = getModulePartMap(name);
libraries = getOwnPropertyNames(partMap).cast<String>(); libraries = getOwnPropertyNames(partMap).cast<String>();
for (var library in libraries) { for (var library in libraries) {
_parts[library] = List.from(JS('List', '#.#', partMap, library)); _parts![library] = List.from(JS('List', '#.#', partMap, library));
} }
} }
} }
@ -191,11 +189,11 @@ _computeLibraryMetadata() {
/// Returns the JS library object for a given library [uri] or /// Returns the JS library object for a given library [uri] or
/// undefined / null if it isn't loaded. Top-level types and /// undefined / null if it isn't loaded. Top-level types and
/// methods are available on this object. /// methods are available on this object.
Object getLibrary(String uri) { Object? getLibrary(String uri) {
if (_libraryObjects == null) { if (_libraryObjects == null) {
_computeLibraryMetadata(); _computeLibraryMetadata();
} }
return _libraryObjects[uri]; return _libraryObjects![uri];
} }
/// Returns a JSArray of library uris (e.g, /// Returns a JSArray of library uris (e.g,
@ -205,7 +203,7 @@ List<String> getLibraries() {
if (_libraries == null) { if (_libraries == null) {
_computeLibraryMetadata(); _computeLibraryMetadata();
} }
return _libraries; return _libraries!;
} }
/// Returns a JSArray of part uris for a given [libraryUri]. /// Returns a JSArray of part uris for a given [libraryUri].
@ -225,5 +223,5 @@ List<String> getParts(String libraryUri) {
if (_parts == null) { if (_parts == null) {
_computeLibraryMetadata(); _computeLibraryMetadata();
} }
return _parts[libraryUri] ?? []; return _parts![libraryUri] ?? [];
} }

View file

@ -2,8 +2,6 @@
// for details. All rights reserved. Use of this source code is governed by a // for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file. // BSD-style license that can be found in the LICENSE file.
// @dart = 2.6
@ReifyFunctionTypes(false) @ReifyFunctionTypes(false)
library dart._runtime; library dart._runtime;

View file

@ -2,8 +2,6 @@
// for details. All rights reserved. Use of this source code is governed by a // for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file. // BSD-style license that can be found in the LICENSE file.
// @dart = 2.6
/// This library defines the representation of runtime types. /// This library defines the representation of runtime types.
part of dart._runtime; part of dart._runtime;
@ -118,7 +116,7 @@ class DynamicType extends DartType {
bool is_T(object) => true; bool is_T(object) => true;
@JSExportName('as') @JSExportName('as')
Object as_T(Object object) => object; Object? as_T(Object? object) => object;
} }
@notNull @notNull
@ -144,7 +142,7 @@ bool isDartFunction(obj) =>
Expando<Function> _assertInteropExpando = Expando<Function>(); Expando<Function> _assertInteropExpando = Expando<Function>();
@NoReifyGeneric() @NoReifyGeneric()
F tearoffInterop<F extends Function>(F f) { F tearoffInterop<F extends Function?>(F f) {
// Wrap a JS function with a closure that ensures all function arguments are // Wrap a JS function with a closure that ensures all function arguments are
// native JS functions. // native JS functions.
if (!_isJsObject(f) || f == null) return f; if (!_isJsObject(f) || f == null) return f;
@ -171,10 +169,10 @@ F tearoffInterop<F extends Function>(F f) {
/// we disable type checks for in these cases, and allow any JS object to work /// we disable type checks for in these cases, and allow any JS object to work
/// as if it were an instance of this JS type. /// as if it were an instance of this JS type.
class LazyJSType extends DartType { class LazyJSType extends DartType {
Function() _getRawJSTypeFn; Function()? _getRawJSTypeFn;
@notNull @notNull
final String _dartName; final String _dartName;
Object _rawJSType; Object? _rawJSType;
LazyJSType(this._getRawJSTypeFn, this._dartName); LazyJSType(this._getRawJSTypeFn, this._dartName);
@ -183,7 +181,7 @@ class LazyJSType extends DartType {
return raw != null ? typeName(raw) : "JSObject<$_dartName>"; return raw != null ? typeName(raw) : "JSObject<$_dartName>";
} }
Object _getRawJSType() { Object? _getRawJSType() {
var raw = _rawJSType; var raw = _rawJSType;
if (raw != null) return raw; if (raw != null) return raw;
@ -193,7 +191,7 @@ class LazyJSType extends DartType {
// overhead, especially if exceptions are being thrown. Also it means the // overhead, especially if exceptions are being thrown. Also it means the
// behavior of a given type check can change later on. // behavior of a given type check can change later on.
try { try {
raw = _getRawJSTypeFn(); raw = _getRawJSTypeFn!();
} catch (e) {} } catch (e) {}
if (raw == null) { if (raw == null) {
@ -434,7 +432,7 @@ class VoidType extends DartType {
bool is_T(object) => true; bool is_T(object) => true;
@JSExportName('as') @JSExportName('as')
Object as_T(Object object) => object; Object? as_T(Object? object) => object;
} }
@JSExportName('void') @JSExportName('void')
@ -685,7 +683,7 @@ class FunctionType extends AbstractFunctionType {
// Named arguments native JS Object of the form { namedArgName: namedArgType } // Named arguments native JS Object of the form { namedArgName: namedArgType }
final named; final named;
final requiredNamed; final requiredNamed;
String _stringValue; String? _stringValue;
/// Construct a function type. /// Construct a function type.
/// ///
@ -743,7 +741,7 @@ class FunctionType extends AbstractFunctionType {
} }
/// Maps argument names to their canonicalized type. /// Maps argument names to their canonicalized type.
Map<String, Object> _createNameMap(List<Object> names) { Map<String, Object> _createNameMap(List<Object?> names) {
var result = <String, Object>{}; var result = <String, Object>{};
// TODO: Remove this sort if ordering can be conserved. // TODO: Remove this sort if ordering can be conserved.
JS('', '#.sort()', names); JS('', '#.sort()', names);
@ -763,7 +761,7 @@ class FunctionType extends AbstractFunctionType {
_createNameMap(getOwnPropertyNames(requiredNamed).toList()); _createNameMap(getOwnPropertyNames(requiredNamed).toList());
get name { get name {
if (_stringValue != null) return _stringValue; if (_stringValue != null) return _stringValue!;
var buffer = '('; var buffer = '(';
for (var i = 0; JS<bool>('!', '# < #.length', i, args); ++i) { for (var i = 0; JS<bool>('!', '# < #.length', i, args); ++i) {
if (i > 0) { if (i > 0) {
@ -858,7 +856,7 @@ class GenericFunctionTypeIdentifier extends AbstractFunctionType {
final typeFormals; final typeFormals;
final typeBounds; final typeBounds;
final FunctionType function; final FunctionType function;
String _stringValue; String? _stringValue;
GenericFunctionTypeIdentifier( GenericFunctionTypeIdentifier(
this.typeFormals, this.typeBounds, this.function); this.typeFormals, this.typeBounds, this.function);
@ -869,7 +867,7 @@ class GenericFunctionTypeIdentifier extends AbstractFunctionType {
/// Type formal names may not correspond to those of the originating type. /// Type formal names may not correspond to those of the originating type.
/// We should consider auto-generating these to avoid confusion. /// We should consider auto-generating these to avoid confusion.
toString() { toString() {
if (_stringValue != null) return _stringValue; if (_stringValue != null) return _stringValue!;
String s = "<"; String s = "<";
var typeFormals = this.typeFormals; var typeFormals = this.typeFormals;
var typeBounds = this.typeBounds; var typeBounds = this.typeBounds;
@ -994,7 +992,7 @@ class GenericFunctionType extends AbstractFunctionType {
// formal if known, or it will be the original TypeVariable if we are still // formal if known, or it will be the original TypeVariable if we are still
// solving for it. This array is passed to `instantiateToBounds` as we are // solving for it. This array is passed to `instantiateToBounds` as we are
// progressively solving for type variables. // progressively solving for type variables.
var defaults = List<Object>.filled(typeFormals.length, null); var defaults = List<Object?>.filled(typeFormals.length, null);
// not ground // not ground
var partials = Map<TypeVariable, Object>.identity(); var partials = Map<TypeVariable, Object>.identity();
@ -1037,9 +1035,9 @@ class GenericFunctionType extends AbstractFunctionType {
while (hasProgress) { while (hasProgress) {
hasProgress = false; hasProgress = false;
for (var typeFormal in partials.keys) { for (var typeFormal in partials.keys) {
var partialBound = partials[typeFormal]; var partialBound = partials[typeFormal]!;
if (!hasFreeFormal(partialBound)) { if (!hasFreeFormal(partialBound)) {
int index = all[typeFormal]; int index = all[typeFormal]!;
defaults[index] = instantiateTypeBounds(defaults)[index]; defaults[index] = instantiateTypeBounds(defaults)[index];
partials.remove(typeFormal); partials.remove(typeFormal);
hasProgress = true; hasProgress = true;
@ -1079,7 +1077,7 @@ class GenericFunctionType extends AbstractFunctionType {
} }
} }
List<TypeVariable> _typeFormalsFromFunction(Object typeConstructor) { List<TypeVariable> _typeFormalsFromFunction(Object? typeConstructor) {
// Extract parameter names from the function parameters. // Extract parameter names from the function parameters.
// //
// This is not robust in general for user-defined JS functions, but it // This is not robust in general for user-defined JS functions, but it
@ -1610,7 +1608,7 @@ bool _isInterfaceSubtype(t1, t2, @notNull bool strictMode) => JS('', '''(() => {
return false; return false;
})()'''); })()''');
Object extractTypeArguments<T>(T instance, Function f) { Object? extractTypeArguments<T>(T instance, Function f) {
if (instance == null) { if (instance == null) {
throw ArgumentError('Cannot extract type of null instance.'); throw ArgumentError('Cannot extract type of null instance.');
} }
@ -1622,7 +1620,7 @@ Object extractTypeArguments<T>(T instance, Function f) {
throw ArgumentError('Cannot extract from non-class type ($type).'); throw ArgumentError('Cannot extract from non-class type ($type).');
} }
var typeArguments = getGenericArgs(type); var typeArguments = getGenericArgs(type);
if (typeArguments.isEmpty) { if (typeArguments!.isEmpty) {
throw ArgumentError('Cannot extract from non-generic type ($type).'); throw ArgumentError('Cannot extract from non-generic type ($type).');
} }
var supertype = _getMatchingSupertype(getReifiedType(instance), type); var supertype = _getMatchingSupertype(getReifiedType(instance), type);
@ -1646,14 +1644,14 @@ class _TypeInferrer {
typeVariables, typeVariables.map((_) => TypeConstraint())); typeVariables, typeVariables.map((_) => TypeConstraint()));
/// Returns the inferred types based on the current constraints. /// Returns the inferred types based on the current constraints.
List<Object> getInferredTypes() { List<Object>? getInferredTypes() {
var result = <Object>[]; var result = <Object>[];
for (var constraint in _typeVariables.values) { for (var constraint in _typeVariables.values) {
// Prefer the known bound, if any. // Prefer the known bound, if any.
if (constraint.lower != null) { if (constraint.lower != null) {
result.add(constraint.lower); result.add(constraint.lower!);
} else if (constraint.upper != null) { } else if (constraint.upper != null) {
result.add(constraint.upper); result.add(constraint.upper!);
} else { } else {
return null; return null;
} }
@ -1670,11 +1668,11 @@ class _TypeInferrer {
_isSubtypeMatch(subtype, supertype); _isSubtypeMatch(subtype, supertype);
void _constrainLower(TypeVariable parameter, Object lower) { void _constrainLower(TypeVariable parameter, Object lower) {
_typeVariables[parameter]._constrainLower(lower); _typeVariables[parameter]!._constrainLower(lower);
} }
void _constrainUpper(TypeVariable parameter, Object upper) { void _constrainUpper(TypeVariable parameter, Object upper) {
_typeVariables[parameter]._constrainUpper(upper); _typeVariables[parameter]!._constrainUpper(upper);
} }
bool _isFunctionSubtypeMatch(FunctionType subtype, FunctionType supertype) { bool _isFunctionSubtypeMatch(FunctionType subtype, FunctionType supertype) {
@ -1740,13 +1738,13 @@ class _TypeInferrer {
for (var name in supertypeNamed.keys) { for (var name in supertypeNamed.keys) {
var subtypeParamType = subtypeNamed[name]; var subtypeParamType = subtypeNamed[name];
if (subtypeParamType == null) return false; if (subtypeParamType == null) return false;
if (!_isSubtypeMatch(supertypeNamed[name], subtypeParamType)) { if (!_isSubtypeMatch(supertypeNamed[name]!, subtypeParamType)) {
return false; return false;
} }
} }
for (var name in supertypeRequiredNamed.keys) { for (var name in supertypeRequiredNamed.keys) {
var subtypeParamType = subtypeRequiredNamed[name] ?? subtypeNamed[name]; var subtypeParamType = subtypeRequiredNamed[name] ?? subtypeNamed[name]!;
if (!_isSubtypeMatch(supertypeRequiredNamed[name], subtypeParamType)) { if (!_isSubtypeMatch(supertypeRequiredNamed[name]!, subtypeParamType)) {
return false; return false;
} }
} }
@ -1777,8 +1775,8 @@ class _TypeInferrer {
var matchingSupertype = _getMatchingSupertype(subtype, supertype); var matchingSupertype = _getMatchingSupertype(subtype, supertype);
if (matchingSupertype == null) return false; if (matchingSupertype == null) return false;
var matchingTypeArgs = getGenericArgs(matchingSupertype); var matchingTypeArgs = getGenericArgs(matchingSupertype)!;
var supertypeTypeArgs = getGenericArgs(supertype); var supertypeTypeArgs = getGenericArgs(supertype)!;
for (int i = 0; i < supertypeTypeArgs.length; i++) { for (int i = 0; i < supertypeTypeArgs.length; i++) {
if (!_isSubtypeMatch(matchingTypeArgs[i], supertypeTypeArgs[i])) { if (!_isSubtypeMatch(matchingTypeArgs[i], supertypeTypeArgs[i])) {
return false; return false;
@ -1824,13 +1822,13 @@ class _TypeInferrer {
// Handle FutureOr<T> union type. // Handle FutureOr<T> union type.
if (_isFutureOr(subtype)) { if (_isFutureOr(subtype)) {
var subtypeArg = getGenericArgs(subtype)[0]; var subtypeArg = getGenericArgs(subtype)![0];
if (_isFutureOr(supertype)) { if (_isFutureOr(supertype)) {
// `FutureOr<P>` is a subtype match for `FutureOr<Q>` with respect to `L` // `FutureOr<P>` is a subtype match for `FutureOr<Q>` with respect to `L`
// under constraints `C`: // under constraints `C`:
// - If `P` is a subtype match for `Q` with respect to `L` under constraints // - If `P` is a subtype match for `Q` with respect to `L` under constraints
// `C`. // `C`.
var supertypeArg = getGenericArgs(supertype)[0]; var supertypeArg = getGenericArgs(supertype)![0];
return _isSubtypeMatch(subtypeArg, supertypeArg); return _isSubtypeMatch(subtypeArg, supertypeArg);
} }
@ -1843,7 +1841,7 @@ class _TypeInferrer {
var subtypeFuture = var subtypeFuture =
JS<Object>('!', '#(#)', getGenericClass(Future), subtypeArg); JS<Object>('!', '#(#)', getGenericClass(Future), subtypeArg);
return _isSubtypeMatch(subtypeFuture, supertype) && return _isSubtypeMatch(subtypeFuture, supertype) &&
_isSubtypeMatch(subtypeArg, supertype); _isSubtypeMatch(subtypeArg!, supertype);
} }
if (_isFutureOr(supertype)) { if (_isFutureOr(supertype)) {
@ -1855,7 +1853,7 @@ class _TypeInferrer {
// constraints `C` // constraints `C`
// - And `P` is a subtype match for `Q` with respect to `L` under // - And `P` is a subtype match for `Q` with respect to `L` under
// constraints `C` // constraints `C`
var supertypeArg = getGenericArgs(supertype)[0]; var supertypeArg = getGenericArgs(supertype)![0];
var supertypeFuture = var supertypeFuture =
JS<Object>('!', '#(#)', getGenericClass(Future), supertypeArg); JS<Object>('!', '#(#)', getGenericClass(Future), supertypeArg);
return _isSubtypeMatch(subtype, supertypeFuture) || return _isSubtypeMatch(subtype, supertypeFuture) ||
@ -1950,11 +1948,11 @@ class _TypeInferrer {
class TypeConstraint { class TypeConstraint {
/// The lower bound of the type being constrained. This bound must be a /// The lower bound of the type being constrained. This bound must be a
/// subtype of the type being constrained. /// subtype of the type being constrained.
Object lower; Object? lower;
/// The upper bound of the type being constrained. The type being constrained /// The upper bound of the type being constrained. The type being constrained
/// must be a subtype of this bound. /// must be a subtype of this bound.
Object upper; Object? upper;
void _constrainLower(Object type) { void _constrainLower(Object type) {
var _lower = lower; var _lower = lower;
@ -1991,7 +1989,7 @@ class TypeConstraint {
/// Finds a supertype of [subtype] that matches the class [supertype], but may /// Finds a supertype of [subtype] that matches the class [supertype], but may
/// contain different generic type arguments. /// contain different generic type arguments.
Object _getMatchingSupertype(Object subtype, Object supertype) { Object? _getMatchingSupertype(Object? subtype, Object supertype) {
if (identical(subtype, supertype)) return supertype; if (identical(subtype, supertype)) return supertype;
if (subtype == null || _equalType(subtype, Object)) return null; if (subtype == null || _equalType(subtype, Object)) return null;
@ -2014,7 +2012,7 @@ Object _getMatchingSupertype(Object subtype, Object supertype) {
// Check interfaces. // Check interfaces.
var getInterfaces = getImplements(subtype); var getInterfaces = getImplements(subtype);
if (getInterfaces != null) { if (getInterfaces != null) {
for (var iface in getInterfaces()) { for (var iface in getInterfaces()!) {
result = _getMatchingSupertype(iface, supertype); result = _getMatchingSupertype(iface, supertype);
if (result != null) return result; if (result != null) return result;
} }

View file

@ -2,8 +2,6 @@
// for details. All rights reserved. Use of this source code is governed by a // for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file. // BSD-style license that can be found in the LICENSE file.
// @dart = 2.6
part of dart._runtime; part of dart._runtime;
/// This library defines a set of general javascript utilities for us /// This library defines a set of general javascript utilities for us
@ -19,11 +17,11 @@ defineValue(obj, name, value) {
} }
final Function(Object, Object, final Function(Object, Object,
{Object get, {Object? get,
Object set, Object? set,
Object value, Object? value,
bool configurable, bool? configurable,
bool writable}) defineAccessor = JS('', 'Object.defineProperty'); bool? writable}) defineAccessor = JS('', 'Object.defineProperty');
final dynamic Function(Object, Object) getOwnPropertyDescriptor = final dynamic Function(Object, Object) getOwnPropertyDescriptor =
JS('', 'Object.getOwnPropertyDescriptor'); JS('', 'Object.getOwnPropertyDescriptor');

View file

@ -2,8 +2,6 @@
// for details. All rights reserved. Use of this source code is governed by a // for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file. // BSD-style license that can be found in the LICENSE file.
// @dart = 2.6
library dart._debugger; library dart._debugger;
import 'dart:_foreign_helper' show JS; import 'dart:_foreign_helper' show JS;
@ -171,7 +169,7 @@ bool hasMethod(object, String name) {
/// [JsonMLFormatter] consumes [NameValuePair] objects and /// [JsonMLFormatter] consumes [NameValuePair] objects and
class NameValuePair { class NameValuePair {
NameValuePair( NameValuePair(
{this.name, {this.name = '',
this.value, this.value,
this.config = JsonMLConfig.none, this.config = JsonMLConfig.none,
this.hideName = false}); this.hideName = false});
@ -187,7 +185,7 @@ class NameValuePair {
int get hashCode => name.hashCode; int get hashCode => name.hashCode;
final String name; final String name;
final Object value; final Object? value;
final JsonMLConfig config; final JsonMLConfig config;
final bool hideName; final bool hideName;
@ -197,8 +195,8 @@ class NameValuePair {
class MapEntry { class MapEntry {
MapEntry({this.key, this.value}); MapEntry({this.key, this.value});
final Object key; final Object? key;
final Object value; final Object? value;
} }
class IterableSpan { class IterableSpan {
@ -216,7 +214,7 @@ class IterableSpan {
/// 10000-length subset and 1 1-length subset. /// 10000-length subset and 1 1-length subset.
int get maxPowerOfSubsetSize => int get maxPowerOfSubsetSize =>
(log(length - .5) / log(_maxSpanLength)).truncate(); (log(length - .5) / log(_maxSpanLength)).truncate();
int get subsetSize => pow(_maxSpanLength, maxPowerOfSubsetSize); int get subsetSize => pow(_maxSpanLength, maxPowerOfSubsetSize).toInt();
Map<int, dynamic> asMap() => Map<int, dynamic> asMap() =>
iterable.skip(start).take(length).toList().asMap(); iterable.skip(start).take(length).toList().asMap();
@ -284,7 +282,7 @@ safeProperties(object) => Map.fromIterable(
/// Devtools Formatter API. /// Devtools Formatter API.
class JsonMLElement { class JsonMLElement {
dynamic _attributes; dynamic _attributes;
List _jsonML; late List _jsonML;
JsonMLElement(tagName) { JsonMLElement(tagName) {
_attributes = JS('', '{}'); _attributes = JS('', '{}');
@ -408,7 +406,7 @@ class JsonMLFormatter {
// The value is indented when it is on a different line from the name // The value is indented when it is on a different line from the name
// by setting right padding of the name to -13px and the padding of the // by setting right padding of the name to -13px and the padding of the
// value to 13px. // value to 13px.
JsonMLElement nameSpan; JsonMLElement? nameSpan;
var valueStyle = ''; var valueStyle = '';
if (!child.hideName) { if (!child.hideName) {
nameSpan = JsonMLElement('span') nameSpan = JsonMLElement('span')
@ -444,38 +442,36 @@ class JsonMLFormatter {
abstract class Formatter { abstract class Formatter {
bool accept(object, config); bool accept(object, config);
String preview(object); String? preview(object);
bool hasChildren(object); bool hasChildren(object);
List<NameValuePair> children(object); List<NameValuePair>? children(object);
} }
class DartFormatter { class DartFormatter {
List<Formatter> _formatters; final List<Formatter> _formatters;
DartFormatter() { DartFormatter()
// The order of formatters matters as formatters earlier in the list take : _formatters = [
// precedence. // Formatters earlier in the list take precedence.
_formatters = [ ObjectInternalsFormatter(),
ObjectInternalsFormatter(), ClassFormatter(),
ClassFormatter(), TypeFormatter(),
TypeFormatter(), NamedConstructorFormatter(),
NamedConstructorFormatter(), MapFormatter(),
MapFormatter(), MapOverviewFormatter(),
MapOverviewFormatter(), IterableFormatter(),
IterableFormatter(), IterableSpanFormatter(),
IterableSpanFormatter(), MapEntryFormatter(),
MapEntryFormatter(), StackTraceFormatter(),
StackTraceFormatter(), ErrorAndExceptionFormatter(),
ErrorAndExceptionFormatter(), FunctionFormatter(),
FunctionFormatter(), HeritageClauseFormatter(),
HeritageClauseFormatter(), LibraryModuleFormatter(),
LibraryModuleFormatter(), LibraryFormatter(),
LibraryFormatter(), ObjectFormatter(),
ObjectFormatter(), ];
];
}
String preview(object, config) { String? preview(object, config) {
try { try {
if (object == null || if (object == null ||
object is num || object is num ||
@ -509,7 +505,7 @@ class DartFormatter {
return false; return false;
} }
List<NameValuePair> children(object, config) { List<NameValuePair>? children(object, config) {
try { try {
if (object != null) { if (object != null) {
for (var formatter in _formatters) { for (var formatter in _formatters) {
@ -558,7 +554,7 @@ class ObjectFormatter extends Formatter {
bool hasChildren(object) => true; bool hasChildren(object) => true;
List<NameValuePair> children(object) { children(object) {
var type = dart.getType(object); var type = dart.getType(object);
var ret = LinkedHashSet<NameValuePair>(); var ret = LinkedHashSet<NameValuePair>();
// We use a Set rather than a List to avoid duplicates. // We use a Set rather than a List to avoid duplicates.
@ -591,12 +587,12 @@ class ObjectInternalsFormatter extends ObjectFormatter {
/// Formatter for module Dart Library objects. /// Formatter for module Dart Library objects.
class LibraryModuleFormatter implements Formatter { class LibraryModuleFormatter implements Formatter {
accept(object, config) => dart.getModuleName(object) != null; bool accept(object, config) => dart.getModuleName(object) != null;
bool hasChildren(object) => true; bool hasChildren(object) => true;
String preview(object) { String preview(object) {
var libraryNames = dart.getModuleName(object).split('/'); var libraryNames = dart.getModuleName(object)!.split('/');
// Library names are received with a repeat directory name, so strip the // Library names are received with a repeat directory name, so strip the
// last directory entry here to make the path cleaner. For example, the // last directory entry here to make the path cleaner. For example, the
// library "third_party/dart/utf/utf" shoud display as // library "third_party/dart/utf/utf" shoud display as
@ -622,7 +618,7 @@ class LibraryModuleFormatter implements Formatter {
class LibraryFormatter implements Formatter { class LibraryFormatter implements Formatter {
var genericParameters = HashMap<String, String>(); var genericParameters = HashMap<String, String>();
accept(object, config) => object is Library; bool accept(object, config) => object is Library;
bool hasChildren(object) => true; bool hasChildren(object) => true;
@ -657,7 +653,7 @@ class LibraryFormatter implements Formatter {
/// we can distinguish them based on whether they have been tagged with /// we can distinguish them based on whether they have been tagged with
/// runtime type information. /// runtime type information.
class FunctionFormatter implements Formatter { class FunctionFormatter implements Formatter {
accept(object, config) { bool accept(object, config) {
if (_typeof(object) != 'function') return false; if (_typeof(object) != 'function') return false;
return dart.getReifiedType(object) != null; return dart.getReifiedType(object) != null;
} }
@ -690,7 +686,7 @@ class FunctionFormatter implements Formatter {
class MapOverviewFormatter implements Formatter { class MapOverviewFormatter implements Formatter {
// Because this comes after MapFormatter in the list, internal // Because this comes after MapFormatter in the list, internal
// maps will be picked up by that formatter. // maps will be picked up by that formatter.
accept(object, config) => object is Map; bool accept(object, config) => object is Map;
bool hasChildren(object) => true; bool hasChildren(object) => true;
@ -718,7 +714,7 @@ class MapOverviewFormatter implements Formatter {
/// This is only used for internal maps, or when shown as [[entries]] /// This is only used for internal maps, or when shown as [[entries]]
/// from MapOverViewFormatter. /// from MapOverViewFormatter.
class MapFormatter implements Formatter { class MapFormatter implements Formatter {
accept(object, config) => bool accept(object, config) =>
object is InternalMap || config == JsonMLConfig.asMap; object is InternalMap || config == JsonMLConfig.asMap;
bool hasChildren(object) => true; bool hasChildren(object) => true;
@ -779,7 +775,7 @@ class IterableFormatter implements Formatter {
} }
class NamedConstructorFormatter implements Formatter { class NamedConstructorFormatter implements Formatter {
accept(object, config) => object is NamedConstructor; bool accept(object, config) => object is NamedConstructor;
// TODO(bmilligan): Display the signature of the named constructor as the // TODO(bmilligan): Display the signature of the named constructor as the
// preview. // preview.
@ -798,7 +794,7 @@ class NamedConstructorFormatter implements Formatter {
/// Formatter for synthetic MapEntry objects used to display contents of a Map /// Formatter for synthetic MapEntry objects used to display contents of a Map
/// cleanly. /// cleanly.
class MapEntryFormatter implements Formatter { class MapEntryFormatter implements Formatter {
accept(object, config) => object is MapEntry; bool accept(object, config) => object is MapEntry;
String preview(object) { String preview(object) {
MapEntry entry = object; MapEntry entry = object;
@ -839,7 +835,7 @@ class HeritageClauseFormatter implements Formatter {
/// Formatter for synthetic IterableSpan objects used to display contents of /// Formatter for synthetic IterableSpan objects used to display contents of
/// an Iterable cleanly. /// an Iterable cleanly.
class IterableSpanFormatter implements Formatter { class IterableSpanFormatter implements Formatter {
accept(object, config) => object is IterableSpan; bool accept(object, config) => object is IterableSpan;
String preview(object) { String preview(object) {
return '[${object.start}...${object.end - 1}]'; return '[${object.start}...${object.end - 1}]';
@ -854,7 +850,7 @@ class IterableSpanFormatter implements Formatter {
class ErrorAndExceptionFormatter extends ObjectFormatter { class ErrorAndExceptionFormatter extends ObjectFormatter {
static final RegExp _pattern = RegExp(r'\d+\:\d+'); static final RegExp _pattern = RegExp(r'\d+\:\d+');
accept(object, config) => object is Error || object is Exception; bool accept(object, config) => object is Error || object is Exception;
bool hasChildren(object) => true; bool hasChildren(object) => true;
@ -867,8 +863,8 @@ class ErrorAndExceptionFormatter extends ObjectFormatter {
l.contains(_pattern) && l.contains(_pattern) &&
!l.contains('dart:sdk') && !l.contains('dart:sdk') &&
!l.contains('dart_sdk'), !l.contains('dart_sdk'),
orElse: () => null); orElse: () => '');
return line != null ? '${object} at ${line}' : '${object}'; return line != '' ? '${object} at ${line}' : '${object}';
} }
List<NameValuePair> children(object) { List<NameValuePair> children(object) {
@ -890,7 +886,7 @@ class ErrorAndExceptionFormatter extends ObjectFormatter {
} }
class StackTraceFormatter implements Formatter { class StackTraceFormatter implements Formatter {
accept(object, config) => object is StackTrace; bool accept(object, config) => object is StackTrace;
String preview(object) => 'StackTrace'; String preview(object) => 'StackTrace';
@ -908,13 +904,13 @@ class StackTraceFormatter implements Formatter {
} }
class ClassFormatter implements Formatter { class ClassFormatter implements Formatter {
accept(object, config) => config == JsonMLConfig.asClass; bool accept(object, config) => config == JsonMLConfig.asClass;
String preview(type) { String preview(type) {
var implements = dart.getImplements(type); var implements = dart.getImplements(type)();
var typeName = getTypeName(type); var typeName = getTypeName(type);
if (implements != null) { if (implements != null) {
var typeNames = implements().map(getTypeName); var typeNames = implements.map(getTypeName);
return '${typeName} implements ${typeNames.join(", ")}'; return '${typeName} implements ${typeNames.join(", ")}';
} else { } else {
return typeName; return typeName;
@ -979,7 +975,7 @@ class ClassFormatter implements Formatter {
} }
class TypeFormatter implements Formatter { class TypeFormatter implements Formatter {
accept(object, config) => object is Type; bool accept(object, config) => object is Type;
String preview(object) => object.toString(); String preview(object) => object.toString();
@ -995,7 +991,7 @@ typedef String StackTraceMapper(String stackTrace);
/// ///
/// Raw JS stack traces are used if $dartStackTraceUtility has not been /// Raw JS stack traces are used if $dartStackTraceUtility has not been
/// specified. /// specified.
StackTraceMapper get stackTraceMapper { StackTraceMapper? get stackTraceMapper {
var _util = JS('', r'#.$dartStackTraceUtility', dart.global_); var _util = JS('', r'#.$dartStackTraceUtility', dart.global_);
return _util != null ? JS('!', '#.mapper', _util) : null; return _util != null ? JS('!', '#.mapper', _util) : null;
} }

View file

@ -2,8 +2,6 @@
// for details. All rights reserved. Use of this source code is governed by a // for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file. // BSD-style license that can be found in the LICENSE file.
// @dart = 2.6
library dart._foreign_helper; library dart._foreign_helper;
/** /**
@ -108,7 +106,7 @@ library dart._foreign_helper;
*/ */
// Add additional optional arguments if needed. The method is treated internally // Add additional optional arguments if needed. The method is treated internally
// as a variable argument method. // as a variable argument method.
T JS<T extends Object>(String typeDescription, String codeTemplate, external T JS<T extends Object?>(String typeDescription, String codeTemplate,
[arg0, [arg0,
arg1, arg1,
arg2, arg2,
@ -128,7 +126,7 @@ T JS<T extends Object>(String typeDescription, String codeTemplate,
arg16, arg16,
arg17, arg17,
arg18, arg18,
arg19]) {} arg19]);
/// Annotates the compiled Js name for fields and methods. /// Annotates the compiled Js name for fields and methods.
/// Similar behaviour to `JS` from `package:js/js.dart` (but usable from runtime /// Similar behaviour to `JS` from `package:js/js.dart` (but usable from runtime
@ -161,73 +159,73 @@ JS_INTERCEPTOR_CONSTANT(Type type) {}
/** /**
* Returns the prefix used for generated is checks on classes. * Returns the prefix used for generated is checks on classes.
*/ */
String JS_OPERATOR_IS_PREFIX() {} external String JS_OPERATOR_IS_PREFIX();
/** /**
* Returns the prefix used for generated type argument substitutions on classes. * Returns the prefix used for generated type argument substitutions on classes.
*/ */
String JS_OPERATOR_AS_PREFIX() {} external String JS_OPERATOR_AS_PREFIX();
/// Returns the name of the class `Object` in the generated code. /// Returns the name of the class `Object` in the generated code.
String JS_OBJECT_CLASS_NAME() {} external String JS_OBJECT_CLASS_NAME();
/// Returns the name of the class `Null` in the generated code. /// Returns the name of the class `Null` in the generated code.
String JS_NULL_CLASS_NAME() {} external String JS_NULL_CLASS_NAME();
/// Returns the name of the class `Function` in the generated code. /// Returns the name of the class `Function` in the generated code.
String JS_FUNCTION_CLASS_NAME() {} external String JS_FUNCTION_CLASS_NAME();
/** /**
* Returns the field name used for determining if an object or its * Returns the field name used for determining if an object or its
* interceptor has JavaScript indexing behavior. * interceptor has JavaScript indexing behavior.
*/ */
String JS_IS_INDEXABLE_FIELD_NAME() {} external String JS_IS_INDEXABLE_FIELD_NAME();
/// Returns the name used for generated function types on classes and methods. /// Returns the name used for generated function types on classes and methods.
String JS_SIGNATURE_NAME() {} external String JS_SIGNATURE_NAME();
/// Returns the name used to tag typedefs. /// Returns the name used to tag typedefs.
String JS_TYPEDEF_TAG() {} external String JS_TYPEDEF_TAG();
/// Returns the name used to tag function type representations in JavaScript. /// Returns the name used to tag function type representations in JavaScript.
String JS_FUNCTION_TYPE_TAG() {} external String JS_FUNCTION_TYPE_TAG();
/** /**
* Returns the name used to tag void return in function type representations * Returns the name used to tag void return in function type representations
* in JavaScript. * in JavaScript.
*/ */
String JS_FUNCTION_TYPE_VOID_RETURN_TAG() {} external String JS_FUNCTION_TYPE_VOID_RETURN_TAG();
/** /**
* Returns the name used to tag return types in function type representations * Returns the name used to tag return types in function type representations
* in JavaScript. * in JavaScript.
*/ */
String JS_FUNCTION_TYPE_RETURN_TYPE_TAG() {} external String JS_FUNCTION_TYPE_RETURN_TYPE_TAG();
/** /**
* Returns the name used to tag required parameters in function type * Returns the name used to tag required parameters in function type
* representations in JavaScript. * representations in JavaScript.
*/ */
String JS_FUNCTION_TYPE_REQUIRED_PARAMETERS_TAG() {} external String JS_FUNCTION_TYPE_REQUIRED_PARAMETERS_TAG();
/** /**
* Returns the name used to tag optional parameters in function type * Returns the name used to tag optional parameters in function type
* representations in JavaScript. * representations in JavaScript.
*/ */
String JS_FUNCTION_TYPE_OPTIONAL_PARAMETERS_TAG() {} external String JS_FUNCTION_TYPE_OPTIONAL_PARAMETERS_TAG();
/** /**
* Returns the name used to tag named parameters in function type * Returns the name used to tag named parameters in function type
* representations in JavaScript. * representations in JavaScript.
*/ */
String JS_FUNCTION_TYPE_NAMED_PARAMETERS_TAG() {} external String JS_FUNCTION_TYPE_NAMED_PARAMETERS_TAG();
/// Returns the JS name for [name] from the Namer. /// Returns the JS name for [name] from the Namer.
String JS_GET_NAME(String name) {} external String JS_GET_NAME(String name);
/// Returns the state of a flag that is determined by the state of the compiler /// Returns the state of a flag that is determined by the state of the compiler
/// when the program has been analyzed. /// when the program has been analyzed.
bool JS_GET_FLAG(String name) {} external bool JS_GET_FLAG(String name);
/** /**
* Pretend [code] is executed. Generates no executable code. This is used to * Pretend [code] is executed. Generates no executable code. This is used to

View file

@ -2,8 +2,6 @@
// for details. All rights reserved. Use of this source code is governed by a // for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file. // BSD-style license that can be found in the LICENSE file.
// @dart = 2.6
part of dart._js_helper; part of dart._js_helper;
class IdentityMap<K, V> extends InternalMap<K, V> { class IdentityMap<K, V> extends InternalMap<K, V> {
@ -35,11 +33,11 @@ class IdentityMap<K, V> extends InternalMap<K, V> {
Iterable<K> get keys => _JSMapIterable<K>(this, true); Iterable<K> get keys => _JSMapIterable<K>(this, true);
Iterable<V> get values => _JSMapIterable<V>(this, false); Iterable<V> get values => _JSMapIterable<V>(this, false);
bool containsKey(Object key) { bool containsKey(Object? key) {
return JS<bool>('!', '#.has(#)', _map, key); return JS<bool>('!', '#.has(#)', _map, key);
} }
bool containsValue(Object value) { bool containsValue(Object? value) {
for (var v in JS('', '#.values()', _map)) { for (var v in JS('', '#.values()', _map)) {
if (v == value) return true; if (v == value) return true;
} }
@ -56,7 +54,7 @@ class IdentityMap<K, V> extends InternalMap<K, V> {
} }
} }
V operator [](Object key) { V? operator [](Object? key) {
V value = JS('', '#.get(#)', _map, key); V value = JS('', '#.get(#)', _map, key);
return value == null ? null : value; // coerce undefined to null. return value == null ? null : value; // coerce undefined to null.
} }
@ -75,13 +73,13 @@ class IdentityMap<K, V> extends InternalMap<K, V> {
return JS('', '#.get(#)', _map, key); return JS('', '#.get(#)', _map, key);
} }
V value = ifAbsent(); V value = ifAbsent();
if (value == null) value = null; // coerce undefined to null. if (value == null) JS('', '# = null', value);
JS('', '#.set(#, #)', _map, key, value); JS('', '#.set(#, #)', _map, key, value);
_modifications = (_modifications + 1) & 0x3ffffff; _modifications = (_modifications + 1) & 0x3ffffff;
return value; return value;
} }
V remove(Object key) { V? remove(Object? key) {
V value = JS('', '#.get(#)', _map, key); V value = JS('', '#.get(#)', _map, key);
if (JS<bool>('!', '#.delete(#)', _map, key)) { if (JS<bool>('!', '#.delete(#)', _map, key)) {
_modifications = (_modifications + 1) & 0x3ffffff; _modifications = (_modifications + 1) & 0x3ffffff;
@ -130,10 +128,10 @@ class _JSMapIterable<E> extends EfficientLengthIterable<E> {
Iterator<E> get iterator => DartIterator<E>(_jsIterator()); Iterator<E> get iterator => DartIterator<E>(_jsIterator());
bool contains(Object element) => bool contains(Object? element) =>
_isKeys ? _map.containsKey(element) : _map.containsValue(element); _isKeys ? _map.containsKey(element) : _map.containsValue(element);
void forEach(void f(E element)) { void forEach(void Function(E) f) {
for (var entry in this) f(entry); for (var entry in this) f(entry);
} }
} }

View file

@ -2,8 +2,6 @@
// for details. All rights reserved. Use of this source code is governed by a // for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file. // BSD-style license that can be found in the LICENSE file.
// @dart = 2.6
library dart._interceptors; library dart._interceptors;
import 'dart:collection'; import 'dart:collection';
@ -122,15 +120,15 @@ class JSNoSuchMethodError extends NativeError implements NoSuchMethodError {
static final _extensionName = RegExp(r"^Symbol\(dartx\.(.+)\)$"); static final _extensionName = RegExp(r"^Symbol\(dartx\.(.+)\)$");
static final _privateName = RegExp(r"^Symbol\((_.+)\)$"); static final _privateName = RegExp(r"^Symbol\((_.+)\)$");
String _fieldName(String message) { String? _fieldName(String message) {
var match = _nullError.firstMatch(message); RegExpMatch? match = _nullError.firstMatch(message);
if (match == null) return null; if (match == null) return null;
var name = match[1]; String name = match[1]!;
match = _extensionName.firstMatch(name) ?? _privateName.firstMatch(name); match = _extensionName.firstMatch(name) ?? _privateName.firstMatch(name);
return match != null ? match[1] : name; return match != null ? match[1] : name;
} }
String _functionCallTarget(String message) { String? _functionCallTarget(String message) {
var match = _notAFunction.firstMatch(message); var match = _notAFunction.firstMatch(message);
return match != null ? match[1] : null; return match != null ? match[1] : null;
} }
@ -180,7 +178,7 @@ class JSFunction extends Interceptor {
// TODO(jmesserly): remove these once we canonicalize tearoffs. // TODO(jmesserly): remove these once we canonicalize tearoffs.
operator ==(other) { operator ==(other) {
if (other == null) return false; if (other == null) return false;
var boundObj = JS<Object>('', '#._boundObject', this); var boundObj = JS<Object?>('', '#._boundObject', this);
if (boundObj == null) return JS<bool>('!', '# === #', this, other); if (boundObj == null) return JS<bool>('!', '# === #', this, other);
return JS( return JS(
'bool', 'bool',
@ -192,7 +190,7 @@ class JSFunction extends Interceptor {
} }
get hashCode { get hashCode {
var boundObj = JS<Object>('', '#._boundObject', this); var boundObj = JS<Object?>('', '#._boundObject', this);
if (boundObj == null) return identityHashCode(this); if (boundObj == null) return identityHashCode(this);
var boundMethod = JS<Object>('!', '#._boundMethod', this); var boundMethod = JS<Object>('!', '#._boundMethod', this);
@ -229,7 +227,7 @@ class JSRangeError extends Interceptor implements ArgumentError {
// Warning: calls to these methods need to be removed before custom elements // Warning: calls to these methods need to be removed before custom elements
// and cross-frame dom objects behave correctly in ddc. // and cross-frame dom objects behave correctly in ddc.
// See https://github.com/dart-lang/sdk/issues/28326 // See https://github.com/dart-lang/sdk/issues/28326
findInterceptorConstructorForType(Type type) {} findInterceptorConstructorForType(Type? type) {}
findConstructorForNativeSubclassType(Type type, String name) {} findConstructorForNativeSubclassType(Type? type, String name) {}
getNativeInterceptor(object) {} getNativeInterceptor(object) {}
setDispatchProperty(object, value) {} setDispatchProperty(object, value) {}

View file

@ -2,8 +2,6 @@
// for details. All rights reserved. Use of this source code is governed by a // for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file. // BSD-style license that can be found in the LICENSE file.
// @dart = 2.6
library dart._isolate_helper; library dart._isolate_helper;
import 'dart:_runtime' as dart; import 'dart:_runtime' as dart;
@ -36,7 +34,7 @@ final global = dart.global_;
class TimerImpl implements Timer { class TimerImpl implements Timer {
final bool _once; final bool _once;
int _handle; int? _handle;
int _tick = 0; int _tick = 0;
TimerImpl(int milliseconds, void callback()) : _once = true { TimerImpl(int milliseconds, void callback()) : _once = true {

View file

@ -2,8 +2,6 @@
// for details. All rights reserved. Use of this source code is governed by a // for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file. // BSD-style license that can be found in the LICENSE file.
// @dart = 2.6
part of dart._interceptors; part of dart._interceptors;
/** /**
@ -120,7 +118,7 @@ class JSArray<E> implements List<E>, JSIndexable<E> {
return JS('var', r'#.pop()', this); return JS('var', r'#.pop()', this);
} }
bool remove(Object element) { bool remove(Object? element) {
checkGrowable('remove'); checkGrowable('remove');
var length = this.length; var length = this.length;
for (int i = 0; i < length; i++) { for (int i = 0; i < length; i++) {
@ -135,17 +133,17 @@ class JSArray<E> implements List<E>, JSIndexable<E> {
/** /**
* Removes elements matching [test] from [this] List. * Removes elements matching [test] from [this] List.
*/ */
void removeWhere(bool test(E element)) { void removeWhere(bool Function(E) test) {
checkGrowable('removeWhere'); checkGrowable('removeWhere');
_removeWhere(test, true); _removeWhere(test, true);
} }
void retainWhere(bool test(E element)) { void retainWhere(bool Function(E) test) {
checkGrowable('retainWhere'); checkGrowable('retainWhere');
_removeWhere(test, false); _removeWhere(test, false);
} }
void _removeWhere(bool test(E element), bool removeMatching) { void _removeWhere(bool Function(E) test, bool removeMatching) {
// Performed in two steps, to avoid exposing an inconsistent state // Performed in two steps, to avoid exposing an inconsistent state
// to the [test] function. First the elements to retain are found, and then // to the [test] function. First the elements to retain are found, and then
// the original list is updated to contain those elements. // the original list is updated to contain those elements.
@ -156,8 +154,6 @@ class JSArray<E> implements List<E>, JSIndexable<E> {
List retained = []; List retained = [];
int end = this.length; int end = this.length;
for (int i = 0; i < end; i++) { for (int i = 0; i < end; i++) {
// TODO(22407): Improve bounds check elimination to allow this JS code to
// be replaced by indexing.
var element = JS<E>('', '#[#]', this, i); var element = JS<E>('', '#[#]', this, i);
// !test() ensures bool conversion in checked mode. // !test() ensures bool conversion in checked mode.
if (!test(element) == removeMatching) { if (!test(element) == removeMatching) {
@ -174,11 +170,11 @@ class JSArray<E> implements List<E>, JSIndexable<E> {
} }
} }
Iterable<E> where(bool f(E element)) { Iterable<E> where(bool Function(E) f) {
return WhereIterable<E>(this, f); return WhereIterable<E>(this, f);
} }
Iterable<T> expand<T>(Iterable<T> f(E element)) { Iterable<T> expand<T>(Iterable<T> Function(E) f) {
return ExpandIterable<E, T>(this, f); return ExpandIterable<E, T>(this, f);
} }
@ -196,24 +192,22 @@ class JSArray<E> implements List<E>, JSIndexable<E> {
length = 0; length = 0;
} }
void forEach(void f(E element)) { void forEach(void Function(E) f) {
int end = this.length; int end = this.length;
for (int i = 0; i < end; i++) { for (int i = 0; i < end; i++) {
// TODO(22407): Improve bounds check elimination to allow this JS code to
// be replaced by indexing.
var element = JS<E>('', '#[#]', this, i); var element = JS<E>('', '#[#]', this, i);
f(element); f(element);
if (this.length != end) throw ConcurrentModificationError(this); if (this.length != end) throw ConcurrentModificationError(this);
} }
} }
Iterable<T> map<T>(T f(E element)) { Iterable<T> map<T>(T Function(E) f) {
return MappedListIterable<E, T>(this, f); return MappedListIterable<E, T>(this, f);
} }
String join([String separator = ""]) { String join([String separator = ""]) {
var length = this.length; var length = this.length;
var list = List(length); var list = List<String>.filled(length, "");
for (int i = 0; i < length; i++) { for (int i = 0; i < length; i++) {
list[i] = "${this[i]}"; list[i] = "${this[i]}";
} }
@ -232,7 +226,7 @@ class JSArray<E> implements List<E>, JSIndexable<E> {
return SubListIterable<E>(this, n, null); return SubListIterable<E>(this, n, null);
} }
Iterable<E> skipWhile(bool test(E value)) { Iterable<E> skipWhile(bool Function(E) test) {
return SkipWhileIterable<E>(this, test); return SkipWhileIterable<E>(this, test);
} }
@ -241,8 +235,6 @@ class JSArray<E> implements List<E>, JSIndexable<E> {
if (length == 0) throw IterableElementError.noElement(); if (length == 0) throw IterableElementError.noElement();
E value = this[0]; E value = this[0];
for (int i = 1; i < length; i++) { for (int i = 1; i < length; i++) {
// TODO(22407): Improve bounds check elimination to allow this JS code to
// be replaced by indexing.
var element = JS<E>('', '#[#]', this, i); var element = JS<E>('', '#[#]', this, i);
value = combine(value, element); value = combine(value, element);
if (length != this.length) throw ConcurrentModificationError(this); if (length != this.length) throw ConcurrentModificationError(this);
@ -250,12 +242,10 @@ class JSArray<E> implements List<E>, JSIndexable<E> {
return value; return value;
} }
T fold<T>(T initialValue, T combine(T previousValue, E element)) { T fold<T>(T initialValue, T Function(T previousValue, E element) combine) {
var value = initialValue; var value = initialValue;
int length = this.length; int length = this.length;
for (int i = 0; i < length; i++) { for (int i = 0; i < length; i++) {
// TODO(22407): Improve bounds check elimination to allow this JS code to
// be replaced by indexing.
var element = JS<E>('', '#[#]', this, i); var element = JS<E>('', '#[#]', this, i);
value = combine(value, element); value = combine(value, element);
if (this.length != length) throw ConcurrentModificationError(this); if (this.length != length) throw ConcurrentModificationError(this);
@ -263,11 +253,9 @@ class JSArray<E> implements List<E>, JSIndexable<E> {
return value; return value;
} }
E firstWhere(bool test(E value), {E orElse()}) { E firstWhere(bool Function(E) test, {E Function()? orElse}) {
int end = this.length; int end = this.length;
for (int i = 0; i < end; ++i) { for (int i = 0; i < end; ++i) {
// TODO(22407): Improve bounds check elimination to allow this JS code to
// be replaced by indexing.
var element = JS<E>('', '#[#]', this, i); var element = JS<E>('', '#[#]', this, i);
if (test(element)) return element; if (test(element)) return element;
if (this.length != end) throw ConcurrentModificationError(this); if (this.length != end) throw ConcurrentModificationError(this);
@ -276,11 +264,9 @@ class JSArray<E> implements List<E>, JSIndexable<E> {
throw IterableElementError.noElement(); throw IterableElementError.noElement();
} }
E lastWhere(bool test(E element), {E orElse()}) { E lastWhere(bool Function(E) test, {E Function()? orElse}) {
int length = this.length; int length = this.length;
for (int i = length - 1; i >= 0; i--) { for (int i = length - 1; i >= 0; i--) {
// TODO(22407): Improve bounds check elimination to allow this JS code to
// be replaced by indexing.
var element = JS<E>('', '#[#]', this, i); var element = JS<E>('', '#[#]', this, i);
if (test(element)) return element; if (test(element)) return element;
if (length != this.length) { if (length != this.length) {
@ -291,13 +277,11 @@ class JSArray<E> implements List<E>, JSIndexable<E> {
throw IterableElementError.noElement(); throw IterableElementError.noElement();
} }
E singleWhere(bool test(E element), {E orElse()}) { E singleWhere(bool Function(E) test, {E Function()? orElse}) {
int length = this.length; int length = this.length;
E match = null; E? match = null;
bool matchFound = false; bool matchFound = false;
for (int i = 0; i < length; i++) { for (int i = 0; i < length; i++) {
// TODO(22407): Improve bounds check elimination to allow this JS code to
// be replaced by indexing.
var element = JS<E>('', '#[#]', this, i); var element = JS<E>('', '#[#]', this, i);
if (test(element)) { if (test(element)) {
if (matchFound) { if (matchFound) {
@ -310,7 +294,7 @@ class JSArray<E> implements List<E>, JSIndexable<E> {
throw ConcurrentModificationError(this); throw ConcurrentModificationError(this);
} }
} }
if (matchFound) return match; if (matchFound) return match as E;
if (orElse != null) return orElse(); if (orElse != null) return orElse();
throw IterableElementError.noElement(); throw IterableElementError.noElement();
} }
@ -319,7 +303,7 @@ class JSArray<E> implements List<E>, JSIndexable<E> {
return this[index]; return this[index];
} }
List<E> sublist(@nullCheck int start, [int end]) { List<E> sublist(@nullCheck int start, [int? end]) {
if (start < 0 || start > length) { if (start < 0 || start > length) {
throw RangeError.range(start, 0, length, "start"); throw RangeError.range(start, 0, length, "start");
} }
@ -373,7 +357,7 @@ class JSArray<E> implements List<E>, JSIndexable<E> {
if (length == 0) return; if (length == 0) return;
RangeError.checkNotNegative(skipCount, "skipCount"); RangeError.checkNotNegative(skipCount, "skipCount");
List<E> otherList; var otherList = <E>[];
int otherStart = 0; int otherStart = 0;
// TODO(floitsch): Make this accept more. // TODO(floitsch): Make this accept more.
if (iterable is List<E>) { if (iterable is List<E>) {
@ -405,12 +389,12 @@ class JSArray<E> implements List<E>, JSIndexable<E> {
} }
} }
void fillRange(@nullCheck int start, @nullCheck int end, [E fillValue]) { void fillRange(@nullCheck int start, @nullCheck int end, [E? fillValue]) {
checkMutable('fill range'); checkMutable('fill range');
RangeError.checkValidRange(start, end, this.length); RangeError.checkValidRange(start, end, this.length);
E checkedFillValue = fillValue as E;
for (int i = start; i < end; i++) { for (int i = start; i < end; i++) {
// Store is safe since [fillValue] type has been checked as parameter. JS('', '#[#] = #', this, i, checkedFillValue);
JS('', '#[#] = #', this, i, fillValue);
} }
} }
@ -443,11 +427,9 @@ class JSArray<E> implements List<E>, JSIndexable<E> {
} }
} }
bool any(bool test(E element)) { bool any(bool Function(E) test) {
int end = this.length; int end = this.length;
for (int i = 0; i < end; i++) { for (int i = 0; i < end; i++) {
// TODO(22407): Improve bounds check elimination to allow this JS code to
// be replaced by indexing.
var element = JS<E>('', '#[#]', this, i); var element = JS<E>('', '#[#]', this, i);
if (test(element)) return true; if (test(element)) return true;
if (this.length != end) throw ConcurrentModificationError(this); if (this.length != end) throw ConcurrentModificationError(this);
@ -455,11 +437,9 @@ class JSArray<E> implements List<E>, JSIndexable<E> {
return false; return false;
} }
bool every(bool test(E element)) { bool every(bool Function(E) test) {
int end = this.length; int end = this.length;
for (int i = 0; i < end; i++) { for (int i = 0; i < end; i++) {
// TODO(22407): Improve bounds check elimination to allow this JS code to
// be replaced by indexing.
var element = JS<E>('', '#[#]', this, i); var element = JS<E>('', '#[#]', this, i);
if (!test(element)) return false; if (!test(element)) return false;
if (this.length != end) throw ConcurrentModificationError(this); if (this.length != end) throw ConcurrentModificationError(this);
@ -469,16 +449,17 @@ class JSArray<E> implements List<E>, JSIndexable<E> {
Iterable<E> get reversed => ReversedListIterable<E>(this); Iterable<E> get reversed => ReversedListIterable<E>(this);
void sort([int compare(E a, E b)]) { void sort([int Function(E, E)? compare]) {
checkMutable('sort'); checkMutable('sort');
if (compare == null) { if (compare == null) {
Sort.sort(this, (a, b) => Comparable.compare(a, b)); Sort.sort(
this, (a, b) => Comparable.compare(a as Comparable, b as Comparable));
} else { } else {
Sort.sort(this, compare); Sort.sort(this, compare);
} }
} }
void shuffle([Random random]) { void shuffle([Random? random]) {
checkMutable('shuffle'); checkMutable('shuffle');
if (random == null) random = Random(); if (random == null) random = Random();
int length = this.length; int length = this.length;
@ -491,7 +472,7 @@ class JSArray<E> implements List<E>, JSIndexable<E> {
} }
} }
int indexOf(Object element, [@nullCheck int start = 0]) { int indexOf(Object? element, [@nullCheck int start = 0]) {
int length = this.length; int length = this.length;
if (start >= length) { if (start >= length) {
return -1; return -1;
@ -507,15 +488,15 @@ class JSArray<E> implements List<E>, JSIndexable<E> {
return -1; return -1;
} }
int lastIndexOf(Object element, [int _startIndex]) { int lastIndexOf(Object? element, [int? startIndex]) {
@notNull @notNull
int startIndex = _startIndex ?? this.length - 1; int start = startIndex ?? this.length - 1;
if (startIndex >= this.length) { if (start >= this.length) {
startIndex = this.length - 1; start = this.length - 1;
} else if (startIndex < 0) { } else if (start < 0) {
return -1; return -1;
} }
for (int i = startIndex; i >= 0; i--) { for (int i = start; i >= 0; i--) {
if (this[i] == element) { if (this[i] == element) {
return i; return i;
} }
@ -523,7 +504,7 @@ class JSArray<E> implements List<E>, JSIndexable<E> {
return -1; return -1;
} }
bool contains(Object other) { bool contains(Object? other) {
var length = this.length; var length = this.length;
for (int i = 0; i < length; i++) { for (int i = 0; i < length; i++) {
var element = JS<E>('', '#[#]', this, i); var element = JS<E>('', '#[#]', this, i);
@ -601,15 +582,9 @@ class JSArray<E> implements List<E>, JSIndexable<E> {
Iterable<T> whereType<T>() => new WhereTypeIterable<T>(this); Iterable<T> whereType<T>() => new WhereTypeIterable<T>(this);
List<E> operator +(List<E> other) { List<E> operator +(List<E> other) => [...this, ...other];
int totalLength = this.length + other.length;
return <E>[]
..length = totalLength
..setRange(0, this.length, this)
..setRange(this.length, totalLength, other);
}
int indexWhere(bool test(E element), [int start = 0]) { int indexWhere(bool Function(E) test, [int start = 0]) {
if (start >= this.length) return -1; if (start >= this.length) return -1;
if (start < 0) start = 0; if (start < 0) start = 0;
for (int i = start; i < this.length; i++) { for (int i = start; i < this.length; i++) {
@ -618,7 +593,7 @@ class JSArray<E> implements List<E>, JSIndexable<E> {
return -1; return -1;
} }
int lastIndexWhere(bool test(E element), [int start]) { int lastIndexWhere(bool Function(E) test, [int? start]) {
if (start == null) start = this.length - 1; if (start == null) start = this.length - 1;
if (start < 0) return -1; if (start < 0) return -1;
for (int i = start; i >= 0; i--) { for (int i = start; i >= 0; i--) {
@ -665,14 +640,14 @@ class ArrayIterator<E> implements Iterator<E> {
final int _length; final int _length;
@notNull @notNull
int _index; int _index;
E _current; E? _current;
ArrayIterator(JSArray<E> iterable) ArrayIterator(JSArray<E> iterable)
: _iterable = iterable, : _iterable = iterable,
_length = iterable.length, _length = iterable.length,
_index = 0; _index = 0;
E get current => _current; E get current => _current as E;
bool moveNext() { bool moveNext() {
@notNull @notNull

View file

@ -2,8 +2,6 @@
// for details. All rights reserved. Use of this source code is governed by a // for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file. // BSD-style license that can be found in the LICENSE file.
// @dart = 2.6
library dart._js_helper; library dart._js_helper;
import 'dart:collection'; import 'dart:collection';
@ -45,11 +43,11 @@ const _Patch patch = _Patch();
// https://github.com/dart-lang/sdk/issues/28320 // https://github.com/dart-lang/sdk/issues/28320
class DartIterator<E> implements Iterator<E> { class DartIterator<E> implements Iterator<E> {
final _jsIterator; final _jsIterator;
E _current; E? _current;
DartIterator(this._jsIterator); DartIterator(this._jsIterator);
E get current => _current; E get current => _current as E;
bool moveNext() { bool moveNext() {
final ret = JS('', '#.next()', _jsIterator); final ret = JS('', '#.next()', _jsIterator);
@ -70,11 +68,11 @@ class SyncIterable<E> extends IterableBase<E> {
} }
class Primitives { class Primitives {
static int parseInt(@nullCheck String source, int _radix) { static int? parseInt(@nullCheck String source, int? _radix) {
var re = JS('', r'/^\s*[+-]?((0x[a-f0-9]+)|(\d+)|([a-z0-9]+))\s*$/i'); var re = JS('', r'/^\s*[+-]?((0x[a-f0-9]+)|(\d+)|([a-z0-9]+))\s*$/i');
// TODO(jmesserly): this isn't reified List<String>, but it's safe to use as // TODO(jmesserly): this isn't reified List<String>, but it's safe to use as
// long as we use it locally and don't expose it to user code. // long as we use it locally and don't expose it to user code.
List<String> match = JS('', '#.exec(#)', re, source); List<String>? match = JS('', '#.exec(#)', re, source);
int digitsIndex = 1; int digitsIndex = 1;
int hexIndex = 2; int hexIndex = 2;
int decimalIndex = 3; int decimalIndex = 3;
@ -84,7 +82,7 @@ class Primitives {
// again. // again.
return null; return null;
} }
String decimalMatch = match[decimalIndex]; String? decimalMatch = match[decimalIndex];
if (_radix == null) { if (_radix == null) {
if (decimalMatch != null) { if (decimalMatch != null) {
// Cannot fail because we know that the digits are all decimal. // Cannot fail because we know that the digits are all decimal.
@ -140,7 +138,7 @@ class Primitives {
return JS<int>('!', r'parseInt(#, #)', source, radix); return JS<int>('!', r'parseInt(#, #)', source, radix);
} }
static double parseDouble(@nullCheck String source) { static double? parseDouble(@nullCheck String source) {
// Notice that JS parseFloat accepts garbage at the end of the string. // Notice that JS parseFloat accepts garbage at the end of the string.
// Accept only: // Accept only:
// - [+/-]NaN // - [+/-]NaN
@ -171,10 +169,9 @@ class Primitives {
static int dateNow() => JS<int>('!', r'Date.now()'); static int dateNow() => JS<int>('!', r'Date.now()');
static void initTicker() { static void initTicker() {
if (timerFrequency != null) return; if (timerFrequency != 0) return;
// Start with low-resolution. We overwrite the fields if we find better. // Start with low-resolution. We overwrite the fields if we find better.
timerFrequency = 1000; timerFrequency = 1000;
timerTicks = dateNow;
if (JS<bool>('!', 'typeof window == "undefined"')) return; if (JS<bool>('!', 'typeof window == "undefined"')) return;
var jsWindow = JS('var', 'window'); var jsWindow = JS('var', 'window');
if (jsWindow == null) return; if (jsWindow == null) return;
@ -185,8 +182,9 @@ class Primitives {
timerTicks = () => (1000 * JS<num>('!', '#.now()', performance)).floor(); timerTicks = () => (1000 * JS<num>('!', '#.now()', performance)).floor();
} }
static int timerFrequency; /// 0 frequency indicates the default uninitialized state.
static num Function() timerTicks; static int timerFrequency = 0;
static int Function() timerTicks = dateNow; // Low-resolution version.
static bool get isD8 { static bool get isD8 {
return JS( return JS(
@ -310,7 +308,7 @@ class Primitives {
// Example: "Wed May 16 2012 21:13:00 GMT+0200 (CEST)". // Example: "Wed May 16 2012 21:13:00 GMT+0200 (CEST)".
// We extract this name using a regexp. // We extract this name using a regexp.
var d = lazyAsJsDate(receiver); var d = lazyAsJsDate(receiver);
List match = JS('JSArray|Null', r'/\((.*)\)/.exec(#.toString())', d); List? match = JS('JSArray|Null', r'/\((.*)\)/.exec(#.toString())', d);
if (match != null) return match[1]; if (match != null) return match[1];
// Internet Explorer 10+ emits the zone name without parenthesis: // Internet Explorer 10+ emits the zone name without parenthesis:
@ -345,7 +343,7 @@ class Primitives {
return -JS<int>('!', r'#.getTimezoneOffset()', lazyAsJsDate(receiver)); return -JS<int>('!', r'#.getTimezoneOffset()', lazyAsJsDate(receiver));
} }
static num valueFromDecomposedDate( static int? valueFromDecomposedDate(
@nullCheck int years, @nullCheck int years,
@nullCheck int month, @nullCheck int month,
@nullCheck int day, @nullCheck int day,
@ -356,12 +354,12 @@ class Primitives {
@nullCheck bool isUtc) { @nullCheck bool isUtc) {
final int MAX_MILLISECONDS_SINCE_EPOCH = 8640000000000000; final int MAX_MILLISECONDS_SINCE_EPOCH = 8640000000000000;
var jsMonth = month - 1; var jsMonth = month - 1;
num value; int value;
if (isUtc) { if (isUtc) {
value = JS('!', r'Date.UTC(#, #, #, #, #, #, #)', years, jsMonth, day, value = JS<int>('!', r'Date.UTC(#, #, #, #, #, #, #)', years, jsMonth,
hours, minutes, seconds, milliseconds); day, hours, minutes, seconds, milliseconds);
} else { } else {
value = JS('!', r'new Date(#, #, #, #, #, #, #).valueOf()', years, value = JS<int>('!', r'new Date(#, #, #, #, #, #, #).valueOf()', years,
jsMonth, day, hours, minutes, seconds, milliseconds); jsMonth, day, hours, minutes, seconds, milliseconds);
} }
if (value.isNaN || if (value.isNaN ||
@ -373,14 +371,14 @@ class Primitives {
return value; return value;
} }
static num patchUpY2K(value, years, isUtc) { static int patchUpY2K(value, years, isUtc) {
var date = JS('', r'new Date(#)', value); var date = JS<int>('!', r'new Date(#)', value);
if (isUtc) { if (isUtc) {
JS('', r'#.setUTCFullYear(#)', date, years); JS<int>('!', r'#.setUTCFullYear(#)', date, years);
} else { } else {
JS('', r'#.setFullYear(#)', date, years); JS<int>('!', r'#.setFullYear(#)', date, years);
} }
return JS('!', r'#.valueOf()', date); return JS<int>('!', r'#.valueOf()', date);
} }
// Lazily keep a JS Date stored in the JS object. // Lazily keep a JS Date stored in the JS object.
@ -453,7 +451,7 @@ class Primitives {
return value; return value;
} }
static getProperty(object, key) { static Object? getProperty(Object? object, Object key) {
if (object == null || object is bool || object is num || object is String) { if (object == null || object is bool || object is num || object is String) {
throw argumentErrorValue(object); throw argumentErrorValue(object);
} }
@ -489,7 +487,7 @@ Error diagnoseIndexError(indexable, int index) {
* describes the problem. * describes the problem.
*/ */
@NoInline() @NoInline()
Error diagnoseRangeError(int start, int end, int length) { Error diagnoseRangeError(int? start, int? end, int length) {
if (start == null) { if (start == null) {
return ArgumentError.value(start, 'start'); return ArgumentError.value(start, 'start');
} }
@ -538,9 +536,9 @@ throwConcurrentModificationError(collection) {
} }
class JsNoSuchMethodError extends Error implements NoSuchMethodError { class JsNoSuchMethodError extends Error implements NoSuchMethodError {
final String _message; final String? _message;
final String _method; final String? _method;
final String _receiver; final String? _receiver;
JsNoSuchMethodError(this._message, match) JsNoSuchMethodError(this._message, match)
: _method = match == null ? null : JS('String|Null', '#.method', match), : _method = match == null ? null : JS('String|Null', '#.method', match),
@ -582,11 +580,11 @@ fillLiteralMap(keyValuePairs, Map result) {
return result; return result;
} }
bool jsHasOwnProperty(var jsObject, String property) { bool jsHasOwnProperty(jsObject, String property) {
return JS<bool>('!', r'#.hasOwnProperty(#)', jsObject, property); return JS<bool>('!', r'#.hasOwnProperty(#)', jsObject, property);
} }
jsPropertyAccess(var jsObject, String property) { jsPropertyAccess(jsObject, String property) {
return JS('var', r'#[#]', jsObject, property); return JS('var', r'#[#]', jsObject, property);
} }
@ -720,12 +718,12 @@ class RuntimeError extends Error {
/// Error thrown by DDC when an `assert()` fails (with or without a message). /// Error thrown by DDC when an `assert()` fails (with or without a message).
class AssertionErrorImpl extends AssertionError { class AssertionErrorImpl extends AssertionError {
final String _fileUri; final String? _fileUri;
final int _line; final int? _line;
final int _column; final int? _column;
final String _conditionSource; final String? _conditionSource;
AssertionErrorImpl(Object message, AssertionErrorImpl(Object? message,
[this._fileUri, this._line, this._column, this._conditionSource]) [this._fileUri, this._line, this._column, this._conditionSource])
: super(message); : super(message);
@ -791,7 +789,7 @@ class PrivateSymbol implements Symbol {
static String getName(Symbol symbol) => (symbol as PrivateSymbol)._name; static String getName(Symbol symbol) => (symbol as PrivateSymbol)._name;
static Object getNativeSymbol(Symbol symbol) { static Object? getNativeSymbol(Symbol symbol) {
if (symbol is PrivateSymbol) return symbol._nativeSymbol; if (symbol is PrivateSymbol) return symbol._nativeSymbol;
return null; return null;
} }

View file

@ -2,8 +2,6 @@
// for details. All rights reserved. Use of this source code is governed by a // for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file. // BSD-style license that can be found in the LICENSE file.
// @dart = 2.6
part of dart._interceptors; part of dart._interceptors;
/** /**
@ -55,14 +53,14 @@ class JSNumber extends Interceptor implements int, double {
@notNull @notNull
JSNumber remainder(@nullCheck num b) { JSNumber remainder(@nullCheck num b) {
return JS<num>('!', r'# % #', this, b); return JS<JSNumber>('!', r'# % #', this, b);
} }
@notNull @notNull
JSNumber abs() => JS<num>('!', r'Math.abs(#)', this); JSNumber abs() => JS<JSNumber>('!', r'Math.abs(#)', this);
@notNull @notNull
JSNumber get sign => this > 0 ? 1 : this < 0 ? -1 : this; JSNumber get sign => (this > 0 ? 1 : this < 0 ? -1 : this) as JSNumber;
@notNull @notNull
static const int _MIN_INT32 = -0x80000000; static const int _MIN_INT32 = -0x80000000;
@ -112,17 +110,17 @@ class JSNumber extends Interceptor implements int, double {
} }
@notNull @notNull
double ceilToDouble() => JS<num>('!', r'Math.ceil(#)', this); double ceilToDouble() => JS<double>('!', r'Math.ceil(#)', this);
@notNull @notNull
double floorToDouble() => JS<num>('!', r'Math.floor(#)', this); double floorToDouble() => JS<double>('!', r'Math.floor(#)', this);
@notNull @notNull
double roundToDouble() { double roundToDouble() {
if (this < 0) { if (this < 0) {
return JS<num>('!', r'-Math.round(-#)', this); return JS<double>('!', r'-Math.round(-#)', this);
} else { } else {
return JS<num>('!', r'Math.round(#)', this); return JS<double>('!', r'Math.round(#)', this);
} }
} }
@ -153,7 +151,7 @@ class JSNumber extends Interceptor implements int, double {
} }
@notNull @notNull
String toStringAsExponential([int fractionDigits]) { String toStringAsExponential([int? fractionDigits]) {
String result; String result;
if (fractionDigits != null) { if (fractionDigits != null) {
@notNull @notNull
@ -196,7 +194,7 @@ class JSNumber extends Interceptor implements int, double {
static String _handleIEtoString(String result) { static String _handleIEtoString(String result) {
// Result is probably IE's untraditional format for large numbers, // Result is probably IE's untraditional format for large numbers,
// e.g., "8.0000000000008(e+15)" for 0x8000000000000800.toString(16). // e.g., "8.0000000000008(e+15)" for 0x8000000000000800.toString(16).
var match = JS<List>( var match = JS<List?>(
'', r'/^([\da-z]+)(?:\.([\da-z]+))?\(e\+(\d+)\)$/.exec(#)', result); '', r'/^([\da-z]+)(?:\.([\da-z]+))?\(e\+(\d+)\)$/.exec(#)', result);
if (match == null) { if (match == null) {
// Then we don't know how to handle it at all. // Then we don't know how to handle it at all.
@ -258,38 +256,38 @@ class JSNumber extends Interceptor implements int, double {
} }
@notNull @notNull
JSNumber operator -() => JS<num>('!', r'-#', this); JSNumber operator -() => JS<JSNumber>('!', r'-#', this);
@notNull @notNull
JSNumber operator +(@nullCheck num other) { JSNumber operator +(@nullCheck num other) {
return JS<num>('!', '# + #', this, other); return JS<JSNumber>('!', '# + #', this, other);
} }
@notNull @notNull
JSNumber operator -(@nullCheck num other) { JSNumber operator -(@nullCheck num other) {
return JS<num>('!', '# - #', this, other); return JS<JSNumber>('!', '# - #', this, other);
} }
@notNull @notNull
double operator /(@nullCheck num other) { double operator /(@nullCheck num other) {
return JS<num>('!', '# / #', this, other); return JS<double>('!', '# / #', this, other);
} }
@notNull @notNull
JSNumber operator *(@nullCheck num other) { JSNumber operator *(@nullCheck num other) {
return JS<num>('!', '# * #', this, other); return JS<JSNumber>('!', '# * #', this, other);
} }
@notNull @notNull
JSNumber operator %(@nullCheck num other) { JSNumber operator %(@nullCheck num other) {
// Euclidean Modulo. // Euclidean Modulo.
num result = JS<num>('!', r'# % #', this, other); JSNumber result = JS<JSNumber>('!', r'# % #', this, other);
if (result == 0) return (0 as JSNumber); // Make sure we don't return -0.0. if (result == 0) return (0 as JSNumber); // Make sure we don't return -0.0.
if (result > 0) return result; if (result > 0) return result;
if (JS<num>('!', '#', other) < 0) { if (JS<JSNumber>('!', '#', other) < 0) {
return result - JS<num>('!', '#', other); return result - JS<JSNumber>('!', '#', other);
} else { } else {
return result + JS<num>('!', '#', other); return result + JS<JSNumber>('!', '#', other);
} }
} }
@ -308,7 +306,7 @@ class JSNumber extends Interceptor implements int, double {
@notNull @notNull
int _tdivSlow(num other) { int _tdivSlow(num other) {
return (JS<num>('!', r'# / #', this, other)).toInt(); return JS<num>('!', r'# / #', this, other).toInt();
} }
// TODO(ngeoffray): Move the bit operations below to [JSInt] and // TODO(ngeoffray): Move the bit operations below to [JSInt] and

View file

@ -2,8 +2,6 @@
// for details. All rights reserved. Use of this source code is governed by a // for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file. // BSD-style license that can be found in the LICENSE file.
// @dart = 2.6
/// dart2js "primitives", that is, features that cannot be implemented without /// dart2js "primitives", that is, features that cannot be implemented without
/// access to JavaScript features. /// access to JavaScript features.
library dart2js._js_primitives; library dart2js._js_primitives;

View file

@ -2,28 +2,26 @@
// for details. All rights reserved. Use of this source code is governed by a // for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file. // BSD-style license that can be found in the LICENSE file.
// @dart = 2.6
part of dart._js_helper; part of dart._js_helper;
// TODO(leafp): Maybe get rid of this? Currently used by the interceptors // TODO(leafp): Maybe get rid of this? Currently used by the interceptors
// library, but that should probably be culled as well. // library, but that should probably be culled as well.
Type getRuntimeType(var object) => Type? getRuntimeType(object) =>
JS('Type|null', 'dart.getReifiedType(#)', object); JS('Type|null', 'dart.getReifiedType(#)', object);
/// Returns the property [index] of the JavaScript array [array]. /// Returns the property [index] of the JavaScript array [array].
getIndex(var array, int index) { getIndex(array, int index) {
assert(isJsArray(array)); assert(isJsArray(array));
return JS('var', r'#[#]', array, index); return JS('var', r'#[#]', array, index);
} }
/// Returns the length of the JavaScript array [array]. /// Returns the length of the JavaScript array [array].
int getLength(var array) { int getLength(array) {
assert(isJsArray(array)); assert(isJsArray(array));
return JS<int>('!', r'#.length', array); return JS<int>('!', r'#.length', array);
} }
/// Returns whether [value] is a JavaScript array. /// Returns whether [value] is a JavaScript array.
bool isJsArray(var value) { bool isJsArray(value) {
return value is JSArray; return value is JSArray;
} }

View file

@ -2,8 +2,6 @@
// for details. All rights reserved. Use of this source code is governed by a // for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file. // BSD-style license that can be found in the LICENSE file.
// @dart = 2.6
part of dart._interceptors; part of dart._interceptors;
/** /**
@ -37,7 +35,7 @@ class JSString extends Interceptor implements String, JSIndexable<String> {
return allMatchesInStringUnchecked(this, string, start); return allMatchesInStringUnchecked(this, string, start);
} }
Match matchAsPrefix(@nullCheck String string, [@nullCheck int start = 0]) { Match? matchAsPrefix(@nullCheck String string, [@nullCheck int start = 0]) {
int stringLength = JS('!', '#.length', string); int stringLength = JS('!', '#.length', string);
if (start < 0 || start > stringLength) { if (start < 0 || start > stringLength) {
throw RangeError.range(start, 0, stringLength); throw RangeError.range(start, 0, stringLength);
@ -71,13 +69,13 @@ class JSString extends Interceptor implements String, JSIndexable<String> {
} }
@notNull @notNull
String replaceAllMapped(Pattern from, String convert(Match match)) { String replaceAllMapped(Pattern from, String Function(Match) convert) {
return this.splitMapJoin(from, onMatch: convert); return this.splitMapJoin(from, onMatch: convert);
} }
@notNull @notNull
String splitMapJoin(Pattern from, String splitMapJoin(Pattern from,
{String onMatch(Match match), String onNonMatch(String nonMatch)}) { {String Function(Match)? onMatch, String Function(String)? onNonMatch}) {
return stringReplaceAllFuncUnchecked(this, from, onMatch, onNonMatch); return stringReplaceAllFuncUnchecked(this, from, onMatch, onNonMatch);
} }
@ -110,9 +108,9 @@ class JSString extends Interceptor implements String, JSIndexable<String> {
@notNull @notNull
String replaceRange( String replaceRange(
@nullCheck int start, int end, @nullCheck String replacement) { @nullCheck int start, int? end, @nullCheck String replacement) {
end = RangeError.checkValidRange(start, end, this.length); var e = RangeError.checkValidRange(start, end, this.length);
return stringReplaceRangeUnchecked(this, start, end, replacement); return stringReplaceRangeUnchecked(this, start, e, replacement);
} }
@notNull @notNull
@ -166,7 +164,7 @@ class JSString extends Interceptor implements String, JSIndexable<String> {
} }
@notNull @notNull
String substring(@nullCheck int startIndex, [int _endIndex]) { String substring(@nullCheck int startIndex, [int? _endIndex]) {
var length = this.length; var length = this.length;
final endIndex = _endIndex ?? length; final endIndex = _endIndex ?? length;
if (startIndex < 0) throw RangeError.value(startIndex); if (startIndex < 0) throw RangeError.value(startIndex);
@ -418,7 +416,7 @@ class JSString extends Interceptor implements String, JSIndexable<String> {
} }
if (pattern is JSSyntaxRegExp) { if (pattern is JSSyntaxRegExp) {
JSSyntaxRegExp re = pattern; JSSyntaxRegExp re = pattern;
Match match = firstMatchAfter(re, this, start); Match? match = firstMatchAfter(re, this, start);
return (match == null) ? -1 : match.start; return (match == null) ? -1 : match.start;
} }
var length = this.length; var length = this.length;
@ -429,7 +427,7 @@ class JSString extends Interceptor implements String, JSIndexable<String> {
} }
@notNull @notNull
int lastIndexOf(@nullCheck Pattern pattern, [int _start]) { int lastIndexOf(@nullCheck Pattern pattern, [int? _start]) {
var length = this.length; var length = this.length;
var start = _start ?? length; var start = _start ?? length;
if (start < 0 || start > length) { if (start < 0 || start > length) {
@ -497,7 +495,7 @@ class JSString extends Interceptor implements String, JSIndexable<String> {
Type get runtimeType => String; Type get runtimeType => String;
@notNull @notNull
final int length; int get length native;
@notNull @notNull
String operator [](@nullCheck int index) { String operator [](@nullCheck int index) {

View file

@ -2,8 +2,6 @@
// for details. All rights reserved. Use of this source code is governed by a // for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file. // BSD-style license that can be found in the LICENSE file.
// @dart = 2.6
// Efficient JavaScript based implementation of a linked hash map used as a // Efficient JavaScript based implementation of a linked hash map used as a
// backing map for constant maps and the [LinkedHashMap] patch // backing map for constant maps and the [LinkedHashMap] patch
@ -74,7 +72,7 @@ class LinkedMap<K, V> extends InternalMap<K, V> {
K key = JS('', '#[#]', entries, i); K key = JS('', '#[#]', entries, i);
V value = JS('', '#[#]', entries, i + 1); V value = JS('', '#[#]', entries, i + 1);
if (key == null) { if (key == null) {
key = null; key = JS('', 'null');
} else if (JS<bool>('!', '#[#] !== #', key, } else if (JS<bool>('!', '#[#] !== #', key,
dart.extensionSymbol('_equals'), dart.identityEquals)) { dart.extensionSymbol('_equals'), dart.identityEquals)) {
key = putLinkedMapKey(key, keyMap); key = putLinkedMapKey(key, keyMap);
@ -96,17 +94,15 @@ class LinkedMap<K, V> extends InternalMap<K, V> {
Iterable<V> get values => _JSMapIterable<V>(this, false); Iterable<V> get values => _JSMapIterable<V>(this, false);
@notNull @notNull
bool containsKey(Object key) { bool containsKey(Object? key) {
if (key == null) { if (key == null) {
key = null; key = JS('', 'null');
} else if (JS<bool>('!', '#[#] !== #', key, dart.extensionSymbol('_equals'), } else if (JS<bool>('!', '#[#] !== #', key, dart.extensionSymbol('_equals'),
dart.identityEquals)) { dart.identityEquals)) {
@notNull var buckets = JS('', '#.get(# & 0x3ffffff)', _keyMap, key.hashCode);
var k = key;
var buckets = JS('', '#.get(# & 0x3ffffff)', _keyMap, k.hashCode);
if (buckets != null) { if (buckets != null) {
for (int i = 0, n = JS('!', '#.length', buckets); i < n; i++) { for (int i = 0, n = JS('!', '#.length', buckets); i < n; i++) {
k = JS('', '#[#]', buckets, i); K k = JS('', '#[#]', buckets, i);
if (k == key) return true; if (k == key) return true;
} }
} }
@ -115,7 +111,7 @@ class LinkedMap<K, V> extends InternalMap<K, V> {
return JS<bool>('!', '#.has(#)', _map, key); return JS<bool>('!', '#.has(#)', _map, key);
} }
bool containsValue(Object value) { bool containsValue(Object? value) {
for (var v in JS('', '#.values()', _map)) { for (var v in JS('', '#.values()', _map)) {
if (v == value) return true; if (v == value) return true;
} }
@ -127,7 +123,7 @@ class LinkedMap<K, V> extends InternalMap<K, V> {
int length = JS('', '#.size', map); int length = JS('', '#.size', map);
other.forEach((K key, V value) { other.forEach((K key, V value) {
if (key == null) { if (key == null) {
key = null; key = JS('', 'null');
} else if (JS<bool>('!', '#[#] !== #', key, } else if (JS<bool>('!', '#[#] !== #', key,
dart.extensionSymbol('_equals'), dart.identityEquals)) { dart.extensionSymbol('_equals'), dart.identityEquals)) {
key = putLinkedMapKey(key, _keyMap); key = putLinkedMapKey(key, _keyMap);
@ -139,17 +135,15 @@ class LinkedMap<K, V> extends InternalMap<K, V> {
} }
} }
V operator [](Object key) { V? operator [](Object? key) {
if (key == null) { if (key == null) {
key = null; key = JS('', 'null');
} else if (JS<bool>('!', '#[#] !== #', key, dart.extensionSymbol('_equals'), } else if (JS<bool>('!', '#[#] !== #', key, dart.extensionSymbol('_equals'),
dart.identityEquals)) { dart.identityEquals)) {
@notNull var buckets = JS('', '#.get(# & 0x3ffffff)', _keyMap, key.hashCode);
var k = key;
var buckets = JS('', '#.get(# & 0x3ffffff)', _keyMap, k.hashCode);
if (buckets != null) { if (buckets != null) {
for (int i = 0, n = JS('!', '#.length', buckets); i < n; i++) { for (int i = 0, n = JS('!', '#.length', buckets); i < n; i++) {
k = JS('', '#[#]', buckets, i); K k = JS('', '#[#]', buckets, i);
if (k == key) return JS('', '#.get(#)', _map, k); if (k == key) return JS('', '#.get(#)', _map, k);
} }
} }
@ -161,7 +155,7 @@ class LinkedMap<K, V> extends InternalMap<K, V> {
void operator []=(K key, V value) { void operator []=(K key, V value) {
if (key == null) { if (key == null) {
key = null; key = JS('', 'null');
} else if (JS<bool>('!', '#[#] !== #', key, dart.extensionSymbol('_equals'), } else if (JS<bool>('!', '#[#] !== #', key, dart.extensionSymbol('_equals'),
dart.identityEquals)) { dart.identityEquals)) {
key = putLinkedMapKey(key, _keyMap); key = putLinkedMapKey(key, _keyMap);
@ -177,7 +171,7 @@ class LinkedMap<K, V> extends InternalMap<K, V> {
V putIfAbsent(K key, V ifAbsent()) { V putIfAbsent(K key, V ifAbsent()) {
var map = _map; var map = _map;
if (key == null) { if (key == null) {
key = null; key = JS('', 'null');
if (JS<bool>('!', '#.has(null)', map)) return JS('', '#.get(null)', map); if (JS<bool>('!', '#.has(null)', map)) return JS('', '#.get(null)', map);
} else if (JS<bool>('!', '#[#] !== #', key, dart.extensionSymbol('_equals'), } else if (JS<bool>('!', '#[#] !== #', key, dart.extensionSymbol('_equals'),
dart.identityEquals)) { dart.identityEquals)) {
@ -198,24 +192,25 @@ class LinkedMap<K, V> extends InternalMap<K, V> {
return JS('', '#.get(#)', map, key); return JS('', '#.get(#)', map, key);
} }
V value = ifAbsent(); V value = ifAbsent();
if (value == null) value = null; // coerce undefined to null. if (value == null) {
value = JS('', 'null');
}
JS('', '#.set(#, #)', map, key, value); JS('', '#.set(#, #)', map, key, value);
_modifications = (_modifications + 1) & 0x3ffffff; _modifications = (_modifications + 1) & 0x3ffffff;
return value; return value;
} }
V remove(Object key) { V? remove(Object? key) {
if (key == null) { if (key == null) {
key = null; key = JS('', 'null');
} else if (JS<bool>('!', '#[#] !== #', key, dart.extensionSymbol('_equals'), } else if (JS<bool>('!', '#[#] !== #', key, dart.extensionSymbol('_equals'),
dart.identityEquals)) { dart.identityEquals)) {
@notNull @notNull
var k = key; var hash = JS<int>('!', '# & 0x3ffffff', key.hashCode);
var hash = JS<int>('!', '# & 0x3ffffff', k.hashCode);
var buckets = JS('', '#.get(#)', _keyMap, hash); var buckets = JS('', '#.get(#)', _keyMap, hash);
if (buckets == null) return null; // not found if (buckets == null) return null; // not found
for (int i = 0, n = JS('!', '#.length', buckets);;) { for (int i = 0, n = JS('!', '#.length', buckets);;) {
k = JS('', '#[#]', buckets, i); K k = JS('', '#[#]', buckets, i);
if (k == key) { if (k == key) {
key = k; key = k;
if (n == 1) { if (n == 1) {
@ -266,14 +261,14 @@ K putLinkedMapKey<K>(@notNull K key, keyMap) {
class ImmutableMap<K, V> extends LinkedMap<K, V> { class ImmutableMap<K, V> extends LinkedMap<K, V> {
ImmutableMap.from(JSArray entries) : super.from(entries); ImmutableMap.from(JSArray entries) : super.from(entries);
void operator []=(Object key, Object value) { void operator []=(K key, V value) {
throw _unsupported(); throw _unsupported();
} }
void addAll(Object other) => throw _unsupported(); void addAll(Object other) => throw _unsupported();
void clear() => throw _unsupported(); void clear() => throw _unsupported();
V remove(Object key) => throw _unsupported(); V? remove(Object? key) => throw _unsupported();
V putIfAbsent(Object key, Object ifAbsent()) => throw _unsupported(); V putIfAbsent(K key, V ifAbsent()) => throw _unsupported();
static Error _unsupported() => static Error _unsupported() =>
UnsupportedError("Cannot modify unmodifiable map"); UnsupportedError("Cannot modify unmodifiable map");

View file

@ -1,7 +1,6 @@
// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a // for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file. // BSD-style license that can be found in the LICENSE file.
// @dart = 2.6
/** /**
* Helps dealing with reflection in the case that the source code has been * Helps dealing with reflection in the case that the source code has been

View file

@ -2,8 +2,6 @@
// for details. All rights reserved. Use of this source code is governed by a // for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file. // BSD-style license that can be found in the LICENSE file.
// @dart = 2.6
part of dart._js_helper; part of dart._js_helper;
// Obsolete in dart dev compiler. Added only so that the same version of // Obsolete in dart dev compiler. Added only so that the same version of

View file

@ -2,8 +2,6 @@
// for details. All rights reserved. Use of this source code is governed by a // for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file. // BSD-style license that can be found in the LICENSE file.
// @dart = 2.6
/// Specialized integers and floating point numbers, /// Specialized integers and floating point numbers,
/// with SIMD support and efficient lists. /// with SIMD support and efficient lists.
library dart.typed_data.implementation; library dart.typed_data.implementation;
@ -32,69 +30,69 @@ class NativeByteBuffer implements ByteBuffer {
Type get runtimeType => ByteBuffer; Type get runtimeType => ByteBuffer;
Uint8List asUint8List([int offsetInBytes = 0, int length]) { Uint8List asUint8List([int offsetInBytes = 0, int? length]) {
return NativeUint8List.view(this, offsetInBytes, length); return NativeUint8List.view(this, offsetInBytes, length);
} }
Int8List asInt8List([int offsetInBytes = 0, int length]) { Int8List asInt8List([int offsetInBytes = 0, int? length]) {
return NativeInt8List.view(this, offsetInBytes, length); return NativeInt8List.view(this, offsetInBytes, length);
} }
Uint8ClampedList asUint8ClampedList([int offsetInBytes = 0, int length]) { Uint8ClampedList asUint8ClampedList([int offsetInBytes = 0, int? length]) {
return NativeUint8ClampedList.view(this, offsetInBytes, length); return NativeUint8ClampedList.view(this, offsetInBytes, length);
} }
Uint16List asUint16List([int offsetInBytes = 0, int length]) { Uint16List asUint16List([int offsetInBytes = 0, int? length]) {
return NativeUint16List.view(this, offsetInBytes, length); return NativeUint16List.view(this, offsetInBytes, length);
} }
Int16List asInt16List([int offsetInBytes = 0, int length]) { Int16List asInt16List([int offsetInBytes = 0, int? length]) {
return NativeInt16List.view(this, offsetInBytes, length); return NativeInt16List.view(this, offsetInBytes, length);
} }
Uint32List asUint32List([int offsetInBytes = 0, int length]) { Uint32List asUint32List([int offsetInBytes = 0, int? length]) {
return NativeUint32List.view(this, offsetInBytes, length); return NativeUint32List.view(this, offsetInBytes, length);
} }
Int32List asInt32List([int offsetInBytes = 0, int length]) { Int32List asInt32List([int offsetInBytes = 0, int? length]) {
return NativeInt32List.view(this, offsetInBytes, length); return NativeInt32List.view(this, offsetInBytes, length);
} }
Uint64List asUint64List([int offsetInBytes = 0, int length]) { Uint64List asUint64List([int offsetInBytes = 0, int? length]) {
throw UnsupportedError("Uint64List not supported by dart2js."); throw UnsupportedError("Uint64List not supported by dart2js.");
} }
Int64List asInt64List([int offsetInBytes = 0, int length]) { Int64List asInt64List([int offsetInBytes = 0, int? length]) {
throw UnsupportedError("Int64List not supported by dart2js."); throw UnsupportedError("Int64List not supported by dart2js.");
} }
Int32x4List asInt32x4List([int offsetInBytes = 0, int length]) { Int32x4List asInt32x4List([int offsetInBytes = 0, int? length]) {
NativeInt32List storage = var storage =
this.asInt32List(offsetInBytes, length != null ? length * 4 : null); this.asInt32List(offsetInBytes, length != null ? length * 4 : null);
return NativeInt32x4List._externalStorage(storage); return NativeInt32x4List._externalStorage(storage);
} }
Float32List asFloat32List([int offsetInBytes = 0, int length]) { Float32List asFloat32List([int offsetInBytes = 0, int? length]) {
return NativeFloat32List.view(this, offsetInBytes, length); return NativeFloat32List.view(this, offsetInBytes, length);
} }
Float64List asFloat64List([int offsetInBytes = 0, int length]) { Float64List asFloat64List([int offsetInBytes = 0, int? length]) {
return NativeFloat64List.view(this, offsetInBytes, length); return NativeFloat64List.view(this, offsetInBytes, length);
} }
Float32x4List asFloat32x4List([int offsetInBytes = 0, int length]) { Float32x4List asFloat32x4List([int offsetInBytes = 0, int? length]) {
NativeFloat32List storage = var storage =
this.asFloat32List(offsetInBytes, length != null ? length * 4 : null); this.asFloat32List(offsetInBytes, length != null ? length * 4 : null);
return NativeFloat32x4List._externalStorage(storage); return NativeFloat32x4List._externalStorage(storage);
} }
Float64x2List asFloat64x2List([int offsetInBytes = 0, int length]) { Float64x2List asFloat64x2List([int offsetInBytes = 0, int? length]) {
NativeFloat64List storage = var storage =
this.asFloat64List(offsetInBytes, length != null ? length * 2 : null); this.asFloat64List(offsetInBytes, length != null ? length * 2 : null);
return NativeFloat64x2List._externalStorage(storage); return NativeFloat64x2List._externalStorage(storage);
} }
ByteData asByteData([int offsetInBytes = 0, int length]) { ByteData asByteData([int offsetInBytes = 0, int? length]) {
return NativeByteData.view(this, offsetInBytes, length); return NativeByteData.view(this, offsetInBytes, length);
} }
} }
@ -105,7 +103,7 @@ class NativeByteBuffer implements ByteBuffer {
class NativeFloat32x4List extends Object class NativeFloat32x4List extends Object
with ListMixin<Float32x4>, FixedLengthListMixin<Float32x4> with ListMixin<Float32x4>, FixedLengthListMixin<Float32x4>
implements Float32x4List { implements Float32x4List {
final NativeFloat32List _storage; final Float32List _storage;
/// Creates a [Float32x4List] of the specified length (in elements), /// Creates a [Float32x4List] of the specified length (in elements),
/// all of whose elements are initially zero. /// all of whose elements are initially zero.
@ -164,10 +162,10 @@ class NativeFloat32x4List extends Object
_storage[(index * 4) + 3] = value.w; _storage[(index * 4) + 3] = value.w;
} }
Float32x4List sublist(int start, [int end]) { Float32x4List sublist(int start, [int? end]) {
end = _checkValidRange(start, end, this.length); var stop = _checkValidRange(start, end, this.length);
return NativeFloat32x4List._externalStorage( return NativeFloat32x4List._externalStorage(
_storage.sublist(start * 4, end * 4)); _storage.sublist(start * 4, stop * 4));
} }
} }
@ -236,10 +234,10 @@ class NativeInt32x4List extends Object
_storage[(index * 4) + 3] = value.w; _storage[(index * 4) + 3] = value.w;
} }
Int32x4List sublist(int start, [int end]) { Int32x4List sublist(int start, [int? end]) {
end = _checkValidRange(start, end, this.length); var stop = _checkValidRange(start, end, this.length);
return NativeInt32x4List._externalStorage( return NativeInt32x4List._externalStorage(
_storage.sublist(start * 4, end * 4)); _storage.sublist(start * 4, stop * 4));
} }
} }
@ -249,7 +247,7 @@ class NativeInt32x4List extends Object
class NativeFloat64x2List extends Object class NativeFloat64x2List extends Object
with ListMixin<Float64x2>, FixedLengthListMixin<Float64x2> with ListMixin<Float64x2>, FixedLengthListMixin<Float64x2>
implements Float64x2List { implements Float64x2List {
final NativeFloat64List _storage; final Float64List _storage;
/// Creates a [Float64x2List] of the specified length (in elements), /// Creates a [Float64x2List] of the specified length (in elements),
/// all of whose elements are initially zero. /// all of whose elements are initially zero.
@ -302,10 +300,10 @@ class NativeFloat64x2List extends Object
_storage[(index * 2) + 1] = value.y; _storage[(index * 2) + 1] = value.y;
} }
Float64x2List sublist(int start, [int end]) { Float64x2List sublist(int start, [int? end]) {
end = _checkValidRange(start, end, this.length); var stop = _checkValidRange(start, end, this.length);
return NativeFloat64x2List._externalStorage( return NativeFloat64x2List._externalStorage(
_storage.sublist(start * 2, end * 2)); _storage.sublist(start * 2, stop * 2));
} }
} }
@ -313,8 +311,7 @@ class NativeFloat64x2List extends Object
class NativeTypedData implements TypedData { class NativeTypedData implements TypedData {
/// Returns the byte buffer associated with this object. /// Returns the byte buffer associated with this object.
@Creates('NativeByteBuffer') @Creates('NativeByteBuffer')
// May be Null for IE's CanvasPixelArray. @Returns('NativeByteBuffer')
@Returns('NativeByteBuffer|Null')
external ByteBuffer get buffer; external ByteBuffer get buffer;
/// Returns the length of this view, in bytes. /// Returns the length of this view, in bytes.
@ -366,7 +363,7 @@ void _checkViewArguments(buffer, offsetInBytes, length) {
if (offsetInBytes is! int) { if (offsetInBytes is! int) {
throw ArgumentError('Invalid view offsetInBytes $offsetInBytes'); throw ArgumentError('Invalid view offsetInBytes $offsetInBytes');
} }
if (length != null && length is! int) { if (length is! int?) {
throw ArgumentError('Invalid view length $length'); throw ArgumentError('Invalid view length $length');
} }
} }
@ -375,7 +372,7 @@ void _checkViewArguments(buffer, offsetInBytes, length) {
// returns a copy of the list. // returns a copy of the list.
List _ensureNativeList(List list) { List _ensureNativeList(List list) {
if (list is JSIndexable) return list; if (list is JSIndexable) return list;
List result = List(list.length); List result = List.filled(list.length, null);
for (int i = 0; i < list.length; i++) { for (int i = 0; i < list.length; i++) {
result[i] = list[i]; result[i] = list[i];
} }
@ -399,7 +396,7 @@ class NativeByteData extends NativeTypedData implements ByteData {
/// if [offsetInBytes] + ([length] * elementSizeInBytes) is greater than /// if [offsetInBytes] + ([length] * elementSizeInBytes) is greater than
/// the length of [buffer]. /// the length of [buffer].
factory NativeByteData.view( factory NativeByteData.view(
ByteBuffer buffer, int offsetInBytes, int length) { ByteBuffer buffer, int offsetInBytes, int? length) {
_checkViewArguments(buffer, offsetInBytes, length); _checkViewArguments(buffer, offsetInBytes, length);
return length == null return length == null
? _create2(buffer, offsetInBytes) ? _create2(buffer, offsetInBytes)
@ -421,7 +418,7 @@ class NativeByteData extends NativeTypedData implements ByteData {
@JSName('getFloat32') @JSName('getFloat32')
@Returns('double') @Returns('double')
double _getFloat32(int byteOffset, [bool littleEndian]) native; double _getFloat32(int byteOffset, [bool? littleEndian]) native;
/// Returns the floating point number represented by the eight bytes at /// Returns the floating point number represented by the eight bytes at
/// the specified [byteOffset] in this object, in IEEE 754 /// the specified [byteOffset] in this object, in IEEE 754
@ -434,7 +431,7 @@ class NativeByteData extends NativeTypedData implements ByteData {
@JSName('getFloat64') @JSName('getFloat64')
@Returns('double') @Returns('double')
double _getFloat64(int byteOffset, [bool littleEndian]) native; double _getFloat64(int byteOffset, [bool? littleEndian]) native;
/// Returns the (possibly negative) integer represented by the two bytes at /// Returns the (possibly negative) integer represented by the two bytes at
/// the specified [byteOffset] in this object, in two's complement binary /// the specified [byteOffset] in this object, in two's complement binary
@ -449,7 +446,7 @@ class NativeByteData extends NativeTypedData implements ByteData {
@JSName('getInt16') @JSName('getInt16')
@Returns('int') @Returns('int')
int _getInt16(int byteOffset, [bool littleEndian]) native; int _getInt16(int byteOffset, [bool? littleEndian]) native;
/// Returns the (possibly negative) integer represented by the four bytes at /// Returns the (possibly negative) integer represented by the four bytes at
/// the specified [byteOffset] in this object, in two's complement binary /// the specified [byteOffset] in this object, in two's complement binary
@ -464,7 +461,7 @@ class NativeByteData extends NativeTypedData implements ByteData {
@JSName('getInt32') @JSName('getInt32')
@Returns('int') @Returns('int')
int _getInt32(int byteOffset, [bool littleEndian]) native; int _getInt32(int byteOffset, [bool? littleEndian]) native;
/// Returns the (possibly negative) integer represented by the eight bytes at /// Returns the (possibly negative) integer represented by the eight bytes at
/// the specified [byteOffset] in this object, in two's complement binary /// the specified [byteOffset] in this object, in two's complement binary
@ -498,7 +495,7 @@ class NativeByteData extends NativeTypedData implements ByteData {
@JSName('getUint16') @JSName('getUint16')
@Returns('int') @Returns('int')
int _getUint16(int byteOffset, [bool littleEndian]) native; int _getUint16(int byteOffset, [bool? littleEndian]) native;
/// Returns the positive integer represented by the four bytes starting /// Returns the positive integer represented by the four bytes starting
/// at the specified [byteOffset] in this object, in unsigned binary /// at the specified [byteOffset] in this object, in unsigned binary
@ -512,7 +509,7 @@ class NativeByteData extends NativeTypedData implements ByteData {
@JSName('getUint32') @JSName('getUint32')
@Returns('int') @Returns('int')
int _getUint32(int byteOffset, [bool littleEndian]) native; int _getUint32(int byteOffset, [bool? littleEndian]) native;
/// Returns the positive integer represented by the eight bytes starting /// Returns the positive integer represented by the eight bytes starting
/// at the specified [byteOffset] in this object, in unsigned binary /// at the specified [byteOffset] in this object, in unsigned binary
@ -552,7 +549,7 @@ class NativeByteData extends NativeTypedData implements ByteData {
_setFloat32(byteOffset, value, Endian.little == endian); _setFloat32(byteOffset, value, Endian.little == endian);
@JSName('setFloat32') @JSName('setFloat32')
void _setFloat32(int byteOffset, num value, [bool littleEndian]) native; void _setFloat32(int byteOffset, num value, [bool? littleEndian]) native;
/// Sets the eight bytes starting at the specified [byteOffset] in this /// Sets the eight bytes starting at the specified [byteOffset] in this
/// object to the IEEE 754 double-precision binary floating-point /// object to the IEEE 754 double-precision binary floating-point
@ -564,7 +561,7 @@ class NativeByteData extends NativeTypedData implements ByteData {
_setFloat64(byteOffset, value, Endian.little == endian); _setFloat64(byteOffset, value, Endian.little == endian);
@JSName('setFloat64') @JSName('setFloat64')
void _setFloat64(int byteOffset, num value, [bool littleEndian]) native; void _setFloat64(int byteOffset, num value, [bool? littleEndian]) native;
/// Sets the two bytes starting at the specified [byteOffset] in this /// Sets the two bytes starting at the specified [byteOffset] in this
/// object to the two's complement binary representation of the specified /// object to the two's complement binary representation of the specified
@ -577,7 +574,7 @@ class NativeByteData extends NativeTypedData implements ByteData {
_setInt16(byteOffset, value, Endian.little == endian); _setInt16(byteOffset, value, Endian.little == endian);
@JSName('setInt16') @JSName('setInt16')
void _setInt16(int byteOffset, int value, [bool littleEndian]) native; void _setInt16(int byteOffset, int value, [bool? littleEndian]) native;
/// Sets the four bytes starting at the specified [byteOffset] in this /// Sets the four bytes starting at the specified [byteOffset] in this
/// object to the two's complement binary representation of the specified /// object to the two's complement binary representation of the specified
@ -590,7 +587,7 @@ class NativeByteData extends NativeTypedData implements ByteData {
_setInt32(byteOffset, value, Endian.little == endian); _setInt32(byteOffset, value, Endian.little == endian);
@JSName('setInt32') @JSName('setInt32')
void _setInt32(int byteOffset, int value, [bool littleEndian]) native; void _setInt32(int byteOffset, int value, [bool? littleEndian]) native;
/// Sets the eight bytes starting at the specified [byteOffset] in this /// Sets the eight bytes starting at the specified [byteOffset] in this
/// object to the two's complement binary representation of the specified /// object to the two's complement binary representation of the specified
@ -623,7 +620,7 @@ class NativeByteData extends NativeTypedData implements ByteData {
_setUint16(byteOffset, value, Endian.little == endian); _setUint16(byteOffset, value, Endian.little == endian);
@JSName('setUint16') @JSName('setUint16')
void _setUint16(int byteOffset, int value, [bool littleEndian]) native; void _setUint16(int byteOffset, int value, [bool? littleEndian]) native;
/// Sets the four bytes starting at the specified [byteOffset] in this object /// Sets the four bytes starting at the specified [byteOffset] in this object
/// to the unsigned binary representation of the specified [value], /// to the unsigned binary representation of the specified [value],
@ -636,7 +633,7 @@ class NativeByteData extends NativeTypedData implements ByteData {
_setUint32(byteOffset, value, Endian.little == endian); _setUint32(byteOffset, value, Endian.little == endian);
@JSName('setUint32') @JSName('setUint32')
void _setUint32(int byteOffset, int value, [bool littleEndian]) native; void _setUint32(int byteOffset, int value, [bool? littleEndian]) native;
/// Sets the eight bytes starting at the specified [byteOffset] in this object /// Sets the eight bytes starting at the specified [byteOffset] in this object
/// to the unsigned binary representation of the specified [value], /// to the unsigned binary representation of the specified [value],
@ -751,7 +748,7 @@ class NativeFloat32List extends NativeTypedArrayOfDouble
_create1(_ensureNativeList(elements)); _create1(_ensureNativeList(elements));
factory NativeFloat32List.view( factory NativeFloat32List.view(
ByteBuffer buffer, int offsetInBytes, int length) { ByteBuffer buffer, int offsetInBytes, int? length) {
_checkViewArguments(buffer, offsetInBytes, length); _checkViewArguments(buffer, offsetInBytes, length);
return length == null return length == null
? _create2(buffer, offsetInBytes) ? _create2(buffer, offsetInBytes)
@ -760,10 +757,10 @@ class NativeFloat32List extends NativeTypedArrayOfDouble
Type get runtimeType => Float32List; Type get runtimeType => Float32List;
Float32List sublist(int start, [int end]) { Float32List sublist(int start, [int? end]) {
end = _checkValidRange(start, end, this.length); var stop = _checkValidRange(start, end, this.length);
var source = var source =
JS<NativeFloat32List>('!', '#.subarray(#, #)', this, start, end); JS<NativeFloat32List>('!', '#.subarray(#, #)', this, start, stop);
return _create1(source); return _create1(source);
} }
@ -786,7 +783,7 @@ class NativeFloat64List extends NativeTypedArrayOfDouble
_create1(_ensureNativeList(elements)); _create1(_ensureNativeList(elements));
factory NativeFloat64List.view( factory NativeFloat64List.view(
ByteBuffer buffer, int offsetInBytes, int length) { ByteBuffer buffer, int offsetInBytes, int? length) {
_checkViewArguments(buffer, offsetInBytes, length); _checkViewArguments(buffer, offsetInBytes, length);
return length == null return length == null
? _create2(buffer, offsetInBytes) ? _create2(buffer, offsetInBytes)
@ -795,9 +792,9 @@ class NativeFloat64List extends NativeTypedArrayOfDouble
Type get runtimeType => Float64List; Type get runtimeType => Float64List;
Float64List sublist(int start, [int end]) { Float64List sublist(int start, [int? end]) {
end = _checkValidRange(start, end, this.length); var stop = _checkValidRange(start, end, this.length);
var source = JS('NativeFloat64List', '#.subarray(#, #)', this, start, end); var source = JS('NativeFloat64List', '#.subarray(#, #)', this, start, stop);
return _create1(source); return _create1(source);
} }
@ -819,7 +816,7 @@ class NativeInt16List extends NativeTypedArrayOfInt implements Int16List {
_create1(_ensureNativeList(elements)); _create1(_ensureNativeList(elements));
factory NativeInt16List.view( factory NativeInt16List.view(
NativeByteBuffer buffer, int offsetInBytes, int length) { NativeByteBuffer buffer, int offsetInBytes, int? length) {
_checkViewArguments(buffer, offsetInBytes, length); _checkViewArguments(buffer, offsetInBytes, length);
return length == null return length == null
? _create2(buffer, offsetInBytes) ? _create2(buffer, offsetInBytes)
@ -833,9 +830,9 @@ class NativeInt16List extends NativeTypedArrayOfInt implements Int16List {
return JS<int>('!', '#[#]', this, index); return JS<int>('!', '#[#]', this, index);
} }
Int16List sublist(int start, [int end]) { Int16List sublist(int start, [int? end]) {
end = _checkValidRange(start, end, this.length); var stop = _checkValidRange(start, end, this.length);
var source = JS('NativeInt16List', '#.subarray(#, #)', this, start, end); var source = JS('NativeInt16List', '#.subarray(#, #)', this, start, stop);
return _create1(source); return _create1(source);
} }
@ -857,7 +854,7 @@ class NativeInt32List extends NativeTypedArrayOfInt implements Int32List {
_create1(_ensureNativeList(elements)); _create1(_ensureNativeList(elements));
factory NativeInt32List.view( factory NativeInt32List.view(
ByteBuffer buffer, int offsetInBytes, int length) { ByteBuffer buffer, int offsetInBytes, int? length) {
_checkViewArguments(buffer, offsetInBytes, length); _checkViewArguments(buffer, offsetInBytes, length);
return length == null return length == null
? _create2(buffer, offsetInBytes) ? _create2(buffer, offsetInBytes)
@ -871,9 +868,10 @@ class NativeInt32List extends NativeTypedArrayOfInt implements Int32List {
return JS<int>('!', '#[#]', this, index); return JS<int>('!', '#[#]', this, index);
} }
Int32List sublist(int start, [int end]) { Int32List sublist(int start, [int? end]) {
end = _checkValidRange(start, end, this.length); var stop = _checkValidRange(start, end, this.length);
var source = JS<NativeInt32List>('!', '#.subarray(#, #)', this, start, end); var source =
JS<NativeInt32List>('!', '#.subarray(#, #)', this, start, stop);
return _create1(source); return _create1(source);
} }
@ -895,7 +893,7 @@ class NativeInt8List extends NativeTypedArrayOfInt implements Int8List {
_create1(_ensureNativeList(elements)); _create1(_ensureNativeList(elements));
factory NativeInt8List.view( factory NativeInt8List.view(
ByteBuffer buffer, int offsetInBytes, int length) { ByteBuffer buffer, int offsetInBytes, int? length) {
_checkViewArguments(buffer, offsetInBytes, length); _checkViewArguments(buffer, offsetInBytes, length);
return length == null return length == null
? _create2(buffer, offsetInBytes) ? _create2(buffer, offsetInBytes)
@ -909,9 +907,9 @@ class NativeInt8List extends NativeTypedArrayOfInt implements Int8List {
return JS<int>('!', '#[#]', this, index); return JS<int>('!', '#[#]', this, index);
} }
Int8List sublist(int start, [int end]) { Int8List sublist(int start, [int? end]) {
end = _checkValidRange(start, end, this.length); var stop = _checkValidRange(start, end, this.length);
var source = JS<NativeInt8List>('!', '#.subarray(#, #)', this, start, end); var source = JS<NativeInt8List>('!', '#.subarray(#, #)', this, start, stop);
return _create1(source); return _create1(source);
} }
@ -921,7 +919,7 @@ class NativeInt8List extends NativeTypedArrayOfInt implements Int8List {
static NativeInt8List _create2(arg1, arg2) => static NativeInt8List _create2(arg1, arg2) =>
JS<NativeInt8List>('!', 'new Int8Array(#, #)', arg1, arg2); JS<NativeInt8List>('!', 'new Int8Array(#, #)', arg1, arg2);
static Int8List _create3(arg1, arg2, arg3) => static NativeInt8List _create3(arg1, arg2, arg3) =>
JS<NativeInt8List>('!', 'new Int8Array(#, #, #)', arg1, arg2, arg3); JS<NativeInt8List>('!', 'new Int8Array(#, #, #)', arg1, arg2, arg3);
} }
@ -933,7 +931,7 @@ class NativeUint16List extends NativeTypedArrayOfInt implements Uint16List {
_create1(_ensureNativeList(list)); _create1(_ensureNativeList(list));
factory NativeUint16List.view( factory NativeUint16List.view(
ByteBuffer buffer, int offsetInBytes, int length) { ByteBuffer buffer, int offsetInBytes, int? length) {
_checkViewArguments(buffer, offsetInBytes, length); _checkViewArguments(buffer, offsetInBytes, length);
return length == null return length == null
? _create2(buffer, offsetInBytes) ? _create2(buffer, offsetInBytes)
@ -947,10 +945,10 @@ class NativeUint16List extends NativeTypedArrayOfInt implements Uint16List {
return JS<int>('!', '#[#]', this, index); return JS<int>('!', '#[#]', this, index);
} }
Uint16List sublist(int start, [int end]) { Uint16List sublist(int start, [int? end]) {
end = _checkValidRange(start, end, this.length); var stop = _checkValidRange(start, end, this.length);
var source = var source =
JS<NativeUint16List>('!', '#.subarray(#, #)', this, start, end); JS<NativeUint16List>('!', '#.subarray(#, #)', this, start, stop);
return _create1(source); return _create1(source);
} }
@ -972,7 +970,7 @@ class NativeUint32List extends NativeTypedArrayOfInt implements Uint32List {
_create1(_ensureNativeList(elements)); _create1(_ensureNativeList(elements));
factory NativeUint32List.view( factory NativeUint32List.view(
ByteBuffer buffer, int offsetInBytes, int length) { ByteBuffer buffer, int offsetInBytes, int? length) {
_checkViewArguments(buffer, offsetInBytes, length); _checkViewArguments(buffer, offsetInBytes, length);
return length == null return length == null
? _create2(buffer, offsetInBytes) ? _create2(buffer, offsetInBytes)
@ -986,10 +984,10 @@ class NativeUint32List extends NativeTypedArrayOfInt implements Uint32List {
return JS<int>('!', '#[#]', this, index); return JS<int>('!', '#[#]', this, index);
} }
Uint32List sublist(int start, [int end]) { Uint32List sublist(int start, [int? end]) {
end = _checkValidRange(start, end, this.length); var stop = _checkValidRange(start, end, this.length);
var source = var source =
JS<NativeUint32List>('!', '#.subarray(#, #)', this, start, end); JS<NativeUint32List>('!', '#.subarray(#, #)', this, start, stop);
return _create1(source); return _create1(source);
} }
@ -1012,7 +1010,7 @@ class NativeUint8ClampedList extends NativeTypedArrayOfInt
_create1(_ensureNativeList(elements)); _create1(_ensureNativeList(elements));
factory NativeUint8ClampedList.view( factory NativeUint8ClampedList.view(
ByteBuffer buffer, int offsetInBytes, int length) { ByteBuffer buffer, int offsetInBytes, int? length) {
_checkViewArguments(buffer, offsetInBytes, length); _checkViewArguments(buffer, offsetInBytes, length);
return length == null return length == null
? _create2(buffer, offsetInBytes) ? _create2(buffer, offsetInBytes)
@ -1028,10 +1026,10 @@ class NativeUint8ClampedList extends NativeTypedArrayOfInt
return JS<int>('!', '#[#]', this, index); return JS<int>('!', '#[#]', this, index);
} }
Uint8ClampedList sublist(int start, [int end]) { Uint8ClampedList sublist(int start, [int? end]) {
end = _checkValidRange(start, end, this.length); var stop = _checkValidRange(start, end, this.length);
var source = var source =
JS<NativeUint8ClampedList>('!', '#.subarray(#, #)', this, start, end); JS<NativeUint8ClampedList>('!', '#.subarray(#, #)', this, start, stop);
return _create1(source); return _create1(source);
} }
@ -1062,7 +1060,7 @@ class NativeUint8List extends NativeTypedArrayOfInt implements Uint8List {
_create1(_ensureNativeList(elements)); _create1(_ensureNativeList(elements));
factory NativeUint8List.view( factory NativeUint8List.view(
ByteBuffer buffer, int offsetInBytes, int length) { ByteBuffer buffer, int offsetInBytes, int? length) {
_checkViewArguments(buffer, offsetInBytes, length); _checkViewArguments(buffer, offsetInBytes, length);
return length == null return length == null
? _create2(buffer, offsetInBytes) ? _create2(buffer, offsetInBytes)
@ -1078,9 +1076,10 @@ class NativeUint8List extends NativeTypedArrayOfInt implements Uint8List {
return JS<int>('!', '#[#]', this, index); return JS<int>('!', '#[#]', this, index);
} }
Uint8List sublist(int start, [int end]) { Uint8List sublist(int start, [int? end]) {
end = _checkValidRange(start, end, this.length); var stop = _checkValidRange(start, end, this.length);
var source = JS<NativeUint8List>('!', '#.subarray(#, #)', this, start, end); var source =
JS<NativeUint8List>('!', '#.subarray(#, #)', this, start, stop);
return _create1(source); return _create1(source);
} }
@ -1466,7 +1465,7 @@ class NativeInt32x4 implements Int32x4 {
floatList[1] = f.y; floatList[1] = f.y;
floatList[2] = f.z; floatList[2] = f.z;
floatList[3] = f.w; floatList[3] = f.w;
NativeInt32List view = floatList.buffer.asInt32List(); Int32List view = floatList.buffer.asInt32List();
return NativeInt32x4._truncated(view[0], view[1], view[2], view[3]); return NativeInt32x4._truncated(view[0], view[1], view[2], view[3]);
} }
@ -1684,7 +1683,7 @@ class NativeFloat64x2 implements Float64x2 {
final double y; final double y;
static NativeFloat64List _list = NativeFloat64List(2); static NativeFloat64List _list = NativeFloat64List(2);
static NativeUint32List _uint32View = _list.buffer.asUint32List(); static Uint32List _uint32View = _list.buffer.asUint32List();
NativeFloat64x2(this.x, this.y) { NativeFloat64x2(this.x, this.y) {
if (x is! num) throw ArgumentError(x); if (x is! num) throw ArgumentError(x);
@ -1815,7 +1814,7 @@ void _checkValidIndex(int index, List list, int length) {
/// ///
/// Returns the actual value of `end`, which is `length` if `end` is `null`, and /// Returns the actual value of `end`, which is `length` if `end` is `null`, and
/// the original value of `end` otherwise. /// the original value of `end` otherwise.
int _checkValidRange(int start, int end, int length) { int _checkValidRange(int start, int? end, int length) {
if (_isInvalidArrayIndex(start) || // Ensures start is non-negative int. if (_isInvalidArrayIndex(start) || // Ensures start is non-negative int.
((end == null) ((end == null)
? start > length ? start > length

View file

@ -2,19 +2,15 @@
// for details. All rights reserved. Use of this source code is governed by a // for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file. // BSD-style license that can be found in the LICENSE file.
// @dart = 2.6
/// This file supports profiling dynamic calls. /// This file supports profiling dynamic calls.
part of dart._debugger; part of dart._debugger;
class _MethodStats { class _MethodStats {
final String typeName; final String typeName;
final String frame; final String frame;
double count; double count = 0.0;
_MethodStats(this.typeName, this.frame) { _MethodStats(this.typeName, this.frame);
count = 0.0;
}
} }
class _CallMethodRecord { class _CallMethodRecord {
@ -29,7 +25,7 @@ int _callRecordSampleSize = 5000;
/// If the number of dynamic calls exceeds [_callRecordSampleSize] this list /// If the number of dynamic calls exceeds [_callRecordSampleSize] this list
/// will represent a random sample of the dynamic calls made. /// will represent a random sample of the dynamic calls made.
List<_CallMethodRecord> _callMethodRecords = List(); var _callMethodRecords = <_CallMethodRecord>[];
/// If the number of dynamic calls exceeds [_callRecordSampleSize] this value /// If the number of dynamic calls exceeds [_callRecordSampleSize] this value
/// will be greater than [_callMethodRecords.length]. /// will be greater than [_callMethodRecords.length].
@ -45,7 +41,7 @@ num _minCount = 2;
/// speedup lookup of source map frames when running the profiler. /// speedup lookup of source map frames when running the profiler.
/// The number of source map entries looked up makes caching more important /// The number of source map entries looked up makes caching more important
/// in this case than for typical source map use cases. /// in this case than for typical source map use cases.
Map<String, String> _frameMappingCache = Map(); var _frameMappingCache = <String, String>{};
List<List<Object>> getDynamicStats() { List<List<Object>> getDynamicStats() {
// Process the accumulated method stats. This may be quite slow as processing // Process the accumulated method stats. This may be quite slow as processing
@ -56,7 +52,7 @@ List<List<Object>> getDynamicStats() {
// raw number of dynamic calls so that the magnitude of the dynamic call // raw number of dynamic calls so that the magnitude of the dynamic call
// performance hit is clear to users. // performance hit is clear to users.
Map<String, _MethodStats> callMethodStats = Map(); var callMethodStats = <String, _MethodStats>{};
if (_callMethodRecords.length > 0) { if (_callMethodRecords.length > 0) {
// Ratio between total record count and sampled records count. // Ratio between total record count and sampled records count.
var recordRatio = _totalCallRecords / _callMethodRecords.length; var recordRatio = _totalCallRecords / _callMethodRecords.length;
@ -67,8 +63,8 @@ List<List<Object>> getDynamicStats() {
// runtime. // runtime.
var src = frames var src = frames
.skip(2) .skip(2)
.map((f) => .map((f) => _frameMappingCache.putIfAbsent(
_frameMappingCache.putIfAbsent(f, () => stackTraceMapper('\n$f'))) f, () => stackTraceMapper!('\n$f')))
.firstWhere((f) => !f.startsWith('dart:'), orElse: () => ''); .firstWhere((f) => !f.startsWith('dart:'), orElse: () => '');
var actualTypeName = dart.typeName(record.type); var actualTypeName = dart.typeName(record.type);
@ -83,7 +79,7 @@ List<List<Object>> getDynamicStats() {
// complete profile. // complete profile.
if (_totalCallRecords != _callMethodRecords.length) { if (_totalCallRecords != _callMethodRecords.length) {
for (var k in callMethodStats.keys.toList()) { for (var k in callMethodStats.keys.toList()) {
var stats = callMethodStats[k]; var stats = callMethodStats[k]!;
var threshold = _minCount * recordRatio; var threshold = _minCount * recordRatio;
if (stats.count + 0.001 < threshold) { if (stats.count + 0.001 < threshold) {
callMethodStats.remove(k); callMethodStats.remove(k);
@ -94,12 +90,11 @@ List<List<Object>> getDynamicStats() {
_callMethodRecords.clear(); _callMethodRecords.clear();
_totalCallRecords = 0; _totalCallRecords = 0;
var keys = callMethodStats.keys.toList(); var keys = callMethodStats.keys.toList();
keys.sort( keys.sort(
(a, b) => callMethodStats[b].count.compareTo(callMethodStats[a].count)); (a, b) => callMethodStats[b]!.count.compareTo(callMethodStats[a]!.count));
List<List<Object>> ret = []; var ret = <List<Object>>[];
for (var key in keys) { for (var key in keys) {
var stats = callMethodStats[key]; var stats = callMethodStats[key]!;
ret.add([stats.typeName, stats.frame, stats.count.round()]); ret.add([stats.typeName, stats.frame, stats.count.round()]);
} }
return ret; return ret;

View file

@ -2,8 +2,6 @@
// for details. All rights reserved. Use of this source code is governed by a // for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file. // BSD-style license that can be found in the LICENSE file.
// @dart = 2.6
part of dart._js_helper; part of dart._js_helper;
// Helper method used by internal libraries. // Helper method used by internal libraries.
@ -117,10 +115,11 @@ class JSSyntaxRegExp implements RegExp {
throw FormatException("Illegal RegExp pattern: $source, $errorMessage"); throw FormatException("Illegal RegExp pattern: $source, $errorMessage");
} }
RegExpMatch firstMatch(@nullCheck String string) { RegExpMatch? firstMatch(@nullCheck String string) {
List m = JS('JSExtendableArray|Null', r'#.exec(#)', _nativeRegExp, string); List<String>? m =
JS('JSExtendableArray|Null', r'#.exec(#)', _nativeRegExp, string);
if (m == null) return null; if (m == null) return null;
return _MatchImplementation(this, JSArray<String>.of(m)); return _MatchImplementation(this, m);
} }
@notNull @notNull
@ -128,7 +127,7 @@ class JSSyntaxRegExp implements RegExp {
return JS<bool>('!', r'#.test(#)', _nativeRegExp, string); return JS<bool>('!', r'#.test(#)', _nativeRegExp, string);
} }
String stringMatch(String string) { String? stringMatch(String string) {
var match = firstMatch(string); var match = firstMatch(string);
if (match != null) return match.group(0); if (match != null) return match.group(0);
return null; return null;
@ -142,27 +141,29 @@ class JSSyntaxRegExp implements RegExp {
return _AllMatchesIterable(this, string, start); return _AllMatchesIterable(this, string, start);
} }
RegExpMatch _execGlobal(String string, int start) { RegExpMatch? _execGlobal(String string, int start) {
Object regexp = _nativeGlobalVersion; Object regexp = _nativeGlobalVersion;
JS("void", "#.lastIndex = #", regexp, start); JS("void", "#.lastIndex = #", regexp, start);
List match = JS("JSExtendableArray|Null", "#.exec(#)", regexp, string); List<String>? match =
JS("JSExtendableArray|Null", "#.exec(#)", regexp, string);
if (match == null) return null; if (match == null) return null;
return _MatchImplementation(this, JSArray<String>.of(match)); return _MatchImplementation(this, match);
} }
RegExpMatch _execAnchored(String string, int start) { RegExpMatch? _execAnchored(String string, int start) {
Object regexp = _nativeAnchoredVersion; Object regexp = _nativeAnchoredVersion;
JS("void", "#.lastIndex = #", regexp, start); JS("void", "#.lastIndex = #", regexp, start);
List match = JS("JSExtendableArray|Null", "#.exec(#)", regexp, string); List<String>? match =
JS("JSExtendableArray|Null", "#.exec(#)", regexp, string);
if (match == null) return null; if (match == null) return null;
// If the last capture group participated, the original regexp did not // If the last capture group participated, the original regexp did not
// match at the start position. // match at the start position.
if (match[match.length - 1] != null) return null; if (match[match.length - 1] != null) return null;
match.length -= 1; match.length -= 1;
return _MatchImplementation(this, JSArray<String>.of(match)); return _MatchImplementation(this, match);
} }
RegExpMatch matchAsPrefix(String string, [int start = 0]) { Match? matchAsPrefix(String string, [int start = 0]) {
if (start < 0 || start > string.length) { if (start < 0 || start > string.length) {
throw RangeError.range(start, 0, string.length); throw RangeError.range(start, 0, string.length);
} }
@ -190,22 +191,22 @@ class _MatchImplementation implements RegExpMatch {
int get start => JS("int", "#.index", _match); int get start => JS("int", "#.index", _match);
int get end => start + _match[0].length; int get end => start + _match[0].length;
String group(int index) => _match[index]; String? group(int index) => _match[index];
String operator [](int index) => group(index); String? operator [](int index) => group(index);
int get groupCount => _match.length - 1; int get groupCount => _match.length - 1;
List<String> groups(List<int> groups) { List<String?> groups(List<int> groups) {
List<String> out = []; List<String?> out = [];
for (int i in groups) { for (int i in groups) {
out.add(group(i)); out.add(group(i));
} }
return out; return out;
} }
String namedGroup(String name) { String? namedGroup(String name) {
var groups = JS('Object|Null', '#.groups', _match); var groups = JS<Object?>('Object|Null', '#.groups', _match);
if (groups != null) { if (groups != null) {
var result = JS('String|Null', '#[#]', groups, name); var result = JS<String?>('', '#[#]', groups, name);
if (result != null || JS<bool>('!', '# in #', name, groups)) { if (result != null || JS<bool>('!', '# in #', name, groups)) {
return result; return result;
} }
@ -214,7 +215,7 @@ class _MatchImplementation implements RegExpMatch {
} }
Iterable<String> get groupNames { Iterable<String> get groupNames {
var groups = JS('Object|Null', '#.groups', _match); var groups = JS<Object?>('Object|Null', '#.groups', _match);
if (groups != null) { if (groups != null) {
var keys = JSArray<String>.of(JS('', 'Object.keys(#)', groups)); var keys = JSArray<String>.of(JS('', 'Object.keys(#)', groups));
return SubListIterable(keys, 0, null); return SubListIterable(keys, 0, null);
@ -236,13 +237,13 @@ class _AllMatchesIterable extends IterableBase<RegExpMatch> {
class _AllMatchesIterator implements Iterator<RegExpMatch> { class _AllMatchesIterator implements Iterator<RegExpMatch> {
final JSSyntaxRegExp _regExp; final JSSyntaxRegExp _regExp;
String _string; String? _string;
int _nextIndex; int _nextIndex;
RegExpMatch _current; RegExpMatch? _current;
_AllMatchesIterator(this._regExp, this._string, this._nextIndex); _AllMatchesIterator(this._regExp, this._string, this._nextIndex);
RegExpMatch get current => _current; RegExpMatch get current => _current as RegExpMatch;
static bool _isLeadSurrogate(int c) { static bool _isLeadSurrogate(int c) {
return c >= 0xd800 && c <= 0xdbff; return c >= 0xd800 && c <= 0xdbff;
@ -253,9 +254,10 @@ class _AllMatchesIterator implements Iterator<RegExpMatch> {
} }
bool moveNext() { bool moveNext() {
if (_string == null) return false; var string = _string;
if (_nextIndex <= _string.length) { if (string == null) return false;
var match = _regExp._execGlobal(_string, _nextIndex); if (_nextIndex <= string.length) {
var match = _regExp._execGlobal(string, _nextIndex);
if (match != null) { if (match != null) {
_current = match; _current = match;
int nextIndex = match.end; int nextIndex = match.end;
@ -264,9 +266,9 @@ class _AllMatchesIterator implements Iterator<RegExpMatch> {
// is in unicode mode and it would put us within a surrogate // is in unicode mode and it would put us within a surrogate
// pair. In that case, advance past the code point as a whole. // pair. In that case, advance past the code point as a whole.
if (_regExp.isUnicode && if (_regExp.isUnicode &&
_nextIndex + 1 < _string.length && _nextIndex + 1 < string.length &&
_isLeadSurrogate(_string.codeUnitAt(_nextIndex)) && _isLeadSurrogate(string.codeUnitAt(_nextIndex)) &&
_isTrailSurrogate(_string.codeUnitAt(_nextIndex + 1))) { _isTrailSurrogate(string.codeUnitAt(_nextIndex + 1))) {
nextIndex++; nextIndex++;
} }
nextIndex++; nextIndex++;
@ -282,6 +284,6 @@ class _AllMatchesIterator implements Iterator<RegExpMatch> {
} }
/** Find the first match of [regExp] in [string] at or after [start]. */ /** Find the first match of [regExp] in [string] at or after [start]. */
RegExpMatch firstMatchAfter(JSSyntaxRegExp regExp, String string, int start) { RegExpMatch? firstMatchAfter(JSSyntaxRegExp regExp, String string, int start) {
return regExp._execGlobal(string, start); return regExp._execGlobal(string, start);
} }

View file

@ -2,8 +2,6 @@
// for details. All rights reserved. Use of this source code is governed by a // for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file. // BSD-style license that can be found in the LICENSE file.
// @dart = 2.6
part of dart._js_helper; part of dart._js_helper;
@notNull @notNull
@ -41,7 +39,7 @@ class StringMatch implements Match {
} }
List<String> groups(List<int> groups_) { List<String> groups(List<int> groups_) {
List<String> result = List<String>(); List<String> result = <String>[];
for (int g in groups_) { for (int g in groups_) {
result.add(group(g)); result.add(group(g));
} }
@ -81,7 +79,7 @@ class _StringAllMatchesIterator implements Iterator<Match> {
final String _input; final String _input;
final String _pattern; final String _pattern;
int _index; int _index;
Match _current; Match? _current;
_StringAllMatchesIterator(this._input, this._pattern, this._index); _StringAllMatchesIterator(this._input, this._pattern, this._index);
@ -104,7 +102,7 @@ class _StringAllMatchesIterator implements Iterator<Match> {
return true; return true;
} }
Match get current => _current; Match get current => _current!;
} }
@notNull @notNull
@ -176,15 +174,15 @@ String stringReplaceAllUnchecked(@notNull String receiver,
} }
} }
String _matchString(Match match) => match[0]; String _matchString(Match match) => match[0]!;
String _stringIdentity(String string) => string; String _stringIdentity(String string) => string;
@notNull @notNull
String stringReplaceAllFuncUnchecked( String stringReplaceAllFuncUnchecked(
String receiver, String receiver,
@nullCheck Pattern pattern, @nullCheck Pattern pattern,
String onMatch(Match match), String Function(Match)? onMatch,
String onNonMatch(String nonMatch)) { String Function(String)? onNonMatch) {
if (onMatch == null) onMatch = _matchString; if (onMatch == null) onMatch = _matchString;
if (onNonMatch == null) onNonMatch = _stringIdentity; if (onNonMatch == null) onNonMatch = _stringIdentity;
if (pattern is String) { if (pattern is String) {

View file

@ -2,8 +2,6 @@
// for details. All rights reserved. Use of this source code is governed by a // for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file. // BSD-style license that can be found in the LICENSE file.
// @dart = 2.6
part of _js_helper; part of _js_helper;
/// Marks a class as native and defines its JavaScript name(s). /// Marks a class as native and defines its JavaScript name(s).

View file

@ -2,8 +2,6 @@
// for details. All rights reserved. Use of this source code is governed by a // for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file. // BSD-style license that can be found in the LICENSE file.
// @dart = 2.6
// Patch file for the dart:async library. // Patch file for the dart:async library.
import 'dart:_js_helper' import 'dart:_js_helper'
@ -122,7 +120,7 @@ class Timer {
class _TimerImpl implements Timer { class _TimerImpl implements Timer {
final bool _once; final bool _once;
int _handle; int? _handle;
int _tick = 0; int _tick = 0;
_TimerImpl(int milliseconds, void callback()) : _once = true { _TimerImpl(int milliseconds, void callback()) : _once = true {
@ -197,15 +195,24 @@ class _AsyncAwaitCompleter<T> implements Completer<T> {
_AsyncAwaitCompleter() : isSync = false; _AsyncAwaitCompleter() : isSync = false;
void complete([FutureOr<T> value]) { void complete([FutureOr<T>? value]) {
if (!isSync || value is Future<T>) { // All paths require that if value is null, null as T succeeds.
value = (value == null) ? value as T : value;
if (!isSync) {
_future._asyncComplete(value); _future._asyncComplete(value);
} else if (value is Future<T>) {
assert(!_future._isComplete);
_future._chainFuture(value);
} else { } else {
_future._completeWithValue(value); // TODO(40014): Remove cast when type promotion works.
// This would normally be `as T` but we use `as dynamic` to make the
// unneeded check be implict to match dart2js unsound optimizations in the
// user code.
_future._completeWithValue(value as dynamic);
} }
} }
void completeError(Object e, [StackTrace st]) { void completeError(Object e, [StackTrace? st]) {
st ??= AsyncError.defaultStackTrace(e); st ??= AsyncError.defaultStackTrace(e);
if (isSync) { if (isSync) {
_future._completeError(e, st); _future._completeError(e, st);
@ -280,7 +287,7 @@ dynamic _asyncRethrow(dynamic object, Completer completer) {
/// The [bodyFunction] argument is the continuation that should be invoked /// The [bodyFunction] argument is the continuation that should be invoked
/// when the future completes. /// when the future completes.
void _awaitOnObject(object, _WrappedAsyncBody bodyFunction) { void _awaitOnObject(object, _WrappedAsyncBody bodyFunction) {
Function thenCallback = FutureOr<dynamic> Function(dynamic) thenCallback =
(result) => bodyFunction(async_error_codes.SUCCESS, result); (result) => bodyFunction(async_error_codes.SUCCESS, result);
Function errorCallback = (dynamic error, StackTrace stackTrace) { Function errorCallback = (dynamic error, StackTrace stackTrace) {
@ -377,7 +384,7 @@ void _asyncStarHelper(
if (identical(bodyFunctionOrErrorCode, async_error_codes.SUCCESS)) { if (identical(bodyFunctionOrErrorCode, async_error_codes.SUCCESS)) {
// This happens on return from the async* function. // This happens on return from the async* function.
if (controller.isCanceled) { if (controller.isCanceled) {
controller.cancelationFuture._completeWithValue(null); controller.cancelationFuture!._completeWithValue(null);
} else { } else {
controller.close(); controller.close();
} }
@ -385,7 +392,7 @@ void _asyncStarHelper(
} else if (identical(bodyFunctionOrErrorCode, async_error_codes.ERROR)) { } else if (identical(bodyFunctionOrErrorCode, async_error_codes.ERROR)) {
// The error is a js-error. // The error is a js-error.
if (controller.isCanceled) { if (controller.isCanceled) {
controller.cancelationFuture._completeError( controller.cancelationFuture!._completeError(
unwrapException(object), getTraceFromException(object)); unwrapException(object), getTraceFromException(object));
} else { } else {
controller.addError( controller.addError(
@ -451,7 +458,7 @@ Stream _streamOfController(_AsyncStarStreamController controller) {
/// If yielding while the subscription is paused it will become suspended. And /// If yielding while the subscription is paused it will become suspended. And
/// only resume after the subscription is resumed or canceled. /// only resume after the subscription is resumed or canceled.
class _AsyncStarStreamController<T> { class _AsyncStarStreamController<T> {
StreamController<T> controller; late StreamController<T> controller;
Stream get stream => controller.stream; Stream get stream => controller.stream;
/// True when the async* function has yielded while being paused. /// True when the async* function has yielded while being paused.
@ -461,7 +468,7 @@ class _AsyncStarStreamController<T> {
bool get isPaused => controller.isPaused; bool get isPaused => controller.isPaused;
_Future cancelationFuture = null; _Future? cancelationFuture = null;
/// True after the StreamSubscription has been cancelled. /// True after the StreamSubscription has been cancelled.
/// When this is true, errors thrown from the async* body should go to the /// When this is true, errors thrown from the async* body should go to the
@ -565,22 +572,21 @@ class _SyncStarIterator<T> implements Iterator<T> {
dynamic _body; dynamic _body;
// The current value, unless iterating a non-sync* nested iterator. // The current value, unless iterating a non-sync* nested iterator.
T _current = null; T? _current = null;
// This is the nested iterator when iterating a yield* of a non-sync iterator. // This is the nested iterator when iterating a yield* of a non-sync iterator.
// TODO(32956): In strong-mode, yield* takes an Iterable<T> (possibly checked Iterator<T>? _nestedIterator = null;
// with an implicit downcast), so change type to Iterator<T>.
Iterator _nestedIterator = null;
// Stack of suspended state machines when iterating a yield* of a sync* // Stack of suspended state machines when iterating a yield* of a sync*
// iterator. // iterator.
List _suspendedBodies = null; List? _suspendedBodies = null;
_SyncStarIterator(this._body); _SyncStarIterator(this._body);
T get current { T get current {
if (_nestedIterator == null) return _current; var nested = _nestedIterator;
return _nestedIterator.current; if (nested == null) return _current as dynamic; // implicit: as T;
return nested.current;
} }
_runBody() { _runBody() {
@ -611,7 +617,7 @@ class _SyncStarIterator<T> implements Iterator<T> {
bool moveNext() { bool moveNext() {
while (true) { while (true) {
if (_nestedIterator != null) { if (_nestedIterator != null) {
if (_nestedIterator.moveNext()) { if (_nestedIterator!.moveNext()) {
return true; return true;
} else { } else {
_nestedIterator = null; _nestedIterator = null;
@ -621,13 +627,14 @@ class _SyncStarIterator<T> implements Iterator<T> {
if (value is _IterationMarker) { if (value is _IterationMarker) {
int state = value.state; int state = value.state;
if (state == _IterationMarker.ITERATION_ENDED) { if (state == _IterationMarker.ITERATION_ENDED) {
if (_suspendedBodies == null || _suspendedBodies.isEmpty) { var suspendedBodies = _suspendedBodies;
if (suspendedBodies == null || suspendedBodies.isEmpty) {
_current = null; _current = null;
// Rely on [_body] to repeatedly return `ITERATION_ENDED`. // Rely on [_body] to repeatedly return `ITERATION_ENDED`.
return false; return false;
} }
// Resume the innermost suspended iterator. // Resume the innermost suspended iterator.
_body = _suspendedBodies.removeLast(); _body = suspendedBodies.removeLast();
continue; continue;
} else if (state == _IterationMarker.UNCAUGHT_ERROR) { } else if (state == _IterationMarker.UNCAUGHT_ERROR) {
// Rely on [_body] to repeatedly return `UNCAUGHT_ERROR`. // Rely on [_body] to repeatedly return `UNCAUGHT_ERROR`.
@ -636,8 +643,12 @@ class _SyncStarIterator<T> implements Iterator<T> {
JS('', 'throw #', value.value); JS('', 'throw #', value.value);
} else { } else {
assert(state == _IterationMarker.YIELD_STAR); assert(state == _IterationMarker.YIELD_STAR);
Iterator inner = value.value.iterator; Iterator<T> inner = value.value.iterator;
if (inner is _SyncStarIterator) { if (inner is _SyncStarIterator) {
// The test needs to be 'is _SyncStarIterator<T>' for promotion to
// work. However, that test is much more expensive, so we use an
// unsafe cast.
_SyncStarIterator<T> innerSyncStarIterator = JS('', '#', inner);
// Suspend the current state machine and start acting on behalf of // Suspend the current state machine and start acting on behalf of
// the nested state machine. // the nested state machine.
// //
@ -645,7 +656,7 @@ class _SyncStarIterator<T> implements Iterator<T> {
// suspending the current body when all it will do is step without // suspending the current body when all it will do is step without
// effect to ITERATION_ENDED. // effect to ITERATION_ENDED.
(_suspendedBodies ??= []).add(_body); (_suspendedBodies ??= []).add(_body);
_body = inner._body; _body = innerSyncStarIterator._body;
continue; continue;
} else { } else {
_nestedIterator = inner; _nestedIterator = inner;

View file

@ -2,8 +2,6 @@
// for details. All rights reserved. Use of this source code is governed by a // for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file. // BSD-style license that can be found in the LICENSE file.
// @dart = 2.6
// Patch file for dart:collection classes. // Patch file for dart:collection classes.
import 'dart:_foreign_helper' show JS; import 'dart:_foreign_helper' show JS;
import 'dart:_js_helper' import 'dart:_js_helper'
@ -30,9 +28,9 @@ const int _mask30 = 0x3fffffff; // Low 30 bits.
class HashMap<K, V> { class HashMap<K, V> {
@patch @patch
factory HashMap( factory HashMap(
{bool equals(K key1, K key2), {bool equals(K key1, K key2)?,
int hashCode(K key), int hashCode(K key)?,
bool isValidKey(potentialKey)}) { bool isValidKey(potentialKey)?}) {
if (isValidKey == null) { if (isValidKey == null) {
if (hashCode == null) { if (hashCode == null) {
if (equals == null) { if (equals == null) {
@ -82,7 +80,7 @@ class _HashMap<K, V> extends MapBase<K, V> implements HashMap<K, V> {
// list of all the keys. We cache that on the instance and clear the // list of all the keys. We cache that on the instance and clear the
// the cache whenever the key set changes. This is also used to // the cache whenever the key set changes. This is also used to
// guard against concurrent modifications. // guard against concurrent modifications.
List _keys; List? _keys;
_HashMap(); _HashMap();
@ -95,10 +93,10 @@ class _HashMap<K, V> extends MapBase<K, V> implements HashMap<K, V> {
} }
Iterable<V> get values { Iterable<V> get values {
return new MappedIterable<K, V>(keys, (each) => this[each]); return new MappedIterable<K, V>(keys, (each) => this[each] as V);
} }
bool containsKey(Object key) { bool containsKey(Object? key) {
if (_isStringKey(key)) { if (_isStringKey(key)) {
var strings = _strings; var strings = _strings;
return (strings == null) ? false : _hasTableEntry(strings, key); return (strings == null) ? false : _hasTableEntry(strings, key);
@ -110,14 +108,14 @@ class _HashMap<K, V> extends MapBase<K, V> implements HashMap<K, V> {
} }
} }
bool _containsKey(Object key) { bool _containsKey(Object? key) {
var rest = _rest; var rest = _rest;
if (rest == null) return false; if (rest == null) return false;
var bucket = _getBucket(rest, key); var bucket = _getBucket(rest, key);
return _findBucketIndex(bucket, key) >= 0; return _findBucketIndex(bucket, key) >= 0;
} }
bool containsValue(Object value) { bool containsValue(Object? value) {
return _computeKeys().any((each) => this[each] == value); return _computeKeys().any((each) => this[each] == value);
} }
@ -127,7 +125,7 @@ class _HashMap<K, V> extends MapBase<K, V> implements HashMap<K, V> {
}); });
} }
V operator [](Object key) { V? operator [](Object? key) {
if (_isStringKey(key)) { if (_isStringKey(key)) {
var strings = _strings; var strings = _strings;
return JS('', '#', strings == null ? null : _getTableEntry(strings, key)); return JS('', '#', strings == null ? null : _getTableEntry(strings, key));
@ -139,7 +137,7 @@ class _HashMap<K, V> extends MapBase<K, V> implements HashMap<K, V> {
} }
} }
V _get(Object key) { V? _get(Object? key) {
var rest = _rest; var rest = _rest;
if (rest == null) return null; if (rest == null) return null;
var bucket = _getBucket(rest, key); var bucket = _getBucket(rest, key);
@ -183,13 +181,13 @@ class _HashMap<K, V> extends MapBase<K, V> implements HashMap<K, V> {
} }
V putIfAbsent(K key, V ifAbsent()) { V putIfAbsent(K key, V ifAbsent()) {
if (containsKey(key)) return this[key]; if (containsKey(key)) return this[key] as V;
V value = ifAbsent(); V value = ifAbsent();
this[key] = value; this[key] = value;
return value; return value;
} }
V remove(Object key) { V? remove(Object? key) {
if (_isStringKey(key)) { if (_isStringKey(key)) {
return _removeHashTableEntry(_strings, key); return _removeHashTableEntry(_strings, key);
} else if (_isNumericKey(key)) { } else if (_isNumericKey(key)) {
@ -199,7 +197,7 @@ class _HashMap<K, V> extends MapBase<K, V> implements HashMap<K, V> {
} }
} }
V _remove(Object key) { V? _remove(Object? key) {
var rest = _rest; var rest = _rest;
if (rest == null) return null; if (rest == null) return null;
var hash = _computeHashCode(key); var hash = _computeHashCode(key);
@ -228,7 +226,7 @@ class _HashMap<K, V> extends MapBase<K, V> implements HashMap<K, V> {
List keys = _computeKeys(); List keys = _computeKeys();
for (int i = 0, length = keys.length; i < length; i++) { for (int i = 0, length = keys.length; i < length; i++) {
var key = JS('var', '#[#]', keys, i); var key = JS('var', '#[#]', keys, i);
action(key, this[key]); action(key, this[key] as V);
if (JS('bool', '# !== #', keys, _keys)) { if (JS('bool', '# !== #', keys, _keys)) {
throw new ConcurrentModificationError(this); throw new ConcurrentModificationError(this);
} }
@ -236,8 +234,9 @@ class _HashMap<K, V> extends MapBase<K, V> implements HashMap<K, V> {
} }
List _computeKeys() { List _computeKeys() {
if (_keys != null) return _keys; var result = _keys;
List result = new List(_length); if (result != null) return result;
result = List.filled(_length, null);
int index = 0; int index = 0;
// Add all string keys to the list. // Add all string keys to the list.
@ -283,7 +282,8 @@ class _HashMap<K, V> extends MapBase<K, V> implements HashMap<K, V> {
} }
} }
assert(index == _length); assert(index == _length);
return _keys = result; _keys = result;
return result;
} }
void _addHashTableEntry(var table, K key, V value) { void _addHashTableEntry(var table, K key, V value) {
@ -294,7 +294,7 @@ class _HashMap<K, V> extends MapBase<K, V> implements HashMap<K, V> {
_setTableEntry(table, key, value); _setTableEntry(table, key, value);
} }
V _removeHashTableEntry(var table, Object key) { V? _removeHashTableEntry(var table, Object? key) {
if (table != null && _hasTableEntry(table, key)) { if (table != null && _hasTableEntry(table, key)) {
V value = _getTableEntry(table, key); V value = _getTableEntry(table, key);
_deleteTableEntry(table, key); _deleteTableEntry(table, key);
@ -408,10 +408,10 @@ class _CustomHashMap<K, V> extends _HashMap<K, V> {
final _Hasher<K> _hashCode; final _Hasher<K> _hashCode;
final _Predicate _validKey; final _Predicate _validKey;
_CustomHashMap(this._equals, this._hashCode, bool validKey(potentialKey)) _CustomHashMap(this._equals, this._hashCode, bool validKey(potentialKey)?)
: _validKey = (validKey != null) ? validKey : ((v) => v is K); : _validKey = (validKey != null) ? validKey : ((v) => v is K);
V operator [](Object key) { V? operator [](Object? key) {
if (!_validKey(key)) return null; if (!_validKey(key)) return null;
return super._get(key); return super._get(key);
} }
@ -420,12 +420,12 @@ class _CustomHashMap<K, V> extends _HashMap<K, V> {
super._set(key, value); super._set(key, value);
} }
bool containsKey(Object key) { bool containsKey(Object? key) {
if (!_validKey(key)) return false; if (!_validKey(key)) return false;
return super._containsKey(key); return super._containsKey(key);
} }
V remove(Object key) { V? remove(Object? key) {
if (!_validKey(key)) return null; if (!_validKey(key)) return null;
return super._remove(key); return super._remove(key);
} }
@ -458,7 +458,7 @@ class _HashMapKeyIterable<E> extends EfficientLengthIterable<E> {
return new _HashMapKeyIterator<E>(_map, _map._computeKeys()); return new _HashMapKeyIterator<E>(_map, _map._computeKeys());
} }
bool contains(Object element) { bool contains(Object? element) {
return _map.containsKey(element); return _map.containsKey(element);
} }
@ -477,11 +477,11 @@ class _HashMapKeyIterator<E> implements Iterator<E> {
final _map; final _map;
final List _keys; final List _keys;
int _offset = 0; int _offset = 0;
E _current; E? _current;
_HashMapKeyIterator(this._map, this._keys); _HashMapKeyIterator(this._map, this._keys);
E get current => _current; E get current => _current as E;
bool moveNext() { bool moveNext() {
var keys = _keys; var keys = _keys;
@ -506,9 +506,9 @@ class _HashMapKeyIterator<E> implements Iterator<E> {
class LinkedHashMap<K, V> { class LinkedHashMap<K, V> {
@patch @patch
factory LinkedHashMap( factory LinkedHashMap(
{bool equals(K key1, K key2), {bool equals(K key1, K key2)?,
int hashCode(K key), int hashCode(K key)?,
bool isValidKey(potentialKey)}) { bool isValidKey(potentialKey)?}) {
if (isValidKey == null) { if (isValidKey == null) {
if (hashCode == null) { if (hashCode == null) {
if (equals == null) { if (equals == null) {
@ -613,11 +613,11 @@ class _Es6LinkedIdentityHashMap<K, V> extends _LinkedIdentityHashMap<K, V>
Iterable<V> get values => new _Es6MapIterable<V>(this, false); Iterable<V> get values => new _Es6MapIterable<V>(this, false);
bool containsKey(Object key) { bool containsKey(Object? key) {
return JS('bool', '#.has(#)', _map, key); return JS('bool', '#.has(#)', _map, key);
} }
bool containsValue(Object value) { bool containsValue(Object? value) {
return values.any((each) => each == value); return values.any((each) => each == value);
} }
@ -627,7 +627,7 @@ class _Es6LinkedIdentityHashMap<K, V> extends _LinkedIdentityHashMap<K, V>
}); });
} }
V operator [](Object key) { V? operator [](Object? key) {
return JS('var', '#.get(#)', _map, key); return JS('var', '#.get(#)', _map, key);
} }
@ -637,14 +637,14 @@ class _Es6LinkedIdentityHashMap<K, V> extends _LinkedIdentityHashMap<K, V>
} }
V putIfAbsent(K key, V ifAbsent()) { V putIfAbsent(K key, V ifAbsent()) {
if (containsKey(key)) return this[key]; if (containsKey(key)) return this[key] as V;
V value = ifAbsent(); V value = ifAbsent();
this[key] = value; this[key] = value;
return value; return value;
} }
V remove(Object key) { V? remove(Object? key) {
V value = this[key]; V? value = this[key];
JS('bool', '#.delete(#)', _map, key); JS('bool', '#.delete(#)', _map, key);
_modified(); _modified();
return value; return value;
@ -693,7 +693,7 @@ class _Es6MapIterable<E> extends EfficientLengthIterable<E> {
Iterator<E> get iterator => Iterator<E> get iterator =>
new _Es6MapIterator<E>(_map, _map._modifications, _isKeys); new _Es6MapIterator<E>(_map, _map._modifications, _isKeys);
bool contains(Object element) => _map.containsKey(element); bool contains(Object? element) => _map.containsKey(element);
void forEach(void f(E element)) { void forEach(void f(E element)) {
var jsIterator; var jsIterator;
@ -722,8 +722,8 @@ class _Es6MapIterator<E> implements Iterator<E> {
final bool _isKeys; final bool _isKeys;
var _jsIterator; var _jsIterator;
var _next; var _next;
E _current; E? _current;
bool _done; bool _done = false;
_Es6MapIterator(this._map, this._modifications, this._isKeys) { _Es6MapIterator(this._map, this._modifications, this._isKeys) {
if (_isKeys) { if (_isKeys) {
@ -731,10 +731,9 @@ class _Es6MapIterator<E> implements Iterator<E> {
} else { } else {
_jsIterator = JS('var', '#.values()', _map._map); _jsIterator = JS('var', '#.values()', _map._map);
} }
_done = false;
} }
E get current => _current; E get current => _current as E;
bool moveNext() { bool moveNext() {
if (_modifications != _map._modifications) { if (_modifications != _map._modifications) {
@ -761,10 +760,10 @@ class _LinkedCustomHashMap<K, V> extends JsLinkedHashMap<K, V> {
final _Predicate _validKey; final _Predicate _validKey;
_LinkedCustomHashMap( _LinkedCustomHashMap(
this._equals, this._hashCode, bool validKey(potentialKey)) this._equals, this._hashCode, bool validKey(potentialKey)?)
: _validKey = (validKey != null) ? validKey : ((v) => v is K); : _validKey = (validKey != null) ? validKey : ((v) => v is K);
V operator [](Object key) { V? operator [](Object? key) {
if (!_validKey(key)) return null; if (!_validKey(key)) return null;
return super.internalGet(key); return super.internalGet(key);
} }
@ -773,12 +772,12 @@ class _LinkedCustomHashMap<K, V> extends JsLinkedHashMap<K, V> {
super.internalSet(key, value); super.internalSet(key, value);
} }
bool containsKey(Object key) { bool containsKey(Object? key) {
if (!_validKey(key)) return false; if (!_validKey(key)) return false;
return super.internalContainsKey(key); return super.internalContainsKey(key);
} }
V remove(Object key) { V? remove(Object? key) {
if (!_validKey(key)) return null; if (!_validKey(key)) return null;
return super.internalRemove(key); return super.internalRemove(key);
} }
@ -805,9 +804,9 @@ class _LinkedCustomHashMap<K, V> extends JsLinkedHashMap<K, V> {
class HashSet<E> { class HashSet<E> {
@patch @patch
factory HashSet( factory HashSet(
{bool equals(E e1, E e2), {bool equals(E e1, E e2)?,
int hashCode(E e), int hashCode(E e)?,
bool isValidKey(potentialKey)}) { bool isValidKey(potentialKey)?}) {
if (isValidKey == null) { if (isValidKey == null) {
if (hashCode == null) { if (hashCode == null) {
if (equals == null) { if (equals == null) {
@ -858,7 +857,7 @@ class _HashSet<E> extends _SetBase<E> implements HashSet<E> {
// list of all the elements. We cache that on the instance and clear // list of all the elements. We cache that on the instance and clear
// the cache whenever the set changes. This is also used to // the cache whenever the set changes. This is also used to
// guard against concurrent modifications. // guard against concurrent modifications.
List _elements; List? _elements;
_HashSet(); _HashSet();
@ -874,7 +873,7 @@ class _HashSet<E> extends _SetBase<E> implements HashSet<E> {
bool get isEmpty => _length == 0; bool get isEmpty => _length == 0;
bool get isNotEmpty => !isEmpty; bool get isNotEmpty => !isEmpty;
bool contains(Object object) { bool contains(Object? object) {
if (_isStringElement(object)) { if (_isStringElement(object)) {
var strings = _strings; var strings = _strings;
return (strings == null) ? false : _hasTableEntry(strings, object); return (strings == null) ? false : _hasTableEntry(strings, object);
@ -886,21 +885,21 @@ class _HashSet<E> extends _SetBase<E> implements HashSet<E> {
} }
} }
bool _contains(Object object) { bool _contains(Object? object) {
var rest = _rest; var rest = _rest;
if (rest == null) return false; if (rest == null) return false;
var bucket = _getBucket(rest, object); var bucket = _getBucket(rest, object);
return _findBucketIndex(bucket, object) >= 0; return _findBucketIndex(bucket, object) >= 0;
} }
E lookup(Object object) { E? lookup(Object? object) {
if (_isStringElement(object) || _isNumericElement(object)) { if (_isStringElement(object) || _isNumericElement(object)) {
return this.contains(object) ? object : null; return this.contains(object) ? object as E : null;
} }
return _lookup(object); return _lookup(object);
} }
E _lookup(Object object) { E? _lookup(Object? object) {
var rest = _rest; var rest = _rest;
if (rest == null) return null; if (rest == null) return null;
var bucket = _getBucket(rest, object); var bucket = _getBucket(rest, object);
@ -947,7 +946,7 @@ class _HashSet<E> extends _SetBase<E> implements HashSet<E> {
} }
} }
bool remove(Object object) { bool remove(Object? object) {
if (_isStringElement(object)) { if (_isStringElement(object)) {
return _removeHashTableEntry(_strings, object); return _removeHashTableEntry(_strings, object);
} else if (_isNumericElement(object)) { } else if (_isNumericElement(object)) {
@ -957,7 +956,7 @@ class _HashSet<E> extends _SetBase<E> implements HashSet<E> {
} }
} }
bool _remove(Object object) { bool _remove(Object? object) {
var rest = _rest; var rest = _rest;
if (rest == null) return false; if (rest == null) return false;
var hash = _computeHashCode(object); var hash = _computeHashCode(object);
@ -985,8 +984,9 @@ class _HashSet<E> extends _SetBase<E> implements HashSet<E> {
} }
List _computeElements() { List _computeElements() {
if (_elements != null) return _elements; var result = _elements;
List result = new List(_length); if (result != null) return result;
result = List.filled(_length, null);
int index = 0; int index = 0;
// Add all string elements to the list. // Add all string elements to the list.
@ -1031,7 +1031,8 @@ class _HashSet<E> extends _SetBase<E> implements HashSet<E> {
} }
} }
assert(index == _length); assert(index == _length);
return _elements = result; _elements = result;
return result;
} }
bool _addHashTableEntry(var table, E element) { bool _addHashTableEntry(var table, E element) {
@ -1042,7 +1043,7 @@ class _HashSet<E> extends _SetBase<E> implements HashSet<E> {
return true; return true;
} }
bool _removeHashTableEntry(var table, Object element) { bool _removeHashTableEntry(var table, Object? element) {
if (table != null && _hasTableEntry(table, element)) { if (table != null && _hasTableEntry(table, element)) {
_deleteTableEntry(table, element); _deleteTableEntry(table, element);
_length--; _length--;
@ -1143,7 +1144,7 @@ class _CustomHashSet<E> extends _HashSet<E> {
_Equality<E> _equality; _Equality<E> _equality;
_Hasher<E> _hasher; _Hasher<E> _hasher;
_Predicate _validKey; _Predicate _validKey;
_CustomHashSet(this._equality, this._hasher, bool validKey(potentialKey)) _CustomHashSet(this._equality, this._hasher, bool validKey(potentialKey)?)
: _validKey = (validKey != null) ? validKey : ((x) => x is E); : _validKey = (validKey != null) ? validKey : ((x) => x is E);
Set<E> _newSet() => new _CustomHashSet<E>(_equality, _hasher, _validKey); Set<E> _newSet() => new _CustomHashSet<E>(_equality, _hasher, _validKey);
@ -1168,17 +1169,17 @@ class _CustomHashSet<E> extends _HashSet<E> {
bool add(E object) => super._add(object); bool add(E object) => super._add(object);
bool contains(Object object) { bool contains(Object? object) {
if (!_validKey(object)) return false; if (!_validKey(object)) return false;
return super._contains(object); return super._contains(object);
} }
E lookup(Object object) { E? lookup(Object? object) {
if (!_validKey(object)) return null; if (!_validKey(object)) return null;
return super._lookup(object); return super._lookup(object);
} }
bool remove(Object object) { bool remove(Object? object) {
if (!_validKey(object)) return false; if (!_validKey(object)) return false;
return super._remove(object); return super._remove(object);
} }
@ -1189,11 +1190,11 @@ class _HashSetIterator<E> implements Iterator<E> {
final _set; final _set;
final List _elements; final List _elements;
int _offset = 0; int _offset = 0;
E _current; E? _current;
_HashSetIterator(this._set, this._elements); _HashSetIterator(this._set, this._elements);
E get current => _current; E get current => _current as E;
bool moveNext() { bool moveNext() {
var elements = _elements; var elements = _elements;
@ -1218,9 +1219,9 @@ class _HashSetIterator<E> implements Iterator<E> {
class LinkedHashSet<E> { class LinkedHashSet<E> {
@patch @patch
factory LinkedHashSet( factory LinkedHashSet(
{bool equals(E e1, E e2), {bool equals(E e1, E e2)?,
int hashCode(E e), int hashCode(E e)?,
bool isValidKey(potentialKey)}) { bool isValidKey(potentialKey)?}) {
if (isValidKey == null) { if (isValidKey == null) {
if (hashCode == null) { if (hashCode == null) {
if (equals == null) { if (equals == null) {
@ -1293,8 +1294,8 @@ class _LinkedHashSet<E> extends _SetBase<E> implements LinkedHashSet<E> {
// The elements are stored in cells that are linked together // The elements are stored in cells that are linked together
// to form a double linked list. // to form a double linked list.
_LinkedHashSetCell _first; _LinkedHashSetCell? _first;
_LinkedHashSetCell _last; _LinkedHashSetCell? _last;
// We track the number of modifications done to the element set to // We track the number of modifications done to the element set to
// be able to throw when the set is modified while being iterated // be able to throw when the set is modified while being iterated
@ -1319,38 +1320,38 @@ class _LinkedHashSet<E> extends _SetBase<E> implements LinkedHashSet<E> {
bool get isEmpty => _length == 0; bool get isEmpty => _length == 0;
bool get isNotEmpty => !isEmpty; bool get isNotEmpty => !isEmpty;
bool contains(Object object) { bool contains(Object? object) {
if (_isStringElement(object)) { if (_isStringElement(object)) {
var strings = _strings; var strings = _strings;
if (strings == null) return false; if (strings == null) return false;
_LinkedHashSetCell cell = _getTableEntry(strings, object); _LinkedHashSetCell? cell = _getTableEntry(strings, object);
return cell != null; return cell != null;
} else if (_isNumericElement(object)) { } else if (_isNumericElement(object)) {
var nums = _nums; var nums = _nums;
if (nums == null) return false; if (nums == null) return false;
_LinkedHashSetCell cell = _getTableEntry(nums, object); _LinkedHashSetCell? cell = _getTableEntry(nums, object);
return cell != null; return cell != null;
} else { } else {
return _contains(object); return _contains(object);
} }
} }
bool _contains(Object object) { bool _contains(Object? object) {
var rest = _rest; var rest = _rest;
if (rest == null) return false; if (rest == null) return false;
var bucket = _getBucket(rest, object); var bucket = _getBucket(rest, object);
return _findBucketIndex(bucket, object) >= 0; return _findBucketIndex(bucket, object) >= 0;
} }
E lookup(Object object) { E? lookup(Object? object) {
if (_isStringElement(object) || _isNumericElement(object)) { if (_isStringElement(object) || _isNumericElement(object)) {
return this.contains(object) ? object : null; return this.contains(object) ? object as E : null;
} else { } else {
return _lookup(object); return _lookup(object);
} }
} }
E _lookup(Object object) { E? _lookup(Object? object) {
var rest = _rest; var rest = _rest;
if (rest == null) return null; if (rest == null) return null;
var bucket = _getBucket(rest, object); var bucket = _getBucket(rest, object);
@ -1360,7 +1361,7 @@ class _LinkedHashSet<E> extends _SetBase<E> implements LinkedHashSet<E> {
} }
void forEach(void action(E element)) { void forEach(void action(E element)) {
_LinkedHashSetCell cell = _first; _LinkedHashSetCell? cell = _first;
int modifications = _modifications; int modifications = _modifications;
while (cell != null) { while (cell != null) {
action(cell._element); action(cell._element);
@ -1372,13 +1373,15 @@ class _LinkedHashSet<E> extends _SetBase<E> implements LinkedHashSet<E> {
} }
E get first { E get first {
if (_first == null) throw new StateError("No elements"); var first = _first;
return _first._element; if (first == null) throw new StateError("No elements");
return first._element;
} }
E get last { E get last {
if (_last == null) throw new StateError("No elements"); var last = _last;
return _last._element; if (last == null) throw new StateError("No elements");
return last._element;
} }
// Collection. // Collection.
@ -1413,7 +1416,7 @@ class _LinkedHashSet<E> extends _SetBase<E> implements LinkedHashSet<E> {
return true; return true;
} }
bool remove(Object object) { bool remove(Object? object) {
if (_isStringElement(object)) { if (_isStringElement(object)) {
return _removeHashTableEntry(_strings, object); return _removeHashTableEntry(_strings, object);
} else if (_isNumericElement(object)) { } else if (_isNumericElement(object)) {
@ -1423,7 +1426,7 @@ class _LinkedHashSet<E> extends _SetBase<E> implements LinkedHashSet<E> {
} }
} }
bool _remove(Object object) { bool _remove(Object? object) {
var rest = _rest; var rest = _rest;
if (rest == null) return false; if (rest == null) return false;
var hash = _computeHashCode(object); var hash = _computeHashCode(object);
@ -1448,10 +1451,10 @@ class _LinkedHashSet<E> extends _SetBase<E> implements LinkedHashSet<E> {
} }
void _filterWhere(bool test(E element), bool removeMatching) { void _filterWhere(bool test(E element), bool removeMatching) {
_LinkedHashSetCell cell = _first; _LinkedHashSetCell? cell = _first;
while (cell != null) { while (cell != null) {
E element = cell._element; E element = cell._element;
_LinkedHashSetCell next = cell._next; _LinkedHashSetCell? next = cell._next;
int modifications = _modifications; int modifications = _modifications;
bool shouldRemove = (removeMatching == test(element)); bool shouldRemove = (removeMatching == test(element));
if (modifications != _modifications) { if (modifications != _modifications) {
@ -1471,15 +1474,15 @@ class _LinkedHashSet<E> extends _SetBase<E> implements LinkedHashSet<E> {
} }
bool _addHashTableEntry(var table, E element) { bool _addHashTableEntry(var table, E element) {
_LinkedHashSetCell cell = _getTableEntry(table, element); _LinkedHashSetCell? cell = _getTableEntry(table, element);
if (cell != null) return false; if (cell != null) return false;
_setTableEntry(table, element, _newLinkedCell(element)); _setTableEntry(table, element, _newLinkedCell(element));
return true; return true;
} }
bool _removeHashTableEntry(var table, Object element) { bool _removeHashTableEntry(var table, Object? element) {
if (table == null) return false; if (table == null) return false;
_LinkedHashSetCell cell = _getTableEntry(table, element); _LinkedHashSetCell? cell = _getTableEntry(table, element);
if (cell == null) return false; if (cell == null) return false;
_unlinkCell(cell); _unlinkCell(cell);
_deleteTableEntry(table, element); _deleteTableEntry(table, element);
@ -1499,7 +1502,7 @@ class _LinkedHashSet<E> extends _SetBase<E> implements LinkedHashSet<E> {
if (_first == null) { if (_first == null) {
_first = _last = cell; _first = _last = cell;
} else { } else {
_LinkedHashSetCell last = _last; _LinkedHashSetCell last = _last!;
cell._previous = last; cell._previous = last;
_last = last._next = cell; _last = last._next = cell;
} }
@ -1510,8 +1513,8 @@ class _LinkedHashSet<E> extends _SetBase<E> implements LinkedHashSet<E> {
// Unlink the given cell from the linked list of cells. // Unlink the given cell from the linked list of cells.
void _unlinkCell(_LinkedHashSetCell cell) { void _unlinkCell(_LinkedHashSetCell cell) {
_LinkedHashSetCell previous = cell._previous; _LinkedHashSetCell? previous = cell._previous;
_LinkedHashSetCell next = cell._next; _LinkedHashSetCell? next = cell._next;
if (previous == null) { if (previous == null) {
assert(cell == _first); assert(cell == _first);
_first = next; _first = next;
@ -1617,7 +1620,7 @@ class _LinkedCustomHashSet<E> extends _LinkedHashSet<E> {
_Hasher<E> _hasher; _Hasher<E> _hasher;
_Predicate _validKey; _Predicate _validKey;
_LinkedCustomHashSet( _LinkedCustomHashSet(
this._equality, this._hasher, bool validKey(potentialKey)) this._equality, this._hasher, bool validKey(potentialKey)?)
: _validKey = (validKey != null) ? validKey : ((x) => x is E); : _validKey = (validKey != null) ? validKey : ((x) => x is E);
Set<E> _newSet() => Set<E> _newSet() =>
@ -1644,30 +1647,30 @@ class _LinkedCustomHashSet<E> extends _LinkedHashSet<E> {
bool add(E element) => super._add(element); bool add(E element) => super._add(element);
bool contains(Object object) { bool contains(Object? object) {
if (!_validKey(object)) return false; if (!_validKey(object)) return false;
return super._contains(object); return super._contains(object);
} }
E lookup(Object object) { E? lookup(Object? object) {
if (!_validKey(object)) return null; if (!_validKey(object)) return null;
return super._lookup(object); return super._lookup(object);
} }
bool remove(Object object) { bool remove(Object? object) {
if (!_validKey(object)) return false; if (!_validKey(object)) return false;
return super._remove(object); return super._remove(object);
} }
bool containsAll(Iterable<Object> elements) { bool containsAll(Iterable<Object?> elements) {
for (Object element in elements) { for (Object? element in elements) {
if (!_validKey(element) || !this.contains(element)) return false; if (!_validKey(element) || !this.contains(element)) return false;
} }
return true; return true;
} }
void removeAll(Iterable<Object> elements) { void removeAll(Iterable<Object?> elements) {
for (Object element in elements) { for (Object? element in elements) {
if (_validKey(element)) { if (_validKey(element)) {
super._remove(element); super._remove(element);
} }
@ -1678,8 +1681,8 @@ class _LinkedCustomHashSet<E> extends _LinkedHashSet<E> {
class _LinkedHashSetCell { class _LinkedHashSetCell {
final _element; final _element;
_LinkedHashSetCell _next; _LinkedHashSetCell? _next;
_LinkedHashSetCell _previous; _LinkedHashSetCell? _previous;
_LinkedHashSetCell(this._element); _LinkedHashSetCell(this._element);
} }
@ -1688,52 +1691,26 @@ class _LinkedHashSetCell {
class _LinkedHashSetIterator<E> implements Iterator<E> { class _LinkedHashSetIterator<E> implements Iterator<E> {
final _set; final _set;
final int _modifications; final int _modifications;
_LinkedHashSetCell _cell; _LinkedHashSetCell? _cell;
E _current; E? _current;
_LinkedHashSetIterator(this._set, this._modifications) { _LinkedHashSetIterator(this._set, this._modifications) {
_cell = _set._first; _cell = _set._first;
} }
E get current => _current; E get current => _current as E;
bool moveNext() { bool moveNext() {
var cell = _cell;
if (_modifications != _set._modifications) { if (_modifications != _set._modifications) {
throw new ConcurrentModificationError(_set); throw new ConcurrentModificationError(_set);
} else if (_cell == null) { } else if (cell == null) {
_current = null; _current = null;
return false; return false;
} else { } else {
_current = _cell._element; _current = cell._element;
_cell = _cell._next; _cell = cell._next;
return true; return true;
} }
} }
} }
@patch
abstract class _SplayTree<K, Node extends _SplayTreeNode<K>> {
@patch
Node _splayMin(Node node) {
Node current = node;
while (current.left != null) {
Node left = current.left;
current.left = left.right;
left.right = current;
current = left;
}
return current;
}
@patch
Node _splayMax(Node node) {
Node current = node;
while (current.right != null) {
Node right = current.right;
current.right = right.left;
right.left = current;
current = right;
}
return current;
}
}

View file

@ -2,8 +2,6 @@
// for details. All rights reserved. Use of this source code is governed by a // for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file. // BSD-style license that can be found in the LICENSE file.
// @dart = 2.6
part of _js_helper; part of _js_helper;
class ConstantMapView<K, V> extends UnmodifiableMapView<K, V> class ConstantMapView<K, V> extends UnmodifiableMapView<K, V>
@ -14,7 +12,7 @@ class ConstantMapView<K, V> extends UnmodifiableMapView<K, V>
abstract class ConstantMap<K, V> implements Map<K, V> { abstract class ConstantMap<K, V> implements Map<K, V> {
// Used to create unmodifiable maps from other maps. // Used to create unmodifiable maps from other maps.
factory ConstantMap.from(Map other) { factory ConstantMap.from(Map other) {
List keys = new List<K>.from(other.keys); var keys = new List<K>.from(other.keys);
bool allStrings = true; bool allStrings = true;
for (var k in keys) { for (var k in keys) {
if (k is! String) { if (k is! String) {
@ -30,7 +28,7 @@ abstract class ConstantMap<K, V> implements Map<K, V> {
for (var k in keys) { for (var k in keys) {
V v = other[k]; V v = other[k];
if (k != '__proto__') { if (k != '__proto__') {
if (!jsHasOwnProperty(object, k)) length++; if (!jsHasOwnProperty(object, k as String)) length++;
JS('void', '#[#] = #', object, k, v); JS('void', '#[#] = #', object, k, v);
} else { } else {
containsProto = true; containsProto = true;
@ -56,18 +54,27 @@ abstract class ConstantMap<K, V> implements Map<K, V> {
String toString() => MapBase.mapToString(this); String toString() => MapBase.mapToString(this);
static Null _throwUnmodifiable() { static Never _throwUnmodifiable() {
throw new UnsupportedError('Cannot modify unmodifiable Map'); throw new UnsupportedError('Cannot modify unmodifiable Map');
} }
void operator []=(K key, V val) => _throwUnmodifiable(); void operator []=(K key, V val) {
V putIfAbsent(K key, V ifAbsent()) => _throwUnmodifiable(); _throwUnmodifiable();
V remove(Object key) => _throwUnmodifiable(); }
V putIfAbsent(K key, V ifAbsent()) {
_throwUnmodifiable();
}
V? remove(Object? key) {
_throwUnmodifiable();
}
void clear() => _throwUnmodifiable(); void clear() => _throwUnmodifiable();
void addAll(Map<K, V> other) => _throwUnmodifiable(); void addAll(Map<K, V> other) => _throwUnmodifiable();
Iterable<MapEntry<K, V>> get entries sync* { Iterable<MapEntry<K, V>> get entries sync* {
for (var key in keys) yield new MapEntry<K, V>(key, this[key]); for (var key in keys) yield new MapEntry<K, V>(key, this[key]!);
} }
void addEntries(Iterable<MapEntry<K, V>> entries) { void addEntries(Iterable<MapEntry<K, V>> entries) {
@ -83,7 +90,7 @@ abstract class ConstantMap<K, V> implements Map<K, V> {
return result; return result;
} }
V update(K key, V update(V value), {V ifAbsent()}) { V update(K key, V update(V value), {V ifAbsent()?}) {
_throwUnmodifiable(); _throwUnmodifiable();
} }
@ -111,17 +118,17 @@ class ConstantStringMap<K, V> extends ConstantMap<K, V> {
int get length => JS('JSUInt31', '#', _length); int get length => JS('JSUInt31', '#', _length);
List<K> get _keysArray => JS('JSUnmodifiableArray', '#', _keys); List<K> get _keysArray => JS('JSUnmodifiableArray', '#', _keys);
bool containsValue(Object needle) { bool containsValue(Object? needle) {
return values.any((V value) => value == needle); return values.any((V value) => value == needle);
} }
bool containsKey(Object key) { bool containsKey(Object? key) {
if (key is! String) return false; if (key is! String) return false;
if ('__proto__' == key) return false; if ('__proto__' == key) return false;
return jsHasOwnProperty(_jsObject, key); return jsHasOwnProperty(_jsObject, key);
} }
V operator [](Object key) { V? operator [](Object? key) {
if (!containsKey(key)) return null; if (!containsKey(key)) return null;
return JS('', '#', _fetch(key)); return JS('', '#', _fetch(key));
} }
@ -157,7 +164,7 @@ class ConstantProtoMap<K, V> extends ConstantStringMap<K, V> {
final V _protoValue; final V _protoValue;
bool containsKey(Object key) { bool containsKey(Object? key) {
if (key is! String) return false; if (key is! String) return false;
if ('__proto__' == key) return true; if ('__proto__' == key) return true;
return jsHasOwnProperty(_jsObject, key); return jsHasOwnProperty(_jsObject, key);
@ -187,7 +194,7 @@ class GeneralConstantMap<K, V> extends ConstantMap<K, V> {
// We cannot create the backing map on creation since hashCode interceptors // We cannot create the backing map on creation since hashCode interceptors
// have not been defined when constants are created. // have not been defined when constants are created.
Map<K, V> _getMap() { Map<K, V> _getMap() {
LinkedHashMap<K, V> backingMap = JS('LinkedHashMap|Null', r'#.$map', this); LinkedHashMap<K, V>? backingMap = JS('LinkedHashMap|Null', r'#.$map', this);
if (backingMap == null) { if (backingMap == null) {
backingMap = new JsLinkedHashMap<K, V>(); backingMap = new JsLinkedHashMap<K, V>();
fillLiteralMap(_jsData, backingMap); fillLiteralMap(_jsData, backingMap);
@ -196,15 +203,15 @@ class GeneralConstantMap<K, V> extends ConstantMap<K, V> {
return backingMap; return backingMap;
} }
bool containsValue(Object needle) { bool containsValue(Object? needle) {
return _getMap().containsValue(needle); return _getMap().containsValue(needle);
} }
bool containsKey(Object key) { bool containsKey(Object? key) {
return _getMap().containsKey(key); return _getMap().containsKey(key);
} }
V operator [](Object key) { V? operator [](Object? key) {
return _getMap()[key]; return _getMap()[key];
} }

View file

@ -2,8 +2,6 @@
// for details. All rights reserved. Use of this source code is governed by a // for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file. // BSD-style license that can be found in the LICENSE file.
// @dart = 2.6
// Patch file for dart:convert library. // Patch file for dart:convert library.
import 'dart:_js_helper' show argumentErrorValue, patch; import 'dart:_js_helper' show argumentErrorValue, patch;
@ -28,7 +26,7 @@ import 'dart:_native_typed_data' show NativeUint8List;
/// ///
/// Throws [FormatException] if the input is not valid JSON text. /// Throws [FormatException] if the input is not valid JSON text.
@patch @patch
_parseJson(String source, reviver(key, value)) { _parseJson(String source, reviver(key, value)?) {
if (source is! String) throw argumentErrorValue(source); if (source is! String) throw argumentErrorValue(source);
var parsed; var parsed;
@ -36,7 +34,7 @@ _parseJson(String source, reviver(key, value)) {
parsed = JS('=Object|JSExtendableArray|Null|bool|num|String', parsed = JS('=Object|JSExtendableArray|Null|bool|num|String',
'JSON.parse(#)', source); 'JSON.parse(#)', source);
} catch (e) { } catch (e) {
throw new FormatException(JS('String', 'String(#)', e)); throw FormatException(JS<String>('String', 'String(#)', e));
} }
if (reviver == null) { if (reviver == null) {
@ -49,20 +47,20 @@ _parseJson(String source, reviver(key, value)) {
/// Walks the raw JavaScript value [json], replacing JavaScript Objects with /// Walks the raw JavaScript value [json], replacing JavaScript Objects with
/// Maps. [json] is expected to be freshly allocated so elements can be replaced /// Maps. [json] is expected to be freshly allocated so elements can be replaced
/// in-place. /// in-place.
_convertJsonToDart(json, reviver(key, value)) { _convertJsonToDart(json, reviver(Object? key, Object? value)) {
assert(reviver != null);
walk(e) { walk(e) {
// JavaScript null, string, number, bool are in the correct representation. // JavaScript null, string, number, bool are in the correct representation.
if (JS('bool', '# == null', e) || JS('bool', 'typeof # != "object"', e)) { if (JS<bool>('bool', '# == null', e) ||
JS<bool>('bool', 'typeof # != "object"', e)) {
return e; return e;
} }
// This test is needed to avoid identifying '{"__proto__":[]}' as an Array. // This test is needed to avoid identifying '{"__proto__":[]}' as an Array.
// TODO(sra): Replace this test with cheaper '#.constructor === Array' when // TODO(sra): Replace this test with cheaper '#.constructor === Array' when
// bug 621 below is fixed. // bug 621 below is fixed.
if (JS('bool', 'Object.getPrototypeOf(#) === Array.prototype', e)) { if (JS<bool>('bool', 'Object.getPrototypeOf(#) === Array.prototype', e)) {
// In-place update of the elements since JS Array is a Dart List. // In-place update of the elements since JS Array is a Dart List.
for (int i = 0; i < JS('int', '#.length', e); i++) { for (int i = 0; i < JS<int>('int', '#.length', e); i++) {
// Use JS indexing to avoid range checks. We know this is the only // Use JS indexing to avoid range checks. We know this is the only
// reference to the list, but the compiler will likely never be able to // reference to the list, but the compiler will likely never be able to
// tell that this instance of the list cannot have its length changed by // tell that this instance of the list cannot have its length changed by
@ -76,7 +74,7 @@ _convertJsonToDart(json, reviver(key, value)) {
// Otherwise it is a plain object, so copy to a JSON map, so we process // Otherwise it is a plain object, so copy to a JSON map, so we process
// and revive all entries recursively. // and revive all entries recursively.
_JsonMap map = new _JsonMap(e); _JsonMap map = _JsonMap(e);
var processed = map._processed; var processed = map._processed;
List<String> keys = map._computeKeys(); List<String> keys = map._computeKeys();
for (int i = 0; i < keys.length; i++) { for (int i = 0; i < keys.length; i++) {
@ -98,19 +96,20 @@ _convertJsonToDartLazy(object) {
if (object == null) return null; if (object == null) return null;
// JavaScript string, number, bool already has the correct representation. // JavaScript string, number, bool already has the correct representation.
if (JS('bool', 'typeof # != "object"', object)) { if (JS<bool>('bool', 'typeof # != "object"', object)) {
return object; return object;
} }
// This test is needed to avoid identifying '{"__proto__":[]}' as an array. // This test is needed to avoid identifying '{"__proto__":[]}' as an array.
// TODO(sra): Replace this test with cheaper '#.constructor === Array' when // TODO(sra): Replace this test with cheaper '#.constructor === Array' when
// bug https://code.google.com/p/v8/issues/detail?id=621 is fixed. // bug https://code.google.com/p/v8/issues/detail?id=621 is fixed.
if (JS('bool', 'Object.getPrototypeOf(#) !== Array.prototype', object)) { if (JS<bool>(
return new _JsonMap(object); 'bool', 'Object.getPrototypeOf(#) !== Array.prototype', object)) {
return _JsonMap(object);
} }
// Update the elements in place since JS arrays are Dart lists. // Update the elements in place since JS arrays are Dart lists.
for (int i = 0; i < JS('int', '#.length', object); i++) { for (int i = 0; i < JS<int>('int', '#.length', object); i++) {
// Use JS indexing to avoid range checks. We know this is the only // Use JS indexing to avoid range checks. We know this is the only
// reference to the list, but the compiler will likely never be able to // reference to the list, but the compiler will likely never be able to
// tell that this instance of the list cannot have its length changed by // tell that this instance of the list cannot have its length changed by
@ -157,12 +156,12 @@ class _JsonMap extends MapBase<String, dynamic> {
Iterable<String> get keys { Iterable<String> get keys {
if (_isUpgraded) return _upgradedMap.keys; if (_isUpgraded) return _upgradedMap.keys;
return new _JsonMapKeyIterable(this); return _JsonMapKeyIterable(this);
} }
Iterable get values { Iterable get values {
if (_isUpgraded) return _upgradedMap.values; if (_isUpgraded) return _upgradedMap.values;
return new MappedIterable(_computeKeys(), (each) => this[each]); return MappedIterable(_computeKeys(), (each) => this[each]);
} }
operator []=(key, value) { operator []=(key, value) {
@ -209,7 +208,7 @@ class _JsonMap extends MapBase<String, dynamic> {
return value; return value;
} }
remove(Object key) { remove(Object? key) {
if (!_isUpgraded && !containsKey(key)) return null; if (!_isUpgraded && !containsKey(key)) return null;
return _upgrade().remove(key); return _upgrade().remove(key);
} }
@ -249,7 +248,7 @@ class _JsonMap extends MapBase<String, dynamic> {
// Check if invoking the callback function changed // Check if invoking the callback function changed
// the key set. If so, throw an exception. // the key set. If so, throw an exception.
if (!identical(keys, _data)) { if (!identical(keys, _data)) {
throw new ConcurrentModificationError(this); throw ConcurrentModificationError(this);
} }
} }
} }
@ -270,7 +269,7 @@ class _JsonMap extends MapBase<String, dynamic> {
List<String> _computeKeys() { List<String> _computeKeys() {
assert(!_isUpgraded); assert(!_isUpgraded);
List keys = _data; List? keys = _data;
if (keys == null) { if (keys == null) {
keys = _data = new JSArray<String>.typed(_getPropertyNames(_original)); keys = _data = new JSArray<String>.typed(_getPropertyNames(_original));
} }
@ -293,7 +292,7 @@ class _JsonMap extends MapBase<String, dynamic> {
// safely force a concurrent modification error in case // safely force a concurrent modification error in case
// someone is iterating over the map here. // someone is iterating over the map here.
if (keys.isEmpty) { if (keys.isEmpty) {
keys.add(null); keys.add("");
} else { } else {
keys.clear(); keys.clear();
} }
@ -316,15 +315,15 @@ class _JsonMap extends MapBase<String, dynamic> {
// Private JavaScript helper methods. // Private JavaScript helper methods.
// ------------------------------------------ // ------------------------------------------
static bool _hasProperty(object, String key) => static bool _hasProperty(object, String key) => JS<bool>(
JS('bool', 'Object.prototype.hasOwnProperty.call(#,#)', object, key); 'bool', 'Object.prototype.hasOwnProperty.call(#,#)', object, key);
static _getProperty(object, String key) => JS('', '#[#]', object, key); static _getProperty(object, String key) => JS('', '#[#]', object, key);
static _setProperty(object, String key, value) => static _setProperty(object, String key, value) =>
JS('', '#[#]=#', object, key, value); JS('', '#[#]=#', object, key, value);
static List _getPropertyNames(object) => static List _getPropertyNames(object) =>
JS('JSExtendableArray', 'Object.keys(#)', object); JS('JSExtendableArray', 'Object.keys(#)', object);
static bool _isUnprocessed(object) => static bool _isUnprocessed(object) =>
JS('bool', 'typeof(#)=="undefined"', object); JS<bool>('bool', 'typeof(#)=="undefined"', object);
static _newJavaScriptObject() => JS('=Object', 'Object.create(null)'); static _newJavaScriptObject() => JS('=Object', 'Object.create(null)');
} }
@ -352,14 +351,14 @@ class _JsonMapKeyIterable extends ListIterable<String> {
/// Delegate to [parent.containsKey] to ensure the performance expected /// Delegate to [parent.containsKey] to ensure the performance expected
/// from [Map.keys.containsKey]. /// from [Map.keys.containsKey].
bool contains(Object key) => _parent.containsKey(key); bool contains(Object? key) => _parent.containsKey(key);
} }
@patch @patch
class JsonDecoder { class JsonDecoder {
@patch @patch
StringConversionSink startChunkedConversion(Sink<Object> sink) { StringConversionSink startChunkedConversion(Sink<Object?> sink) {
return new _JsonDecoderSink(_reviver, sink); return _JsonDecoderSink(_reviver, sink);
} }
} }
@ -368,18 +367,17 @@ class JsonDecoder {
/// ///
/// The sink only creates one object, but its input can be chunked. /// The sink only creates one object, but its input can be chunked.
// TODO(floitsch): don't accumulate everything before starting to decode. // TODO(floitsch): don't accumulate everything before starting to decode.
class _JsonDecoderSink extends _StringSinkConversionSink { class _JsonDecoderSink extends _StringSinkConversionSink<StringBuffer> {
final Function(Object key, Object value) _reviver; final Object? Function(Object? key, Object? value)? _reviver;
final Sink<Object> _sink; final Sink<Object?> _sink;
_JsonDecoderSink(this._reviver, this._sink) : super(new StringBuffer('')); _JsonDecoderSink(this._reviver, this._sink) : super(StringBuffer(''));
void close() { void close() {
super.close(); super.close();
StringBuffer buffer = _stringSink; String accumulated = _stringSink.toString();
String accumulated = buffer.toString(); _stringSink.clear();
buffer.clear(); Object? decoded = _parseJson(accumulated, _reviver);
Object decoded = _parseJson(accumulated, _reviver);
_sink.add(decoded); _sink.add(decoded);
_sink.close(); _sink.close();
} }
@ -397,19 +395,20 @@ class Utf8Decoder {
} }
@patch @patch
static String _convertIntercepted( static String? _convertIntercepted(
bool allowMalformed, List<int> codeUnits, int start, int end) { bool allowMalformed, List<int> codeUnits, int start, int? end) {
// Test `codeUnits is NativeUint8List`. Dart's NativeUint8List is // Test `codeUnits is NativeUint8List`. Dart's NativeUint8List is
// implemented by JavaScript's Uint8Array. // implemented by JavaScript's Uint8Array.
if (JS('bool', '# instanceof Uint8Array', codeUnits)) { if (JS<bool>('bool', '# instanceof Uint8Array', codeUnits)) {
// JS 'cast' to avoid a downcast equivalent to the is-check we hand-coded. // JS 'cast' to avoid a downcast equivalent to the is-check we hand-coded.
NativeUint8List casted = JS('NativeUint8List', '#', codeUnits); NativeUint8List casted =
JS<NativeUint8List>('NativeUint8List', '#', codeUnits);
// Always use Dart implementation for short strings. // Always use Dart implementation for short strings.
end ??= casted.length; end ??= casted.length;
if (end - start < _shortInputThreshold) { if (end - start < _shortInputThreshold) {
return null; return null;
} }
String result = String? result =
_convertInterceptedUint8List(allowMalformed, casted, start, end); _convertInterceptedUint8List(allowMalformed, casted, start, end);
if (result != null && allowMalformed) { if (result != null && allowMalformed) {
// In principle, TextDecoder should have provided the correct result // In principle, TextDecoder should have provided the correct result
@ -425,7 +424,7 @@ class Utf8Decoder {
return null; // This call was not intercepted. return null; // This call was not intercepted.
} }
static String _convertInterceptedUint8List( static String? _convertInterceptedUint8List(
bool allowMalformed, NativeUint8List codeUnits, int start, int end) { bool allowMalformed, NativeUint8List codeUnits, int start, int end) {
final decoder = allowMalformed ? _decoderNonfatal : _decoder; final decoder = allowMalformed ? _decoderNonfatal : _decoder;
if (decoder == null) return null; if (decoder == null) return null;
@ -436,16 +435,18 @@ class Utf8Decoder {
int length = codeUnits.length; int length = codeUnits.length;
end = RangeError.checkValidRange(start, end, length); end = RangeError.checkValidRange(start, end, length);
return _useTextDecoder(decoder, return _useTextDecoder(
JS('NativeUint8List', '#.subarray(#, #)', codeUnits, start, end)); decoder,
JS<NativeUint8List>(
'NativeUint8List', '#.subarray(#, #)', codeUnits, start, end));
} }
static String _useTextDecoder(decoder, NativeUint8List codeUnits) { static String? _useTextDecoder(decoder, NativeUint8List codeUnits) {
// If the input is malformed, catch the exception and return `null` to fall // If the input is malformed, catch the exception and return `null` to fall
// back on unintercepted decoder. The fallback will either succeed in // back on unintercepted decoder. The fallback will either succeed in
// decoding, or report the problem better than TextDecoder. // decoding, or report the problem better than TextDecoder.
try { try {
return JS('String', '#.decode(#)', decoder, codeUnits); return JS<String>('String', '#.decode(#)', decoder, codeUnits);
} catch (e) {} } catch (e) {}
return null; return null;
} }
@ -472,12 +473,12 @@ class _Utf8Decoder {
_Utf8Decoder(this.allowMalformed) : _state = beforeBom; _Utf8Decoder(this.allowMalformed) : _state = beforeBom;
@patch @patch
String convertSingle(List<int> codeUnits, int start, int maybeEnd) { String convertSingle(List<int> codeUnits, int start, int? maybeEnd) {
return convertGeneral(codeUnits, start, maybeEnd, true); return convertGeneral(codeUnits, start, maybeEnd, true);
} }
@patch @patch
String convertChunked(List<int> codeUnits, int start, int maybeEnd) { String convertChunked(List<int> codeUnits, int start, int? maybeEnd) {
return convertGeneral(codeUnits, start, maybeEnd, false); return convertGeneral(codeUnits, start, maybeEnd, false);
} }
} }

View file

@ -2,8 +2,6 @@
// for details. All rights reserved. Use of this source code is governed by a // for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file. // BSD-style license that can be found in the LICENSE file.
// @dart = 2.6
// Patch file for dart:core classes. // Patch file for dart:core classes.
import "dart:_internal" hide Symbol, LinkedList, LinkedListEntry; import "dart:_internal" hide Symbol, LinkedList, LinkedListEntry;
import "dart:_internal" as _symbol_dev; import "dart:_internal" as _symbol_dev;
@ -34,9 +32,10 @@ import "dart:convert" show Encoding, utf8;
import 'dart:typed_data' show Endian, Uint8List, Uint16List; import 'dart:typed_data' show Endian, Uint8List, Uint16List;
String _symbolToString(Symbol symbol) => _symbol_dev.Symbol.getName(symbol); String _symbolToString(Symbol symbol) =>
_symbol_dev.Symbol.getName(symbol as _symbol_dev.Symbol);
Map<String, dynamic> _symbolMapToStringMap(Map<Symbol, dynamic> map) { Map<String, dynamic>? _symbolMapToStringMap(Map<Symbol, dynamic>? map) {
if (map == null) return null; if (map == null) return null;
var result = new Map<String, dynamic>(); var result = new Map<String, dynamic>();
map.forEach((Symbol key, value) { map.forEach((Symbol key, value) {
@ -46,13 +45,13 @@ Map<String, dynamic> _symbolMapToStringMap(Map<Symbol, dynamic> map) {
} }
@patch @patch
int identityHashCode(Object object) => objectHashCode(object); int identityHashCode(Object? object) => objectHashCode(object);
// Patch for Object implementation. // Patch for Object implementation.
@patch @patch
class Object { class Object {
@patch @patch
bool operator ==(other) => identical(this, other); bool operator ==(Object other) => identical(this, other);
@patch @patch
int get hashCode => Primitives.objectHashCode(this); int get hashCode => Primitives.objectHashCode(this);
@ -80,8 +79,8 @@ class Null {
@patch @patch
class Function { class Function {
@patch @patch
static apply(Function function, List positionalArguments, static apply(Function function, List<dynamic>? positionalArguments,
[Map<Symbol, dynamic> namedArguments]) { [Map<Symbol, dynamic>? namedArguments]) {
return Primitives.applyFunction( return Primitives.applyFunction(
function, function,
positionalArguments, positionalArguments,
@ -103,27 +102,27 @@ class Expando<T> {
final Object _jsWeakMapOrKey; final Object _jsWeakMapOrKey;
@patch @patch
Expando([String name]) Expando([String? name])
: this.name = name, : this.name = name,
_jsWeakMapOrKey = JS('bool', 'typeof WeakMap == "function"') _jsWeakMapOrKey = JS('bool', 'typeof WeakMap == "function"')
? JS('=Object', 'new WeakMap()') ? JS('=Object', 'new WeakMap()')
: _createKey(); : _createKey();
@patch @patch
T operator [](Object object) { T? operator [](Object object) {
if (_jsWeakMapOrKey is! String) { if (_jsWeakMapOrKey is! String) {
_checkType(object); // WeakMap doesn't check on reading, only writing. _checkType(object); // WeakMap doesn't check on reading, only writing.
return JS('', '#.get(#)', _jsWeakMapOrKey, object); return JS('', '#.get(#)', _jsWeakMapOrKey, object);
} }
return _getFromObject(_jsWeakMapOrKey, object); return _getFromObject(_jsWeakMapOrKey as String, object) as T?;
} }
@patch @patch
void operator []=(Object object, T value) { void operator []=(Object object, T? value) {
if (_jsWeakMapOrKey is! String) { if (_jsWeakMapOrKey is! String) {
JS('void', '#.set(#, #)', _jsWeakMapOrKey, object, value); JS('void', '#.set(#, #)', _jsWeakMapOrKey, object, value);
} else { } else {
_setOnObject(_jsWeakMapOrKey, object, value); _setOnObject(_jsWeakMapOrKey as String, object, value);
} }
} }
@ -132,7 +131,7 @@ class Expando<T> {
return (values == null) ? null : Primitives.getProperty(values, key); return (values == null) ? null : Primitives.getProperty(values, key);
} }
static void _setOnObject(String key, Object object, Object value) { static void _setOnObject(String key, Object object, Object? value) {
var values = Primitives.getProperty(object, _EXPANDO_PROPERTY_NAME); var values = Primitives.getProperty(object, _EXPANDO_PROPERTY_NAME);
if (values == null) { if (values == null) {
values = new Object(); values = new Object();
@ -155,15 +154,15 @@ class Expando<T> {
class int { class int {
@patch @patch
static int parse(String source, static int parse(String source,
{int radix, @deprecated int onError(String source)}) { {int? radix, @deprecated int onError(String source)?}) {
int value = tryParse(source, radix: radix); int? value = tryParse(source, radix: radix);
if (value != null) return value; if (value != null) return value;
if (onError != null) return onError(source); if (onError != null) return onError(source);
throw new FormatException(source); throw new FormatException(source);
} }
@patch @patch
static int tryParse(String source, {int radix}) { static int? tryParse(String source, {int? radix}) {
return Primitives.parseInt(source, radix); return Primitives.parseInt(source, radix);
} }
} }
@ -172,15 +171,15 @@ class int {
class double { class double {
@patch @patch
static double parse(String source, static double parse(String source,
[@deprecated double onError(String source)]) { [@deprecated double onError(String source)?]) {
double value = tryParse(source); double? value = tryParse(source);
if (value != null) return value; if (value != null) return value;
if (onError != null) return onError(source); if (onError != null) return onError(source);
throw new FormatException('Invalid double', source); throw new FormatException('Invalid double', source);
} }
@patch @patch
static double tryParse(String source) { static double? tryParse(String source) {
return Primitives.parseDouble(source); return Primitives.parseDouble(source);
} }
} }
@ -195,11 +194,11 @@ class BigInt implements Comparable<BigInt> {
static BigInt get two => _BigIntImpl.two; static BigInt get two => _BigIntImpl.two;
@patch @patch
static BigInt parse(String source, {int radix}) => static BigInt parse(String source, {int? radix}) =>
_BigIntImpl.parse(source, radix: radix); _BigIntImpl.parse(source, radix: radix);
@patch @patch
static BigInt tryParse(String source, {int radix}) => static BigInt? tryParse(String source, {int? radix}) =>
_BigIntImpl._tryParse(source, radix: radix); _BigIntImpl._tryParse(source, radix: radix);
@patch @patch
@ -221,7 +220,7 @@ class Error {
} }
@patch @patch
StackTrace get stackTrace => Primitives.extractStackTrace(this); StackTrace? get stackTrace => Primitives.extractStackTrace(this);
} }
@patch @patch
@ -286,7 +285,7 @@ class DateTime {
} }
@patch @patch
static int _brokenDownDateToValue(int year, int month, int day, int hour, static int? _brokenDownDateToValue(int year, int month, int day, int hour,
int minute, int second, int millisecond, int microsecond, bool isUtc) { int minute, int second, int millisecond, int microsecond, bool isUtc) {
return Primitives.valueFromDecomposedDate( return Primitives.valueFromDecomposedDate(
year, year,
@ -362,7 +361,7 @@ class DateTime {
int get weekday => Primitives.getWeekday(this); int get weekday => Primitives.getWeekday(this);
@patch @patch
bool operator ==(dynamic other) => bool operator ==(Object other) =>
other is DateTime && other is DateTime &&
_value == other.millisecondsSinceEpoch && _value == other.millisecondsSinceEpoch &&
isUtc == other.isUtc; isUtc == other.isUtc;
@ -386,9 +385,9 @@ class DateTime {
@patch @patch
class Stopwatch { class Stopwatch {
@patch @patch
static void _initTicker() { static int _initTicker() {
Primitives.initTicker(); Primitives.initTicker();
_frequency = Primitives.timerFrequency; return Primitives.timerFrequency;
} }
@patch @patch
@ -415,11 +414,11 @@ class Stopwatch {
@patch @patch
class List<E> { class List<E> {
@patch @patch
factory List([int length]) = JSArray<E>.list; factory List([int? length]) = JSArray<E>.list;
@patch @patch
factory List.filled(int length, E fill, {bool growable: false}) { factory List.filled(int length, E fill, {bool growable: false}) {
List result = growable var result = growable
? new JSArray<E>.growable(length) ? new JSArray<E>.growable(length)
: new JSArray<E>.fixed(length); : new JSArray<E>.fixed(length);
if (length != 0 && fill != null) { if (length != 0 && fill != null) {
@ -433,6 +432,11 @@ class List<E> {
return result; return result;
} }
@patch
factory List.empty({bool growable: false}) {
return growable ? new JSArray<E>.growable(0) : new JSArray<E>.fixed(0);
}
@patch @patch
factory List.from(Iterable elements, {bool growable: true}) { factory List.from(Iterable elements, {bool growable: true}) {
List<E> list = <E>[]; List<E> list = <E>[];
@ -449,9 +453,21 @@ class List<E> {
return List.from(elements, growable: growable); return List.from(elements, growable: growable);
} }
@patch
factory List.generate(int length, E generator(int index),
{bool growable = true}) {
final result = growable
? new JSArray<E>.growable(length)
: new JSArray<E>.fixed(length);
for (int i = 0; i < length; i++) {
result[i] = generator(i);
}
return result;
}
@patch @patch
factory List.unmodifiable(Iterable elements) { factory List.unmodifiable(Iterable elements) {
List result = new List<E>.from(elements, growable: false); var result = List<E>.from(elements, growable: false);
return makeFixedListUnmodifiable(result); return makeFixedListUnmodifiable(result);
} }
} }
@ -469,9 +485,12 @@ class Map<K, V> {
class String { class String {
@patch @patch
factory String.fromCharCodes(Iterable<int> charCodes, factory String.fromCharCodes(Iterable<int> charCodes,
[int start = 0, int end]) { [int start = 0, int? end]) {
if (charCodes is JSArray) { if (charCodes is JSArray) {
JSArray<int> array = charCodes; // Type promotion doesn't work unless the check is `is JSArray<int>`,
// which is more expensive.
// TODO(41383): Optimize `is JSArray<int>` rather than do weird 'casts'.
JSArray array = JS('JSArray', '#', charCodes);
return _stringFromJSArray(array, start, end); return _stringFromJSArray(array, start, end);
} }
if (charCodes is NativeUint8List) { if (charCodes is NativeUint8List) {
@ -485,24 +504,24 @@ class String {
return Primitives.stringFromCharCode(charCode); return Primitives.stringFromCharCode(charCode);
} }
static String _stringFromJSArray(List list, int start, int endOrNull) { static String _stringFromJSArray(JSArray list, int start, int? endOrNull) {
int len = list.length; int len = list.length;
int end = RangeError.checkValidRange(start, endOrNull, len); int end = RangeError.checkValidRange(start, endOrNull, len);
if (start > 0 || end < len) { if (start > 0 || end < len) {
list = list.sublist(start, end); list = JS('JSArray', '#.slice(#, #)', list, start, end);
} }
return Primitives.stringFromCharCodes(list); return Primitives.stringFromCharCodes(list);
} }
static String _stringFromUint8List( static String _stringFromUint8List(
NativeUint8List charCodes, int start, int endOrNull) { NativeUint8List charCodes, int start, int? endOrNull) {
int len = charCodes.length; int len = charCodes.length;
int end = RangeError.checkValidRange(start, endOrNull, len); int end = RangeError.checkValidRange(start, endOrNull, len);
return Primitives.stringFromNativeUint8List(charCodes, start, end); return Primitives.stringFromNativeUint8List(charCodes, start, end);
} }
static String _stringFromIterable( static String _stringFromIterable(
Iterable<int> charCodes, int start, int end) { Iterable<int> charCodes, int start, int? end) {
if (start < 0) throw new RangeError.range(start, 0, charCodes.length); if (start < 0) throw new RangeError.range(start, 0, charCodes.length);
if (end != null && end < start) { if (end != null && end < start) {
throw new RangeError.range(end, start, charCodes.length); throw new RangeError.range(end, start, charCodes.length);
@ -557,7 +576,7 @@ class RegExp {
@pragma( @pragma(
'dart2js:noInline') // No inlining since we recognize the call in optimizer. 'dart2js:noInline') // No inlining since we recognize the call in optimizer.
@patch @patch
bool identical(Object a, Object b) { bool identical(Object? a, Object? b) {
return JS('bool', '(# == null ? # == null : # === #)', a, b, a, b); return JS('bool', '(# == null ? # == null : # === #)', a, b, a, b);
} }
@ -572,7 +591,7 @@ class StringBuffer {
int get length => _contents.length; int get length => _contents.length;
@patch @patch
void write(Object obj) { void write(Object? obj) {
_writeString('$obj'); _writeString('$obj');
} }
@ -582,12 +601,12 @@ class StringBuffer {
} }
@patch @patch
void writeAll(Iterable objects, [String separator = ""]) { void writeAll(Iterable<dynamic> objects, [String separator = ""]) {
_contents = _writeAll(_contents, objects, separator); _contents = _writeAll(_contents, objects, separator);
} }
@patch @patch
void writeln([Object obj = ""]) { void writeln([Object? obj = ""]) {
_writeString('$obj\n'); _writeString('$obj\n');
} }
@ -599,7 +618,7 @@ class StringBuffer {
@patch @patch
String toString() => Primitives.flattenString(_contents); String toString() => Primitives.flattenString(_contents);
void _writeString(str) { void _writeString(String str) {
_contents = Primitives.stringConcatUnchecked(_contents, str); _contents = Primitives.stringConcatUnchecked(_contents, str);
} }
@ -620,28 +639,28 @@ class StringBuffer {
return string; return string;
} }
static String _writeOne(String string, Object obj) { static String _writeOne(String string, Object? obj) {
return Primitives.stringConcatUnchecked(string, '$obj'); return Primitives.stringConcatUnchecked(string, '$obj');
} }
} }
@patch @patch
class NoSuchMethodError { class NoSuchMethodError {
final Object _receiver; final Object? _receiver;
final Symbol _memberName; final Symbol _memberName;
final List _arguments; final List? _arguments;
final Map<Symbol, dynamic> _namedArguments; final Map<Symbol, dynamic>? _namedArguments;
final List _existingArgumentNames; final List? _existingArgumentNames;
@patch @patch
NoSuchMethodError.withInvocation(Object receiver, Invocation invocation) NoSuchMethodError.withInvocation(Object? receiver, Invocation invocation)
: this(receiver, invocation.memberName, invocation.positionalArguments, : this(receiver, invocation.memberName, invocation.positionalArguments,
invocation.namedArguments); invocation.namedArguments);
@patch @patch
NoSuchMethodError(Object receiver, Symbol memberName, NoSuchMethodError(Object? receiver, Symbol memberName,
List positionalArguments, Map<Symbol, dynamic> namedArguments, List? positionalArguments, Map<Symbol, dynamic>? namedArguments,
[List existingArgumentNames = null]) [List? existingArgumentNames = null])
: _receiver = receiver, : _receiver = receiver,
_memberName = memberName, _memberName = memberName,
_arguments = positionalArguments, _arguments = positionalArguments,
@ -650,17 +669,19 @@ class NoSuchMethodError {
@patch @patch
String toString() { String toString() {
StringBuffer sb = new StringBuffer(''); StringBuffer sb = StringBuffer('');
String comma = ''; String comma = '';
if (_arguments != null) { var arguments = _arguments;
for (var argument in _arguments) { if (arguments != null) {
for (var argument in arguments) {
sb.write(comma); sb.write(comma);
sb.write(Error.safeToString(argument)); sb.write(Error.safeToString(argument));
comma = ', '; comma = ', ';
} }
} }
if (_namedArguments != null) { var namedArguments = _namedArguments;
_namedArguments.forEach((Symbol key, var value) { if (namedArguments != null) {
namedArguments.forEach((Symbol key, var value) {
sb.write(comma); sb.write(comma);
sb.write(_symbolToString(key)); sb.write(_symbolToString(key));
sb.write(": "); sb.write(": ");
@ -671,12 +692,13 @@ class NoSuchMethodError {
String memberName = _symbolToString(_memberName); String memberName = _symbolToString(_memberName);
String receiverText = Error.safeToString(_receiver); String receiverText = Error.safeToString(_receiver);
String actualParameters = '$sb'; String actualParameters = '$sb';
if (_existingArgumentNames == null) { var existingArgumentNames = _existingArgumentNames;
if (existingArgumentNames == null) {
return "NoSuchMethodError: method not found: '$memberName'\n" return "NoSuchMethodError: method not found: '$memberName'\n"
"Receiver: ${receiverText}\n" "Receiver: ${receiverText}\n"
"Arguments: [$actualParameters]"; "Arguments: [$actualParameters]";
} else { } else {
String formalParameters = _existingArgumentNames.join(', '); String formalParameters = existingArgumentNames.join(', ');
return "NoSuchMethodError: incorrect number of arguments passed to " return "NoSuchMethodError: incorrect number of arguments passed to "
"method named '$memberName'\n" "method named '$memberName'\n"
"Receiver: ${receiverText}\n" "Receiver: ${receiverText}\n"
@ -697,7 +719,7 @@ class _CompileTimeError extends Error {
class Uri { class Uri {
@patch @patch
static Uri get base { static Uri get base {
String uri = Primitives.currentUri(); String? uri = Primitives.currentUri();
if (uri != null) return Uri.parse(uri); if (uri != null) return Uri.parse(uri);
throw new UnsupportedError("'Uri.base' is not supported"); throw new UnsupportedError("'Uri.base' is not supported");
} }
@ -924,14 +946,14 @@ class _BigIntImpl implements BigInt {
// Result cache for last _divRem call. // Result cache for last _divRem call.
// Result cache for last _divRem call. // Result cache for last _divRem call.
static Uint16List _lastDividendDigits; static Uint16List? _lastDividendDigits;
static int _lastDividendUsed; static int? _lastDividendUsed;
static Uint16List _lastDivisorDigits; static Uint16List? _lastDivisorDigits;
static int _lastDivisorUsed; static int? _lastDivisorUsed;
static Uint16List _lastQuoRemDigits; static late Uint16List _lastQuoRemDigits;
static int _lastQuoRemUsed; static late int _lastQuoRemUsed;
static int _lastRemUsed; static late int _lastRemUsed;
static int _lastRem_nsh; static late int _lastRem_nsh;
/// Whether this bigint is negative. /// Whether this bigint is negative.
final bool _isNegative; final bool _isNegative;
@ -970,7 +992,7 @@ class _BigIntImpl implements BigInt {
/// ///
/// Throws a [FormatException] if the [source] is not a valid integer literal, /// Throws a [FormatException] if the [source] is not a valid integer literal,
/// optionally prefixed by a sign. /// optionally prefixed by a sign.
static _BigIntImpl parse(String source, {int radix}) { static _BigIntImpl parse(String source, {int? radix}) {
var result = _tryParse(source, radix: radix); var result = _tryParse(source, radix: radix);
if (result == null) { if (result == null) {
throw new FormatException("Could not parse BigInt", source); throw new FormatException("Could not parse BigInt", source);
@ -989,7 +1011,7 @@ class _BigIntImpl implements BigInt {
// Read in the source 4 digits at a time. // Read in the source 4 digits at a time.
// The first part may have a few leading virtual '0's to make the remaining // The first part may have a few leading virtual '0's to make the remaining
// parts all have exactly 4 digits. // parts all have exactly 4 digits.
int digitInPartCount = 4 - source.length.remainder(4); var digitInPartCount = 4 - source.length.remainder(4);
if (digitInPartCount == 4) digitInPartCount = 0; if (digitInPartCount == 4) digitInPartCount = 0;
for (int i = 0; i < source.length; i++) { for (int i = 0; i < source.length; i++) {
part = part * 10 + source.codeUnitAt(i) - _0; part = part * 10 + source.codeUnitAt(i) - _0;
@ -1031,7 +1053,7 @@ class _BigIntImpl implements BigInt {
/// If [isNegative] is true, negates the result before returning it. /// If [isNegative] is true, negates the result before returning it.
/// ///
/// The [source] (substring) must be a valid hex literal. /// The [source] (substring) must be a valid hex literal.
static _BigIntImpl _parseHex(String source, int startPos, bool isNegative) { static _BigIntImpl? _parseHex(String source, int startPos, bool isNegative) {
int hexDigitsPerChunk = _digitBits ~/ 4; int hexDigitsPerChunk = _digitBits ~/ 4;
int sourceLength = source.length - startPos; int sourceLength = source.length - startPos;
int chunkCount = (sourceLength / hexDigitsPerChunk).ceil(); int chunkCount = (sourceLength / hexDigitsPerChunk).ceil();
@ -1065,7 +1087,7 @@ class _BigIntImpl implements BigInt {
/// ///
/// The [source] will be checked for invalid characters. If it is invalid, /// The [source] will be checked for invalid characters. If it is invalid,
/// this function returns `null`. /// this function returns `null`.
static _BigIntImpl _parseRadix(String source, int radix, bool isNegative) { static _BigIntImpl? _parseRadix(String source, int radix, bool isNegative) {
var result = zero; var result = zero;
var base = new _BigIntImpl._fromInt(radix); var base = new _BigIntImpl._fromInt(radix);
for (int i = 0; i < source.length; i++) { for (int i = 0; i < source.length; i++) {
@ -1082,7 +1104,7 @@ class _BigIntImpl implements BigInt {
/// Returns the parsed big integer, or `null` if it failed. /// Returns the parsed big integer, or `null` if it failed.
/// ///
/// If the [radix] is `null` accepts decimal literals or `0x` hex literals. /// If the [radix] is `null` accepts decimal literals or `0x` hex literals.
static _BigIntImpl _tryParse(String source, {int radix}) { static _BigIntImpl? _tryParse(String source, {int? radix}) {
if (source == "") return null; if (source == "") return null;
var match = _parseRE.firstMatch(source); var match = _parseRE.firstMatch(source);
@ -1094,9 +1116,9 @@ class _BigIntImpl implements BigInt {
bool isNegative = match[signIndex] == "-"; bool isNegative = match[signIndex] == "-";
String decimalMatch = match[decimalIndex]; String? decimalMatch = match[decimalIndex];
String hexMatch = match[hexIndex]; String? hexMatch = match[hexIndex];
String nonDecimalMatch = match[nonDecimalHexIndex]; String? nonDecimalMatch = match[nonDecimalHexIndex];
if (radix == null) { if (radix == null) {
if (decimalMatch != null) { if (decimalMatch != null) {
@ -1120,11 +1142,11 @@ class _BigIntImpl implements BigInt {
return _parseDecimal(decimalMatch, isNegative); return _parseDecimal(decimalMatch, isNegative);
} }
if (radix == 16 && (decimalMatch != null || nonDecimalMatch != null)) { if (radix == 16 && (decimalMatch != null || nonDecimalMatch != null)) {
return _parseHex(decimalMatch ?? nonDecimalMatch, 0, isNegative); return _parseHex(decimalMatch ?? nonDecimalMatch!, 0, isNegative);
} }
return _parseRadix( return _parseRadix(
decimalMatch ?? nonDecimalMatch ?? hexMatch, radix, isNegative); decimalMatch ?? nonDecimalMatch ?? hexMatch!, radix, isNegative);
} }
static RegExp _parseRE = RegExp( static RegExp _parseRE = RegExp(
@ -1173,7 +1195,7 @@ class _BigIntImpl implements BigInt {
if (value.abs() < 0x100000000) if (value.abs() < 0x100000000)
return new _BigIntImpl._fromInt(value.toInt()); return new _BigIntImpl._fromInt(value.toInt());
if (value is double) return new _BigIntImpl._fromDouble(value); if (value is double) return new _BigIntImpl._fromDouble(value);
return new _BigIntImpl._fromInt(value); return new _BigIntImpl._fromInt(value as int);
} }
factory _BigIntImpl._fromInt(int value) { factory _BigIntImpl._fromInt(int value) {

View file

@ -2,8 +2,6 @@
// for details. All rights reserved. Use of this source code is governed by a // for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file. // BSD-style license that can be found in the LICENSE file.
// @dart = 2.6
// Patch file for dart:developer library. // Patch file for dart:developer library.
import 'dart:_js_helper' show patch, ForceInline; import 'dart:_js_helper' show patch, ForceInline;
@ -13,7 +11,7 @@ import 'dart:isolate';
@patch @patch
@pragma('dart2js:tryInline') @pragma('dart2js:tryInline')
bool debugger({bool when: true, String message}) { bool debugger({bool when = true, String? message}) {
if (when) { if (when) {
JS('', 'debugger'); JS('', 'debugger');
} }
@ -21,26 +19,26 @@ bool debugger({bool when: true, String message}) {
} }
@patch @patch
Object inspect(Object object) { Object? inspect(Object? object) {
return object; return object;
} }
@patch @patch
void log(String message, void log(String message,
{DateTime time, {DateTime? time,
int sequenceNumber, int? sequenceNumber,
int level: 0, int level = 0,
String name: '', String name = '',
Zone zone, Zone? zone,
Object error, Object? error,
StackTrace stackTrace}) { StackTrace? stackTrace}) {
// TODO. // TODO.
} }
final _extensions = new Map<String, ServiceExtensionHandler>(); final _extensions = <String, ServiceExtensionHandler>{};
@patch @patch
ServiceExtensionHandler _lookupExtension(String method) { ServiceExtensionHandler? _lookupExtension(String method) {
return _extensions[method]; return _extensions[method];
} }
@ -110,7 +108,7 @@ void _webServerControl(SendPort sendPort, bool enable) {
} }
@patch @patch
String _getIsolateIDFromSendPort(SendPort sendPort) { String? _getIsolateIDFromSendPort(SendPort sendPort) {
return null; return null;
} }
@ -124,7 +122,7 @@ class UserTag {
} }
class _FakeUserTag implements UserTag { class _FakeUserTag implements UserTag {
static Map _instances = {}; static final _instances = <String, _FakeUserTag>{};
_FakeUserTag.real(this.label); _FakeUserTag.real(this.label);
@ -136,13 +134,10 @@ class _FakeUserTag implements UserTag {
} }
// Throw an exception if we've reached the maximum number of user tags. // Throw an exception if we've reached the maximum number of user tags.
if (_instances.length == UserTag.MAX_USER_TAGS) { if (_instances.length == UserTag.MAX_USER_TAGS) {
throw new UnsupportedError( throw UnsupportedError(
'UserTag instance limit (${UserTag.MAX_USER_TAGS}) reached.'); 'UserTag instance limit (${UserTag.MAX_USER_TAGS}) reached.');
} }
// Create a new instance and add it to the instance map. return _instances[label] = _FakeUserTag.real(label);
var instance = new _FakeUserTag.real(label);
_instances[label] = instance;
return instance;
} }
final String label; final String label;

View file

@ -2,8 +2,6 @@
// for details. All rights reserved. Use of this source code is governed by a // for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file. // BSD-style license that can be found in the LICENSE file.
// @dart = 2.6
library _foreign_helper; library _foreign_helper;
import 'dart:_js_embedded_names' show JsGetName, JsBuiltin; import 'dart:_js_embedded_names' show JsGetName, JsBuiltin;

View file

@ -2,8 +2,6 @@
// for details. All rights reserved. Use of this source code is governed by a // for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file. // BSD-style license that can be found in the LICENSE file.
// @dart = 2.6
part of _js_helper; part of _js_helper;
/// Support class for generic function type instantiation (binding of types). /// Support class for generic function type instantiation (binding of types).

View file

@ -2,8 +2,6 @@
// for details. All rights reserved. Use of this source code is governed by a // for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file. // BSD-style license that can be found in the LICENSE file.
// @dart = 2.6
library _interceptors; library _interceptors;
import 'dart:_js_embedded_names' import 'dart:_js_embedded_names'
@ -63,17 +61,6 @@ part 'js_string.dart';
final String DART_CLOSURE_PROPERTY_NAME = final String DART_CLOSURE_PROPERTY_NAME =
getIsolateAffinityTag(r'_$dart_dartClosure'); getIsolateAffinityTag(r'_$dart_dartClosure');
String _symbolToString(Symbol symbol) => _symbol_dev.Symbol.getName(symbol);
_symbolMapToStringMap(Map<Symbol, dynamic> map) {
if (map == null) return null;
var result = new Map<String, dynamic>();
map.forEach((Symbol key, value) {
result[_symbolToString(key)] = value;
});
return result;
}
getDispatchProperty(object) { getDispatchProperty(object) {
return JS( return JS(
'', '#[#]', object, JS_EMBEDDED_GLOBAL('String', DISPATCH_PROPERTY_NAME)); '', '#[#]', object, JS_EMBEDDED_GLOBAL('String', DISPATCH_PROPERTY_NAME));
@ -123,7 +110,7 @@ makeDispatchRecord(interceptor, proto, extension, indexability) {
dispatchRecordInterceptor(record) => JS('', '#.i', record); dispatchRecordInterceptor(record) => JS('', '#.i', record);
dispatchRecordProto(record) => JS('', '#.p', record); dispatchRecordProto(record) => JS('', '#.p', record);
dispatchRecordExtension(record) => JS('', '#.e', record); dispatchRecordExtension(record) => JS('', '#.e', record);
dispatchRecordIndexability(record) => JS('bool|Null', '#.x', record); bool? dispatchRecordIndexability(record) => JS('bool|Null', '#.x', record);
/// Returns the interceptor for a native class instance. Used by /// Returns the interceptor for a native class instance. Used by
/// [getInterceptor]. /// [getInterceptor].
@ -197,7 +184,10 @@ getNativeInterceptor(object) {
} }
// A JS String or Symbol. // A JS String or Symbol.
final JS_INTEROP_INTERCEPTOR_TAG = getIsolateAffinityTag(r'_$dart_js'); dynamic _JS_INTEROP_INTERCEPTOR_TAG = null;
get JS_INTEROP_INTERCEPTOR_TAG {
return _JS_INTEROP_INTERCEPTOR_TAG ??= getIsolateAffinityTag(r'_$dart_js');
}
lookupInterceptorByConstructor(constructor) { lookupInterceptorByConstructor(constructor) {
return constructor == null return constructor == null
@ -236,7 +226,7 @@ get typeToInterceptorMap {
return JS_EMBEDDED_GLOBAL('', TYPE_TO_INTERCEPTOR_MAP); return JS_EMBEDDED_GLOBAL('', TYPE_TO_INTERCEPTOR_MAP);
} }
int findIndexForNativeSubclassType(Type type) { int? findIndexForNativeSubclassType(Type? type) {
if (JS('bool', '# == null', typeToInterceptorMap)) return null; if (JS('bool', '# == null', typeToInterceptorMap)) return null;
List map = JS('JSFixedArray', '#', typeToInterceptorMap); List map = JS('JSFixedArray', '#', typeToInterceptorMap);
for (int i = 0; i + 1 < map.length; i += 3) { for (int i = 0; i + 1 < map.length; i += 3) {
@ -247,7 +237,7 @@ int findIndexForNativeSubclassType(Type type) {
return null; return null;
} }
findInterceptorConstructorForType(Type type) { findInterceptorConstructorForType(Type? type) {
var index = findIndexForNativeSubclassType(type); var index = findIndexForNativeSubclassType(type);
if (index == null) return null; if (index == null) return null;
List map = JS('JSFixedArray', '#', typeToInterceptorMap); List map = JS('JSFixedArray', '#', typeToInterceptorMap);
@ -258,7 +248,7 @@ findInterceptorConstructorForType(Type type) {
/// `null` if there is no such constructor. /// `null` if there is no such constructor.
/// ///
/// The returned function takes one argument, the web component object. /// The returned function takes one argument, the web component object.
findConstructorForNativeSubclassType(Type type, String name) { findConstructorForNativeSubclassType(Type? type, String name) {
var index = findIndexForNativeSubclassType(type); var index = findIndexForNativeSubclassType(type);
if (index == null) return null; if (index == null) return null;
List map = JS('JSFixedArray', '#', typeToInterceptorMap); List map = JS('JSFixedArray', '#', typeToInterceptorMap);
@ -267,7 +257,7 @@ findConstructorForNativeSubclassType(Type type, String name) {
return constructorFn; return constructorFn;
} }
findInterceptorForType(Type type) { findInterceptorForType(Type? type) {
var constructor = findInterceptorConstructorForType(type); var constructor = findInterceptorConstructorForType(type);
if (constructor == null) return null; if (constructor == null) return null;
return JS('', '#.prototype', constructor); return JS('', '#.prototype', constructor);

View file

@ -2,15 +2,20 @@
// for details. All rights reserved. Use of this source code is governed by a // for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file. // BSD-style license that can be found in the LICENSE file.
// @dart = 2.6
import 'dart:core' hide Symbol; import 'dart:core' hide Symbol;
import 'dart:core' as core; import 'dart:core' as core show Symbol;
import 'dart:_js_primitives' show printString; import 'dart:_js_primitives' show printString;
import 'dart:_js_helper' show patch, NoInline; import 'dart:_js_helper' show patch;
import 'dart:_interceptors' show JSArray; import 'dart:_interceptors' show JSArray;
import 'dart:_foreign_helper' show JS, JS_GET_FLAG; import 'dart:_foreign_helper' show JS, JS_GET_FLAG;
@patch
@pragma('dart2js:tryInline')
bool typeAcceptsNull<T>() {
bool isLegacySubtyping = JS_GET_FLAG('LEGACY');
return isLegacySubtyping || null is T;
}
@patch @patch
class Symbol implements core.Symbol { class Symbol implements core.Symbol {
@patch @patch
@ -18,7 +23,7 @@ class Symbol implements core.Symbol {
@patch @patch
int get hashCode { int get hashCode {
int hash = JS('int|Null', '#._hashCode', this); int? hash = JS('int|Null', '#._hashCode', this);
if (hash != null) return hash; if (hash != null) return hash;
const arbitraryPrime = 664597; const arbitraryPrime = 664597;
hash = 0x1fffffff & (arbitraryPrime * _name.hashCode); hash = 0x1fffffff & (arbitraryPrime * _name.hashCode);

View file

@ -2,8 +2,6 @@
// for details. All rights reserved. Use of this source code is governed by a // for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file. // BSD-style license that can be found in the LICENSE file.
// @dart = 2.6
import 'dart:_js_helper' show patch; import 'dart:_js_helper' show patch;
import 'dart:_internal' hide Symbol; import 'dart:_internal' hide Symbol;
import 'dart:async'; import 'dart:async';
@ -75,7 +73,7 @@ class _AsyncDirectoryListerOps {
@patch @patch
class _EventHandler { class _EventHandler {
@patch @patch
static void _sendData(Object sender, SendPort sendPort, int data) { static void _sendData(Object? sender, SendPort sendPort, int data) {
throw new UnsupportedError("EventHandler._sendData"); throw new UnsupportedError("EventHandler._sendData");
} }
} }
@ -305,7 +303,7 @@ class _Platform {
@patch @patch
class _ProcessUtils { class _ProcessUtils {
@patch @patch
static void _exit(int status) { static Never _exit(int status) {
throw new UnsupportedError("ProcessUtils._exit"); throw new UnsupportedError("ProcessUtils._exit");
} }
@ -325,7 +323,7 @@ class _ProcessUtils {
} }
@patch @patch
static int _pid(Process process) { static int _pid(Process? process) {
throw new UnsupportedError("ProcessUtils._pid"); throw new UnsupportedError("ProcessUtils._pid");
} }
@ -352,8 +350,8 @@ class ProcessInfo {
class Process { class Process {
@patch @patch
static Future<Process> start(String executable, List<String> arguments, static Future<Process> start(String executable, List<String> arguments,
{String workingDirectory, {String? workingDirectory,
Map<String, String> environment, Map<String, String>? environment,
bool includeParentEnvironment: true, bool includeParentEnvironment: true,
bool runInShell: false, bool runInShell: false,
ProcessStartMode mode: ProcessStartMode.normal}) { ProcessStartMode mode: ProcessStartMode.normal}) {
@ -362,8 +360,8 @@ class Process {
@patch @patch
static Future<ProcessResult> run(String executable, List<String> arguments, static Future<ProcessResult> run(String executable, List<String> arguments,
{String workingDirectory, {String? workingDirectory,
Map<String, String> environment, Map<String, String>? environment,
bool includeParentEnvironment: true, bool includeParentEnvironment: true,
bool runInShell: false, bool runInShell: false,
Encoding stdoutEncoding: systemEncoding, Encoding stdoutEncoding: systemEncoding,
@ -373,8 +371,8 @@ class Process {
@patch @patch
static ProcessResult runSync(String executable, List<String> arguments, static ProcessResult runSync(String executable, List<String> arguments,
{String workingDirectory, {String? workingDirectory,
Map<String, String> environment, Map<String, String>? environment,
bool includeParentEnvironment: true, bool includeParentEnvironment: true,
bool runInShell: false, bool runInShell: false,
Encoding stdoutEncoding: systemEncoding, Encoding stdoutEncoding: systemEncoding,
@ -411,13 +409,13 @@ class InternetAddress {
} }
@patch @patch
factory InternetAddress(String address, {InternetAddressType type}) { factory InternetAddress(String address, {InternetAddressType? type}) {
throw new UnsupportedError("InternetAddress"); throw new UnsupportedError("InternetAddress");
} }
@patch @patch
factory InternetAddress.fromRawAddress(Uint8List rawAddress, factory InternetAddress.fromRawAddress(Uint8List rawAddress,
{InternetAddressType type}) { {InternetAddressType? type}) {
throw new UnsupportedError("InternetAddress.fromRawAddress"); throw new UnsupportedError("InternetAddress.fromRawAddress");
} }
@ -434,8 +432,8 @@ class InternetAddress {
} }
@patch @patch
static InternetAddress tryParse(String address) { static InternetAddress? tryParse(String address) {
throw new UnsupportedError("InternetAddress.tryParse"); throw UnsupportedError("InternetAddress.tryParse");
} }
} }
@ -476,14 +474,14 @@ class ServerSocket {
@patch @patch
class RawSocket { class RawSocket {
@patch @patch
static Future<RawSocket> connect(host, int port, static Future<RawSocket> connect(dynamic host, int port,
{sourceAddress, Duration timeout}) { {dynamic sourceAddress, Duration? timeout}) {
throw new UnsupportedError("RawSocket constructor"); throw new UnsupportedError("RawSocket constructor");
} }
@patch @patch
static Future<ConnectionTask<RawSocket>> startConnect(host, int port, static Future<ConnectionTask<RawSocket>> startConnect(dynamic host, int port,
{sourceAddress}) { {dynamic sourceAddress}) {
throw new UnsupportedError("RawSocket constructor"); throw new UnsupportedError("RawSocket constructor");
} }
} }
@ -491,14 +489,14 @@ class RawSocket {
@patch @patch
class Socket { class Socket {
@patch @patch
static Future<Socket> _connect(host, int port, static Future<Socket> _connect(dynamic host, int port,
{sourceAddress, Duration timeout}) { {dynamic sourceAddress, Duration? timeout}) {
throw new UnsupportedError("Socket constructor"); throw new UnsupportedError("Socket constructor");
} }
@patch @patch
static Future<ConnectionTask<Socket>> _startConnect(host, int port, static Future<ConnectionTask<Socket>> _startConnect(dynamic host, int port,
{sourceAddress}) { {dynamic sourceAddress}) {
throw new UnsupportedError("Socket constructor"); throw new UnsupportedError("Socket constructor");
} }
} }
@ -514,7 +512,7 @@ class SecureSocket {
@patch @patch
class RawSynchronousSocket { class RawSynchronousSocket {
@patch @patch
static RawSynchronousSocket connectSync(host, int port) { static RawSynchronousSocket connectSync(dynamic host, int port) {
throw new UnsupportedError("RawSynchronousSocket.connectSync"); throw new UnsupportedError("RawSynchronousSocket.connectSync");
} }
} }
@ -556,7 +554,7 @@ class X509Certificate {
@patch @patch
class RawDatagramSocket { class RawDatagramSocket {
@patch @patch
static Future<RawDatagramSocket> bind(host, int port, static Future<RawDatagramSocket> bind(dynamic host, int port,
{bool reuseAddress: true, bool reusePort: false, int ttl: 1}) { {bool reuseAddress: true, bool reusePort: false, int ttl: 1}) {
throw new UnsupportedError("RawDatagramSocket.bind"); throw new UnsupportedError("RawDatagramSocket.bind");
} }
@ -618,14 +616,14 @@ class RawZLibFilter {
int windowBits, int windowBits,
int memLevel, int memLevel,
int strategy, int strategy,
List<int> dictionary, List<int>? dictionary,
bool raw) { bool raw) {
throw new UnsupportedError("_newZLibDeflateFilter"); throw new UnsupportedError("_newZLibDeflateFilter");
} }
@patch @patch
static RawZLibFilter _makeZLibInflateFilter( static RawZLibFilter _makeZLibInflateFilter(
int windowBits, List<int> dictionary, bool raw) { int windowBits, List<int>? dictionary, bool raw) {
throw new UnsupportedError("_newZLibInflateFilter"); throw new UnsupportedError("_newZLibInflateFilter");
} }
} }

View file

@ -2,14 +2,12 @@
// for details. All rights reserved. Use of this source code is governed by a // for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file. // BSD-style license that can be found in the LICENSE file.
// @dart = 2.6
// Patch file for the dart:isolate library. // Patch file for the dart:isolate library.
import "dart:async"; import "dart:async";
import 'dart:_foreign_helper' show JS; import 'dart:_foreign_helper' show JS;
import 'dart:_js_helper' show patch; import 'dart:_js_helper' show patch;
import "dart:typed_data" show ByteData, TypedData, Uint8List; import "dart:typed_data" show TypedData;
@patch @patch
class Isolate { class Isolate {
@ -19,45 +17,46 @@ class Isolate {
} }
@patch @patch
String get debugName { String? get debugName {
throw new UnsupportedError("Isolate.debugName"); throw new UnsupportedError("Isolate.debugName");
} }
@patch @patch
static Future<Uri> get packageRoot { static Future<Uri?> get packageRoot {
throw new UnsupportedError("Isolate.packageRoot"); throw new UnsupportedError("Isolate.packageRoot");
} }
@patch @patch
static Future<Uri> get packageConfig { static Future<Uri?> get packageConfig {
throw new UnsupportedError("Isolate.packageConfig"); throw new UnsupportedError("Isolate.packageConfig");
} }
@patch @patch
static Future<Uri> resolvePackageUri(Uri packageUri) { static Future<Uri?> resolvePackageUri(Uri packageUri) {
throw new UnsupportedError("Isolate.resolvePackageUri"); throw new UnsupportedError("Isolate.resolvePackageUri");
} }
@patch @patch
static Future<Isolate> spawn<T>(void entryPoint(T message), T message, static Future<Isolate> spawn<T>(void entryPoint(T message), T message,
{bool paused: false, {bool paused = false,
bool errorsAreFatal, bool errorsAreFatal = true,
SendPort onExit, SendPort? onExit,
SendPort onError}) { SendPort? onError}) {
throw new UnsupportedError("Isolate.spawn"); throw new UnsupportedError("Isolate.spawn");
} }
@patch @patch
static Future<Isolate> spawnUri(Uri uri, List<String> args, var message, static Future<Isolate> spawnUri(Uri uri, List<String> args, var message,
{bool paused: false, {bool paused = false,
SendPort onExit, SendPort? onExit,
SendPort onError, SendPort? onError,
bool errorsAreFatal, bool errorsAreFatal = true,
bool checked, bool? checked,
Map<String, String> environment, Map<String, String>? environment,
Uri packageRoot, Uri? packageRoot,
Uri packageConfig, Uri? packageConfig,
bool automaticPackageResolution: false}) { bool automaticPackageResolution = false,
String? debugName}) {
throw new UnsupportedError("Isolate.spawnUri"); throw new UnsupportedError("Isolate.spawnUri");
} }
@ -72,7 +71,7 @@ class Isolate {
} }
@patch @patch
void addOnExitListener(SendPort responsePort, {Object response}) { void addOnExitListener(SendPort responsePort, {Object? response}) {
throw new UnsupportedError("Isolate.addOnExitListener"); throw new UnsupportedError("Isolate.addOnExitListener");
} }
@ -87,12 +86,13 @@ class Isolate {
} }
@patch @patch
void kill({int priority: beforeNextEvent}) { void kill({int priority = beforeNextEvent}) {
throw new UnsupportedError("Isolate.kill"); throw new UnsupportedError("Isolate.kill");
} }
@patch @patch
void ping(SendPort responsePort, {Object response, int priority: immediate}) { void ping(SendPort responsePort,
{Object? response, int priority = immediate}) {
throw new UnsupportedError("Isolate.ping"); throw new UnsupportedError("Isolate.ping");
} }
@ -119,8 +119,10 @@ class ReceivePort {
} }
class _ReceivePortImpl extends Stream implements ReceivePort { class _ReceivePortImpl extends Stream implements ReceivePort {
StreamSubscription listen(void onData(var event), StreamSubscription listen(void Function(dynamic)? onData,
{Function onError, void onDone(), bool cancelOnError}) { {Function? onError,
void Function()? onDone,
bool? cancelOnError = true}) {
throw new UnsupportedError("ReceivePort.listen"); throw new UnsupportedError("ReceivePort.listen");
} }
@ -132,7 +134,7 @@ class _ReceivePortImpl extends Stream implements ReceivePort {
@patch @patch
class RawReceivePort { class RawReceivePort {
@patch @patch
factory RawReceivePort([Function handler]) { factory RawReceivePort([Function? handler]) {
throw new UnsupportedError('new RawReceivePort'); throw new UnsupportedError('new RawReceivePort');
} }
} }

View file

@ -2,8 +2,6 @@
// for details. All rights reserved. Use of this source code is governed by a // for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file. // BSD-style license that can be found in the LICENSE file.
// @dart = 2.6
part of _interceptors; part of _interceptors;
class _Growable { class _Growable {
@ -16,7 +14,7 @@ const _ListConstructorSentinel = const _Growable();
/// class as an interceptor, and changes references to [:this:] to /// class as an interceptor, and changes references to [:this:] to
/// actually use the receiver of the method, which is generated as an extra /// actually use the receiver of the method, which is generated as an extra
/// argument added to each member. /// argument added to each member.
class JSArray<E> extends Interceptor implements List<E>, JSIndexable { class JSArray<E> extends Interceptor implements List<E>, JSIndexable<E> {
const JSArray(); const JSArray();
// This factory constructor is the redirection target of the List() factory // This factory constructor is the redirection target of the List() factory
@ -82,7 +80,7 @@ class JSArray<E> extends Interceptor implements List<E>, JSIndexable {
factory JSArray.markGrowable(allocation) => factory JSArray.markGrowable(allocation) =>
JS('JSExtendableArray', '#', new JSArray<E>.typed(allocation)); JS('JSExtendableArray', '#', new JSArray<E>.typed(allocation));
static List markFixedList(List list) { static List<T> markFixedList<T>(List<T> list) {
// Functions are stored in the hidden class and not as properties in // Functions are stored in the hidden class and not as properties in
// the object. We never actually look at the value, but only want // the object. We never actually look at the value, but only want
// to know if the property exists. // to know if the property exists.
@ -90,7 +88,7 @@ class JSArray<E> extends Interceptor implements List<E>, JSIndexable {
return JS('JSFixedArray', '#', list); return JS('JSFixedArray', '#', list);
} }
static List markUnmodifiableList(List list) { static List<T> markUnmodifiableList<T>(List list) {
// Functions are stored in the hidden class and not as properties in // Functions are stored in the hidden class and not as properties in
// the object. We never actually look at the value, but only want // the object. We never actually look at the value, but only want
// to know if the property exists. // to know if the property exists.
@ -178,7 +176,7 @@ class JSArray<E> extends Interceptor implements List<E>, JSIndexable {
return JS('', r'#.pop()', this); return JS('', r'#.pop()', this);
} }
bool remove(Object element) { bool remove(Object? element) {
checkGrowable('remove'); checkGrowable('remove');
for (int i = 0; i < this.length; i++) { for (int i = 0; i < this.length; i++) {
if (this[i] == element) { if (this[i] == element) {
@ -266,7 +264,7 @@ class JSArray<E> extends Interceptor implements List<E>, JSIndexable {
} }
String join([String separator = '']) { String join([String separator = '']) {
var list = new List(this.length); var list = List.filled(this.length, "");
for (int i = 0; i < this.length; i++) { for (int i = 0; i < this.length; i++) {
list[i] = '${this[i]}'; list[i] = '${this[i]}';
} }
@ -316,7 +314,7 @@ class JSArray<E> extends Interceptor implements List<E>, JSIndexable {
return value; return value;
} }
E firstWhere(bool test(E value), {E orElse()}) { E firstWhere(bool Function(E) test, {E Function()? orElse}) {
var end = this.length; var end = this.length;
for (int i = 0; i < end; ++i) { for (int i = 0; i < end; ++i) {
// TODO(22407): Improve bounds check elimination to allow this JS code to // TODO(22407): Improve bounds check elimination to allow this JS code to
@ -329,7 +327,7 @@ class JSArray<E> extends Interceptor implements List<E>, JSIndexable {
throw IterableElementError.noElement(); throw IterableElementError.noElement();
} }
E lastWhere(bool test(E element), {E orElse()}) { E lastWhere(bool Function(E) test, {E Function()? orElse}) {
int length = this.length; int length = this.length;
for (int i = length - 1; i >= 0; i--) { for (int i = length - 1; i >= 0; i--) {
// TODO(22407): Improve bounds check elimination to allow this JS code to // TODO(22407): Improve bounds check elimination to allow this JS code to
@ -344,9 +342,9 @@ class JSArray<E> extends Interceptor implements List<E>, JSIndexable {
throw IterableElementError.noElement(); throw IterableElementError.noElement();
} }
E singleWhere(bool test(E element), {E orElse()}) { E singleWhere(bool Function(E) test, {E Function()? orElse}) {
int length = this.length; int length = this.length;
E match = null; E? match = null;
bool matchFound = false; bool matchFound = false;
for (int i = 0; i < length; i++) { for (int i = 0; i < length; i++) {
// TODO(22407): Improve bounds check elimination to allow this JS code to // TODO(22407): Improve bounds check elimination to allow this JS code to
@ -363,7 +361,7 @@ class JSArray<E> extends Interceptor implements List<E>, JSIndexable {
throw new ConcurrentModificationError(this); throw new ConcurrentModificationError(this);
} }
} }
if (matchFound) return match; if (matchFound) return match as E;
if (orElse != null) return orElse(); if (orElse != null) return orElse();
throw IterableElementError.noElement(); throw IterableElementError.noElement();
} }
@ -372,7 +370,7 @@ class JSArray<E> extends Interceptor implements List<E>, JSIndexable {
return this[index]; return this[index];
} }
List<E> sublist(int start, [int end]) { List<E> sublist(int start, [int? end]) {
checkNull(start); // TODO(ahe): This is not specified but co19 tests it. checkNull(start); // TODO(ahe): This is not specified but co19 tests it.
if (start is! int) throw argumentErrorValue(start); if (start is! int) throw argumentErrorValue(start);
if (start < 0 || start > length) { if (start < 0 || start > length) {
@ -431,7 +429,7 @@ class JSArray<E> extends Interceptor implements List<E>, JSIndexable {
int otherStart; int otherStart;
// TODO(floitsch): Make this accept more. // TODO(floitsch): Make this accept more.
if (iterable is List) { if (iterable is List) {
otherList = iterable; otherList = JS<List<E>>('', '#', iterable);
otherStart = skipCount; otherStart = skipCount;
} else { } else {
otherList = iterable.skip(skipCount).toList(growable: false); otherList = iterable.skip(skipCount).toList(growable: false);
@ -459,12 +457,14 @@ class JSArray<E> extends Interceptor implements List<E>, JSIndexable {
} }
} }
void fillRange(int start, int end, [E fillValue]) { void fillRange(int start, int end, [E? fillValue]) {
checkMutable('fill range'); checkMutable('fill range');
RangeError.checkValidRange(start, end, this.length); RangeError.checkValidRange(start, end, this.length);
E checkedFillValue = fillValue as E;
for (int i = start; i < end; i++) { for (int i = start; i < end; i++) {
// Store is safe since [fillValue] type has been checked as parameter. // Store is safe since [checkedFillValue] type has been checked as
JS('', '#[#] = #', this, i, fillValue); // parameter and for null.
JS('', '#[#] = #', this, i, checkedFillValue);
} }
} }
@ -521,18 +521,16 @@ class JSArray<E> extends Interceptor implements List<E>, JSIndexable {
Iterable<E> get reversed => new ReversedListIterable<E>(this); Iterable<E> get reversed => new ReversedListIterable<E>(this);
void sort([int compare(E a, E b)]) { void sort([int Function(E, E)? compare]) {
checkMutable('sort'); checkMutable('sort');
Sort.sort(this, compare ?? _compareAny); Sort.sort(this, compare ?? _compareAny);
} }
static int _compareAny(a, b) { static int _compareAny(a, b) {
// In strong mode Comparable.compare requires an implicit cast to ensure
// `a` and `b` are Comparable.
return Comparable.compare(a, b); return Comparable.compare(a, b);
} }
void shuffle([Random random]) { void shuffle([Random? random]) {
checkMutable('shuffle'); checkMutable('shuffle');
if (random == null) random = new Random(); if (random == null) random = new Random();
int length = this.length; int length = this.length;
@ -545,14 +543,15 @@ class JSArray<E> extends Interceptor implements List<E>, JSIndexable {
} }
} }
int indexOf(Object element, [int start = 0]) { int indexOf(Object? element, [int start = 0]) {
if (start >= this.length) { int length = this.length;
if (start >= length) {
return -1; return -1;
} }
if (start < 0) { if (start < 0) {
start = 0; start = 0;
} }
for (int i = start; i < this.length; i++) { for (int i = start; i < length; i++) {
if (this[i] == element) { if (this[i] == element) {
return i; return i;
} }
@ -560,18 +559,15 @@ class JSArray<E> extends Interceptor implements List<E>, JSIndexable {
return -1; return -1;
} }
int lastIndexOf(Object element, [int startIndex]) { int lastIndexOf(Object? element, [int? startIndex]) {
if (startIndex == null) { int start = startIndex ?? this.length - 1;
startIndex = this.length - 1; if (start < 0) {
} else { return -1;
if (startIndex < 0) {
return -1;
}
if (startIndex >= this.length) {
startIndex = this.length - 1;
}
} }
for (int i = startIndex; i >= 0; i--) { if (start >= this.length) {
start = this.length - 1;
}
for (int i = start; i >= 0; i--) {
if (this[i] == element) { if (this[i] == element) {
return i; return i;
} }
@ -579,9 +575,10 @@ class JSArray<E> extends Interceptor implements List<E>, JSIndexable {
return -1; return -1;
} }
bool contains(Object other) { bool contains(Object? other) {
for (int i = 0; i < length; i++) { for (int i = 0; i < length; i++) {
if (this[i] == other) return true; E element = JS('', '#[#]', this, i);
if (element == other) return true;
} }
return false; return false;
} }
@ -646,13 +643,7 @@ class JSArray<E> extends Interceptor implements List<E>, JSIndexable {
Iterable<T> whereType<T>() => new WhereTypeIterable<T>(this); Iterable<T> whereType<T>() => new WhereTypeIterable<T>(this);
List<E> operator +(List<E> other) { List<E> operator +(List<E> other) => [...this, ...other];
int totalLength = this.length + other.length;
return <E>[]
..length = totalLength
..setRange(0, this.length, this)
..setRange(this.length, totalLength, other);
}
int indexWhere(bool test(E element), [int start = 0]) { int indexWhere(bool test(E element), [int start = 0]) {
if (start >= this.length) return -1; if (start >= this.length) return -1;
@ -663,7 +654,7 @@ class JSArray<E> extends Interceptor implements List<E>, JSIndexable {
return -1; return -1;
} }
int lastIndexWhere(bool test(E element), [int start]) { int lastIndexWhere(bool test(E element), [int? start]) {
if (start == null) start = this.length - 1; if (start == null) start = this.length - 1;
if (start < 0) return -1; if (start < 0) return -1;
for (int i = start; i >= 0; i--) { for (int i = start; i >= 0; i--) {
@ -692,7 +683,7 @@ class JSArray<E> extends Interceptor implements List<E>, JSIndexable {
/// 'isGrowable' and 'isMutable' checks into the getInterceptor implementation /// 'isGrowable' and 'isMutable' checks into the getInterceptor implementation
/// so these classes can have specialized implementations. Doing so will /// so these classes can have specialized implementations. Doing so will
/// challenge many assumptions in the JS backend. /// challenge many assumptions in the JS backend.
class JSMutableArray<E> extends JSArray<E> implements JSMutableIndexable {} class JSMutableArray<E> extends JSArray<E> implements JSMutableIndexable<E> {}
class JSFixedArray<E> extends JSMutableArray<E> {} class JSFixedArray<E> extends JSMutableArray<E> {}
@ -706,14 +697,14 @@ class ArrayIterator<E> implements Iterator<E> {
final JSArray<E> _iterable; final JSArray<E> _iterable;
final int _length; final int _length;
int _index; int _index;
E _current; E? _current;
ArrayIterator(JSArray<E> iterable) ArrayIterator(JSArray<E> iterable)
: _iterable = iterable, : _iterable = iterable,
_length = iterable.length, _length = iterable.length,
_index = 0; _index = 0;
E get current => _current; E get current => _current as E;
bool moveNext() { bool moveNext() {
int length = _iterable.length; int length = _iterable.length;

Some files were not shown because too many files have changed in this diff Show more