Version 2.6.0-dev.2.0
Merge commit '2b4a84efd01e0d1cab8d00152bd8dee25aae4270' into dev
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 8574697..e6efa0d 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -4,8 +4,25 @@
### Language
+* **Breaking change** [#37985](https://github.com/dart-lang/sdk/issues/37985):
+ Inference is changed when using `Null` values in a `FutureOr` context.
+ Namely, constraints of the forms similar to `Null` <: `FutureOr<T>` now
+ yield `Null` as the solution for `T`. For example, the following code will
+ now print "Null", and it was printing "dynamic" before (note that the
+ anonymous closure `() {}` in the example has `Null` as its return type):
+
+```dart
+import 'dart:async';
+void foo<T>(FutureOr<T> Function() f) { print(T); }
+main() { foo(() {}); }
+```
+
+
### Core libraries
+* Default values of parameters of abstract methods are no longer available
+ via `dart:mirrors`.
+
### Dart VM
### Tools
diff --git a/PRESUBMIT.py b/PRESUBMIT.py
index 63a5b47..abfe139 100644
--- a/PRESUBMIT.py
+++ b/PRESUBMIT.py
@@ -18,6 +18,26 @@
def is_cpp_file(path):
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 _CheckFormat(input_api,
identification,
extension,
@@ -243,6 +263,7 @@
def _CommonChecks(input_api, output_api):
results = []
+ results.extend(_CheckNnbdSdkSync(input_api, output_api))
results.extend(_CheckValidHostsInDEPS(input_api, output_api))
results.extend(_CheckDartFormat(input_api, output_api))
results.extend(_CheckStatusFiles(input_api, output_api))
diff --git a/WATCHLISTS b/WATCHLISTS
index 1e08225..c4d820c 100644
--- a/WATCHLISTS
+++ b/WATCHLISTS
@@ -27,6 +27,8 @@
'dart2js': {
'filepath': (
'^pkg/compiler|'
+ '^sdk/lib/_internal/js_runtime|'
+ '^sdk_nnbd/lib/_internal/js_runtime|'
'^tests/compiler/dart2js'
)
},
diff --git a/build/config/linux/BUILD.gn b/build/config/linux/BUILD.gn
index 0db95b7..141ea68 100644
--- a/build/config/linux/BUILD.gn
+++ b/build/config/linux/BUILD.gn
@@ -11,15 +11,13 @@
"-lc++",
"-lc",
"-lm",
+ "-lpthread",
"-lclang_rt.builtins",
"-Wl,--exclude-libs=libc++.a",
]
if (is_asan) {
- ldflags += [
- "-lpthread",
- "-lrt",
- ]
+ ldflags += [ "-lrt" ]
}
if (sysroot != "") {
diff --git a/pkg/analysis_server/lib/protocol/protocol_constants.dart b/pkg/analysis_server/lib/protocol/protocol_constants.dart
index 686011c..55a6571 100644
--- a/pkg/analysis_server/lib/protocol/protocol_constants.dart
+++ b/pkg/analysis_server/lib/protocol/protocol_constants.dart
@@ -172,6 +172,7 @@
'includePedanticFixes';
const String EDIT_REQUEST_DARTFIX_INCLUDE_REQUIRED_FIXES =
'includeRequiredFixes';
+const String EDIT_REQUEST_DARTFIX_OUTPUT_DIR = 'outputDir';
const String EDIT_REQUEST_FORMAT = 'edit.format';
const String EDIT_REQUEST_FORMAT_FILE = 'file';
const String EDIT_REQUEST_FORMAT_LINE_LENGTH = 'lineLength';
diff --git a/pkg/analysis_server/lib/protocol/protocol_generated.dart b/pkg/analysis_server/lib/protocol/protocol_generated.dart
index 46ed75f..74a1344 100644
--- a/pkg/analysis_server/lib/protocol/protocol_generated.dart
+++ b/pkg/analysis_server/lib/protocol/protocol_generated.dart
@@ -7964,6 +7964,7 @@
* "includePedanticFixes": optional bool
* "includeRequiredFixes": optional bool
* "excludedFixes": optional List<String>
+ * "outputDir": optional FilePath
* }
*
* Clients may not extend, implement or mix-in this class.
@@ -7979,6 +7980,8 @@
List<String> _excludedFixes;
+ String _outputDir;
+
/**
* A list of the files and directories for which edits should be suggested.
*
@@ -8066,16 +8069,36 @@
this._excludedFixes = value;
}
+ /**
+ * The absolute and normalized path to a directory to which non-nullability
+ * migration output will be written. The output is only produced if the
+ * non-nullable fix is included. Files in the directory might be overwritten,
+ * but no previously existing files will be deleted.
+ */
+ String get outputDir => _outputDir;
+
+ /**
+ * The absolute and normalized path to a directory to which non-nullability
+ * migration output will be written. The output is only produced if the
+ * non-nullable fix is included. Files in the directory might be overwritten,
+ * but no previously existing files will be deleted.
+ */
+ void set outputDir(String value) {
+ this._outputDir = value;
+ }
+
EditDartfixParams(List<String> included,
{List<String> includedFixes,
bool includePedanticFixes,
bool includeRequiredFixes,
- List<String> excludedFixes}) {
+ List<String> excludedFixes,
+ String outputDir}) {
this.included = included;
this.includedFixes = includedFixes;
this.includePedanticFixes = includePedanticFixes;
this.includeRequiredFixes = includeRequiredFixes;
this.excludedFixes = excludedFixes;
+ this.outputDir = outputDir;
}
factory EditDartfixParams.fromJson(
@@ -8111,11 +8134,17 @@
excludedFixes = jsonDecoder.decodeList(jsonPath + ".excludedFixes",
json["excludedFixes"], jsonDecoder.decodeString);
}
+ String outputDir;
+ if (json.containsKey("outputDir")) {
+ outputDir = jsonDecoder.decodeString(
+ jsonPath + ".outputDir", json["outputDir"]);
+ }
return new EditDartfixParams(included,
includedFixes: includedFixes,
includePedanticFixes: includePedanticFixes,
includeRequiredFixes: includeRequiredFixes,
- excludedFixes: excludedFixes);
+ excludedFixes: excludedFixes,
+ outputDir: outputDir);
} else {
throw jsonDecoder.mismatch(jsonPath, "edit.dartfix params", json);
}
@@ -8142,6 +8171,9 @@
if (excludedFixes != null) {
result["excludedFixes"] = excludedFixes;
}
+ if (outputDir != null) {
+ result["outputDir"] = outputDir;
+ }
return result;
}
@@ -8163,7 +8195,8 @@
includePedanticFixes == other.includePedanticFixes &&
includeRequiredFixes == other.includeRequiredFixes &&
listEqual(excludedFixes, other.excludedFixes,
- (String a, String b) => a == b);
+ (String a, String b) => a == b) &&
+ outputDir == other.outputDir;
}
return false;
}
@@ -8176,6 +8209,7 @@
hash = JenkinsSmiHash.combine(hash, includePedanticFixes.hashCode);
hash = JenkinsSmiHash.combine(hash, includeRequiredFixes.hashCode);
hash = JenkinsSmiHash.combine(hash, excludedFixes.hashCode);
+ hash = JenkinsSmiHash.combine(hash, outputDir.hashCode);
return JenkinsSmiHash.finish(hash);
}
}
diff --git a/pkg/analysis_server/lib/src/computer/computer_overrides.dart b/pkg/analysis_server/lib/src/computer/computer_overrides.dart
index 9bd9102..c1fbda3 100644
--- a/pkg/analysis_server/lib/src/computer/computer_overrides.dart
+++ b/pkg/analysis_server/lib/src/computer/computer_overrides.dart
@@ -131,7 +131,7 @@
List<Element> _superElements = <Element>[];
List<Element> _interfaceElements = <Element>[];
- Set<InterfaceType> _visited = new Set<InterfaceType>();
+ Set<ClassElement> _visited = Set<ClassElement>();
_OverriddenElementsFinder(Element seed) {
_seed = seed;
@@ -152,53 +152,57 @@
*/
OverriddenElements find() {
_visited.clear();
- _addSuperOverrides(_class.type, withThisType: false);
+ _addSuperOverrides(_class, withThisType: false);
_visited.clear();
- _addInterfaceOverrides(_class.type, false);
+ _addInterfaceOverrides(_class, false);
_superElements.forEach(_interfaceElements.remove);
return new OverriddenElements(_seed, _superElements, _interfaceElements);
}
- void _addInterfaceOverrides(InterfaceType type, bool checkType) {
- if (type == null) {
+ void _addInterfaceOverrides(ClassElement class_, bool checkType) {
+ if (class_ == null) {
return;
}
- if (!_visited.add(type)) {
+ if (!_visited.add(class_)) {
return;
}
// this type
if (checkType) {
- Element element = _lookupMember(type.element);
+ Element element = _lookupMember(class_);
if (element != null && !_interfaceElements.contains(element)) {
_interfaceElements.add(element);
}
}
// interfaces
- for (InterfaceType interfaceType in type.interfaces) {
- _addInterfaceOverrides(interfaceType, true);
+ for (InterfaceType interfaceType in class_.interfaces) {
+ _addInterfaceOverrides(interfaceType.element, true);
}
// super
- _addInterfaceOverrides(type.superclass, checkType);
+ _addInterfaceOverrides(class_.supertype?.element, checkType);
}
- void _addSuperOverrides(InterfaceType type, {bool withThisType = true}) {
- if (type == null) {
+ void _addSuperOverrides(ClassElement class_, {bool withThisType = true}) {
+ if (class_ == null) {
return;
}
- if (!_visited.add(type)) {
+ if (!_visited.add(class_)) {
return;
}
if (withThisType) {
- Element element = _lookupMember(type.element);
+ Element element = _lookupMember(class_);
if (element != null && !_superElements.contains(element)) {
_superElements.add(element);
}
}
- _addSuperOverrides(type.superclass);
- type.mixins.forEach(_addSuperOverrides);
- type.superclassConstraints.forEach(_addSuperOverrides);
+ _addSuperOverrides(class_.supertype?.element);
+ for (var mixin_ in class_.mixins) {
+ _addSuperOverrides(mixin_.element);
+ }
+ for (var constraint in class_.superclassConstraints) {
+ _addSuperOverrides(constraint.element);
+ }
}
Element _lookupMember(ClassElement classElement) {
diff --git a/pkg/analysis_server/lib/src/domain_completion.dart b/pkg/analysis_server/lib/src/domain_completion.dart
index 146f3a5..8b5d142 100644
--- a/pkg/analysis_server/lib/src/domain_completion.dart
+++ b/pkg/analysis_server/lib/src/domain_completion.dart
@@ -19,7 +19,6 @@
import 'package:analysis_server/src/services/completion/token_details/token_detail_builder.dart';
import 'package:analyzer/dart/analysis/results.dart';
import 'package:analyzer/dart/analysis/session.dart';
-import 'package:analyzer/dart/element/element.dart' as analyzer;
import 'package:analyzer/src/dart/analysis/driver.dart';
import 'package:analyzer_plugin/protocol/protocol.dart' as plugin;
import 'package:analyzer_plugin/protocol/protocol_common.dart';
@@ -199,46 +198,10 @@
var analysisDriver = server.getAnalysisDriver(file);
var session = analysisDriver.currentSession;
- var fileElement = await session.getUnitElement(file);
- var libraryPath = fileElement.element.librarySource.fullName;
-
- var resolvedLibrary = await session.getResolvedLibrary(libraryPath);
-
- analyzer.LibraryElement requestedLibraryElement;
- try {
- requestedLibraryElement = await session.getLibraryByUri(
- library.uriStr,
- );
- } on ArgumentError catch (e) {
- server.sendResponse(Response.invalidParameter(
- request,
- 'uri',
- 'Invalid URI: ${library.uriStr}\n$e',
- ));
- return;
- }
-
- var requestedElement =
- requestedLibraryElement.exportNamespace.get(requestedName);
- if (requestedElement == null) {
- server.sendResponse(Response.invalidParameter(
- request,
- 'label',
- 'No such element: $requestedName',
- ));
- return;
- }
-
var completion = params.label;
var builder = DartChangeBuilder(session);
- await builder.addFileEdit(libraryPath, (builder) {
- var result = builder.importLibraryElement(
- targetLibrary: resolvedLibrary,
- targetPath: libraryPath,
- targetOffset: params.offset,
- requestedLibrary: requestedLibraryElement,
- requestedElement: requestedElement,
- );
+ await builder.addFileEdit(file, (builder) {
+ var result = builder.importLibraryElement(library.uri);
if (result.prefix != null) {
completion = '${result.prefix}.$completion';
}
diff --git a/pkg/analysis_server/lib/src/edit/edit_dartfix.dart b/pkg/analysis_server/lib/src/edit/edit_dartfix.dart
index fb322eb..6ba64fa 100644
--- a/pkg/analysis_server/lib/src/edit/edit_dartfix.dart
+++ b/pkg/analysis_server/lib/src/edit/edit_dartfix.dart
@@ -73,7 +73,7 @@
}
}
for (DartFixInfo info in fixInfo) {
- info.setup(this, listener);
+ info.setup(this, listener, params);
}
// Validate each included file and directory.
diff --git a/pkg/analysis_server/lib/src/edit/fix/basic_fix_lint_assist_task.dart b/pkg/analysis_server/lib/src/edit/fix/basic_fix_lint_assist_task.dart
index 6d0eb32..60de435 100644
--- a/pkg/analysis_server/lib/src/edit/fix/basic_fix_lint_assist_task.dart
+++ b/pkg/analysis_server/lib/src/edit/fix/basic_fix_lint_assist_task.dart
@@ -3,6 +3,7 @@
// BSD-style license that can be found in the LICENSE file.
import 'package:analysis_server/plugin/edit/assist/assist_core.dart';
+import 'package:analysis_server/protocol/protocol_generated.dart';
import 'package:analysis_server/src/edit/fix/dartfix_listener.dart';
import 'package:analysis_server/src/edit/fix/dartfix_registrar.dart';
import 'package:analysis_server/src/edit/fix/fix_lint_task.dart';
@@ -47,8 +48,8 @@
}
}
- static void preferForElementsToMapFromIterable(
- DartFixRegistrar registrar, DartFixListener listener) {
+ static void preferForElementsToMapFromIterable(DartFixRegistrar registrar,
+ DartFixListener listener, EditDartfixParams params) {
registrar.registerLintTask(
Registry.ruleRegistry['prefer_for_elements_to_map_fromIterable'],
new BasicFixLintAssistTask(
@@ -57,7 +58,9 @@
}
static void preferIfElementsToConditionalExpressions(
- DartFixRegistrar registrar, DartFixListener listener) {
+ DartFixRegistrar registrar,
+ DartFixListener listener,
+ EditDartfixParams params) {
registrar.registerLintTask(
Registry.ruleRegistry['prefer_if_elements_to_conditional_expressions'],
new BasicFixLintAssistTask(
@@ -65,8 +68,8 @@
);
}
- static void preferIntLiterals(
- DartFixRegistrar registrar, DartFixListener listener) {
+ static void preferIntLiterals(DartFixRegistrar registrar,
+ DartFixListener listener, EditDartfixParams params) {
registrar.registerLintTask(
Registry.ruleRegistry['prefer_int_literals'],
new BasicFixLintAssistTask(
@@ -74,8 +77,8 @@
);
}
- static void preferSpreadCollections(
- DartFixRegistrar registrar, DartFixListener listener) {
+ static void preferSpreadCollections(DartFixRegistrar registrar,
+ DartFixListener listener, EditDartfixParams params) {
registrar.registerLintTask(
Registry.ruleRegistry['prefer_spread_collections'],
new BasicFixLintAssistTask(DartAssistKind.CONVERT_TO_SPREAD, listener),
diff --git a/pkg/analysis_server/lib/src/edit/fix/basic_fix_lint_error_task.dart b/pkg/analysis_server/lib/src/edit/fix/basic_fix_lint_error_task.dart
index 2cc7b1c..8275cf0 100644
--- a/pkg/analysis_server/lib/src/edit/fix/basic_fix_lint_error_task.dart
+++ b/pkg/analysis_server/lib/src/edit/fix/basic_fix_lint_error_task.dart
@@ -2,6 +2,7 @@
// 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.
+import 'package:analysis_server/protocol/protocol_generated.dart';
import 'package:analysis_server/src/edit/fix/dartfix_listener.dart';
import 'package:analysis_server/src/edit/fix/dartfix_registrar.dart';
import 'package:analysis_server/src/edit/fix/fix_lint_task.dart';
@@ -15,8 +16,8 @@
BasicFixLintErrorTask(this.fixKind, DartFixListener listener)
: super(listener);
- static void nullClosures(
- DartFixRegistrar registrar, DartFixListener listener) {
+ static void nullClosures(DartFixRegistrar registrar, DartFixListener listener,
+ EditDartfixParams params) {
registrar.registerLintTask(
Registry.ruleRegistry['null_closures'],
new BasicFixLintErrorTask(
@@ -24,8 +25,8 @@
);
}
- static void preferEqualForDefaultValues(
- DartFixRegistrar registrar, DartFixListener listener) {
+ static void preferEqualForDefaultValues(DartFixRegistrar registrar,
+ DartFixListener listener, EditDartfixParams params) {
registrar.registerLintTask(
Registry.ruleRegistry['prefer_equal_for_default_values'],
new BasicFixLintErrorTask(
@@ -33,16 +34,16 @@
);
}
- static void preferIsEmpty(
- DartFixRegistrar registrar, DartFixListener listener) {
+ static void preferIsEmpty(DartFixRegistrar registrar,
+ DartFixListener listener, EditDartfixParams params) {
registrar.registerLintTask(
Registry.ruleRegistry['prefer_is_empty'],
new BasicFixLintErrorTask(DartFixKind.REPLACE_WITH_IS_EMPTY, listener),
);
}
- static void preferIsNotEmpty(
- DartFixRegistrar registrar, DartFixListener listener) {
+ static void preferIsNotEmpty(DartFixRegistrar registrar,
+ DartFixListener listener, EditDartfixParams params) {
registrar.registerLintTask(
Registry.ruleRegistry['prefer_is_not_empty'],
new BasicFixLintErrorTask(
diff --git a/pkg/analysis_server/lib/src/edit/fix/dartfix_info.dart b/pkg/analysis_server/lib/src/edit/fix/dartfix_info.dart
index 2fa706f..987a5bc 100644
--- a/pkg/analysis_server/lib/src/edit/fix/dartfix_info.dart
+++ b/pkg/analysis_server/lib/src/edit/fix/dartfix_info.dart
@@ -2,15 +2,16 @@
// 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.
-import 'package:analysis_server/protocol/protocol_generated.dart' show DartFix;
+import 'package:analysis_server/protocol/protocol_generated.dart'
+ show DartFix, EditDartfixParams;
import 'package:analysis_server/src/edit/edit_dartfix.dart';
+import 'package:analysis_server/src/edit/fix/basic_fix_lint_assist_task.dart';
+import 'package:analysis_server/src/edit/fix/basic_fix_lint_error_task.dart';
import 'package:analysis_server/src/edit/fix/dartfix_listener.dart';
import 'package:analysis_server/src/edit/fix/dartfix_registrar.dart';
import 'package:analysis_server/src/edit/fix/fix_error_task.dart';
import 'package:analysis_server/src/edit/fix/non_nullable_fix.dart';
import 'package:analysis_server/src/edit/fix/prefer_mixin_fix.dart';
-import 'package:analysis_server/src/edit/fix/basic_fix_lint_assist_task.dart';
-import 'package:analysis_server/src/edit/fix/basic_fix_lint_error_task.dart';
const allFixes = <DartFixInfo>[
//
@@ -186,7 +187,8 @@
final bool isDefault;
final bool isPedantic;
final bool isRequired;
- final void Function(DartFixRegistrar dartfix, DartFixListener listener) setup;
+ final void Function(DartFixRegistrar dartfix, DartFixListener listener,
+ EditDartfixParams params) setup;
const DartFixInfo(
this.key,
diff --git a/pkg/analysis_server/lib/src/edit/fix/fix_error_task.dart b/pkg/analysis_server/lib/src/edit/fix/fix_error_task.dart
index 97c2233..11439bc 100644
--- a/pkg/analysis_server/lib/src/edit/fix/fix_error_task.dart
+++ b/pkg/analysis_server/lib/src/edit/fix/fix_error_task.dart
@@ -3,6 +3,7 @@
// BSD-style license that can be found in the LICENSE file.
import 'package:analysis_server/plugin/edit/fix/fix_core.dart';
+import 'package:analysis_server/protocol/protocol_generated.dart';
import 'package:analysis_server/src/edit/edit_dartfix.dart';
import 'package:analysis_server/src/edit/fix/dartfix_listener.dart';
import 'package:analysis_server/src/edit/fix/dartfix_registrar.dart';
@@ -62,8 +63,8 @@
}
}
- static void fixNamedConstructorTypeArgs(
- DartFixRegistrar registrar, DartFixListener listener) {
+ static void fixNamedConstructorTypeArgs(DartFixRegistrar registrar,
+ DartFixListener listener, EditDartfixParams params) {
registrar.registerErrorTask(
StaticTypeWarningCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS_CONSTRUCTOR,
new FixErrorTask(listener));
diff --git a/pkg/analysis_server/lib/src/edit/fix/non_nullable_fix.dart b/pkg/analysis_server/lib/src/edit/fix/non_nullable_fix.dart
index bc771f2..5a67460 100644
--- a/pkg/analysis_server/lib/src/edit/fix/non_nullable_fix.dart
+++ b/pkg/analysis_server/lib/src/edit/fix/non_nullable_fix.dart
@@ -2,12 +2,15 @@
// 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.
+import 'package:analysis_server/protocol/protocol_generated.dart';
import 'package:analysis_server/src/edit/fix/dartfix_listener.dart';
import 'package:analysis_server/src/edit/fix/dartfix_registrar.dart';
import 'package:analysis_server/src/edit/fix/fix_code_task.dart';
+import 'package:analysis_server/src/edit/nnbd_migration/instrumentation_listener.dart';
import 'package:analyzer/dart/analysis/results.dart';
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/file_system/file_system.dart';
+import 'package:analyzer/file_system/overlay_file_system.dart';
import 'package:analyzer/src/dart/analysis/experiments.dart';
import 'package:analyzer/src/generated/source.dart';
import 'package:analyzer/src/task/options.dart';
@@ -26,17 +29,25 @@
final DartFixListener listener;
- final NullabilityMigration migration;
+ final String outputDir;
+
+ InstrumentationListener instrumentationListener;
+
+ NullabilityMigration migration;
/// If this flag has a value of `false`, then something happened to prevent
/// at least one package from being marked as non-nullable.
/// If this occurs, then don't update any code.
bool _packageIsNNBD = true;
- NonNullableFix(this.listener)
- : migration = new NullabilityMigration(
- new NullabilityMigrationAdapter(listener),
- permissive: _usePermissiveMode);
+ NonNullableFix(this.listener, this.outputDir) {
+ instrumentationListener =
+ outputDir == null ? null : InstrumentationListener();
+ migration = new NullabilityMigration(
+ new NullabilityMigrationAdapter(listener),
+ permissive: _usePermissiveMode,
+ instrumentation: instrumentationListener);
+ }
@override
int get numPhases => 2;
@@ -44,6 +55,14 @@
@override
Future<void> finish() async {
migration.finish();
+ if (outputDir != null) {
+ OverlayResourceProvider provider = listener.server.resourceProvider;
+ Folder outputFolder = provider.getFolder(outputDir);
+ if (!outputFolder.exists) {
+ outputFolder.create();
+ }
+ _generateOutput(outputFolder);
+ }
}
/// If the package contains an analysis_options.yaml file, then update the
@@ -176,8 +195,21 @@
_packageIsNNBD = false;
}
- static void task(DartFixRegistrar registrar, DartFixListener listener) {
- registrar.registerCodeTask(new NonNullableFix(listener));
+ /// Generate output into the given [folder].
+ void _generateOutput(Folder folder) {
+ File main = folder.getChildAssumingFile('main.html');
+ main.writeAsStringSync('''
+<html>
+<body>
+Generated output at ${DateTime.now()}.
+</body>
+</html>
+''');
+ }
+
+ static void task(DartFixRegistrar registrar, DartFixListener listener,
+ EditDartfixParams params) {
+ registrar.registerCodeTask(new NonNullableFix(listener, params.outputDir));
}
}
diff --git a/pkg/analysis_server/lib/src/edit/fix/prefer_mixin_fix.dart b/pkg/analysis_server/lib/src/edit/fix/prefer_mixin_fix.dart
index 0d6bcef..4c784d7 100644
--- a/pkg/analysis_server/lib/src/edit/fix/prefer_mixin_fix.dart
+++ b/pkg/analysis_server/lib/src/edit/fix/prefer_mixin_fix.dart
@@ -3,6 +3,7 @@
// BSD-style license that can be found in the LICENSE file.
import 'package:analysis_server/plugin/edit/assist/assist_core.dart';
+import 'package:analysis_server/protocol/protocol_generated.dart';
import 'package:analysis_server/src/edit/fix/dartfix_listener.dart';
import 'package:analysis_server/src/edit/fix/dartfix_registrar.dart';
import 'package:analysis_server/src/edit/fix/fix_code_task.dart';
@@ -91,7 +92,8 @@
@override
Future<void> processUnit(int phase, ResolvedUnitResult result) async {}
- static void task(DartFixRegistrar registrar, DartFixListener listener) {
+ static void task(DartFixRegistrar registrar, DartFixListener listener,
+ EditDartfixParams params) {
var task = new PreferMixinFix(listener);
registrar.registerLintTask(Registry.ruleRegistry['prefer_mixin'], task);
registrar.registerCodeTask(task);
diff --git a/pkg/analysis_server/lib/src/edit/nnbd_migration/instrumentation_information.dart b/pkg/analysis_server/lib/src/edit/nnbd_migration/instrumentation_information.dart
new file mode 100644
index 0000000..1e60891
--- /dev/null
+++ b/pkg/analysis_server/lib/src/edit/nnbd_migration/instrumentation_information.dart
@@ -0,0 +1,84 @@
+// Copyright (c) 2019, 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.
+
+import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/src/generated/source.dart';
+import 'package:nnbd_migration/instrumentation.dart';
+import 'package:nnbd_migration/nnbd_migration.dart';
+
+/// The instrumentation information gathered from the migration engine.
+class InstrumentationInformation {
+ /// The node used for type sources that are always `null`.
+ NullabilityNodeInfo always;
+
+ /// A map from elements outside of the code being migrated, to the nullability
+ /// nodes associated with the type of the element.
+ final Map<Element, DecoratedTypeInfo> externalDecoratedType = {};
+
+ /// A map from the graph edges between nullability nodes, to information about
+ /// the edge that was created and why it was created.
+ final Map<EdgeInfo, EdgeOriginInfo> edgeOrigin = {};
+
+ /// The node used for type sources that are never `null`.
+ NullabilityNodeInfo never;
+
+ /// A list of the steps in the propagation of nullability information through
+ /// the nullability graph, to report details of the step that was performed
+ /// and why it was performed.
+ final List<PropagationInfo> propagationSteps = [];
+
+ /// The instrumentation information that is specific to a single source.
+ final Map<Source, SourceInformation> sourceInformation = {};
+
+ /// Initialize a newly created holder of instrumentation information.
+ InstrumentationInformation();
+}
+
+/// The instrumentation information gathered from the migration engine that is
+/// specific to a single source.
+class SourceInformation {
+ /// A map from the type annotations found in the source code, to the
+ /// nullability nodes that are associated with that type.
+ final Map<TypeAnnotation, NullabilityNodeInfo> explicitTypeNullability = {};
+
+ /// A map from the fixes that were decided on to the reasons for the fix.
+ final Map<SingleNullabilityFix, List<FixReasonInfo>> fixes = {};
+
+ /// A map from AST nodes that have an implicit return type to the nullability
+ /// node associated with the implicit return type of the AST node. The node
+ /// can be an
+ /// - executable declaration,
+ /// - function-typed formal parameter declaration,
+ /// - function type alias declaration,
+ /// - generic function type, or
+ /// - function expression.
+ final Map<AstNode, DecoratedTypeInfo> implicitReturnType = {};
+
+ /// A map from AST nodes that have an implicit type to the nullability node
+ /// associated with the implicit type of the AST node. The node can be a
+ /// - formal parameter,
+ /// - declared identifier, or
+ /// - variable in a variable declaration list.
+ final Map<AstNode, DecoratedTypeInfo> implicitType = {};
+
+ /// Called whenever the migration engine encounters an AST node with implicit
+ /// type arguments, to report the nullability nodes associated with the
+ /// implicit type arguments of the AST node.
+ ///
+ /// A map from AST nodes that have implicit type arguments to the nullability
+ /// nodes associated with the implicit type arguments of the AST node. The
+ /// node can be a
+ /// - constructor redirection,
+ /// - function expression invocation,
+ /// - method invocation,
+ /// - instance creation expression,
+ /// - list/map/set literal, or
+ /// - type annotation.
+ final Map<AstNode, List<DecoratedTypeInfo>> implicitTypeArguments = {};
+
+ /// Initialize a newly created holder of instrumentation information that is
+ /// specific to a single source.
+ SourceInformation();
+}
diff --git a/pkg/analysis_server/lib/src/edit/nnbd_migration/instrumentation_listener.dart b/pkg/analysis_server/lib/src/edit/nnbd_migration/instrumentation_listener.dart
new file mode 100644
index 0000000..bb3f1d0
--- /dev/null
+++ b/pkg/analysis_server/lib/src/edit/nnbd_migration/instrumentation_listener.dart
@@ -0,0 +1,75 @@
+// Copyright (c) 2019, 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.
+
+import 'package:analysis_server/src/edit/nnbd_migration/instrumentation_information.dart';
+import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/src/generated/source.dart';
+import 'package:nnbd_migration/instrumentation.dart';
+import 'package:nnbd_migration/nnbd_migration.dart';
+
+/// A listener used to gather instrumentation information from the migration
+/// engine.
+class InstrumentationListener implements NullabilityMigrationInstrumentation {
+ /// The instrumentation information being gathered.
+ InstrumentationInformation data = InstrumentationInformation();
+
+ /// Initialize a newly created listener.
+ InstrumentationListener();
+
+ @override
+ void explicitTypeNullability(
+ Source source, TypeAnnotation typeAnnotation, NullabilityNodeInfo node) {
+ _sourceInfo(source).explicitTypeNullability[typeAnnotation] = node;
+ }
+
+ @override
+ void externalDecoratedType(Element element, DecoratedTypeInfo decoratedType) {
+ data.externalDecoratedType[element] = decoratedType;
+ }
+
+ @override
+ void fix(SingleNullabilityFix fix, Iterable<FixReasonInfo> reasons) {
+ _sourceInfo(fix.source).fixes[fix] = reasons.toList();
+ }
+
+ @override
+ void graphEdge(EdgeInfo edge, EdgeOriginInfo originInfo) {
+ data.edgeOrigin[edge] = originInfo;
+ }
+
+ @override
+ void immutableNodes(NullabilityNodeInfo never, NullabilityNodeInfo always) {
+ data.never = never;
+ data.always = always;
+ }
+
+ @override
+ void implicitReturnType(
+ Source source, AstNode node, DecoratedTypeInfo decoratedReturnType) {
+ _sourceInfo(source).implicitReturnType[node] = decoratedReturnType;
+ }
+
+ @override
+ void implicitType(
+ Source source, AstNode node, DecoratedTypeInfo decoratedType) {
+ _sourceInfo(source).implicitType[node] = decoratedType;
+ }
+
+ @override
+ void implicitTypeArguments(
+ Source source, AstNode node, Iterable<DecoratedTypeInfo> types) {
+ _sourceInfo(source).implicitTypeArguments[node] = types.toList();
+ }
+
+ @override
+ void propagationStep(PropagationInfo info) {
+ data.propagationSteps.add(info);
+ }
+
+ /// Return the source information associated with the given [source], creating
+ /// it if there has been no previous information for that source.
+ SourceInformation _sourceInfo(Source source) =>
+ data.sourceInformation.putIfAbsent(source, () => SourceInformation());
+}
diff --git a/pkg/analysis_server/lib/src/edit/nnbd_migration/instrumentation_renderer.dart b/pkg/analysis_server/lib/src/edit/nnbd_migration/instrumentation_renderer.dart
new file mode 100644
index 0000000..0fec5d3
--- /dev/null
+++ b/pkg/analysis_server/lib/src/edit/nnbd_migration/instrumentation_renderer.dart
@@ -0,0 +1,98 @@
+import 'package:analysis_server/src/edit/nnbd_migration/migration_info.dart';
+import 'package:mustache/mustache.dart' as mustache;
+
+/// Instrumentation display output for a library that was migrated to use non-nullable types.
+class InstrumentationRenderer {
+ /// Display information for a library.
+ final LibraryInfo info;
+
+ /// Creates an output object for the given library info.
+ InstrumentationRenderer(this.info);
+
+ /// Builds an HTML view of the instrumentation information in [info].
+ String render() {
+ int previousIndex = 0;
+ Map<String, dynamic> mustacheContext = {'units': <Map<String, dynamic>>[]};
+ for (var compilationUnit in info.units) {
+ StringBuffer buffer = StringBuffer();
+ for (var region in compilationUnit.regions) {
+ if (region.offset > previousIndex) {
+ // Display a region of unmodified content.
+ buffer.write(
+ compilationUnit.content.substring(previousIndex, region.offset));
+ previousIndex = region.offset + region.length;
+ }
+ buffer.write(_regionWithTooltip(region, compilationUnit.content));
+ }
+ if (previousIndex < compilationUnit.content.length) {
+ // Last region of unmodified content.
+ buffer.write(compilationUnit.content.substring(previousIndex));
+ }
+ mustacheContext['units']
+ .add({'path': compilationUnit.path, 'content': buffer.toString()});
+ }
+ return _template.renderString(mustacheContext);
+ }
+
+ String _regionWithTooltip(RegionInfo region, String content) {
+ String regionContent =
+ content.substring(region.offset, region.offset + region.length);
+ return '<span class="region">$regionContent'
+ '<span class="tooltip">${region.explanation}</span></span>';
+ }
+}
+
+/// A mustache template for one library's instrumentation output.
+mustache.Template _template = mustache.Template(r'''
+<html>
+ <head>
+ <title>Non-nullable fix instrumentation report</title>
+ <style>
+h2 {
+ font-size: 1em;
+ font-weight: bold;
+}
+
+div.content {
+ font-family: monospace;
+ whitespace: pre;
+}
+
+.region {
+ /* Green means this region was added. */
+ color: green;
+ display: inline-block;
+ position: relative;
+}
+
+.region .tooltip {
+ background-color: #EEE;
+ border: solid 2px #999;
+ color: #333;
+ left: 50%;
+ margin-left: -50px;
+ padding: 1px;
+ position: absolute;
+ top: 120%;
+ visibility: hidden;
+ width: 100px;
+ z-index: 1;
+}
+
+.region:hover .tooltip {
+ visibility: visible;
+}
+ </style>
+ </head>
+ <body>
+ <h1>Non-nullable fix instrumentation report</h1>
+ <p><em>Well-written introduction to this report.</em></p>
+ {{# units }}
+ <h2>{{ path }}</h2>
+ <div class="content">
+ {{{ content }}}
+ </div> {{! content }}
+ {{/ units }}
+ </body>
+</html>
+''');
diff --git a/pkg/analysis_server/lib/src/edit/nnbd_migration/migration_info.dart b/pkg/analysis_server/lib/src/edit/nnbd_migration/migration_info.dart
new file mode 100644
index 0000000..2f872624
--- /dev/null
+++ b/pkg/analysis_server/lib/src/edit/nnbd_migration/migration_info.dart
@@ -0,0 +1,45 @@
+// Copyright (c) 2019, 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.
+
+/// The migration information associated with a single library.
+class LibraryInfo {
+ /// The information about the units in the library. The information about the
+ /// defining compilation unit is always first.
+ final List<UnitInfo> units;
+
+ /// Initialize a newly created library.
+ LibraryInfo(this.units);
+}
+
+/// A description of an explanation associated with a region of code that was
+/// modified.
+class RegionInfo {
+ /// The offset to the beginning of the region.
+ final int offset;
+
+ /// The length of the region.
+ final int length;
+
+ /// The explanation to be displayed for the region.
+ final String explanation;
+
+ /// Initialize a newly created region.
+ RegionInfo(this.offset, this.length, this.explanation);
+}
+
+/// The migration information associated with a single compilation unit.
+class UnitInfo {
+ /// The absolute and normalized path of the unit.
+ final String path;
+
+ /// The content of unit.
+ final String content;
+
+ /// The information about the regions that have an explanation associated with
+ /// them.
+ final List<RegionInfo> regions;
+
+ /// Initialize a newly created unit.
+ UnitInfo(this.path, this.content, this.regions);
+}
diff --git a/pkg/analysis_server/lib/src/lsp/handlers/handler_completion_resolve.dart b/pkg/analysis_server/lib/src/lsp/handlers/handler_completion_resolve.dart
index 25b0e2d..698e088 100644
--- a/pkg/analysis_server/lib/src/lsp/handlers/handler_completion_resolve.dart
+++ b/pkg/analysis_server/lib/src/lsp/handlers/handler_completion_resolve.dart
@@ -77,11 +77,6 @@
var analysisDriver = server.getAnalysisDriver(data.file);
var session = analysisDriver.currentSession;
- var fileElement = await session.getUnitElement(data.file);
- var libraryPath = fileElement.element.librarySource.fullName;
-
- var resolvedLibrary = await session.getResolvedLibrary(libraryPath);
-
if (token.isCancellationRequested) {
return cancelled();
}
@@ -115,14 +110,8 @@
var newInsertText = item.insertText ?? item.label;
final builder = DartChangeBuilder(session);
- await builder.addFileEdit(libraryPath, (builder) {
- final result = builder.importLibraryElement(
- targetLibrary: resolvedLibrary,
- targetPath: libraryPath,
- targetOffset: data.offset,
- requestedLibrary: requestedLibraryElement,
- requestedElement: requestedElement,
- );
+ await builder.addFileEdit(data.file, (builder) {
+ final result = builder.importLibraryElement(library.uri);
if (result.prefix != null) {
newInsertText = '${result.prefix}.$newInsertText';
}
diff --git a/pkg/analysis_server/lib/src/search/type_hierarchy.dart b/pkg/analysis_server/lib/src/search/type_hierarchy.dart
index e4bcfe5..13e8262 100644
--- a/pkg/analysis_server/lib/src/search/type_hierarchy.dart
+++ b/pkg/analysis_server/lib/src/search/type_hierarchy.dart
@@ -52,12 +52,9 @@
* Returns the computed type hierarchy, maybe `null`.
*/
Future<List<TypeHierarchyItem>> compute() async {
- // TODO(brianwilkerson) Determine whether this await is necessary.
- await null;
if (_pivotClass != null) {
- InterfaceType type = _pivotClass.type;
- _createSuperItem(type);
- await _createSubclasses(_items[0], 0, type);
+ _createSuperItem(_pivotClass, null);
+ await _createSubclasses(_items[0], 0, _pivotClass);
return _items;
}
return null;
@@ -68,19 +65,15 @@
*/
List<TypeHierarchyItem> computeSuper() {
if (_pivotClass != null) {
- InterfaceType type = _pivotClass.type;
- _createSuperItem(type);
+ _createSuperItem(_pivotClass, null);
return _items;
}
return null;
}
Future _createSubclasses(
- TypeHierarchyItem item, int itemId, InterfaceType type) async {
- // TODO(brianwilkerson) Determine whether this await is necessary.
- await null;
- Set<ClassElement> subElements =
- await getDirectSubClasses(_searchEngine, type.element);
+ TypeHierarchyItem item, int itemId, ClassElement classElement) async {
+ var subElements = await getDirectSubClasses(_searchEngine, classElement);
List<int> subItemIds = <int>[];
for (ClassElement subElement in subElements) {
// check for recursion
@@ -110,14 +103,14 @@
for (int subItemId in subItemIds) {
TypeHierarchyItem subItem = _items[subItemId];
ClassElement subItemElement = _itemClassElements[subItemId];
- InterfaceType subType = subItemElement.type;
- await _createSubclasses(subItem, subItemId, subType);
+ await _createSubclasses(subItem, subItemId, subItemElement);
}
}
- int _createSuperItem(InterfaceType type) {
+ int _createSuperItem(
+ ClassElement classElement, List<DartType> typeArguments) {
// check for recursion
- TypeHierarchyItem item = _elementItemMap[type.element];
+ TypeHierarchyItem item = _elementItemMap[classElement];
if (item != null) {
return _items.indexOf(item);
}
@@ -125,10 +118,10 @@
int itemId;
{
String displayName = null;
- if (type.typeArguments.isNotEmpty) {
- displayName = type.toString();
+ if (typeArguments != null && typeArguments.isNotEmpty) {
+ displayName =
+ classElement.displayName + '<' + typeArguments.join(', ') + '>';
}
- ClassElement classElement = type.element;
ExecutableElement memberElement = _findMemberElement(classElement);
item = new TypeHierarchyItem(convertElement(classElement),
displayName: displayName,
@@ -141,19 +134,22 @@
}
// superclass
{
- InterfaceType superType = type.superclass;
+ InterfaceType superType = classElement.supertype;
if (superType != null) {
- item.superclass = _createSuperItem(superType);
+ item.superclass = _createSuperItem(
+ superType.element,
+ superType.typeArguments,
+ );
}
}
// mixins
- type.mixins.forEach((InterfaceType type) {
- int id = _createSuperItem(type);
+ classElement.mixins.forEach((InterfaceType type) {
+ int id = _createSuperItem(type.element, type.typeArguments);
item.mixins.add(id);
});
// interfaces
- type.interfaces.forEach((InterfaceType type) {
- int id = _createSuperItem(type);
+ classElement.interfaces.forEach((InterfaceType type) {
+ int id = _createSuperItem(type.element, type.typeArguments);
item.interfaces.add(id);
});
// done
diff --git a/pkg/analysis_server/lib/src/server/driver.dart b/pkg/analysis_server/lib/src/server/driver.dart
index f6febdc..15e715c 100644
--- a/pkg/analysis_server/lib/src/server/driver.dart
+++ b/pkg/analysis_server/lib/src/server/driver.dart
@@ -6,8 +6,6 @@
import 'dart:ffi' as ffi;
import 'dart:io';
import 'dart:math';
-import 'package:analysis_server/src/utilities/request_statistics.dart';
-import 'package:path/path.dart' as path;
import 'package:analysis_server/protocol/protocol_constants.dart'
show PROTOCOL_VERSION;
@@ -25,11 +23,11 @@
import 'package:analysis_server/src/services/completion/dart/uri_contributor.dart'
show UriContributor;
import 'package:analysis_server/src/socket_server.dart';
+import 'package:analysis_server/src/utilities/request_statistics.dart';
import 'package:analysis_server/starter.dart';
import 'package:analyzer/file_system/physical_file_system.dart';
import 'package:analyzer/instrumentation/file_instrumentation.dart';
import 'package:analyzer/instrumentation/instrumentation.dart';
-import 'package:analyzer/src/dart/analysis/driver.dart';
import 'package:analyzer/src/dart/sdk/sdk.dart';
import 'package:analyzer/src/generated/engine.dart';
import 'package:analyzer/src/generated/sdk.dart';
@@ -37,6 +35,7 @@
import 'package:args/args.dart';
import 'package:front_end/src/fasta/compiler_context.dart';
import 'package:linter/src/rules.dart' as linter;
+import 'package:path/path.dart' as path;
import 'package:telemetry/crash_reporting.dart';
import 'package:telemetry/telemetry.dart' as telemetry;
@@ -300,11 +299,6 @@
static const String COMPLETION_MODEL_FOLDER = "completion-model";
/**
- * The name of the flag to use summary2.
- */
- static const String USE_SUMMARY2 = "use-summary2";
-
- /**
* A directory to analyze in order to train an analysis server snapshot.
*/
static const String TRAIN_USING = "train-using";
@@ -370,8 +364,6 @@
'lexeme');
}
- AnalysisDriver.useSummary2 = results[USE_SUMMARY2];
-
bool disableAnalyticsForSession = results[SUPPRESS_ANALYTICS_FLAG];
if (results.wasParsed(TRAIN_USING)) {
disableAnalyticsForSession = true;
@@ -592,6 +584,36 @@
}
}
+ /// This will be invoked after createAnalysisServer has been called on the
+ /// socket server. At that point, we'll be able to send a server.error
+ /// notification in case model startup fails.
+ void startCompletionRanking(
+ SocketServer socketServer,
+ LspSocketServer lspSocketServer,
+ AnalysisServerOptions analysisServerOptions) {
+ if (analysisServerOptions.completionModelFolder == null ||
+ ffi.sizeOf<ffi.IntPtr>() == 4) {
+ return;
+ }
+
+ // Start completion model isolate if this is a 64 bit system and
+ // analysis server was configured to load a language model on disk.
+ CompletionRanking.instance =
+ CompletionRanking(analysisServerOptions.completionModelFolder);
+ CompletionRanking.instance.start().catchError((error) {
+ // Disable smart ranking if model startup fails.
+ analysisServerOptions.completionModelFolder = null;
+ CompletionRanking.instance = null;
+ if (socketServer != null) {
+ socketServer.analysisServer.sendServerErrorNotification(
+ 'Failed to start ranking model isolate', error, error.stackTrace);
+ } else {
+ lspSocketServer.analysisServer.sendServerErrorNotification(
+ 'Failed to start ranking model isolate', error, error.stackTrace);
+ }
+ });
+ }
+
void startLspServer(
ArgResults args,
AnalysisServerOptions analysisServerOptions,
@@ -634,36 +656,6 @@
});
}
- /// This will be invoked after createAnalysisServer has been called on the
- /// socket server. At that point, we'll be able to send a server.error
- /// notification in case model startup fails.
- void startCompletionRanking(
- SocketServer socketServer,
- LspSocketServer lspSocketServer,
- AnalysisServerOptions analysisServerOptions) {
- if (analysisServerOptions.completionModelFolder == null ||
- ffi.sizeOf<ffi.IntPtr>() == 4) {
- return;
- }
-
- // Start completion model isolate if this is a 64 bit system and
- // analysis server was configured to load a language model on disk.
- CompletionRanking.instance =
- CompletionRanking(analysisServerOptions.completionModelFolder);
- CompletionRanking.instance.start().catchError((error) {
- // Disable smart ranking if model startup fails.
- analysisServerOptions.completionModelFolder = null;
- CompletionRanking.instance = null;
- if (socketServer != null) {
- socketServer.analysisServer.sendServerErrorNotification(
- 'Failed to start ranking model isolate', error, error.stackTrace);
- } else {
- lspSocketServer.analysisServer.sendServerErrorNotification(
- 'Failed to start ranking model isolate', error, error.stackTrace);
- }
- });
- }
-
/**
* Execute the given [callback] within a zone that will capture any unhandled
* exceptions and both report them to the client and send them to the given
@@ -792,8 +784,6 @@
help: "Whether or not to turn on ML ranking for code completion");
parser.addOption(COMPLETION_MODEL_FOLDER,
help: "[path] path to the location of a code completion model");
- parser.addFlag(USE_SUMMARY2,
- defaultsTo: false, help: "Whether to use summary2");
parser.addOption(TRAIN_USING,
help: "Pass in a directory to analyze for purposes of training an "
"analysis server snapshot.");
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/completion_manager.dart b/pkg/analysis_server/lib/src/services/completion/dart/completion_manager.dart
index 4d77c9c..1a90a96 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/completion_manager.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/completion_manager.dart
@@ -41,7 +41,7 @@
import 'package:analyzer/dart/element/type.dart';
import 'package:analyzer/file_system/file_system.dart';
import 'package:analyzer/src/dart/analysis/driver_based_analysis_context.dart';
-import 'package:analyzer/src/generated/engine.dart' hide AnalysisResult;
+import 'package:analyzer/src/generated/engine.dart';
import 'package:analyzer/src/generated/source.dart';
import 'package:analyzer_plugin/protocol/protocol_common.dart';
import 'package:analyzer_plugin/protocol/protocol_common.dart' as protocol;
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/label_contributor.dart b/pkg/analysis_server/lib/src/services/completion/dart/label_contributor.dart
index 8076baf..62a2c8b 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/label_contributor.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/label_contributor.dart
@@ -76,6 +76,11 @@
}
@override
+ void declaredExtension(ExtensionDeclaration declaration) {
+ // ignored
+ }
+
+ @override
void declaredField(FieldDeclaration fieldDecl, VariableDeclaration varDecl) {
// ignored
}
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/local_constructor_contributor.dart b/pkg/analysis_server/lib/src/services/completion/dart/local_constructor_contributor.dart
index 3e3cf86..4332192 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/local_constructor_contributor.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/local_constructor_contributor.dart
@@ -11,8 +11,11 @@
show DartCompletionRequestImpl;
import 'package:analysis_server/src/services/completion/dart/suggestion_builder.dart';
import 'package:analysis_server/src/services/completion/dart/utilities.dart';
+import 'package:analyzer/dart/analysis/features.dart';
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/dart/element/nullability_suffix.dart';
+import 'package:analyzer/dart/element/type.dart';
import 'package:analyzer_plugin/protocol/protocol_common.dart' as protocol
show Element, ElementKind;
import 'package:analyzer_plugin/src/utilities/completion/optype.dart';
@@ -74,6 +77,9 @@
void declaredClassTypeAlias(ClassTypeAlias declaration) {}
@override
+ void declaredExtension(ExtensionDeclaration declaration) {}
+
+ @override
void declaredField(FieldDeclaration fieldDecl, VariableDeclaration varDecl) {}
@override
@@ -113,7 +119,7 @@
ClassElement classElement = classDecl.declaredElement;
int relevance = optype.returnValueSuggestionsFilter(
- classElement?.type, DART_RELEVANCE_DEFAULT);
+ _instantiateClassElement(classElement), DART_RELEVANCE_DEFAULT);
if (constructorDecl != null) {
// Build a suggestion for explicitly declared constructor
ConstructorElement element = constructorDecl.declaredElement;
@@ -157,4 +163,24 @@
suggestions.add(suggestion);
}
}
+
+ InterfaceType _instantiateClassElement(ClassElement element) {
+ var typeParameters = element.typeParameters;
+ var typeArguments = const <DartType>[];
+ if (typeParameters.isNotEmpty) {
+ var typeProvider = request.libraryElement.context.typeProvider;
+ typeArguments = typeParameters.map((t) {
+ return typeProvider.dynamicType;
+ }).toList();
+ }
+
+ var nullabilitySuffix = request.featureSet.isEnabled(Feature.non_nullable)
+ ? NullabilitySuffix.none
+ : NullabilitySuffix.star;
+
+ return element.instantiate(
+ typeArguments: typeArguments,
+ nullabilitySuffix: nullabilitySuffix,
+ );
+ }
}
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/local_library_contributor.dart b/pkg/analysis_server/lib/src/services/completion/dart/local_library_contributor.dart
index 942b514..0aeeb94 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/local_library_contributor.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/local_library_contributor.dart
@@ -8,7 +8,9 @@
import 'package:analysis_server/src/services/completion/dart/completion_manager.dart';
import 'package:analysis_server/src/services/completion/dart/suggestion_builder.dart'
show createSuggestion, ElementSuggestionBuilder;
+import 'package:analyzer/dart/analysis/features.dart';
import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/dart/element/nullability_suffix.dart';
import 'package:analyzer/dart/element/type.dart';
import 'package:analyzer/dart/element/visitor.dart';
import 'package:analyzer_plugin/src/utilities/completion/optype.dart';
@@ -47,21 +49,21 @@
if (optype.includeTypeNameSuggestions) {
// if includeTypeNameSuggestions, then use the filter
int relevance = optype.typeNameSuggestionsFilter(
- element.type, DART_RELEVANCE_DEFAULT);
+ _instantiateClassElement(element), DART_RELEVANCE_DEFAULT);
if (relevance != null) {
addSuggestion(element, prefix: prefix, relevance: relevance);
}
}
if (optype.includeConstructorSuggestions) {
int relevance = optype.returnValueSuggestionsFilter(
- element.type, DART_RELEVANCE_DEFAULT);
+ _instantiateClassElement(element), DART_RELEVANCE_DEFAULT);
_addConstructorSuggestions(element, relevance);
}
if (optype.includeReturnValueSuggestions) {
if (element.isEnum) {
String enumName = element.displayName;
int relevance = optype.returnValueSuggestionsFilter(
- element.type, DART_RELEVANCE_DEFAULT);
+ _instantiateClassElement(element), DART_RELEVANCE_DEFAULT);
for (var field in element.fields) {
if (field.isEnumConstant) {
addSuggestion(field,
@@ -85,6 +87,14 @@
}
@override
+ void visitExtensionElement(ExtensionElement element) {
+ if (optype.includeReturnValueSuggestions) {
+ addSuggestion(element, prefix: prefix, relevance: DART_RELEVANCE_DEFAULT);
+ }
+ element.visitChildren(this);
+ }
+
+ @override
void visitFunctionElement(FunctionElement element) {
// Do not suggest operators or local functions
if (element.isOperator) {
@@ -179,6 +189,26 @@
}
}
}
+
+ InterfaceType _instantiateClassElement(ClassElement element) {
+ var typeParameters = element.typeParameters;
+ var typeArguments = const <DartType>[];
+ if (typeParameters.isNotEmpty) {
+ var typeProvider = request.libraryElement.context.typeProvider;
+ typeArguments = typeParameters.map((t) {
+ return typeProvider.dynamicType;
+ }).toList();
+ }
+
+ var nullabilitySuffix = request.featureSet.isEnabled(Feature.non_nullable)
+ ? NullabilitySuffix.none
+ : NullabilitySuffix.star;
+
+ return element.instantiate(
+ typeArguments: typeArguments,
+ nullabilitySuffix: nullabilitySuffix,
+ );
+ }
}
/**
@@ -190,8 +220,6 @@
@override
Future<List<CompletionSuggestion>> computeSuggestions(
DartCompletionRequest request) async {
- // TODO(brianwilkerson) Determine whether this await is necessary.
- await null;
if (!request.includeIdentifiers) {
return const <CompletionSuggestion>[];
}
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/local_reference_contributor.dart b/pkg/analysis_server/lib/src/services/completion/dart/local_reference_contributor.dart
index f5b9ff3..1e2b426 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/local_reference_contributor.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/local_reference_contributor.dart
@@ -11,9 +11,11 @@
show DartCompletionRequestImpl;
import 'package:analysis_server/src/services/completion/dart/utilities.dart';
import 'package:analysis_server/src/services/correction/strings.dart';
+import 'package:analyzer/dart/analysis/features.dart';
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/ast/token.dart';
import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/dart/element/nullability_suffix.dart';
import 'package:analyzer/dart/element/type.dart';
import 'package:analyzer/src/util/comment.dart';
import 'package:analyzer_plugin/protocol/protocol_common.dart' as protocol
@@ -160,6 +162,18 @@
}
@override
+ void declaredExtension(ExtensionDeclaration declaration) {
+ if (optype.includeReturnValueSuggestions) {
+ _addLocalSuggestion_includeReturnValueSuggestions(
+ declaration.documentationComment,
+ declaration.name,
+ NO_RETURN_TYPE,
+ protocol.ElementKind.EXTENSION,
+ isDeprecated: isDeprecated(declaration));
+ }
+ }
+
+ @override
void declaredField(FieldDeclaration fieldDecl, VariableDeclaration varDecl) {
if ((optype.includeReturnValueSuggestions &&
(!optype.inStaticMethodBody || fieldDecl.isStatic)) ||
@@ -444,8 +458,8 @@
bool isDeprecated = false,
int relevance = DART_RELEVANCE_DEFAULT}) {
ClassElement classElement = enumDeclaration.declaredElement;
- relevance =
- optype.returnValueSuggestionsFilter(classElement?.type, relevance);
+ relevance = optype.returnValueSuggestionsFilter(
+ _instantiateClassElement(classElement), relevance);
if (relevance != null) {
_addLocalSuggestion_enumConstant(constantDeclaration, enumDeclaration,
isAbstract: isAbstract,
@@ -524,6 +538,26 @@
addDefaultArgDetails(suggestion, null, requiredParameters, namedParameters);
}
+ InterfaceType _instantiateClassElement(ClassElement element) {
+ var typeParameters = element.typeParameters;
+ var typeArguments = const <DartType>[];
+ if (typeParameters.isNotEmpty) {
+ var typeProvider = request.libraryElement.context.typeProvider;
+ typeArguments = typeParameters.map((t) {
+ return typeProvider.dynamicType;
+ }).toList();
+ }
+
+ var nullabilitySuffix = request.featureSet.isEnabled(Feature.non_nullable)
+ ? NullabilitySuffix.none
+ : NullabilitySuffix.star;
+
+ return element.instantiate(
+ typeArguments: typeArguments,
+ nullabilitySuffix: nullabilitySuffix,
+ );
+ }
+
bool _isVoid(TypeAnnotation returnType) {
if (returnType is TypeName) {
Identifier id = returnType.name;
@@ -536,7 +570,7 @@
DartType _staticTypeOfIdentifier(Identifier id) {
if (id.staticElement is ClassElement) {
- return (id.staticElement as ClassElement).type;
+ return _instantiateClassElement(id.staticElement as ClassElement);
} else {
return id.staticType;
}
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/override_contributor.dart b/pkg/analysis_server/lib/src/services/completion/dart/override_contributor.dart
index 069c71d..ae865b9 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/override_contributor.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/override_contributor.dart
@@ -9,8 +9,11 @@
import 'package:analysis_server/src/protocol_server.dart' as protocol
hide CompletionSuggestion, CompletionSuggestionKind;
import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart';
+import 'package:analyzer/dart/analysis/features.dart';
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/dart/element/nullability_suffix.dart';
+import 'package:analyzer/dart/element/type.dart';
import 'package:analyzer/src/dart/element/inheritance_manager3.dart';
import 'package:analyzer/src/generated/source.dart';
import 'package:analyzer_plugin/src/utilities/completion/completion_target.dart';
@@ -40,7 +43,8 @@
// Generate a collection of inherited members
var classElem = classDecl.declaredElement;
- var interface = inheritance.getInterface(classElem.type);
+ var classType = _thisType(request, classElem);
+ var interface = inheritance.getInterface(classType);
var interfaceMap = interface.map;
var namesToOverride =
_namesToOverride(classElem.librarySource.uri, interface);
@@ -192,4 +196,25 @@
}
return namesToOverride;
}
+
+ InterfaceType _thisType(
+ DartCompletionRequest request,
+ ClassElement thisElement,
+ ) {
+ var typeParameters = thisElement.typeParameters;
+ var typeArguments = const <DartType>[];
+ if (typeParameters.isNotEmpty) {
+ var nullabilitySuffix = request.featureSet.isEnabled(Feature.non_nullable)
+ ? NullabilitySuffix.none
+ : NullabilitySuffix.star;
+ typeArguments = typeParameters.map((t) {
+ return t.instantiate(nullabilitySuffix: nullabilitySuffix);
+ }).toList();
+ }
+
+ return thisElement.instantiate(
+ typeArguments: typeArguments,
+ nullabilitySuffix: NullabilitySuffix.none,
+ );
+ }
}
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/type_member_contributor.dart b/pkg/analysis_server/lib/src/services/completion/dart/type_member_contributor.dart
index ca30c558..6e3172e 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/type_member_contributor.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/type_member_contributor.dart
@@ -147,6 +147,9 @@
}
@override
+ void declaredExtension(ExtensionDeclaration declaration) {}
+
+ @override
void declaredField(FieldDeclaration fieldDecl, VariableDeclaration varDecl) {
if (varDecl.name.name == targetName) {
// Type provided by the element in computeFull above
diff --git a/pkg/analysis_server/lib/src/services/completion/postfix/postfix_completion.dart b/pkg/analysis_server/lib/src/services/completion/postfix/postfix_completion.dart
index 770f7eb5..c93417d 100644
--- a/pkg/analysis_server/lib/src/services/completion/postfix/postfix_completion.dart
+++ b/pkg/analysis_server/lib/src/services/completion/postfix/postfix_completion.dart
@@ -544,17 +544,6 @@
Expression expr = list.firstWhere((expr) {
DartType type = expr.staticType;
if (type == null) return false;
- if (typeSystem.isSubtypeOf(type, builtInType)) return true;
- Element element = type.element;
- if (element is TypeDefiningElement) {
- TypeDefiningElement typeDefElem = element;
- type = typeDefElem.type;
- if (type is ParameterizedType) {
- ParameterizedType pType = type;
- type = pType.instantiate(new List.filled(
- pType.typeParameters.length, typeProvider.dynamicType));
- }
- }
return typeSystem.isSubtypeOf(type, builtInType);
}, orElse: () => null);
if (expr is SimpleIdentifier && expr.parent is PropertyAccess) {
diff --git a/pkg/analysis_server/lib/src/services/correction/assist.dart b/pkg/analysis_server/lib/src/services/correction/assist.dart
index 3d37042..6c51810 100644
--- a/pkg/analysis_server/lib/src/services/correction/assist.dart
+++ b/pkg/analysis_server/lib/src/services/correction/assist.dart
@@ -31,6 +31,8 @@
* An enumeration of possible assist kinds.
*/
class DartAssistKind {
+ static const ADD_NOT_NULL_ASSERT = const AssistKind(
+ 'dart.assist.addNotNullAssert', 30, "Add a not-null assertion");
static const ADD_TYPE_ANNOTATION = const AssistKind(
'dart.assist.addTypeAnnotation', 30, "Add type annotation");
static const ASSIGN_TO_LOCAL_VARIABLE = const AssistKind(
@@ -156,9 +158,7 @@
static const IMPORT_ADD_SHOW = const AssistKind(
'dart.assist.addShowCombinator', 30, "Add explicit 'show' combinator");
static const INLINE_INVOCATION =
- const AssistKind('dart.assist.inline', 30, "Inline invocation of '{0}'",
- // todo (pq): migrate to (conditional) fix
- associatedErrorCodes: <String>['prefer_inlined_adds']);
+ const AssistKind('dart.assist.inline', 30, "Inline invocation of '{0}'");
static const INTRODUCE_LOCAL_CAST_TYPE = const AssistKind(
'dart.assist.introduceLocalCast',
30,
@@ -176,12 +176,10 @@
static const JOIN_VARIABLE_DECLARATION = const AssistKind(
'dart.assist.joinVariableDeclaration', 30, "Join variable declaration");
static const REMOVE_TYPE_ANNOTATION = const AssistKind(
- 'dart.assist.removeTypeAnnotation', 29, "Remove type annotation",
- // todo (pq): migrate to (conditional) fix
- associatedErrorCodes: <String>[
- 'avoid_return_types_on_setters',
- 'type_init_formals'
- ]);
+ // todo (pq): unify w/ fix
+ 'dart.assist.removeTypeAnnotation',
+ 29,
+ "Remove type annotation");
static const REPLACE_CONDITIONAL_WITH_IF_ELSE = const AssistKind(
'dart.assist.convert.conditionalToIfElse',
30,
@@ -193,11 +191,7 @@
static const SORT_CHILD_PROPERTY_LAST = const AssistKind(
'dart.assist.sort.child.properties.last',
30,
- "Move child property to end of arguments",
- // todo (pq): migrate to (conditional) fix
- associatedErrorCodes: <String>[
- 'sort_child_properties_last',
- ]);
+ "Move child property to end of arguments");
static const SPLIT_AND_CONDITION = const AssistKind(
'dart.assist.splitIfConjunction', 30, "Split && condition");
static const SPLIT_VARIABLE_DECLARATION = const AssistKind(
diff --git a/pkg/analysis_server/lib/src/services/correction/assist_internal.dart b/pkg/analysis_server/lib/src/services/correction/assist_internal.dart
index 8d88015..8daaf7b 100644
--- a/pkg/analysis_server/lib/src/services/correction/assist_internal.dart
+++ b/pkg/analysis_server/lib/src/services/correction/assist_internal.dart
@@ -4,6 +4,7 @@
import 'dart:async';
import 'dart:collection';
+import 'dart:math';
import 'package:analysis_server/plugin/edit/assist/assist_core.dart';
import 'package:analysis_server/plugin/edit/assist/assist_dart.dart';
@@ -20,6 +21,7 @@
import 'package:analyzer/dart/ast/token.dart';
import 'package:analyzer/dart/ast/visitor.dart';
import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/dart/element/nullability_suffix.dart';
import 'package:analyzer/dart/element/type.dart';
import 'package:analyzer/src/dart/ast/token.dart';
import 'package:analyzer/src/dart/ast/utilities.dart';
@@ -60,6 +62,7 @@
)) {
await _addProposals_addTypeAnnotation();
}
+ await _addProposal_addNotNullAssert();
await _addProposal_assignToLocalVariable();
await _addProposal_convertClassToMixin();
await _addProposal_convertDocumentationIntoBlock();
@@ -125,7 +128,11 @@
await _addProposal_flutterWrapWidget();
await _addProposal_flutterWrapWidgets();
await _addProposal_importAddShow();
- await _addProposal_inlineAdd();
+ if (!_containsErrorCode(
+ {LintNames.prefer_inlined_adds},
+ )) {
+ await _addProposal_inlineAdd();
+ }
await _addProposal_introduceLocalTestedType();
await _addProposal_invertIf();
await _addProposal_joinIfStatementInner();
@@ -136,7 +143,11 @@
await _addProposal_reparentFlutterList();
await _addProposal_replaceConditionalWithIfElse();
await _addProposal_replaceIfElseWithConditional();
- await _addProposal_sortChildPropertyLast();
+ if (!_containsErrorCode(
+ {LintNames.sort_child_properties_last},
+ )) {
+ await _addProposal_sortChildPropertyLast();
+ }
await _addProposal_splitAndCondition();
await _addProposal_splitVariableDeclaration();
await _addProposal_surroundWith();
@@ -159,10 +170,16 @@
}
}
if (experimentStatus.spread_collections) {
+ final preferSpreadsLintFound =
+ _containsErrorCode({LintNames.prefer_spread_collections});
+ final preferInlinedAddsLintFound =
+ _containsErrorCode({LintNames.prefer_inlined_adds});
if (!_containsErrorCode(
{LintNames.prefer_spread_collections},
)) {
- await _addProposal_convertAddAllToSpread();
+ await _addProposal_convertAddAllToSpread(
+ preferInlinedAdds: !preferInlinedAddsLintFound,
+ convertToSpreads: !preferSpreadsLintFound);
}
}
@@ -210,6 +227,60 @@
assists.add(new Assist(kind, change));
}
+ Future<void> _addProposal_addNotNullAssert() async {
+ final identifier = this.node;
+ if (identifier is SimpleIdentifier) {
+ if (identifier.parent is FormalParameter) {
+ final exp = identifier.parent.thisOrAncestorMatching(
+ (node) => node is FunctionExpression || node is MethodDeclaration);
+ var body;
+ if (exp is FunctionExpression) {
+ body = exp.body;
+ } else if (exp is MethodDeclaration) {
+ body = exp.body;
+ }
+ if (body is BlockFunctionBody) {
+ // Check for an obvious pre-existing assertion.
+ for (var statement in body.block.statements) {
+ if (statement is AssertStatement) {
+ final condition = statement.condition;
+ if (condition is BinaryExpression) {
+ final leftOperand = condition.leftOperand;
+ if (leftOperand is SimpleIdentifier) {
+ if (leftOperand.staticElement == identifier.staticElement &&
+ condition.operator.type == TokenType.BANG_EQ &&
+ condition.rightOperand is NullLiteral) {
+ return;
+ }
+ }
+ }
+ }
+ }
+
+ final changeBuilder = _newDartChangeBuilder();
+ await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) {
+ final id = identifier.name;
+ final prefix = utils.getNodePrefix(exp);
+ final indent = utils.getIndent(1);
+ // todo (pq): follow-ups:
+ // 1. if the end token is on the same line as the body
+ // we should add an `eol` before the assert as well.
+ // 2. also, consider asking the block for the list of statements and
+ // adding the statement to the beginning of the list, special casing
+ // when there are no statements (or when there's a single statement
+ // and the whole block is on the same line).
+ final int offset = min(utils.getLineNext(body.beginToken.offset),
+ body.endToken.offset);
+ builder.addSimpleInsertion(
+ offset, '$prefix${indent}assert($id != null);$eol');
+ _addAssistFromBuilder(
+ changeBuilder, DartAssistKind.ADD_NOT_NULL_ASSERT);
+ });
+ }
+ }
+ }
+ }
+
Future<void> _addProposal_assignToLocalVariable() async {
// prepare enclosing ExpressionStatement
ExpressionStatement expressionStatement;
@@ -263,9 +334,13 @@
}
}
- Future<void> _addProposal_convertAddAllToSpread() async {
+ Future<void> _addProposal_convertAddAllToSpread(
+ {bool preferInlinedAdds = true, bool convertToSpreads = true}) async {
final change = await createBuilder_convertAddAllToSpread();
if (change != null) {
+ if (change.isLineInvocation && !preferInlinedAdds || !convertToSpreads) {
+ return;
+ }
final kind = change.isLineInvocation
? DartAssistKind.INLINE_INVOCATION
: DartAssistKind.CONVERT_TO_SPREAD;
@@ -497,7 +572,7 @@
InstanceCreationExpression creation = node.thisOrAncestorOfType();
if (creation == null ||
node.offset > creation.argumentList.offset ||
- creation.staticType.element != typeProvider.listType.element ||
+ creation.staticType.element != typeProvider.listElement ||
creation.constructorName.name != null ||
creation.argumentList.arguments.isNotEmpty) {
_coverageMarker();
@@ -576,7 +651,7 @@
Future<void> _addProposal_convertMapConstructorToMapLiteral() async {
bool isMapClass(Element element) =>
element is ClassElement &&
- (element == typeProvider.mapType.element ||
+ (element == typeProvider.mapElement ||
(element.name == 'LinkedHashMap' &&
element.library.name == 'dart.collection'));
//
@@ -642,7 +717,7 @@
InstanceCreationExpression creation = node.thisOrAncestorOfType();
if (creation == null ||
node.offset > creation.argumentList.offset ||
- creation.staticType.element != typeProvider.setType.element) {
+ creation.staticType.element != typeProvider.setElement) {
// TODO(brianwilkerson) Consider also accepting uses of LinkedHashSet.
_coverageMarker();
return;
@@ -699,7 +774,7 @@
if (parent is VariableDeclaration) {
AstNode parent2 = parent.parent;
if (parent2 is VariableDeclarationList &&
- parent2.type?.type?.element == typeProvider.setType.element) {
+ parent2.type?.type?.element == typeProvider.setElement) {
return true;
}
}
@@ -944,9 +1019,8 @@
// iterable should be List
{
DartType iterableType = iterable.staticType;
- InterfaceType listType = typeProvider.listType;
if (iterableType is! InterfaceType ||
- iterableType.element != listType.element) {
+ iterableType.element != typeProvider.listElement) {
_coverageMarker();
return;
}
@@ -1585,12 +1659,11 @@
if (statefulWidgetClass == null || stateClass == null) {
return;
}
- var stateType = stateClass.type.instantiate([widgetClassElement.type]);
var changeBuilder = _newDartChangeBuilder();
await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) {
builder.addReplacement(range.node(superclass), (builder) {
- builder.writeType(statefulWidgetClass.type);
+ builder.writeReference(statefulWidgetClass);
});
int replaceOffset = 0;
@@ -1661,6 +1734,16 @@
// Create the State subclass.
builder.addInsertion(widgetClass.end, (builder) {
+ var stateType = stateClass.instantiate(
+ typeArguments: [
+ widgetClassElement.instantiate(
+ typeArguments: const [],
+ nullabilitySuffix: NullabilitySuffix.none,
+ ),
+ ],
+ nullabilitySuffix: NullabilitySuffix.none,
+ );
+
builder.writeln();
builder.writeln();
builder.writeClassDeclaration(stateName, superclass: stateType,
@@ -1867,7 +1950,7 @@
var changeBuilder = _newDartChangeBuilder();
await changeBuilder.addFileEdit(file, (builder) {
builder.addReplacement(range.node(widgetExpr), (builder) {
- builder.writeType(streamBuilderElement.type);
+ builder.writeReference(streamBuilderElement);
builder.write('<');
builder.addSimpleLinkedEdit('type', 'Object');
@@ -1963,7 +2046,7 @@
if (parentClassElement == null) {
builder.addSimpleLinkedEdit('WIDGET', 'widget');
} else {
- builder.writeType(parentClassElement.type);
+ builder.writeReference(parentClassElement);
}
builder.write('(');
if (widgetSrc.contains(eol) || leadingLines.isNotEmpty) {
@@ -2038,7 +2121,7 @@
var changeBuilder = _newDartChangeBuilder();
await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) {
builder.addReplacement(selectedRange, (DartEditBuilder builder) {
- builder.writeType(parentClassElement.type);
+ builder.writeReference(parentClassElement);
builder.write('(');
String indentOld = utils.getLinePrefix(firstWidget.offset);
@@ -2048,7 +2131,7 @@
builder.write(eol);
builder.write(indentNew1);
builder.write('children: <');
- builder.writeType(widgetClassElement.type);
+ builder.writeReference(widgetClassElement);
builder.write('>[');
builder.write(eol);
@@ -2124,43 +2207,7 @@
}
Future<void> _addProposal_inlineAdd() async {
- AstNode node = this.node;
- if (node is! SimpleIdentifier || node.parent is! MethodInvocation) {
- _coverageMarker();
- return;
- }
- SimpleIdentifier name = node;
- MethodInvocation invocation = node.parent;
- if (name != invocation.methodName ||
- name.name != 'add' ||
- !invocation.isCascaded ||
- invocation.argumentList.arguments.length != 1) {
- _coverageMarker();
- return;
- }
- CascadeExpression cascade = invocation.thisOrAncestorOfType();
- NodeList<Expression> sections = cascade.cascadeSections;
- Expression target = cascade.target;
- if (target is! ListLiteral || sections[0] != invocation) {
- // TODO(brianwilkerson) Consider extending this to handle set literals.
- _coverageMarker();
- return;
- }
- ListLiteral list = target;
- Expression argument = invocation.argumentList.arguments[0];
- String elementText = utils.getNodeText(argument);
-
- DartChangeBuilder changeBuilder = _newDartChangeBuilder();
- await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) {
- if (list.elements.isNotEmpty) {
- // ['a']..add(e);
- builder.addSimpleInsertion(list.elements.last.end, ', $elementText');
- } else {
- // []..add(e);
- builder.addSimpleInsertion(list.leftBracket.end, elementText);
- }
- builder.addDeletion(range.node(invocation));
- });
+ final changeBuilder = await createBuilder_inlineAdd();
_addAssistFromBuilder(changeBuilder, DartAssistKind.INLINE_INVOCATION,
args: ['add']);
}
@@ -2531,46 +2578,9 @@
}
Future<void> _addProposal_removeTypeAnnotation() async {
- VariableDeclarationList declarationList =
- node.thisOrAncestorOfType<VariableDeclarationList>();
- if (declarationList == null) {
- _coverageMarker();
- return;
- }
- // we need a type
- TypeAnnotation typeNode = declarationList.type;
- if (typeNode == null) {
- _coverageMarker();
- return;
- }
- // ignore if an incomplete variable declaration
- if (declarationList.variables.length == 1 &&
- declarationList.variables[0].name.isSynthetic) {
- _coverageMarker();
- return;
- }
- // must be not after the name of the variable
- VariableDeclaration firstVariable = declarationList.variables[0];
- if (selectionOffset > firstVariable.name.end) {
- _coverageMarker();
- return;
- }
- // The variable must have an initializer, otherwise there is no other
- // source for its type.
- if (firstVariable.initializer == null) {
- _coverageMarker();
- return;
- }
- Token keyword = declarationList.keyword;
- var changeBuilder = _newDartChangeBuilder();
- await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) {
- SourceRange typeRange = range.startStart(typeNode, firstVariable);
- if (keyword != null && keyword.lexeme != 'var') {
- builder.addSimpleReplacement(typeRange, '');
- } else {
- builder.addSimpleReplacement(typeRange, 'var ');
- }
- });
+ // todo (pq): unify w/ fix (and then add a guard to not assist on lints:
+ // avoid_return_types_on_setters, type_init_formals)
+ final changeBuilder = await createBuilder_removeTypeAnnotation();
_addAssistFromBuilder(changeBuilder, DartAssistKind.REMOVE_TYPE_ANNOTATION);
}
@@ -2791,42 +2801,7 @@
}
Future<void> _addProposal_sortChildPropertyLast() async {
- NamedExpression childProp = flutter.findNamedExpression(node, 'child');
- if (childProp == null) {
- childProp = flutter.findNamedExpression(node, 'children');
- }
- if (childProp == null) {
- return;
- }
-
- var parent = childProp.parent?.parent;
- if (parent is! InstanceCreationExpression ||
- !flutter.isWidgetCreation(parent)) {
- return;
- }
-
- InstanceCreationExpression creationExpression = parent;
- var args = creationExpression.argumentList;
-
- var last = args.arguments.last;
- if (last == childProp) {
- // Already sorted.
- return;
- }
-
- var changeBuilder = _newDartChangeBuilder();
- await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) {
- var start = childProp.beginToken.previous.end;
- var end = childProp.endToken.next.end;
- var childRange = range.startOffsetEndOffset(start, end);
-
- var childText = utils.getRangeText(childRange);
- builder.addSimpleReplacement(childRange, '');
- builder.addSimpleInsertion(last.end + 1, childText);
-
- changeBuilder.setSelection(new Position(file, last.end + 1));
- });
-
+ final changeBuilder = await createBuilder_sortChildPropertyLast();
_addAssistFromBuilder(
changeBuilder, DartAssistKind.SORT_CHILD_PROPERTY_LAST);
}
diff --git a/pkg/analysis_server/lib/src/services/correction/base_processor.dart b/pkg/analysis_server/lib/src/services/correction/base_processor.dart
index e054c8f..32e627e 100644
--- a/pkg/analysis_server/lib/src/services/correction/base_processor.dart
+++ b/pkg/analysis_server/lib/src/services/correction/base_processor.dart
@@ -17,6 +17,7 @@
import 'package:analyzer/src/dart/ast/utilities.dart';
import 'package:analyzer/src/generated/engine.dart' show AnalysisOptionsImpl;
import 'package:analyzer/src/generated/resolver.dart';
+import 'package:analyzer_plugin/protocol/protocol_common.dart';
import 'package:analyzer_plugin/src/utilities/change_builder/change_builder_dart.dart';
import 'package:analyzer_plugin/utilities/change_builder/change_builder_core.dart';
import 'package:analyzer_plugin/utilities/change_builder/change_builder_dart.dart';
@@ -412,7 +413,7 @@
ConstructorElement element = creation.staticElement;
if (element == null ||
element.name != 'fromIterable' ||
- element.enclosingElement != typeProvider.mapType.element) {
+ element.enclosingElement != typeProvider.mapElement) {
_coverageMarker();
return null;
}
@@ -818,6 +819,132 @@
return null;
}
+ Future<ChangeBuilder> createBuilder_inlineAdd() async {
+ AstNode node = this.node;
+ if (node is! SimpleIdentifier || node.parent is! MethodInvocation) {
+ _coverageMarker();
+ return null;
+ }
+ SimpleIdentifier name = node;
+ MethodInvocation invocation = node.parent;
+ if (name != invocation.methodName ||
+ name.name != 'add' ||
+ !invocation.isCascaded ||
+ invocation.argumentList.arguments.length != 1) {
+ _coverageMarker();
+ return null;
+ }
+ CascadeExpression cascade = invocation.thisOrAncestorOfType();
+ NodeList<Expression> sections = cascade.cascadeSections;
+ Expression target = cascade.target;
+ if (target is! ListLiteral || sections[0] != invocation) {
+ // TODO(brianwilkerson) Consider extending this to handle set literals.
+ _coverageMarker();
+ return null;
+ }
+ ListLiteral list = target;
+ Expression argument = invocation.argumentList.arguments[0];
+ String elementText = utils.getNodeText(argument);
+
+ DartChangeBuilder changeBuilder = _newDartChangeBuilder();
+ await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) {
+ if (list.elements.isNotEmpty) {
+ // ['a']..add(e);
+ builder.addSimpleInsertion(list.elements.last.end, ', $elementText');
+ } else {
+ // []..add(e);
+ builder.addSimpleInsertion(list.leftBracket.end, elementText);
+ }
+ builder.addDeletion(range.node(invocation));
+ });
+ return changeBuilder;
+ }
+
+ Future<ChangeBuilder> createBuilder_sortChildPropertyLast() async {
+ NamedExpression childProp = flutter.findNamedExpression(node, 'child');
+ if (childProp == null) {
+ childProp = flutter.findNamedExpression(node, 'children');
+ }
+ if (childProp == null) {
+ return null;
+ }
+
+ var parent = childProp.parent?.parent;
+ if (parent is! InstanceCreationExpression ||
+ !flutter.isWidgetCreation(parent)) {
+ return null;
+ }
+
+ InstanceCreationExpression creationExpression = parent;
+ var args = creationExpression.argumentList;
+
+ var last = args.arguments.last;
+ if (last == childProp) {
+ // Already sorted.
+ return null;
+ }
+
+ var changeBuilder = _newDartChangeBuilder();
+ await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) {
+ var start = childProp.beginToken.previous.end;
+ var end = childProp.endToken.next.end;
+ var childRange = range.startOffsetEndOffset(start, end);
+
+ var childText = utils.getRangeText(childRange);
+ builder.addSimpleReplacement(childRange, '');
+ builder.addSimpleInsertion(last.end + 1, childText);
+
+ changeBuilder.setSelection(new Position(file, last.end + 1));
+ });
+
+ return changeBuilder;
+ }
+
+ /// todo (pq): unify with similar behavior in fix.
+ Future<ChangeBuilder> createBuilder_removeTypeAnnotation() async {
+ VariableDeclarationList declarationList =
+ node.thisOrAncestorOfType<VariableDeclarationList>();
+ if (declarationList == null) {
+ _coverageMarker();
+ return null;
+ }
+ // we need a type
+ TypeAnnotation typeNode = declarationList.type;
+ if (typeNode == null) {
+ _coverageMarker();
+ return null;
+ }
+ // ignore if an incomplete variable declaration
+ if (declarationList.variables.length == 1 &&
+ declarationList.variables[0].name.isSynthetic) {
+ _coverageMarker();
+ return null;
+ }
+ // must be not after the name of the variable
+ VariableDeclaration firstVariable = declarationList.variables[0];
+ if (selectionOffset > firstVariable.name.end) {
+ _coverageMarker();
+ return null;
+ }
+ // The variable must have an initializer, otherwise there is no other
+ // source for its type.
+ if (firstVariable.initializer == null) {
+ _coverageMarker();
+ return null;
+ }
+ Token keyword = declarationList.keyword;
+ var changeBuilder = _newDartChangeBuilder();
+ await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) {
+ SourceRange typeRange = range.startStart(typeNode, firstVariable);
+ if (keyword != null && keyword.lexeme != 'var') {
+ builder.addSimpleReplacement(typeRange, '');
+ } else {
+ builder.addSimpleReplacement(typeRange, 'var ');
+ }
+ });
+ return changeBuilder;
+ }
+
@protected
Future<ChangeBuilder> createBuilder_useCurlyBraces() async {
Future<ChangeBuilder> doStatement(DoStatement node) async {
diff --git a/pkg/analysis_server/lib/src/services/correction/fix.dart b/pkg/analysis_server/lib/src/services/correction/fix.dart
index bac44cb..b2bc9a3 100644
--- a/pkg/analysis_server/lib/src/services/correction/fix.dart
+++ b/pkg/analysis_server/lib/src/services/correction/fix.dart
@@ -266,6 +266,8 @@
"Move type arguments to after class name");
static const MAKE_VARIABLE_NOT_FINAL = const FixKind(
'MAKE_VARIABLE_NOT_FINAL', 50, "Make variable '{0}' not final");
+ static const QUALIFY_REFERENCE =
+ const FixKind('QUALIFY_REFERENCE', 50, "Use '{0}'");
static const REMOVE_ANNOTATION =
const FixKind('REMOVE_ANNOTATION', 50, "Remove the '{0}' annotation");
static const REMOVE_AWAIT = const FixKind('REMOVE_AWAIT', 50, "Remove await");
@@ -310,15 +312,23 @@
appliedTogetherMessage: "Remove all unnecessary casts in file");
static const REMOVE_UNNECESSARY_CONST = const FixKind(
'REMOVE_UNNECESSARY_CONST', 50, "Remove unnecessary const keyword");
+ static const REMOVE_UNNECESSARY_NEW = const FixKind(
+ 'REMOVE_UNNECESSARY_NEW', 50, "Remove unnecessary new keyword");
static const REMOVE_UNUSED_CATCH_CLAUSE = const FixKind(
'REMOVE_UNUSED_CATCH_CLAUSE', 50, "Remove unused 'catch' clause");
static const REMOVE_UNUSED_CATCH_STACK = const FixKind(
'REMOVE_UNUSED_CATCH_STACK', 50, "Remove unused stack trace variable");
+ static const REMOVE_UNUSED_ELEMENT =
+ const FixKind('REMOVE_UNUSED_ELEMENT', 50, "Remove unused element");
+ static const REMOVE_UNUSED_FIELD =
+ const FixKind('REMOVE_UNUSED_FIELD', 50, "Remove unused field");
static const REMOVE_UNUSED_IMPORT = const FixKind(
'REMOVE_UNUSED_IMPORT', 50, "Remove unused import",
appliedTogetherMessage: "Remove all unused imports in this file");
- static const REMOVE_UNNECESSARY_NEW = const FixKind(
- 'REMOVE_UNNECESSARY_NEW', 50, "Remove unnecessary new keyword");
+ static const REMOVE_UNUSED_LABEL =
+ const FixKind('REMOVE_UNUSED_LABEL', 50, "Remove unused label");
+ static const REMOVE_UNUSED_LOCAL_VARIABLE = const FixKind(
+ 'REMOVE_UNUSED_LOCAL_VARIABLE', 50, "Remove unused local variable");
static const RENAME_TO_CAMEL_CASE =
const FixKind('RENAME_TO_CAMEL_CASE', 50, "Rename to '{0}'");
static const REPLACE_BOOLEAN_WITH_BOOL = const FixKind(
@@ -342,6 +352,8 @@
const FixKind('REPLACE_WITH_BRACKETS', 50, "Replace with { }");
static const REPLACE_WITH_CONDITIONAL_ASSIGNMENT = const FixKind(
'REPLACE_WITH_CONDITIONAL_ASSIGNMENT', 50, "Replace with ??=");
+ static const REPLACE_WITH_EXTENSION_NAME =
+ const FixKind('REPLACE_WITH_EXTENSION_NAME', 50, "Replace with '{0}'");
static const REPLACE_WITH_IDENTIFIER =
const FixKind('REPLACE_WITH_IDENTIFIER', 50, "Replace with identifier");
static const REPLACE_WITH_IS_EMPTY =
@@ -354,6 +366,10 @@
"Replace the '.' with a '?.' in the invocation");
static const REPLACE_WITH_TEAR_OFF = const FixKind(
'REPLACE_WITH_TEAR_OFF', 50, "Replace function literal with tear-off");
+ static const SORT_CHILD_PROPERTY_LAST = const FixKind(
+ 'SORT_CHILD_PROPERTY_LAST',
+ 50,
+ "Move child property to end of arguments");
static const UPDATE_SDK_CONSTRAINTS =
const FixKind('UPDATE_SDK_CONSTRAINTS', 50, "Update the SDK constraints");
static const USE_CONST = const FixKind('USE_CONST', 50, "Change to constant");
diff --git a/pkg/analysis_server/lib/src/services/correction/fix_internal.dart b/pkg/analysis_server/lib/src/services/correction/fix_internal.dart
index 491d0e2..7dff396 100644
--- a/pkg/analysis_server/lib/src/services/correction/fix_internal.dart
+++ b/pkg/analysis_server/lib/src/services/correction/fix_internal.dart
@@ -18,10 +18,13 @@
import 'package:analysis_server/src/services/correction/util.dart';
import 'package:analysis_server/src/services/linter/lint_names.dart';
import 'package:analysis_server/src/services/search/hierarchy.dart';
+import 'package:analyzer/dart/analysis/features.dart';
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/ast/precedence.dart';
import 'package:analyzer/dart/ast/token.dart';
+import 'package:analyzer/dart/ast/visitor.dart';
import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/dart/element/nullability_suffix.dart';
import 'package:analyzer/dart/element/type.dart';
import 'package:analyzer/error/error.dart';
import 'package:analyzer/file_system/file_system.dart';
@@ -191,7 +194,13 @@
workspace: context.workspace,
);
- DartType get coreTypeBool => _getCoreType('bool');
+ DartType get coreTypeBool => context.resolveResult.typeProvider.boolType;
+
+ FeatureSet get _featureSet {
+ return unit.featureSet;
+ }
+
+ bool get _isNonNullable => _featureSet.isEnabled(Feature.non_nullable);
Future<List<Fix>> compute() async {
node = new NodeLocator2(errorOffset).searchWithin(unit);
@@ -363,25 +372,21 @@
if (errorCode == HintCode.UNUSED_CATCH_STACK) {
await _addFix_removeUnusedCatchStack();
}
- // TODO(brianwilkerson) Add a fix to remove the declaration. Decide whether
- // this should be a single general fix, or multiple more specific fixes
- // such as [_addFix_removeMethodDeclaration].
-// if (errorCode == HintCode.UNUSED_ELEMENT ||
-// errorCode == HintCode.UNUSED_FIELD) {
-// await _addFix_removeUnusedDeclaration();
-// }
+ if (errorCode == HintCode.UNUSED_ELEMENT) {
+ await _addFix_removeUnusedElement();
+ }
+ if (errorCode == HintCode.UNUSED_FIELD) {
+ await _addFix_removeUnusedField();
+ }
if (errorCode == HintCode.UNUSED_IMPORT) {
await _addFix_removeUnusedImport();
}
- // TODO(brianwilkerson) Add a fix to remove the label.
-// if (errorCode == HintCode.UNUSED_LABEL) {
-// await _addFix_removeUnusedLabel();
-// }
- // TODO(brianwilkerson) Add a fix to remove the local variable, either with
- // or without the initialization code.
-// if (errorCode == HintCode.UNUSED_LOCAL_VARIABLE) {
-// await _addFix_removeUnusedLocalVariable();
-// }
+ if (errorCode == HintCode.UNUSED_LABEL) {
+ await _addFix_removeUnusedLabel();
+ }
+ if (errorCode == HintCode.UNUSED_LOCAL_VARIABLE) {
+ await _addFix_removeUnusedLocalVariable();
+ }
if (errorCode == HintCode.UNUSED_SHOWN_NAME) {
await _addFix_removeNameFromCombinator();
}
@@ -394,6 +399,9 @@
if (errorCode == ParserErrorCode.VAR_AS_TYPE_NAME) {
await _addFix_replaceVarWithDynamic();
}
+ if (errorCode == ParserErrorCode.MISSING_CONST_FINAL_VAR_OR_TYPE) {
+ await _addFix_addTypeAnnotation();
+ }
if (errorCode == StaticWarningCode.ASSIGNMENT_TO_FINAL) {
await _addFix_makeFieldNotFinal();
}
@@ -563,6 +571,26 @@
if (errorCode == StaticWarningCode.MISSING_ENUM_CONSTANT_IN_SWITCH) {
await _addFix_addMissingEnumCaseClauses();
}
+ if (errorCode ==
+ CompileTimeErrorCode.EXTENSION_OVERRIDE_ACCESS_TO_STATIC_MEMBER) {
+ await _addFix_replaceWithExtensionName();
+ }
+ if (errorCode ==
+ CompileTimeErrorCode
+ .UNQUALIFIED_REFERENCE_TO_STATIC_MEMBER_OF_EXTENDED_TYPE) {
+ await _addFix_qualifyReference();
+ // TODO(brianwilkerson) Consider adding fixes to create a field, getter,
+ // method or setter. The existing _addFix methods would need to be
+ // updated so that only the appropriate subset is generated.
+ }
+ if (errorCode ==
+ StaticTypeWarningCode
+ .UNQUALIFIED_REFERENCE_TO_NON_LOCAL_STATIC_MEMBER) {
+ await _addFix_qualifyReference();
+ // TODO(brianwilkerson) Consider adding fixes to create a field, getter,
+ // method or setter. The existing _addFix methods would need to be
+ // updated so that only the appropriate subset is generated.
+ }
// lints
if (errorCode is LintCode) {
String name = errorCode.name;
@@ -643,6 +671,9 @@
LintNames.prefer_if_elements_to_conditional_expressions) {
await _addFix_convertConditionalToIfElement();
}
+ if (name == LintNames.prefer_inlined_adds) {
+ await _addFix_convertToInlineAdd();
+ }
if (name == LintNames.prefer_int_literals) {
await _addFix_convertToIntLiteral();
}
@@ -668,6 +699,9 @@
if (name == LintNames.prefer_spread_collections) {
await _addFix_convertAddAllToSpread();
}
+ if (name == LintNames.sort_child_properties_last) {
+ await _addFix_sortChildPropertiesLast();
+ }
if (name == LintNames.type_init_formals) {
await _addFix_removeTypeAnnotation();
}
@@ -1287,6 +1321,16 @@
}
}
+ Future<void> _addFix_convertAddAllToSpread() async {
+ final change = await createBuilder_convertAddAllToSpread();
+ if (change != null) {
+ final kind = change.isLineInvocation
+ ? DartFixKind.INLINE_INVOCATION
+ : DartFixKind.CONVERT_TO_SPREAD;
+ _addFixFromBuilder(change.builder, kind, args: change.args);
+ }
+ }
+
Future<void> _addFix_convertConditionalToIfElement() async {
final changeBuilder =
await createBuilder_convertConditionalExpressionToIfElement();
@@ -1383,6 +1427,12 @@
_addFixFromBuilder(changeBuilder, DartFixKind.CONVERT_INTO_EXPRESSION_BODY);
}
+ Future<void> _addFix_convertToInlineAdd() async {
+ final changeBuilder = await createBuilder_inlineAdd();
+ _addFixFromBuilder(changeBuilder, DartFixKind.INLINE_INVOCATION,
+ args: ['add']);
+ }
+
Future<void> _addFix_convertToIntLiteral() async {
final changeBuilder = await createBuilder_convertToIntLiteral();
_addFixFromBuilder(changeBuilder, DartFixKind.CONVERT_TO_INT_LITERAL);
@@ -1594,7 +1644,14 @@
builder.write('const ');
builder.write(className);
builder.write('({');
- builder.writeType(keyClass.type);
+ builder.writeType(
+ keyClass.instantiate(
+ typeArguments: const [],
+ nullabilitySuffix: _isNonNullable
+ ? NullabilitySuffix.question
+ : NullabilitySuffix.star,
+ ),
+ );
builder.write(' key');
List<String> childrenFields = [];
@@ -1877,16 +1934,6 @@
}
}
- Future<void> _addFix_convertAddAllToSpread() async {
- final change = await createBuilder_convertAddAllToSpread();
- if (change != null) {
- final kind = change.isLineInvocation
- ? DartFixKind.INLINE_INVOCATION
- : DartFixKind.CONVERT_TO_SPREAD;
- _addFixFromBuilder(change.builder, kind, args: change.args);
- }
- }
-
Future<void> _addFix_createField() async {
if (node is! SimpleIdentifier) {
return;
@@ -3020,6 +3067,38 @@
_addFixFromBuilder(changeBuilder, DartFixKind.ADD_NE_NULL);
}
+ Future<void> _addFix_qualifyReference() async {
+ if (node is! SimpleIdentifier) {
+ return;
+ }
+ SimpleIdentifier memberName = node;
+ AstNode parent = node.parent;
+ AstNode target = null;
+ if (parent is MethodInvocation && node == parent.methodName) {
+ target = parent.target;
+ } else if (parent is PropertyAccess && node == parent.propertyName) {
+ target = parent.target;
+ }
+ if (target != null) {
+ return;
+ }
+ Element enclosingElement = memberName.staticElement.enclosingElement;
+ if (enclosingElement.library != unitLibraryElement) {
+ // TODO(brianwilkerson) Support qualifying references to members defined
+ // in other libraries. `DartEditBuilder` currently defines the method
+ // `writeType`, which is close, but we also need to handle extensions,
+ // which don't have a type.
+ return;
+ }
+ String containerName = enclosingElement.name;
+ var changeBuilder = _newDartChangeBuilder();
+ await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) {
+ builder.addSimpleInsertion(node.offset, '$containerName.');
+ });
+ _addFixFromBuilder(changeBuilder, DartFixKind.QUALIFY_REFERENCE,
+ args: ['$containerName.${memberName.name}']);
+ }
+
Future<void> _addFix_removeAnnotation() async {
void addFix(Annotation node) async {
if (node == null) {
@@ -3446,6 +3525,110 @@
}
}
+ Future<void> _addFix_removeUnusedField() async {
+ final declaration = node.parent;
+ if (declaration is! VariableDeclaration) {
+ return;
+ }
+ final element = (declaration as VariableDeclaration).declaredElement;
+ if (element is! FieldElement) {
+ return;
+ }
+
+ final sourceRanges = <SourceRange>[];
+ final references = _findAllReferences(unit, element);
+ for (var reference in references) {
+ // todo (pq): consider scoping this to parent or parent.parent.
+ final referenceNode = reference.thisOrAncestorMatching((node) =>
+ node is VariableDeclaration ||
+ node is ExpressionStatement ||
+ node is ConstructorFieldInitializer ||
+ node is FieldFormalParameter);
+ if (referenceNode == null) {
+ return;
+ }
+ var sourceRange;
+ if (referenceNode is VariableDeclaration) {
+ VariableDeclarationList parent = referenceNode.parent;
+ if (parent.variables.length == 1) {
+ sourceRange = utils.getLinesRange(range.node(parent.parent));
+ } else {
+ sourceRange = range.nodeInList(parent.variables, referenceNode);
+ }
+ } else if (referenceNode is ConstructorFieldInitializer) {
+ ConstructorDeclaration cons =
+ referenceNode.parent as ConstructorDeclaration;
+ // A() : _f = 0;
+ if (cons.initializers.length == 1) {
+ sourceRange = range.endEnd(cons.parameters, referenceNode);
+ } else {
+ sourceRange = range.nodeInList(cons.initializers, referenceNode);
+ }
+ } else if (referenceNode is FieldFormalParameter) {
+ FormalParameterList params =
+ referenceNode.parent as FormalParameterList;
+ if (params.parameters.length == 1) {
+ sourceRange =
+ range.endStart(params.leftParenthesis, params.rightParenthesis);
+ } else {
+ sourceRange = range.nodeInList(params.parameters, referenceNode);
+ }
+ } else {
+ sourceRange = utils.getLinesRange(range.node(referenceNode));
+ }
+ sourceRanges.add(sourceRange);
+ }
+
+ final changeBuilder = _newDartChangeBuilder();
+ await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) {
+ for (var sourceRange in sourceRanges) {
+ builder.addDeletion(sourceRange);
+ }
+ });
+ _addFixFromBuilder(changeBuilder, DartFixKind.REMOVE_UNUSED_FIELD);
+ }
+
+ Future<void> _addFix_removeUnusedElement() async {
+ final sourceRanges = <SourceRange>[];
+ final referencedNode = node.parent;
+ if (referencedNode is ClassDeclaration ||
+ referencedNode is EnumDeclaration ||
+ referencedNode is FunctionDeclaration ||
+ referencedNode is FunctionTypeAlias ||
+ referencedNode is MethodDeclaration ||
+ referencedNode is VariableDeclaration) {
+ final element = referencedNode is Declaration
+ ? referencedNode.declaredElement
+ : (referencedNode as NamedCompilationUnitMember).declaredElement;
+ final references = _findAllReferences(unit, element);
+ // todo (pq): consider filtering for references that are limited to within the class.
+ if (references.length == 1) {
+ var sourceRange;
+ if (referencedNode is VariableDeclaration) {
+ VariableDeclarationList parent = referencedNode.parent;
+ if (parent.variables.length == 1) {
+ sourceRange = utils.getLinesRange(range.node(parent.parent));
+ } else {
+ sourceRange = range.nodeInList(parent.variables, node);
+ }
+ } else {
+ sourceRange = utils.getLinesRange(range.node(referencedNode));
+ }
+ sourceRanges.add(sourceRange);
+ }
+ }
+
+ if (sourceRanges.isNotEmpty) {
+ final changeBuilder = _newDartChangeBuilder();
+ await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) {
+ for (var sourceRange in sourceRanges) {
+ builder.addDeletion(sourceRange);
+ }
+ });
+ _addFixFromBuilder(changeBuilder, DartFixKind.REMOVE_UNUSED_ELEMENT);
+ }
+ }
+
Future<void> _addFix_removeUnusedImport() async {
// prepare ImportDirective
ImportDirective importDirective =
@@ -3461,6 +3644,66 @@
_addFixFromBuilder(changeBuilder, DartFixKind.REMOVE_UNUSED_IMPORT);
}
+ Future<void> _addFix_removeUnusedLabel() async {
+ final parent = node.parent;
+ if (parent is Label) {
+ var nextToken = parent.endToken.next;
+ final changeBuilder = _newDartChangeBuilder();
+ await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) {
+ builder.addDeletion(range.startStart(parent, nextToken));
+ });
+ _addFixFromBuilder(changeBuilder, DartFixKind.REMOVE_UNUSED_LABEL);
+ }
+ }
+
+ Future<void> _addFix_removeUnusedLocalVariable() async {
+ final declaration = node.parent;
+ if (!(declaration is VariableDeclaration && declaration.name == node)) {
+ return;
+ }
+ Element element = (declaration as VariableDeclaration).declaredElement;
+ if (element is! LocalElement) {
+ return;
+ }
+
+ final sourceRanges = <SourceRange>[];
+
+ final functionBody = declaration.thisOrAncestorOfType<FunctionBody>();
+ final references = findLocalElementReferences(functionBody, element);
+ for (var reference in references) {
+ final node = reference.thisOrAncestorMatching((node) =>
+ node is VariableDeclaration || node is AssignmentExpression);
+ var sourceRange;
+ if (node is VariableDeclaration) {
+ VariableDeclarationList parent = node.parent;
+ if (parent.variables.length == 1) {
+ sourceRange = utils.getLinesRange(range.node(parent.parent));
+ } else {
+ sourceRange = range.nodeInList(parent.variables, node);
+ }
+ } else if (node is AssignmentExpression) {
+ // todo (pq): consider node.parent is! ExpressionStatement to handle
+ // assignments in parens, etc.
+ if (node.parent is ArgumentList) {
+ sourceRange = range.startStart(node, node.operator.next);
+ } else {
+ sourceRange = utils.getLinesRange(range.node(node.parent));
+ }
+ } else {
+ return;
+ }
+ sourceRanges.add(sourceRange);
+ }
+
+ final changeBuilder = _newDartChangeBuilder();
+ await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) {
+ for (var sourceRange in sourceRanges) {
+ builder.addDeletion(sourceRange);
+ }
+ });
+ _addFixFromBuilder(changeBuilder, DartFixKind.REMOVE_UNUSED_LOCAL_VARIABLE);
+ }
+
Future<void> _addFix_renameToCamelCase() async {
if (node is! SimpleIdentifier) {
return;
@@ -3634,6 +3877,30 @@
}
}
+ Future<void> _addFix_replaceWithExtensionName() async {
+ if (node is! SimpleIdentifier) {
+ return;
+ }
+ AstNode parent = node.parent;
+ AstNode target = null;
+ if (parent is MethodInvocation && node == parent.methodName) {
+ target = parent.target;
+ } else if (parent is PropertyAccess && node == parent.propertyName) {
+ target = parent.target;
+ }
+ if (target is! ExtensionOverride) {
+ return;
+ }
+ ExtensionOverride override = target;
+ var changeBuilder = _newDartChangeBuilder();
+ await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) {
+ builder.addSimpleReplacement(
+ range.node(override), utils.getNodeText(override.extensionName));
+ });
+ _addFixFromBuilder(changeBuilder, DartFixKind.REPLACE_WITH_EXTENSION_NAME,
+ args: [override.extensionName.name]);
+ }
+
Future<void> _addFix_replaceWithIdentifier() async {
final FunctionTypedFormalParameter functionTyped =
node.thisOrAncestorOfType<FunctionTypedFormalParameter>();
@@ -3789,6 +4056,11 @@
}
}
+ Future<void> _addFix_sortChildPropertiesLast() async {
+ final changeBuilder = await createBuilder_sortChildPropertyLast();
+ _addFixFromBuilder(changeBuilder, DartFixKind.SORT_CHILD_PROPERTY_LAST);
+ }
+
Future<void> _addFix_undefinedClass_useSimilar() async {
AstNode node = this.node;
// Prepare the optional import prefix name.
@@ -4324,6 +4596,12 @@
_addFixFromBuilder(changeBuilder, DartFixKind.CREATE_METHOD, args: [name]);
}
+ List<SimpleIdentifier> _findAllReferences(AstNode root, Element element) {
+ var collector = _ElementReferenceCollector(element);
+ root.accept(collector);
+ return collector.references;
+ }
+
/// Return the class, enum or mixin declaration for the given [element].
Future<ClassOrMixinDeclaration> _getClassDeclaration(
ClassElement element) async {
@@ -4350,23 +4628,6 @@
return buffer.toString();
}
- /**
- * Returns the [DartType] with given name from the `dart:core` library.
- */
- DartType _getCoreType(String name) {
- List<LibraryElement> libraries = unitLibraryElement.importedLibraries;
- for (LibraryElement library in libraries) {
- if (library.isDartCore) {
- ClassElement classElement = library.getType(name);
- if (classElement != null) {
- return classElement.type;
- }
- return null;
- }
- }
- return null;
- }
-
/// Return the extension declaration for the given [element].
Future<ExtensionDeclaration> _getExtensionDeclaration(
ExtensionElement element) async {
@@ -4730,6 +4991,32 @@
}
}
+class _ElementReferenceCollector extends RecursiveAstVisitor<void> {
+ final Element element;
+ final List<SimpleIdentifier> references = [];
+
+ _ElementReferenceCollector(this.element);
+
+ @override
+ void visitSimpleIdentifier(SimpleIdentifier node) {
+ final staticElement = node.staticElement;
+ if (staticElement == element) {
+ references.add(node);
+ }
+ // Implicit Setter.
+ else if (staticElement is PropertyAccessorElement) {
+ if (staticElement.variable == element) {
+ references.add(node);
+ }
+ // Field Formals.
+ } else if (staticElement is FieldFormalParameterElement) {
+ if (staticElement.field == element) {
+ references.add(node);
+ }
+ }
+ }
+}
+
/**
* [ExecutableElement], its parameters, and operations on them.
*/
diff --git a/pkg/analysis_server/lib/src/services/flutter/class_description.dart b/pkg/analysis_server/lib/src/services/flutter/class_description.dart
index d8f2e4d..5ab9dca 100644
--- a/pkg/analysis_server/lib/src/services/flutter/class_description.dart
+++ b/pkg/analysis_server/lib/src/services/flutter/class_description.dart
@@ -44,21 +44,17 @@
_map.clear();
}
- /// If the [type] is a class, and we know how to materialize it, return its
- /// [ClassDescription]. Otherwise return `null`.
- ClassDescription get(DartType type) {
- if (type is InterfaceType) {
- var element = type.element;
- var description = _map[element];
- if (description == null) {
- description = _classDescription(element);
- if (description != null) {
- _map[element] = description;
- }
+ /// If we know how to materialize the [element], return [ClassDescription].
+ /// Otherwise return `null`.
+ ClassDescription get(ClassElement element) {
+ var description = _map[element];
+ if (description == null) {
+ description = _classDescription(element);
+ if (description != null) {
+ _map[element] = description;
}
- return description;
}
- return null;
+ return description;
}
/// Return `true` if properties should be created for instances of [type].
diff --git a/pkg/analysis_server/lib/src/services/flutter/widget_descriptions.dart b/pkg/analysis_server/lib/src/services/flutter/widget_descriptions.dart
index 1a16579..85a0e5e 100644
--- a/pkg/analysis_server/lib/src/services/flutter/widget_descriptions.dart
+++ b/pkg/analysis_server/lib/src/services/flutter/widget_descriptions.dart
@@ -199,7 +199,7 @@
(property) => property.name == 'child',
);
} else {
- var containerDescription = classRegistry.get(_classContainer.type);
+ var containerDescription = classRegistry.get(_classContainer);
containerProperty = PropertyDescription(
resolvedUnit: resolvedUnit,
classDescription: containerDescription,
@@ -364,15 +364,18 @@
);
}
} else if (valueExpression == null) {
- var classDescription = classRegistry.get(
- parameter.type,
- );
- if (classDescription != null) {
- _addProperties(
- properties: propertyDescription.children,
- parent: propertyDescription,
- classDescription: classDescription,
+ var type = parameter.type;
+ if (type is InterfaceType) {
+ var classDescription = classRegistry.get(
+ type.element,
);
+ if (classDescription != null) {
+ _addProperties(
+ properties: propertyDescription.children,
+ parent: propertyDescription,
+ classDescription: classDescription,
+ );
+ }
}
}
}
diff --git a/pkg/analysis_server/lib/src/services/kythe/kythe_visitors.dart b/pkg/analysis_server/lib/src/services/kythe/kythe_visitors.dart
index e9346c0..df5ebac 100644
--- a/pkg/analysis_server/lib/src/services/kythe/kythe_visitors.dart
+++ b/pkg/analysis_server/lib/src/services/kythe/kythe_visitors.dart
@@ -4,11 +4,13 @@
import 'dart:convert';
+import 'package:analyzer/dart/analysis/features.dart';
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/ast/syntactic_entity.dart';
import 'package:analyzer/dart/ast/token.dart';
import 'package:analyzer/dart/ast/visitor.dart';
import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/dart/element/nullability_suffix.dart';
import 'package:analyzer/dart/element/type.dart';
import 'package:analyzer/dart/element/visitor.dart';
import 'package:analyzer/file_system/file_system.dart';
@@ -97,8 +99,10 @@
final String _contents;
String _enclosingFilePath = '';
+ FeatureSet _enclosingUnitFeatureSet;
Element _enclosingElement;
ClassElement _enclosingClassElement;
+ InterfaceType _enclosingClassThisType;
KytheVName _enclosingVName;
KytheVName _enclosingFileVName;
KytheVName _enclosingClassVName;
@@ -339,6 +343,7 @@
@override
visitCompilationUnit(CompilationUnit node) {
_enclosingFilePath = _getPath(resourceProvider, node.declaredElement);
+ _enclosingUnitFeatureSet = node.featureSet;
return _withEnclosingElement(node.declaredElement, () {
addFact(_enclosingFileVName, schema.NODE_KIND_FACT,
_encode(schema.FILE_KIND));
@@ -692,7 +697,7 @@
// override edges
var overriddenList = _inheritanceManager.getOverridden(
- _enclosingClassElement.type,
+ _enclosingClassThisType,
new Name(
_enclosingClassElement.library.source.uri,
node.declaredElement.name,
@@ -1080,6 +1085,17 @@
_enclosingClassElement = element;
_enclosingClassVName = _enclosingVName =
_vNameFromElement(_enclosingClassElement, schema.RECORD_KIND);
+ _enclosingClassThisType = element.instantiate(
+ typeArguments: element.typeParameters.map((t) {
+ return t.instantiate(
+ nullabilitySuffix:
+ _enclosingUnitFeatureSet.isEnabled(Feature.non_nullable)
+ ? NullabilitySuffix.none
+ : NullabilitySuffix.star,
+ );
+ }).toList(),
+ nullabilitySuffix: NullabilitySuffix.none,
+ );
} else if (element is MethodElement ||
element is FunctionElement ||
element is ConstructorElement) {
diff --git a/pkg/analysis_server/lib/src/services/linter/lint_names.dart b/pkg/analysis_server/lib/src/services/linter/lint_names.dart
index b935e7f..b3ee6f1 100644
--- a/pkg/analysis_server/lib/src/services/linter/lint_names.dart
+++ b/pkg/analysis_server/lib/src/services/linter/lint_names.dart
@@ -40,6 +40,7 @@
static const String prefer_final_locals = 'prefer_final_locals';
static const String prefer_for_elements_to_map_fromIterable =
'prefer_for_elements_to_map_fromIterable';
+ static const String prefer_inlined_adds = 'prefer_inlined_adds';
static const String prefer_int_literals = 'prefer_int_literals';
static const String prefer_if_elements_to_conditional_expressions =
'prefer_if_elements_to_conditional_expressions';
@@ -48,8 +49,9 @@
static const String prefer_null_aware_operators =
'prefer_null_aware_operators';
static const String prefer_single_quotes = 'prefer_single_quotes';
- static const String slash_for_doc_comments = 'slash_for_doc_comments';
static const String prefer_spread_collections = 'prefer_spread_collections';
+ static const String slash_for_doc_comments = 'slash_for_doc_comments';
+ static const String sort_child_properties_last = 'sort_child_properties_last';
static const String type_annotate_public_apis = 'type_annotate_public_apis';
static const String type_init_formals = 'type_init_formals';
static const String unawaited_futures = 'unawaited_futures';
diff --git a/pkg/analysis_server/lib/src/services/refactoring/extract_method.dart b/pkg/analysis_server/lib/src/services/refactoring/extract_method.dart
index a495f56..74d6eb3 100644
--- a/pkg/analysis_server/lib/src/services/refactoring/extract_method.dart
+++ b/pkg/analysis_server/lib/src/services/refactoring/extract_method.dart
@@ -800,29 +800,28 @@
// TODO(brianwilkerson) Determine whether this await is necessary.
await null;
TypeProvider typeProvider = await resolveResult.session.typeProvider;
- InterfaceType futureType = typeProvider.futureType;
if (_selectionFunctionExpression != null) {
variableType = '';
returnType = '';
} else if (_returnType == null) {
variableType = null;
if (_hasAwait) {
- returnType = _getTypeCode(futureType);
+ returnType = _getTypeCode(typeProvider.futureDynamicType);
} else {
returnType = 'void';
}
} else if (_returnType.isDynamic) {
variableType = '';
if (_hasAwait) {
- returnType = _getTypeCode(futureType);
+ returnType = _getTypeCode(typeProvider.futureDynamicType);
} else {
returnType = '';
}
} else {
variableType = _getTypeCode(_returnType);
if (_hasAwait) {
- if (_returnType.element != futureType.element) {
- returnType = _getTypeCode(futureType.instantiate([_returnType]));
+ if (_returnType.element != typeProvider.futureElement) {
+ returnType = _getTypeCode(typeProvider.futureType2(_returnType));
}
} else {
returnType = variableType;
diff --git a/pkg/analysis_server/lib/src/services/refactoring/extract_widget.dart b/pkg/analysis_server/lib/src/services/refactoring/extract_widget.dart
index d9d3370..3feab8b 100644
--- a/pkg/analysis_server/lib/src/services/refactoring/extract_widget.dart
+++ b/pkg/analysis_server/lib/src/services/refactoring/extract_widget.dart
@@ -13,10 +13,12 @@
import 'package:analysis_server/src/services/search/element_visitors.dart';
import 'package:analysis_server/src/services/search/search_engine.dart';
import 'package:analysis_server/src/utilities/flutter.dart';
+import 'package:analyzer/dart/analysis/features.dart';
import 'package:analyzer/dart/analysis/results.dart';
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/ast/visitor.dart';
import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/dart/element/nullability_suffix.dart';
import 'package:analyzer/dart/element/type.dart';
import 'package:analyzer/src/dart/analysis/session_helper.dart';
import 'package:analyzer/src/dart/ast/utilities.dart';
@@ -84,6 +86,12 @@
return 'Extract Widget';
}
+ FeatureSet get _featureSet {
+ return resolveResult.unit.featureSet;
+ }
+
+ bool get _isNonNullable => _featureSet.isEnabled(Feature.non_nullable);
+
@override
Future<RefactoringStatus> checkFinalConditions() async {
// TODO(brianwilkerson) Determine whether this await is necessary.
@@ -406,7 +414,10 @@
builder.writeln();
builder.writeClassDeclaration(
name,
- superclass: classStatelessWidget.type,
+ superclass: classStatelessWidget.instantiate(
+ typeArguments: const [],
+ nullabilitySuffix: NullabilitySuffix.none,
+ ),
membersWriter: () {
// Add the constructor.
builder.write(' ');
@@ -418,7 +429,15 @@
// Add the required `key` parameter.
builder.write(' ');
- builder.writeParameter('key', type: classKey.type);
+ builder.writeParameter(
+ 'key',
+ type: classKey.instantiate(
+ typeArguments: const [],
+ nullabilitySuffix: _isNonNullable
+ ? NullabilitySuffix.question
+ : NullabilitySuffix.star,
+ ),
+ );
builder.writeln(',');
// Add parameters for fields, local, and method parameters.
@@ -471,9 +490,18 @@
builder.write(' ');
builder.writeFunctionDeclaration(
'build',
- returnType: classWidget.type,
+ returnType: classWidget.instantiate(
+ typeArguments: const [],
+ nullabilitySuffix: NullabilitySuffix.none,
+ ),
parameterWriter: () {
- builder.writeParameter('context', type: classBuildContext.type);
+ builder.writeParameter(
+ 'context',
+ type: classBuildContext.instantiate(
+ typeArguments: const [],
+ nullabilitySuffix: NullabilitySuffix.none,
+ ),
+ );
},
bodyWriter: () {
if (_expression != null) {
diff --git a/pkg/analysis_server/lib/src/services/refactoring/inline_method.dart b/pkg/analysis_server/lib/src/services/refactoring/inline_method.dart
index b487d2d..294ed47 100644
--- a/pkg/analysis_server/lib/src/services/refactoring/inline_method.dart
+++ b/pkg/analysis_server/lib/src/services/refactoring/inline_method.dart
@@ -393,8 +393,10 @@
// "return" statement requires special handling
if (lastStatement is ReturnStatement) {
_methodExpression = lastStatement.expression;
- SourceRange methodExpressionRange = range.node(_methodExpression);
- _methodExpressionPart = _createSourcePart(methodExpressionRange);
+ if (_methodExpression != null) {
+ SourceRange methodExpressionRange = range.node(_methodExpression);
+ _methodExpressionPart = _createSourcePart(methodExpressionRange);
+ }
// exclude "return" statement from statements
statements = statements.sublist(0, statements.length - 1);
}
diff --git a/pkg/analysis_server/lib/src/status/diagnostics.dart b/pkg/analysis_server/lib/src/status/diagnostics.dart
index 112ee48..e0b741a 100644
--- a/pkg/analysis_server/lib/src/status/diagnostics.dart
+++ b/pkg/analysis_server/lib/src/status/diagnostics.dart
@@ -31,7 +31,7 @@
import 'package:analyzer/src/dart/analysis/driver.dart';
import 'package:analyzer/src/dart/sdk/sdk.dart';
import 'package:analyzer/src/dartdoc/dartdoc_directive_info.dart';
-import 'package:analyzer/src/generated/engine.dart' hide AnalysisResult;
+import 'package:analyzer/src/generated/engine.dart';
import 'package:analyzer/src/generated/sdk.dart';
import 'package:analyzer/src/generated/source.dart';
import 'package:analyzer/src/generated/utilities_general.dart';
diff --git a/pkg/analysis_server/lib/src/status/element_writer.dart b/pkg/analysis_server/lib/src/status/element_writer.dart
index a4a20c9..c91f46b 100644
--- a/pkg/analysis_server/lib/src/status/element_writer.dart
+++ b/pkg/analysis_server/lib/src/status/element_writer.dart
@@ -148,9 +148,6 @@
if (element is PropertyInducingElement) {
properties['isStatic'] = element.isStatic;
}
- if (element is TypeDefiningElement) {
- properties['type'] = element.type;
- }
if (element is TypeParameterElement) {
properties['bound'] = element.bound;
}
diff --git a/pkg/analysis_server/pubspec.yaml b/pkg/analysis_server/pubspec.yaml
index 20a9e0e..0990d68 100644
--- a/pkg/analysis_server/pubspec.yaml
+++ b/pkg/analysis_server/pubspec.yaml
@@ -15,6 +15,7 @@
linter: any
logging: any
meta: any
+ mustache: any
nnbd_migration: any
source_span: any
package_config: any
diff --git a/pkg/analysis_server/test/context_manager_test.dart b/pkg/analysis_server/test/context_manager_test.dart
index 228ec3f..ad60430 100644
--- a/pkg/analysis_server/test/context_manager_test.dart
+++ b/pkg/analysis_server/test/context_manager_test.dart
@@ -20,7 +20,7 @@
import 'package:analyzer/src/dart/analysis/restricted_analysis_context.dart';
import 'package:analyzer/src/dart/analysis/session.dart';
import 'package:analyzer/src/error/codes.dart';
-import 'package:analyzer/src/generated/engine.dart' hide AnalysisResult;
+import 'package:analyzer/src/generated/engine.dart';
import 'package:analyzer/src/generated/sdk.dart';
import 'package:analyzer/src/generated/source.dart';
import 'package:analyzer/src/generated/source_io.dart';
diff --git a/pkg/analysis_server/test/domain_edit_dartfix_test.dart b/pkg/analysis_server/test/domain_edit_dartfix_test.dart
index 60c01fe..cabaf02 100644
--- a/pkg/analysis_server/test/domain_edit_dartfix_test.dart
+++ b/pkg/analysis_server/test/domain_edit_dartfix_test.dart
@@ -49,9 +49,9 @@
}
Future<EditDartfixResult> performFix(
- {List<String> includedFixes, bool pedantic}) async {
- var response =
- await performFixRaw(includedFixes: includedFixes, pedantic: pedantic);
+ {List<String> includedFixes, String outputDir, bool pedantic}) async {
+ var response = await performFixRaw(
+ includedFixes: includedFixes, outputDir: outputDir, pedantic: pedantic);
expect(response.error, isNull);
return EditDartfixResult.fromResponse(response);
}
@@ -59,11 +59,13 @@
Future<Response> performFixRaw(
{List<String> includedFixes,
List<String> excludedFixes,
+ String outputDir,
bool pedantic}) async {
final id = nextRequestId;
final params = new EditDartfixParams([projectPath]);
params.includedFixes = includedFixes;
params.excludedFixes = excludedFixes;
+ params.outputDir = outputDir;
params.includePedanticFixes = pedantic;
final request = new Request(id, 'edit.dartfix', params.toJson());
@@ -190,7 +192,7 @@
''');
}
- test_dartfix_non_nullable() async {
+ test_dartfix_nonNullable() async {
// Add analysis options to enable non-nullable analysis
newFile('/project/analysis_options.yaml', content: '''
analyzer:
@@ -218,7 +220,7 @@
''');
}
- test_dartfix_non_nullable_analysis_options_created() async {
+ test_dartfix_nonNullable_analysisOptions_created() async {
// Add pubspec for nnbd migration to detect
newFile('/project/pubspec.yaml', content: '''
name: testnnbd
@@ -237,7 +239,7 @@
''');
}
- test_dartfix_non_nullable_analysis_options_experiments_added() async {
+ test_dartfix_nonNullable_analysisOptions_experimentsAdded() async {
String originalOptions = '''
analyzer:
something:
@@ -265,7 +267,7 @@
''');
}
- test_dartfix_non_nullable_analysis_options_nnbd_added() async {
+ test_dartfix_nonNullable_analysisOptions_nnbdAdded() async {
String originalOptions = '''
analyzer:
enable-experiment:
@@ -290,6 +292,28 @@
''');
}
+ test_dartfix_nonNullable_outputDir() async {
+ // Add analysis options to enable non-nullable analysis
+ newFile('/project/analysis_options.yaml', content: '''
+analyzer:
+ enable-experiment:
+ - non-nullable
+''');
+ addTestFile('''
+int f(int i) => 0;
+int g(int i) => f(i);
+void test() {
+ g(null);
+}
+''');
+ createProject();
+ var outputDir = getFolder('/outputDir');
+ await performFix(
+ includedFixes: ['non-nullable'], outputDir: outputDir.path);
+ expect(outputDir.exists, true);
+ expect(outputDir.getChildren(), isNotEmpty);
+ }
+
test_dartfix_partFile() async {
newFile('/project/lib/lib.dart', content: '''
library lib2;
diff --git a/pkg/analysis_server/test/edit/fixes_test.dart b/pkg/analysis_server/test/edit/fixes_test.dart
index 37bb83e..efdb5d0 100644
--- a/pkg/analysis_server/test/edit/fixes_test.dart
+++ b/pkg/analysis_server/test/edit/fixes_test.dart
@@ -37,6 +37,7 @@
addTestFile('''
main() {
Completer<String> x = null;
+ print(x);
}
''');
await waitForTasksFinished();
diff --git a/pkg/analysis_server/test/edit/nnbd_migration/instrumentation_output_test.dart b/pkg/analysis_server/test/edit/nnbd_migration/instrumentation_output_test.dart
new file mode 100644
index 0000000..8695f99
--- /dev/null
+++ b/pkg/analysis_server/test/edit/nnbd_migration/instrumentation_output_test.dart
@@ -0,0 +1,46 @@
+// Copyright (c) 2019, 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.
+
+import 'package:analysis_server/src/edit/nnbd_migration/instrumentation_renderer.dart';
+import 'package:analysis_server/src/edit/nnbd_migration/migration_info.dart';
+import 'package:test/test.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import '../../analysis_abstract.dart';
+
+main() {
+ defineReflectiveSuite(() {
+ defineReflectiveTests(InstrumentationRendererTest);
+ });
+}
+
+@reflectiveTest
+class InstrumentationRendererTest extends AbstractAnalysisTest {
+ test_outputContainsModifiedAndUnmodifiedRegions() async {
+ LibraryInfo info = LibraryInfo([
+ UnitInfo('/lib/a.dart', 'int? a = null;',
+ [RegionInfo(3, 1, 'null was assigned')]),
+ ]);
+ String output = InstrumentationRenderer(info).render();
+ expect(
+ output,
+ contains('int<span class="region">?'
+ '<span class="tooltip">null was assigned</span></span> a = null;'));
+ }
+
+ test_outputContainsEachPath() async {
+ LibraryInfo info = LibraryInfo([
+ UnitInfo('/lib/a.dart', 'int? a = null;',
+ [RegionInfo(3, 1, 'null was assigned')]),
+ UnitInfo('/lib/part1.dart', 'int? b = null;',
+ [RegionInfo(3, 1, 'null was assigned')]),
+ UnitInfo('/lib/part2.dart', 'int? c = null;',
+ [RegionInfo(3, 1, 'null was assigned')]),
+ ]);
+ String output = InstrumentationRenderer(info).render();
+ expect(output, contains('<h2>/lib/a.dart</h2>'));
+ expect(output, contains('<h2>/lib/part1.dart</h2>'));
+ expect(output, contains('<h2>/lib/part2.dart</h2>'));
+ }
+}
diff --git a/pkg/analysis_server/test/edit/nnbd_migration/test_all.dart b/pkg/analysis_server/test/edit/nnbd_migration/test_all.dart
new file mode 100644
index 0000000..f02f07d
--- /dev/null
+++ b/pkg/analysis_server/test/edit/nnbd_migration/test_all.dart
@@ -0,0 +1,13 @@
+// Copyright (c) 2019, 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.
+
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'instrumentation_output_test.dart' as instrumentation_output;
+
+main() {
+ defineReflectiveSuite(() {
+ instrumentation_output.main();
+ }, name: 'nnbd_migration');
+}
diff --git a/pkg/analysis_server/test/edit/test_all.dart b/pkg/analysis_server/test/edit/test_all.dart
index 62595d3..1867550 100644
--- a/pkg/analysis_server/test/edit/test_all.dart
+++ b/pkg/analysis_server/test/edit/test_all.dart
@@ -7,6 +7,7 @@
import 'assists_test.dart' as assists;
import 'fixes_test.dart' as fixes;
import 'format_test.dart' as format;
+import 'nnbd_migration/test_all.dart' as nnbd_migration;
import 'organize_directives_test.dart' as organize_directives;
import 'postfix_completion_test.dart' as postfix_completion;
import 'refactoring_test.dart' as refactoring;
@@ -19,6 +20,7 @@
assists.main();
fixes.main();
format.main();
+ nnbd_migration.main();
organize_directives.main();
postfix_completion.main();
refactoring.main();
diff --git a/pkg/analysis_server/test/integration/support/integration_test_methods.dart b/pkg/analysis_server/test/integration/support/integration_test_methods.dart
index 1440fe3..1425c1d 100644
--- a/pkg/analysis_server/test/integration/support/integration_test_methods.dart
+++ b/pkg/analysis_server/test/integration/support/integration_test_methods.dart
@@ -1773,6 +1773,13 @@
* If a name is specified that does not match the name of a known fix, an
* error of type UNKNOWN_FIX will be generated.
*
+ * outputDir: FilePath (optional)
+ *
+ * The absolute and normalized path to a directory to which non-nullability
+ * migration output will be written. The output is only produced if the
+ * non-nullable fix is included. Files in the directory might be
+ * overwritten, but no previously existing files will be deleted.
+ *
* Returns
*
* suggestions: List<DartFixSuggestion>
@@ -1806,12 +1813,14 @@
{List<String> includedFixes,
bool includePedanticFixes,
bool includeRequiredFixes,
- List<String> excludedFixes}) async {
+ List<String> excludedFixes,
+ String outputDir}) async {
var params = new EditDartfixParams(included,
includedFixes: includedFixes,
includePedanticFixes: includePedanticFixes,
includeRequiredFixes: includeRequiredFixes,
- excludedFixes: excludedFixes)
+ excludedFixes: excludedFixes,
+ outputDir: outputDir)
.toJson();
var result = await server.send("edit.dartfix", params);
ResponseDecoder decoder = new ResponseDecoder(null);
diff --git a/pkg/analysis_server/test/integration/support/protocol_matchers.dart b/pkg/analysis_server/test/integration/support/protocol_matchers.dart
index 61edec1..4fd9c45 100644
--- a/pkg/analysis_server/test/integration/support/protocol_matchers.dart
+++ b/pkg/analysis_server/test/integration/support/protocol_matchers.dart
@@ -2561,6 +2561,7 @@
* "includePedanticFixes": optional bool
* "includeRequiredFixes": optional bool
* "excludedFixes": optional List<String>
+ * "outputDir": optional FilePath
* }
*/
final Matcher isEditDartfixParams =
@@ -2570,7 +2571,8 @@
"includedFixes": isListOf(isString),
"includePedanticFixes": isBool,
"includeRequiredFixes": isBool,
- "excludedFixes": isListOf(isString)
+ "excludedFixes": isListOf(isString),
+ "outputDir": isFilePath
}));
/**
diff --git a/pkg/analysis_server/test/services/completion/dart/keyword_contributor_test.dart b/pkg/analysis_server/test/services/completion/dart/keyword_contributor_test.dart
index c42a1b6..eb76db8 100644
--- a/pkg/analysis_server/test/services/completion/dart/keyword_contributor_test.dart
+++ b/pkg/analysis_server/test/services/completion/dart/keyword_contributor_test.dart
@@ -4,6 +4,7 @@
import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart';
import 'package:analysis_server/src/services/completion/dart/keyword_contributor.dart';
+import 'package:analyzer/dart/analysis/features.dart';
import 'package:analyzer/dart/ast/token.dart';
import 'package:analyzer/src/dart/analysis/experiments.dart';
import 'package:analyzer_plugin/protocol/protocol_common.dart';
@@ -52,227 +53,330 @@
Keyword.TRUE,
];
- List<Keyword> get classBodyKeywords => [
- Keyword.CONST,
- Keyword.COVARIANT,
- Keyword.DYNAMIC,
- Keyword.FACTORY,
- Keyword.FINAL,
- Keyword.GET,
- Keyword.OPERATOR,
- Keyword.SET,
- Keyword.STATIC,
- Keyword.VAR,
- Keyword.VOID
- ];
+ List<Keyword> get classBodyKeywords {
+ List<Keyword> keywords = [
+ Keyword.CONST,
+ Keyword.COVARIANT,
+ Keyword.DYNAMIC,
+ Keyword.FACTORY,
+ Keyword.FINAL,
+ Keyword.GET,
+ Keyword.OPERATOR,
+ Keyword.SET,
+ Keyword.STATIC,
+ Keyword.VAR,
+ Keyword.VOID
+ ];
+ if (isEnabled(ExperimentalFeatures.non_nullable)) {
+ keywords.add(Keyword.LATE);
+ }
+ return keywords;
+ }
- List<Keyword> get constructorParameter => [Keyword.COVARIANT, Keyword.THIS];
+ List<Keyword> get constructorParameter {
+ List<Keyword> keywords = [Keyword.COVARIANT, Keyword.THIS];
+ if (isEnabled(ExperimentalFeatures.non_nullable)) {
+ keywords.add(Keyword.REQUIRED);
+ }
+ return keywords;
+ }
- List<Keyword> get declarationKeywords => [
- Keyword.ABSTRACT,
- Keyword.CLASS,
- Keyword.CONST,
- Keyword.COVARIANT,
- Keyword.DYNAMIC,
- Keyword.FINAL,
- Keyword.TYPEDEF,
- Keyword.VAR,
- Keyword.VOID
- ];
+ List<Keyword> get declarationKeywords {
+ List<Keyword> keywords = [
+ Keyword.ABSTRACT,
+ Keyword.CLASS,
+ Keyword.CONST,
+ Keyword.COVARIANT,
+ Keyword.DYNAMIC,
+ Keyword.FINAL,
+ Keyword.TYPEDEF,
+ Keyword.VAR,
+ Keyword.VOID
+ ];
+ if (isEnabled(ExperimentalFeatures.extension_methods)) {
+ keywords.add(Keyword.EXTENSION);
+ }
+ if (isEnabled(ExperimentalFeatures.non_nullable)) {
+ keywords.add(Keyword.LATE);
+ }
+ return keywords;
+ }
- List<Keyword> get directiveAndDeclarationKeywords => [
- Keyword.ABSTRACT,
- Keyword.CLASS,
- Keyword.CONST,
- Keyword.COVARIANT,
- Keyword.DYNAMIC,
- Keyword.EXPORT,
- Keyword.FINAL,
- Keyword.IMPORT,
- Keyword.PART,
- Keyword.TYPEDEF,
- Keyword.VAR,
- Keyword.VOID
- ];
+ List<Keyword> get directiveAndDeclarationKeywords {
+ List<Keyword> keywords = [
+ Keyword.ABSTRACT,
+ Keyword.CLASS,
+ Keyword.CONST,
+ Keyword.COVARIANT,
+ Keyword.DYNAMIC,
+ Keyword.EXPORT,
+ Keyword.FINAL,
+ Keyword.IMPORT,
+ Keyword.PART,
+ Keyword.TYPEDEF,
+ Keyword.VAR,
+ Keyword.VOID
+ ];
+ if (isEnabled(ExperimentalFeatures.extension_methods)) {
+ keywords.add(Keyword.EXTENSION);
+ }
+ if (isEnabled(ExperimentalFeatures.non_nullable)) {
+ keywords.add(Keyword.LATE);
+ }
+ return keywords;
+ }
- List<Keyword> get directiveDeclarationAndLibraryKeywords =>
- directiveDeclarationKeywords..add(Keyword.LIBRARY);
+ List<Keyword> get directiveDeclarationAndLibraryKeywords {
+ List<Keyword> keywords = directiveDeclarationKeywords..add(Keyword.LIBRARY);
+ if (isEnabled(ExperimentalFeatures.non_nullable)) {
+ keywords.add(Keyword.LATE);
+ }
+ return keywords;
+ }
- List<Keyword> get directiveDeclarationKeywords => [
- Keyword.ABSTRACT,
- Keyword.CLASS,
- Keyword.CONST,
- Keyword.COVARIANT,
- Keyword.DYNAMIC,
- Keyword.EXPORT,
- Keyword.FINAL,
- Keyword.IMPORT,
- Keyword.PART,
- Keyword.TYPEDEF,
- Keyword.VAR,
- Keyword.VOID
- ];
+ List<Keyword> get directiveDeclarationKeywords {
+ List<Keyword> keywords = [
+ Keyword.ABSTRACT,
+ Keyword.CLASS,
+ Keyword.CONST,
+ Keyword.COVARIANT,
+ Keyword.DYNAMIC,
+ Keyword.EXPORT,
+ Keyword.FINAL,
+ Keyword.IMPORT,
+ Keyword.PART,
+ Keyword.TYPEDEF,
+ Keyword.VAR,
+ Keyword.VOID
+ ];
+ if (isEnabled(ExperimentalFeatures.extension_methods)) {
+ keywords.add(Keyword.EXTENSION);
+ }
+ if (isEnabled(ExperimentalFeatures.non_nullable)) {
+ keywords.add(Keyword.LATE);
+ }
+ return keywords;
+ }
- List<Keyword> get methodParameter => [Keyword.COVARIANT];
+ List<Keyword> get methodParameter {
+ List<Keyword> keywords = [Keyword.COVARIANT];
+ if (isEnabled(ExperimentalFeatures.non_nullable)) {
+ keywords.add(Keyword.REQUIRED);
+ }
+ return keywords;
+ }
- List<Keyword> get statementStartInClass => [
- Keyword.ASSERT,
- Keyword.CONST,
- Keyword.DO,
- Keyword.FINAL,
- Keyword.FOR,
- Keyword.IF,
- Keyword.NEW,
- Keyword.RETURN,
- Keyword.SUPER,
- Keyword.SWITCH,
- Keyword.THIS,
- Keyword.THROW,
- Keyword.TRY,
- Keyword.VAR,
- Keyword.VOID,
- Keyword.WHILE
- ];
+ List<Keyword> get statementStartInClass {
+ List<Keyword> keywords = [
+ Keyword.ASSERT,
+ Keyword.CONST,
+ Keyword.DO,
+ Keyword.FINAL,
+ Keyword.FOR,
+ Keyword.IF,
+ Keyword.NEW,
+ Keyword.RETURN,
+ Keyword.SUPER,
+ Keyword.SWITCH,
+ Keyword.THIS,
+ Keyword.THROW,
+ Keyword.TRY,
+ Keyword.VAR,
+ Keyword.VOID,
+ Keyword.WHILE
+ ];
+ if (isEnabled(ExperimentalFeatures.non_nullable)) {
+ keywords.add(Keyword.LATE);
+ }
+ return keywords;
+ }
- List<Keyword> get statementStartInLoopInClass => [
- Keyword.ASSERT,
- Keyword.BREAK,
- Keyword.CONST,
- Keyword.CONTINUE,
- Keyword.DO,
- Keyword.FINAL,
- Keyword.FOR,
- Keyword.IF,
- Keyword.NEW,
- Keyword.RETURN,
- Keyword.SUPER,
- Keyword.SWITCH,
- Keyword.THIS,
- Keyword.THROW,
- Keyword.TRY,
- Keyword.VAR,
- Keyword.VOID,
- Keyword.WHILE
- ];
+ List<Keyword> get statementStartInLoopInClass {
+ List<Keyword> keywords = [
+ Keyword.ASSERT,
+ Keyword.BREAK,
+ Keyword.CONST,
+ Keyword.CONTINUE,
+ Keyword.DO,
+ Keyword.FINAL,
+ Keyword.FOR,
+ Keyword.IF,
+ Keyword.NEW,
+ Keyword.RETURN,
+ Keyword.SUPER,
+ Keyword.SWITCH,
+ Keyword.THIS,
+ Keyword.THROW,
+ Keyword.TRY,
+ Keyword.VAR,
+ Keyword.VOID,
+ Keyword.WHILE
+ ];
+ if (isEnabled(ExperimentalFeatures.non_nullable)) {
+ keywords.add(Keyword.LATE);
+ }
+ return keywords;
+ }
- List<Keyword> get statementStartInLoopOutsideClass => [
- Keyword.ASSERT,
- Keyword.BREAK,
- Keyword.CONST,
- Keyword.CONTINUE,
- Keyword.DO,
- Keyword.FINAL,
- Keyword.FOR,
- Keyword.IF,
- Keyword.NEW,
- Keyword.RETURN,
- Keyword.SWITCH,
- Keyword.THROW,
- Keyword.TRY,
- Keyword.VAR,
- Keyword.VOID,
- Keyword.WHILE
- ];
+ List<Keyword> get statementStartInLoopOutsideClass {
+ List<Keyword> keywords = [
+ Keyword.ASSERT,
+ Keyword.BREAK,
+ Keyword.CONST,
+ Keyword.CONTINUE,
+ Keyword.DO,
+ Keyword.FINAL,
+ Keyword.FOR,
+ Keyword.IF,
+ Keyword.NEW,
+ Keyword.RETURN,
+ Keyword.SWITCH,
+ Keyword.THROW,
+ Keyword.TRY,
+ Keyword.VAR,
+ Keyword.VOID,
+ Keyword.WHILE
+ ];
+ if (isEnabled(ExperimentalFeatures.non_nullable)) {
+ keywords.add(Keyword.LATE);
+ }
+ return keywords;
+ }
- List<Keyword> get statementStartInSwitchCaseInClass => [
- Keyword.ASSERT,
- Keyword.BREAK,
- Keyword.CONST,
- Keyword.DO,
- Keyword.FINAL,
- Keyword.FOR,
- Keyword.IF,
- Keyword.NEW,
- Keyword.RETURN,
- Keyword.SUPER,
- Keyword.THIS,
- Keyword.SWITCH,
- Keyword.THROW,
- Keyword.TRY,
- Keyword.VAR,
- Keyword.VOID,
- Keyword.WHILE
- ];
+ List<Keyword> get statementStartInSwitchCaseInClass {
+ List<Keyword> keywords = [
+ Keyword.ASSERT,
+ Keyword.BREAK,
+ Keyword.CONST,
+ Keyword.DO,
+ Keyword.FINAL,
+ Keyword.FOR,
+ Keyword.IF,
+ Keyword.NEW,
+ Keyword.RETURN,
+ Keyword.SUPER,
+ Keyword.THIS,
+ Keyword.SWITCH,
+ Keyword.THROW,
+ Keyword.TRY,
+ Keyword.VAR,
+ Keyword.VOID,
+ Keyword.WHILE
+ ];
+ if (isEnabled(ExperimentalFeatures.non_nullable)) {
+ keywords.add(Keyword.LATE);
+ }
+ return keywords;
+ }
- List<Keyword> get statementStartInSwitchCaseOutsideClass => [
- Keyword.ASSERT,
- Keyword.BREAK,
- Keyword.CONST,
- Keyword.DO,
- Keyword.FINAL,
- Keyword.FOR,
- Keyword.IF,
- Keyword.NEW,
- Keyword.RETURN,
- Keyword.SWITCH,
- Keyword.THROW,
- Keyword.TRY,
- Keyword.VAR,
- Keyword.VOID,
- Keyword.WHILE
- ];
+ List<Keyword> get statementStartInSwitchCaseOutsideClass {
+ List<Keyword> keywords = [
+ Keyword.ASSERT,
+ Keyword.BREAK,
+ Keyword.CONST,
+ Keyword.DO,
+ Keyword.FINAL,
+ Keyword.FOR,
+ Keyword.IF,
+ Keyword.NEW,
+ Keyword.RETURN,
+ Keyword.SWITCH,
+ Keyword.THROW,
+ Keyword.TRY,
+ Keyword.VAR,
+ Keyword.VOID,
+ Keyword.WHILE
+ ];
+ if (isEnabled(ExperimentalFeatures.non_nullable)) {
+ keywords.add(Keyword.LATE);
+ }
+ return keywords;
+ }
- List<Keyword> get statementStartInSwitchInClass => [
- Keyword.ASSERT,
- Keyword.BREAK,
- Keyword.CASE,
- Keyword.CONST,
- Keyword.DEFAULT,
- Keyword.DO,
- Keyword.FINAL,
- Keyword.FOR,
- Keyword.IF,
- Keyword.NEW,
- Keyword.RETURN,
- Keyword.SUPER,
- Keyword.SWITCH,
- Keyword.THIS,
- Keyword.THROW,
- Keyword.TRY,
- Keyword.VAR,
- Keyword.VOID,
- Keyword.WHILE
- ];
+ List<Keyword> get statementStartInSwitchInClass {
+ List<Keyword> keywords = [
+ Keyword.ASSERT,
+ Keyword.BREAK,
+ Keyword.CASE,
+ Keyword.CONST,
+ Keyword.DEFAULT,
+ Keyword.DO,
+ Keyword.FINAL,
+ Keyword.FOR,
+ Keyword.IF,
+ Keyword.NEW,
+ Keyword.RETURN,
+ Keyword.SUPER,
+ Keyword.SWITCH,
+ Keyword.THIS,
+ Keyword.THROW,
+ Keyword.TRY,
+ Keyword.VAR,
+ Keyword.VOID,
+ Keyword.WHILE
+ ];
+ if (isEnabled(ExperimentalFeatures.non_nullable)) {
+ keywords.add(Keyword.LATE);
+ }
+ return keywords;
+ }
- List<Keyword> get statementStartInSwitchOutsideClass => [
- Keyword.ASSERT,
- Keyword.BREAK,
- Keyword.CASE,
- Keyword.CONST,
- Keyword.DEFAULT,
- Keyword.DO,
- Keyword.FINAL,
- Keyword.FOR,
- Keyword.IF,
- Keyword.NEW,
- Keyword.RETURN,
- Keyword.SWITCH,
- Keyword.THROW,
- Keyword.TRY,
- Keyword.VAR,
- Keyword.VOID,
- Keyword.WHILE
- ];
+ List<Keyword> get statementStartInSwitchOutsideClass {
+ List<Keyword> keywords = [
+ Keyword.ASSERT,
+ Keyword.BREAK,
+ Keyword.CASE,
+ Keyword.CONST,
+ Keyword.DEFAULT,
+ Keyword.DO,
+ Keyword.FINAL,
+ Keyword.FOR,
+ Keyword.IF,
+ Keyword.NEW,
+ Keyword.RETURN,
+ Keyword.SWITCH,
+ Keyword.THROW,
+ Keyword.TRY,
+ Keyword.VAR,
+ Keyword.VOID,
+ Keyword.WHILE
+ ];
+ if (isEnabled(ExperimentalFeatures.non_nullable)) {
+ keywords.add(Keyword.LATE);
+ }
+ return keywords;
+ }
- List<Keyword> get statementStartOutsideClass => [
- Keyword.ASSERT,
- Keyword.CONST,
- Keyword.DO,
- Keyword.FINAL,
- Keyword.FOR,
- Keyword.IF,
- Keyword.NEW,
- Keyword.RETURN,
- Keyword.SWITCH,
- Keyword.THROW,
- Keyword.TRY,
- Keyword.VAR,
- Keyword.VOID,
- Keyword.WHILE
- ];
+ List<Keyword> get statementStartOutsideClass {
+ List<Keyword> keywords = [
+ Keyword.ASSERT,
+ Keyword.CONST,
+ Keyword.DO,
+ Keyword.FINAL,
+ Keyword.FOR,
+ Keyword.IF,
+ Keyword.NEW,
+ Keyword.RETURN,
+ Keyword.SWITCH,
+ Keyword.THROW,
+ Keyword.TRY,
+ Keyword.VAR,
+ Keyword.VOID,
+ Keyword.WHILE
+ ];
+ if (isEnabled(ExperimentalFeatures.non_nullable)) {
+ keywords.add(Keyword.LATE);
+ }
+ return keywords;
+ }
- List<Keyword> get staticMember =>
- [Keyword.CONST, Keyword.COVARIANT, Keyword.FINAL];
+ List<Keyword> get staticMember {
+ List<Keyword> keywords = [Keyword.CONST, Keyword.COVARIANT, Keyword.FINAL];
+ if (isEnabled(ExperimentalFeatures.non_nullable)) {
+ keywords.add(Keyword.LATE);
+ }
+ return keywords;
+ }
void assertSuggestKeywords(Iterable<Keyword> expectedKeywords,
{List<String> pseudoKeywords = NO_PSEUDO_KEYWORDS,
@@ -344,6 +448,10 @@
return new KeywordContributor();
}
+ /// Return `true` if the given [feature] is enabled.
+ bool isEnabled(Feature feature) =>
+ driver.analysisOptions.contextFeatures.isEnabled(feature);
+
test_after_class_noPrefix() async {
addTestSource('class A {} ^');
await computeSuggestions();
@@ -2078,18 +2186,6 @@
@reflectiveTest
class KeywordContributorWithExtensionMethodsTest
extends KeywordContributorTest {
- @override
- List<Keyword> get declarationKeywords =>
- super.declarationKeywords..add(Keyword.EXTENSION);
-
- @override
- List<Keyword> get directiveAndDeclarationKeywords =>
- super.directiveAndDeclarationKeywords..add(Keyword.EXTENSION);
-
- @override
- List<Keyword> get directiveDeclarationKeywords =>
- super.directiveDeclarationKeywords..add(Keyword.EXTENSION);
-
List<Keyword> get extensionBodyKeywords => [
Keyword.CONST,
Keyword.DYNAMIC,
@@ -2168,69 +2264,6 @@
@reflectiveTest
class KeywordContributorWithNnbdTest extends KeywordContributorTest {
@override
- List<Keyword> get classBodyKeywords =>
- super.classBodyKeywords..add(Keyword.LATE);
-
- @override
- List<Keyword> get constructorParameter =>
- super.constructorParameter..add(Keyword.REQUIRED);
-
- @override
- List<Keyword> get declarationKeywords =>
- super.declarationKeywords..add(Keyword.LATE);
-
- @override
- List<Keyword> get directiveAndDeclarationKeywords =>
- super.directiveAndDeclarationKeywords..add(Keyword.LATE);
-
- @override
- List<Keyword> get directiveDeclarationAndLibraryKeywords =>
- super.directiveDeclarationAndLibraryKeywords..add(Keyword.LATE);
-
- @override
- List<Keyword> get directiveDeclarationKeywords =>
- super.directiveDeclarationKeywords..add(Keyword.LATE);
-
- @override
- List<Keyword> get methodParameter =>
- super.methodParameter..add(Keyword.REQUIRED);
-
- @override
- List<Keyword> get statementStartInClass =>
- super.statementStartInClass..add(Keyword.LATE);
-
- @override
- List<Keyword> get statementStartInLoopInClass =>
- super.statementStartInLoopInClass..add(Keyword.LATE);
-
- @override
- List<Keyword> get statementStartInLoopOutsideClass =>
- super.statementStartInLoopOutsideClass..add(Keyword.LATE);
-
- @override
- List<Keyword> get statementStartInSwitchCaseInClass =>
- super.statementStartInSwitchCaseInClass..add(Keyword.LATE);
-
- @override
- List<Keyword> get statementStartInSwitchCaseOutsideClass =>
- super.statementStartInSwitchCaseOutsideClass..add(Keyword.LATE);
-
- @override
- List<Keyword> get statementStartInSwitchInClass =>
- super.statementStartInSwitchInClass..add(Keyword.LATE);
-
- @override
- List<Keyword> get statementStartInSwitchOutsideClass =>
- super.statementStartInSwitchOutsideClass..add(Keyword.LATE);
-
- @override
- List<Keyword> get statementStartOutsideClass =>
- super.statementStartOutsideClass..add(Keyword.LATE);
-
- @override
- List<Keyword> get staticMember => super.staticMember..add(Keyword.LATE);
-
- @override
void setupResourceProvider() {
super.setupResourceProvider();
createAnalysisOptionsFile(experiments: [EnableString.non_nullable]);
diff --git a/pkg/analysis_server/test/services/completion/dart/local_library_contributor_test.dart b/pkg/analysis_server/test/services/completion/dart/local_library_contributor_test.dart
index 8e5f942..67c4a67 100644
--- a/pkg/analysis_server/test/services/completion/dart/local_library_contributor_test.dart
+++ b/pkg/analysis_server/test/services/completion/dart/local_library_contributor_test.dart
@@ -4,6 +4,7 @@
import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart';
import 'package:analysis_server/src/services/completion/dart/local_library_contributor.dart';
+import 'package:analyzer/src/dart/analysis/experiments.dart';
import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
@@ -12,6 +13,7 @@
main() {
defineReflectiveSuite(() {
defineReflectiveTests(LocalLibraryContributorTest);
+ defineReflectiveTests(LocalLibraryContributorWithExtensionMethodsTest);
});
}
@@ -284,3 +286,29 @@
assertNotSuggested('m');
}
}
+
+@reflectiveTest
+class LocalLibraryContributorWithExtensionMethodsTest
+ extends LocalLibraryContributorTest {
+ @override
+ void setupResourceProvider() {
+ super.setupResourceProvider();
+ createAnalysisOptionsFile(experiments: [EnableString.extension_methods]);
+ }
+
+ test_partFile_extension() async {
+ addSource('/home/test/lib/a.dart', '''
+part of libA;
+extension E on int {}
+''');
+ addTestSource('''
+library libA;
+part "a.dart";
+void f() {^}
+''');
+ await computeSuggestions();
+ expect(replacementOffset, completionOffset);
+ expect(replacementLength, 0);
+ assertSuggest('E');
+ }
+}
diff --git a/pkg/analysis_server/test/services/completion/dart/local_reference_contributor_test.dart b/pkg/analysis_server/test/services/completion/dart/local_reference_contributor_test.dart
index b91a939..083de60 100644
--- a/pkg/analysis_server/test/services/completion/dart/local_reference_contributor_test.dart
+++ b/pkg/analysis_server/test/services/completion/dart/local_reference_contributor_test.dart
@@ -4950,7 +4950,24 @@
super.setUp();
}
- test_extensionDeclaration_body() async {
+ test_extensionDeclaration_inMethod() async {
+ // ExtensionDeclaration CompilationUnit
+ addTestSource('''
+extension E on int {}
+class C {
+ void m() {
+ ^
+ }
+}
+''');
+ await computeSuggestions();
+
+ expect(replacementOffset, completionOffset);
+ expect(replacementLength, 0);
+ assertSuggest('E');
+ }
+
+ test_extensionDeclaration_notInBody() async {
// ExtensionDeclaration CompilationUnit
addSource('/home/test/lib/b.dart', '''
class B { }''');
diff --git a/pkg/analysis_server/test/services/refactoring/inline_method_test.dart b/pkg/analysis_server/test/services/refactoring/inline_method_test.dart
index 061ba99..def1d78 100644
--- a/pkg/analysis_server/test/services/refactoring/inline_method_test.dart
+++ b/pkg/analysis_server/test/services/refactoring/inline_method_test.dart
@@ -470,6 +470,27 @@
''');
}
+ test_function_hasReturn_noExpression() async {
+ await indexTestUnit(r'''
+test(a, b) {
+ print(a);
+ print(b);
+ return;
+}
+main() {
+ test(1, 2);
+}
+''');
+ _createRefactoring('test(a, b)');
+ // validate change
+ return _assertSuccessfulRefactoring(r'''
+main() {
+ print(1);
+ print(2);
+}
+''');
+ }
+
test_function_hasReturn_noVars_oneUsage() async {
await indexTestUnit(r'''
test(a, b) {
diff --git a/pkg/analysis_server/test/src/domains/completion/get_suggestion_details_test.dart b/pkg/analysis_server/test/src/domains/completion/get_suggestion_details_test.dart
index e99991e..33d5226 100644
--- a/pkg/analysis_server/test/src/domains/completion/get_suggestion_details_test.dart
+++ b/pkg/analysis_server/test/src/domains/completion/get_suggestion_details_test.dart
@@ -87,22 +87,6 @@
_assertEmptyChange(result.change);
}
- test_invalid_label() async {
- addTestFile(r'''
-import 'dart:math';
-
-main() {} // ref
-''');
-
- var mathSet = await waitForSetWithUri('dart:math');
-
- var response = await waitResponse(
- _buildRequest(id: mathSet.id, label: 'foo', offset: 0),
- );
-
- expect(response.error.code, RequestErrorCode.INVALID_PARAMETER);
- }
-
test_invalid_library() async {
addTestFile('');
diff --git a/pkg/analysis_server/test/src/services/correction/assist/add_not_null_assert.dart b/pkg/analysis_server/test/src/services/correction/assist/add_not_null_assert.dart
new file mode 100644
index 0000000..e39942c
--- /dev/null
+++ b/pkg/analysis_server/test/src/services/correction/assist/add_not_null_assert.dart
@@ -0,0 +1,74 @@
+// Copyright (c) 2019, 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.
+
+import 'package:analysis_server/src/services/correction/assist.dart';
+import 'package:analyzer_plugin/utilities/assist/assist.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'assist_processor.dart';
+
+main() {
+ defineReflectiveSuite(() {
+ defineReflectiveTests(AddNotNullAssert);
+ });
+}
+
+@reflectiveTest
+class AddNotNullAssert extends AssistProcessorTest {
+ @override
+ AssistKind get kind => DartAssistKind.ADD_NOT_NULL_ASSERT;
+
+ test_function_expressionBody_noAssert() async {
+ await resolveTestUnit('''
+int double(int x) => x * 2;
+''');
+ // todo (pq): support expression bodies.
+ await assertNoAssistAt('x');
+ }
+
+ test_function_noAssert() async {
+ await resolveTestUnit('''
+foo(int x) {
+}
+''');
+ await assertHasAssistAt('x', '''
+foo(int x) {
+ assert(x != null);
+}
+''');
+ }
+
+ test_function_withAssert() async {
+ await resolveTestUnit('''
+foo(int x) {
+ assert(x != null);
+}
+''');
+ await assertNoAssistAt('x');
+ }
+
+ test_function_withAssert2() async {
+ await resolveTestUnit('''
+foo(int x) {
+ print('foo');
+ assert(x != null);
+}
+''');
+ await assertNoAssistAt('x');
+ }
+
+ test_method_noAssert() async {
+ await resolveTestUnit('''
+class A {
+ foo(int x) {
+ }
+}''');
+ await assertHasAssistAt('x', '''
+class A {
+ foo(int x) {
+ assert(x != null);
+ }
+}''');
+ }
+}
diff --git a/pkg/analysis_server/test/src/services/correction/assist/inline_invocation_test.dart b/pkg/analysis_server/test/src/services/correction/assist/inline_invocation_test.dart
index a183e7f..8984a97 100644
--- a/pkg/analysis_server/test/src/services/correction/assist/inline_invocation_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/assist/inline_invocation_test.dart
@@ -3,6 +3,7 @@
// BSD-style license that can be found in the LICENSE file.
import 'package:analysis_server/src/services/correction/assist.dart';
+import 'package:analysis_server/src/services/linter/lint_names.dart';
import 'package:analyzer/src/dart/analysis/experiments.dart';
import 'package:analyzer_plugin/utilities/assist/assist.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
@@ -34,6 +35,15 @@
''');
}
+ test_add_emptyTarget_noAssistWithLint() async {
+ createAnalysisOptionsFile(lints: [LintNames.prefer_inlined_adds]);
+ verifyNoTestUnitErrors = false;
+ await resolveTestUnit('''
+var l = []..ad/*caret*/d('a')..add('b');
+''');
+ await assertNoAssist();
+ }
+
test_add_nonEmptyTarget() async {
await resolveTestUnit('''
var l = ['a']..ad/*caret*/d('b')..add('c');
@@ -78,6 +88,15 @@
''');
}
+ test_addAll_emptyTarget_noAssistWithLint() async {
+ createAnalysisOptionsFile(lints: [LintNames.prefer_inlined_adds]);
+ verifyNoTestUnitErrors = false;
+ await resolveTestUnit('''
+var l = []..add/*caret*/All(['a'])..addAll(['b']);
+''');
+ await assertNoAssist();
+ }
+
test_addAll_nonEmptyTarget() async {
await resolveTestUnit('''
var l = ['a']..add/*caret*/All(['b'])..addAll(['c']);
diff --git a/pkg/analysis_server/test/src/services/correction/assist/sort_child_property_last_test.dart b/pkg/analysis_server/test/src/services/correction/assist/sort_child_property_last_test.dart
index 4cc5973..b8a4916 100644
--- a/pkg/analysis_server/test/src/services/correction/assist/sort_child_property_last_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/assist/sort_child_property_last_test.dart
@@ -3,6 +3,7 @@
// BSD-style license that can be found in the LICENSE file.
import 'package:analysis_server/src/services/correction/assist.dart';
+import 'package:analysis_server/src/services/linter/lint_names.dart';
import 'package:analyzer_plugin/utilities/assist/assist.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
@@ -97,4 +98,24 @@
''');
assertExitPosition(after: "],");
}
+
+ test_sort_noAssistWithLint() async {
+ addFlutterPackage();
+ createAnalysisOptionsFile(lints: [LintNames.sort_child_properties_last]);
+ verifyNoTestUnitErrors = false;
+ await resolveTestUnit('''
+import 'package:flutter/material.dart';
+main() {
+ Column(
+ /*caret*/children: <Widget>[
+ Text('aaa'),
+ Text('bbbbbb'),
+ Text('ccccccccc'),
+ ],
+ crossAxisAlignment: CrossAxisAlignment.center,
+ );
+}
+''');
+ await assertNoAssist();
+ }
}
diff --git a/pkg/analysis_server/test/src/services/correction/assist/test_all.dart b/pkg/analysis_server/test/src/services/correction/assist/test_all.dart
index b26ffb7..5580921 100644
--- a/pkg/analysis_server/test/src/services/correction/assist/test_all.dart
+++ b/pkg/analysis_server/test/src/services/correction/assist/test_all.dart
@@ -4,6 +4,7 @@
import 'package:test_reflective_loader/test_reflective_loader.dart';
+import 'add_not_null_assert.dart' as add_not_null_assert;
import 'add_type_annotation_test.dart' as add_type_annotation;
import 'assign_to_local_variable_test.dart' as assign_to_local_variable;
import 'convert_class_to_mixin_test.dart' as convert_class_to_mixin;
@@ -82,6 +83,7 @@
main() {
defineReflectiveSuite(() {
+ add_not_null_assert.main();
add_type_annotation.main();
assign_to_local_variable.main();
convert_class_to_mixin.main();
diff --git a/pkg/analysis_server/test/src/services/correction/fix/add_async_test.dart b/pkg/analysis_server/test/src/services/correction/fix/add_async_test.dart
index 4d4c30e..fe7ca89 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/add_async_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/add_async_test.dart
@@ -32,7 +32,7 @@
''');
await assertHasFix('''
import 'dart:async';
-Future main(Stream<String> names) async {
+Future<void> main(Stream<String> names) async {
await for (String name in names) {
print(name);
}
diff --git a/pkg/analysis_server/test/src/services/correction/fix/add_type_annotation_test.dart b/pkg/analysis_server/test/src/services/correction/fix/add_type_annotation_test.dart
index a7b406c..e54b689 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/add_type_annotation_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/add_type_annotation_test.dart
@@ -11,12 +11,13 @@
main() {
defineReflectiveSuite(() {
+ defineReflectiveTests(AddTypeAnnotationLintTest);
defineReflectiveTests(AddTypeAnnotationTest);
});
}
@reflectiveTest
-class AddTypeAnnotationTest extends FixProcessorLintTest {
+class AddTypeAnnotationLintTest extends FixProcessorLintTest {
@override
FixKind get kind => DartFixKind.ADD_TYPE_ANNOTATION;
@@ -37,3 +38,37 @@
''');
}
}
+
+@reflectiveTest
+class AddTypeAnnotationTest extends FixProcessorTest {
+ @override
+ FixKind get kind => DartFixKind.ADD_TYPE_ANNOTATION;
+
+ test_missingFieldType() async {
+ // MISSING_CONST_FINAL_VAR_OR_TYPE
+ await resolveTestUnit('''
+class A {
+ f = 0;
+}
+''');
+ await assertHasFix('''
+class A {
+ int f = 0;
+}
+''');
+ }
+
+ test_missingStaticFieldType() async {
+ // MISSING_CONST_FINAL_VAR_OR_TYPE
+ await resolveTestUnit('''
+class A {
+ static f = 0;
+}
+''');
+ await assertHasFix('''
+class A {
+ static int f = 0;
+}
+''');
+ }
+}
diff --git a/pkg/analysis_server/test/src/services/correction/fix/inline_invocation_test.dart b/pkg/analysis_server/test/src/services/correction/fix/inline_invocation_test.dart
new file mode 100644
index 0000000..b3c8344
--- /dev/null
+++ b/pkg/analysis_server/test/src/services/correction/fix/inline_invocation_test.dart
@@ -0,0 +1,35 @@
+// Copyright (c) 2019, 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.
+
+import 'package:analysis_server/src/services/correction/fix.dart';
+import 'package:analysis_server/src/services/linter/lint_names.dart';
+import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'fix_processor.dart';
+
+main() {
+ defineReflectiveSuite(() {
+ defineReflectiveTests(InlineInvocationTest);
+ });
+}
+
+@reflectiveTest
+class InlineInvocationTest extends FixProcessorLintTest {
+ @override
+ FixKind get kind => DartFixKind.INLINE_INVOCATION;
+
+ @override
+ String get lintCode => LintNames.prefer_inlined_adds;
+
+ /// More coverage in the `inline_invocation_test.dart` assist test.
+ test_add_emptyTarget() async {
+ await resolveTestUnit('''
+var l = []../*LINT*/add('a')..add('b');
+''');
+ await assertHasFix('''
+var l = ['a']..add('b');
+''');
+ }
+}
diff --git a/pkg/analysis_server/test/src/services/correction/fix/qualify_reference_test.dart b/pkg/analysis_server/test/src/services/correction/fix/qualify_reference_test.dart
new file mode 100644
index 0000000..1184cb4
--- /dev/null
+++ b/pkg/analysis_server/test/src/services/correction/fix/qualify_reference_test.dart
@@ -0,0 +1,242 @@
+// Copyright (c) 2019, 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.
+
+import 'package:analysis_server/src/services/correction/fix.dart';
+import 'package:analyzer/src/dart/analysis/experiments.dart';
+import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'fix_processor.dart';
+
+main() {
+ defineReflectiveSuite(() {
+ defineReflectiveTests(QualifyReferenceTest);
+ defineReflectiveTests(QualifyReferenceWithExtensionMethodsTest);
+ });
+}
+
+@reflectiveTest
+class QualifyReferenceTest extends FixProcessorTest {
+ @override
+ FixKind get kind => DartFixKind.QUALIFY_REFERENCE;
+
+ test_class_direct() async {
+ await resolveTestUnit('''
+class C {
+ static void m() {}
+}
+class D extends C {
+ void f() {
+ m();
+ }
+}
+''');
+ await assertHasFix('''
+class C {
+ static void m() {}
+}
+class D extends C {
+ void f() {
+ C.m();
+ }
+}
+''');
+ }
+
+ test_class_imported() async {
+ newFile('/home/test/lib/a.dart', content: '''
+class A {
+ static void m() {}
+}
+''');
+ await resolveTestUnit('''
+import 'a.dart';
+class B extends A {
+ void f() {
+ m();
+ }
+}
+''');
+ await assertNoFix();
+ }
+
+ test_class_importedWithPrefix() async {
+ newFile('/home/test/lib/a.dart', content: '''
+class A {
+ static void m() {}
+}
+''');
+ await resolveTestUnit('''
+import 'a.dart' as a;
+class B extends a.A {
+ void f() {
+ m();
+ }
+}
+''');
+ await assertNoFix();
+ }
+
+ test_class_indirect() async {
+ await resolveTestUnit('''
+class A {
+ static void m() {}
+}
+class B extends A {}
+class C extends B {}
+class D extends C {
+ void f() {
+ m();
+ }
+}
+''');
+ await assertHasFix('''
+class A {
+ static void m() {}
+}
+class B extends A {}
+class C extends B {}
+class D extends C {
+ void f() {
+ A.m();
+ }
+}
+''');
+ }
+
+ test_class_notImported() async {
+ newFile('/home/test/lib/a.dart', content: '''
+class A {
+ static void m() {}
+}
+''');
+ newFile('/home/test/lib/b.dart', content: '''
+import 'a.dart';
+class B extends A {}
+''');
+ await resolveTestUnit('''
+import 'b.dart';
+class C extends B {
+ void f() {
+ m();
+ }
+}
+''');
+ await assertNoFix();
+ }
+}
+
+@reflectiveTest
+class QualifyReferenceWithExtensionMethodsTest extends QualifyReferenceTest {
+ @override
+ void setupResourceProvider() {
+ super.setupResourceProvider();
+ createAnalysisOptionsFile(experiments: [EnableString.extension_methods]);
+ }
+
+ test_extension_direct() async {
+ await resolveTestUnit('''
+class C {
+ static void m() {}
+}
+extension E on C {
+ void f() {
+ m();
+ }
+}
+''');
+ await assertHasFix('''
+class C {
+ static void m() {}
+}
+extension E on C {
+ void f() {
+ C.m();
+ }
+}
+''');
+ }
+
+ test_extension_imported() async {
+ newFile('/home/test/lib/a.dart', content: '''
+class A {
+ static void m() {}
+}
+''');
+ await resolveTestUnit('''
+import 'a.dart';
+extension E on A {
+ void f() {
+ m();
+ }
+}
+''');
+ await assertNoFix();
+ }
+
+ test_extension_importedWithPrefix() async {
+ newFile('/home/test/lib/a.dart', content: '''
+class A {
+ static void m() {}
+}
+''');
+ await resolveTestUnit('''
+import 'a.dart' as a;
+extension E on a.A {
+ void f() {
+ m();
+ }
+}
+''');
+ await assertNoFix();
+ }
+
+ test_extension_indirect() async {
+ await resolveTestUnit('''
+class A {
+ static void m() {}
+}
+class B extends A {}
+class C extends B {}
+extension E on C {
+ void f() {
+ m();
+ }
+}
+''');
+ await assertHasFix('''
+class A {
+ static void m() {}
+}
+class B extends A {}
+class C extends B {}
+extension E on C {
+ void f() {
+ A.m();
+ }
+}
+''');
+ }
+
+ test_extension_notImported() async {
+ newFile('/home/test/lib/a.dart', content: '''
+class A {
+ static void m() {}
+}
+''');
+ newFile('/home/test/lib/b.dart', content: '''
+import 'a.dart';
+class B extends A {}
+''');
+ await resolveTestUnit('''
+import 'b.dart';
+extension E on B {
+ void f() {
+ m();
+ }
+}
+''');
+ await assertNoFix();
+ }
+}
diff --git a/pkg/analysis_server/test/src/services/correction/fix/remove_unused_element_test.dart b/pkg/analysis_server/test/src/services/correction/fix/remove_unused_element_test.dart
new file mode 100644
index 0000000..77d6f54
--- /dev/null
+++ b/pkg/analysis_server/test/src/services/correction/fix/remove_unused_element_test.dart
@@ -0,0 +1,157 @@
+// Copyright (c) 2019, 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.
+
+import 'package:analysis_server/src/services/correction/fix.dart';
+import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'fix_processor.dart';
+
+main() {
+ defineReflectiveSuite(() {
+ defineReflectiveTests(RemoveUnusedElementTest);
+ });
+}
+
+@reflectiveTest
+class RemoveUnusedElementTest extends FixProcessorTest {
+ @override
+ FixKind get kind => DartFixKind.REMOVE_UNUSED_ELEMENT;
+
+ test_class_notUsed_inClassMember() async {
+ await resolveTestUnit(r'''
+class _A {
+ static staticMethod() {
+ new _A();
+ }
+}
+''');
+ // todo (pq): consider supporting the case where references are limited to within the class.
+ await assertNoFix();
+ }
+
+ test_class_notUsed_isExpression() async {
+ await resolveTestUnit(r'''
+class _A {}
+main(p) {
+ if (p is _A) {
+ }
+}
+''');
+ // We don't know what to do with the reference.
+ await assertNoFix();
+ }
+
+ test_class_notUsed_noReference() async {
+ await resolveTestUnit(r'''
+class _A {
+}
+''');
+ await assertHasFix(r'''
+''');
+ }
+
+ test_enum_notUsed_noReference() async {
+ await resolveTestUnit(r'''
+enum _MyEnum {A, B, C}
+''');
+ await assertHasFix(r'''
+''');
+ }
+
+ test_functionLocal_notUsed_noReference() async {
+ await resolveTestUnit(r'''
+main() {
+ f() {}
+}
+''');
+ await assertHasFix(r'''
+main() {
+}
+''');
+ }
+
+ test_functionTop_notUsed_noReference() async {
+ await resolveTestUnit(r'''
+_f() {}
+main() {
+}
+''');
+ await assertHasFix(r'''
+main() {
+}
+''');
+ }
+
+ test_functionTypeAlias_notUsed_noReference() async {
+ await resolveTestUnit(r'''
+typedef _F(a, b);
+main() {
+}
+''');
+ await assertHasFix(r'''
+main() {
+}
+''');
+ }
+
+ test_getter_notUsed_noReference() async {
+ await resolveTestUnit(r'''
+class A {
+ get _g => null;
+}
+''');
+ await assertHasFix(r'''
+class A {
+}
+''');
+ }
+
+ test_method_notUsed_noReference() async {
+ await resolveTestUnit(r'''
+class A {
+ static _m() {}
+}
+''');
+ await assertHasFix(r'''
+class A {
+}
+''');
+ }
+
+ test_setter_notUsed_noReference() async {
+ await resolveTestUnit(r'''
+class A {
+ set _s(x) {}
+}
+''');
+ await assertHasFix(r'''
+class A {
+}
+''');
+ }
+
+ test_topLevelVariable_notUsed() async {
+ await resolveTestUnit(r'''
+int _a = 1;
+main() {
+ _a = 2;
+}
+''');
+ // Reference.
+ await assertNoFix();
+ }
+
+ test_topLevelVariable_notUsed_noReference() async {
+ await resolveTestUnit(r'''
+int _a = 1;
+main() {
+}
+''');
+ await assertHasFix(r'''
+main() {
+}
+''');
+ }
+}
diff --git a/pkg/analysis_server/test/src/services/correction/fix/remove_unused_field_test.dart b/pkg/analysis_server/test/src/services/correction/fix/remove_unused_field_test.dart
new file mode 100644
index 0000000..a398ef8
--- /dev/null
+++ b/pkg/analysis_server/test/src/services/correction/fix/remove_unused_field_test.dart
@@ -0,0 +1,185 @@
+// Copyright (c) 2019, 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.
+
+import 'package:analysis_server/src/services/correction/fix.dart';
+import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'fix_processor.dart';
+
+main() {
+ defineReflectiveSuite(() {
+ defineReflectiveTests(RemoveUnusedFieldTest);
+ });
+}
+
+@reflectiveTest
+class RemoveUnusedFieldTest extends FixProcessorTest {
+ @override
+ FixKind get kind => DartFixKind.REMOVE_UNUSED_FIELD;
+
+ test_unusedField_notUsed_assign() async {
+ await resolveTestUnit(r'''
+class A {
+ int _f;
+ main() {
+ _f = 2;
+ }
+}
+''');
+ await assertHasFix(r'''
+class A {
+ main() {
+ }
+}
+''');
+ }
+
+ test_unusedField_notUsed_compoundAssign() async {
+ await resolveTestUnit(r'''
+class A {
+ int _f;
+ main() {
+ _f += 2;
+ }
+}
+''');
+ await assertHasFix(r'''
+class A {
+ main() {
+ }
+}
+''');
+ }
+
+ test_unusedField_notUsed_constructorFieldInitializers() async {
+ await resolveTestUnit(r'''
+class A {
+ int _f;
+ A() : _f = 0;
+}
+''');
+ await assertHasFix(r'''
+class A {
+ A();
+}
+''');
+ }
+
+ test_unusedField_notUsed_constructorFieldInitializers1() async {
+ await resolveTestUnit(r'''
+class A {
+ int _f;
+ int y;
+ A() : _f = 0, y = 1;
+}
+''');
+ await assertHasFix(r'''
+class A {
+ int y;
+ A() : y = 1;
+}
+''');
+ }
+
+ test_unusedField_notUsed_constructorFieldInitializers2() async {
+ await resolveTestUnit(r'''
+class A {
+ int _f;
+ int y;
+ A() : y = 1, _f = 0;
+}
+''');
+ await assertHasFix(r'''
+class A {
+ int y;
+ A() : y = 1;
+}
+''');
+ }
+
+ test_unusedField_notUsed_declarationList() async {
+ await resolveTestUnit(r'''
+class A {
+ int _f, x;
+ A(this._f) {
+ print(x);
+ }
+}
+''');
+ await assertHasFix(r'''
+class A {
+ int x;
+ A() {
+ print(x);
+ }
+}
+''');
+ }
+
+ test_unusedField_notUsed_declarationList2() async {
+ await resolveTestUnit(r'''
+class A {
+ int x, _f;
+ A(this._f) {
+ print(x);
+ }
+}
+''');
+ await assertHasFix(r'''
+class A {
+ int x;
+ A() {
+ print(x);
+ }
+}
+''');
+ }
+
+ test_unusedField_notUsed_fieldFormalParameter() async {
+ await resolveTestUnit(r'''
+class A {
+ int _f;
+ A(this._f);
+}
+''');
+ await assertHasFix(r'''
+class A {
+ A();
+}
+''');
+ }
+
+ test_unusedField_notUsed_fieldFormalParameter2() async {
+ await resolveTestUnit(r'''
+class A {
+ int _f;
+ int x;
+ A(this._f, this.x);
+}
+''');
+ await assertHasFix(r'''
+class A {
+ int x;
+ A(this.x);
+}
+''');
+ }
+
+ test_unusedField_notUsed_fieldFormalParameter3() async {
+ await resolveTestUnit(r'''
+class A {
+ int x;
+ int _f;
+ A(this.x, this._f);
+}
+''');
+ await assertHasFix(r'''
+class A {
+ int x;
+ A(this.x);
+}
+''');
+ }
+}
diff --git a/pkg/analysis_server/test/src/services/correction/fix/remove_unused_label_test.dart b/pkg/analysis_server/test/src/services/correction/fix/remove_unused_label_test.dart
new file mode 100644
index 0000000..3b0f339
--- /dev/null
+++ b/pkg/analysis_server/test/src/services/correction/fix/remove_unused_label_test.dart
@@ -0,0 +1,56 @@
+// Copyright (c) 2019, 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.
+
+import 'package:analysis_server/src/services/correction/fix.dart';
+import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'fix_processor.dart';
+
+main() {
+ defineReflectiveSuite(() {
+ defineReflectiveTests(RemoveUnusedLabelTest);
+ });
+}
+
+@reflectiveTest
+class RemoveUnusedLabelTest extends FixProcessorTest {
+ @override
+ FixKind get kind => DartFixKind.REMOVE_UNUSED_LABEL;
+
+ test_unused_onWhile() async {
+ await resolveTestUnit('''
+f() {
+ x:
+ while (true) {
+ break;
+ }
+}
+''');
+ await assertHasFix('''
+f() {
+ while (true) {
+ break;
+ }
+}
+''');
+ }
+
+ test_unused_onWhile_sameLine() async {
+ await resolveTestUnit('''
+f() {
+ x: while (true) {
+ break;
+ }
+}
+''');
+ await assertHasFix('''
+f() {
+ while (true) {
+ break;
+ }
+}
+''');
+ }
+}
diff --git a/pkg/analysis_server/test/src/services/correction/fix/remove_unused_local_variable_test.dart b/pkg/analysis_server/test/src/services/correction/fix/remove_unused_local_variable_test.dart
new file mode 100644
index 0000000..c05e4cc
--- /dev/null
+++ b/pkg/analysis_server/test/src/services/correction/fix/remove_unused_local_variable_test.dart
@@ -0,0 +1,129 @@
+// Copyright (c) 2019, 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.
+
+import 'package:analysis_server/src/services/correction/fix.dart';
+import 'package:analyzer/src/error/codes.dart';
+import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'fix_processor.dart';
+
+main() {
+ defineReflectiveSuite(() {
+ defineReflectiveTests(RemoveUnusedLocalVariableTest);
+ });
+}
+
+@reflectiveTest
+class RemoveUnusedLocalVariableTest extends FixProcessorTest {
+ @override
+ FixKind get kind => DartFixKind.REMOVE_UNUSED_LOCAL_VARIABLE;
+
+ test_inArgumentList() async {
+ await resolveTestUnit(r'''
+main() {
+ var v = 1;
+ print(v = 2);
+}
+''');
+ await assertHasFix(r'''
+main() {
+ print(2);
+}
+''');
+ }
+
+ test_inArgumentList2() async {
+ await resolveTestUnit(r'''
+main() {
+ var v = 1;
+ f(v = 1, 2);
+}
+void f(a, b) { }
+''');
+ await assertHasFix(r'''
+main() {
+ f(1, 2);
+}
+void f(a, b) { }
+''');
+ }
+
+ test_inArgumentList3() async {
+ await resolveTestUnit(r'''
+main() {
+ var v = 1;
+ f(v = 1, v = 2);
+}
+void f(a, b) { }
+''');
+ await assertHasFix(r'''
+main() {
+ f(1, 2);
+}
+void f(a, b) { }
+''');
+ }
+
+ test_inDeclarationList() async {
+ await resolveTestUnit(r'''
+main() {
+ var v = 1, v2 = 3;
+ v = 2;
+ print(v2);
+}
+''');
+ await assertHasFix(r'''
+main() {
+ var v2 = 3;
+ print(v2);
+}
+''');
+ }
+
+ test_inDeclarationList2() async {
+ await resolveTestUnit(r'''
+main() {
+ var v = 1, v2 = 3;
+ print(v);
+}
+''');
+ await assertHasFix(r'''
+main() {
+ var v = 1;
+ print(v);
+}
+''');
+ }
+
+ test_withReferences() async {
+ await resolveTestUnit(r'''
+main() {
+ var v = 1;
+ v = 2;
+}
+''');
+ await assertHasFix(r'''
+main() {
+}
+''');
+ }
+
+ test_withReferences_beforeDeclaration() async {
+ // CompileTimeErrorCode.REFERENCED_BEFORE_DECLARATION
+ verifyNoTestUnitErrors = false;
+ await resolveTestUnit(r'''
+main() {
+ v = 2;
+ var v = 1;
+}
+''');
+ await assertHasFix(r'''
+main() {
+}
+''',
+ errorFilter: (e) =>
+ e.errorCode != CompileTimeErrorCode.REFERENCED_BEFORE_DECLARATION);
+ }
+}
diff --git a/pkg/analysis_server/test/src/services/correction/fix/replace_with_extension_name_test.dart b/pkg/analysis_server/test/src/services/correction/fix/replace_with_extension_name_test.dart
new file mode 100644
index 0000000..b31de86
--- /dev/null
+++ b/pkg/analysis_server/test/src/services/correction/fix/replace_with_extension_name_test.dart
@@ -0,0 +1,113 @@
+// Copyright (c) 2019, 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.
+
+import 'package:analysis_server/src/services/correction/fix.dart';
+import 'package:analyzer/src/dart/analysis/experiments.dart';
+import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'fix_processor.dart';
+
+main() {
+ defineReflectiveSuite(() {
+ defineReflectiveTests(ReplaceWithExtensionNameTest);
+ });
+}
+
+@reflectiveTest
+class ReplaceWithExtensionNameTest extends FixProcessorTest {
+ @override
+ FixKind get kind => DartFixKind.REPLACE_WITH_EXTENSION_NAME;
+
+ @override
+ void setupResourceProvider() {
+ super.setupResourceProvider();
+ createAnalysisOptionsFile(experiments: [EnableString.extension_methods]);
+ }
+
+ test_getter() async {
+ await resolveTestUnit('''
+extension E on String {
+ static int get g => 0;
+}
+
+void f() {
+ E('a').g;
+}
+''');
+ await assertHasFix('''
+extension E on String {
+ static int get g => 0;
+}
+
+void f() {
+ E.g;
+}
+''');
+ }
+
+ test_method() async {
+ await resolveTestUnit('''
+extension E on String {
+ static int m() => 0;
+}
+
+void f() {
+ E('a').m();
+}
+''');
+ await assertHasFix('''
+extension E on String {
+ static int m() => 0;
+}
+
+void f() {
+ E.m();
+}
+''');
+ }
+
+ test_qualified() async {
+ newFile('/home/test/lib/ext.dart', content: '''
+extension E on String {
+ static int m() => 0;
+}
+''');
+ await resolveTestUnit('''
+import 'ext.dart' as ext;
+
+void f() {
+ ext.E('a').m();
+}
+''');
+ await assertHasFix('''
+import 'ext.dart' as ext;
+
+void f() {
+ ext.E.m();
+}
+''');
+ }
+
+ test_setter() async {
+ await resolveTestUnit('''
+extension E on String {
+ static set s(int i) {}
+}
+
+void f() {
+ E('a').s = 3;
+}
+''');
+ await assertHasFix('''
+extension E on String {
+ static set s(int i) {}
+}
+
+void f() {
+ E.s = 3;
+}
+''');
+ }
+}
diff --git a/pkg/analysis_server/test/src/services/correction/fix/sort_child_property_last_test.dart b/pkg/analysis_server/test/src/services/correction/fix/sort_child_property_last_test.dart
new file mode 100644
index 0000000..9a7ca7c
--- /dev/null
+++ b/pkg/analysis_server/test/src/services/correction/fix/sort_child_property_last_test.dart
@@ -0,0 +1,56 @@
+// Copyright (c) 2019, 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.
+
+import 'package:analysis_server/src/services/correction/fix.dart';
+import 'package:analysis_server/src/services/linter/lint_names.dart';
+import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'fix_processor.dart';
+
+main() {
+ defineReflectiveSuite(() {
+ defineReflectiveTests(SortChildPropertiesLastTest);
+ });
+}
+
+@reflectiveTest
+class SortChildPropertiesLastTest extends FixProcessorLintTest {
+ @override
+ FixKind get kind => DartFixKind.SORT_CHILD_PROPERTY_LAST;
+
+ @override
+ String get lintCode => LintNames.sort_child_properties_last;
+
+ /// More coverage in the `sort_child_properties_last_test.dart` assist test.
+ test_sort() async {
+ addFlutterPackage();
+ await resolveTestUnit('''
+import 'package:flutter/material.dart';
+main() {
+ Column(
+ /*LINT*/children: <Widget>[
+ Text('aaa'),
+ Text('bbbbbb'),
+ Text('ccccccccc'),
+ ],
+ crossAxisAlignment: CrossAxisAlignment.center,
+ );
+}
+''');
+ await assertHasFix('''
+import 'package:flutter/material.dart';
+main() {
+ Column(
+ crossAxisAlignment: CrossAxisAlignment.center,
+ /*LINT*/children: <Widget>[
+ Text('aaa'),
+ Text('bbbbbb'),
+ Text('ccccccccc'),
+ ],
+ );
+}
+''');
+ }
+}
diff --git a/pkg/analysis_server/test/src/services/correction/fix/test_all.dart b/pkg/analysis_server/test/src/services/correction/fix/test_all.dart
index 4e74718..3509418 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/test_all.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/test_all.dart
@@ -69,12 +69,14 @@
import 'import_library_project_test.dart' as import_library_project;
import 'import_library_sdk_test.dart' as import_library_sdk;
import 'import_library_show_test.dart' as import_library_show;
+import 'inline_invocation_test.dart' as inline_invocation;
import 'insert_semicolon_test.dart' as insert_semicolon;
import 'make_class_abstract_test.dart' as make_class_abstract;
import 'make_field_not_final_test.dart' as make_field_not_final;
import 'make_final_test.dart' as make_final;
import 'make_variable_not_final_test.dart' as make_variable_not_final;
import 'move_type_arguments_to_class_test.dart' as move_type_arguments_to_class;
+import 'qualify_reference_test.dart' as qualify_reference;
import 'remove_annotation_test.dart' as remove_annotation;
import 'remove_await_test.dart' as remove_await;
import 'remove_dead_code_test.dart' as remove_dead_code;
@@ -100,7 +102,11 @@
import 'remove_unnecessary_new_test.dart' as remove_unnecessary_new;
import 'remove_unused_catch_clause_test.dart' as remove_unused_catch_clause;
import 'remove_unused_catch_stack_test.dart' as remove_unused_catch_stack;
+import 'remove_unused_element_test.dart' as remove_unused_element;
+import 'remove_unused_field_test.dart' as remove_unused_field;
import 'remove_unused_import_test.dart' as remove_unused_import;
+import 'remove_unused_label_test.dart' as remove_unused_label;
+import 'remove_unused_local_variable_test.dart' as remove_unused_local_variable;
import 'rename_to_camel_case_test.dart' as rename_to_camel_case;
import 'replace_boolean_with_bool_test.dart' as replace_boolean_with_bool;
import 'replace_colon_with_equals_test.dart' as replace_colon_with_equals;
@@ -112,11 +118,13 @@
import 'replace_with_brackets_test.dart' as replace_with_brackets;
import 'replace_with_conditional_assignment_test.dart'
as replace_with_conditional_assignment;
+import 'replace_with_extension_name_test.dart' as replace_with_extension_name;
import 'replace_with_identifier_test.dart' as replace_with_identifier;
import 'replace_with_is_empty_test.dart' as replace_with_is_empty;
import 'replace_with_is_not_empty_test.dart' as replace_with_is_not_empty;
import 'replace_with_null_aware_test.dart' as replace_with_null_aware;
import 'replace_with_tear_off_test.dart' as replace_with_tear_off;
+import 'sort_child_property_last_test.dart' as sort_properties_last;
import 'update_sdk_constraints_test.dart' as update_sdk_constraints;
import 'use_const_test.dart' as use_const;
import 'use_effective_integer_division_test.dart'
@@ -184,12 +192,14 @@
import_library_project.main();
import_library_sdk.main();
import_library_show.main();
+ inline_invocation.main();
insert_semicolon.main();
make_class_abstract.main();
make_field_not_final.main();
make_final.main();
make_variable_not_final.main();
move_type_arguments_to_class.main();
+ qualify_reference.main();
remove_annotation.main();
remove_await.main();
remove_dead_code.main();
@@ -212,7 +222,11 @@
remove_unnecessary_new.main();
remove_unused_catch_clause.main();
remove_unused_catch_stack.main();
+ remove_unused_element.main();
+ remove_unused_field.main();
remove_unused_import.main();
+ remove_unused_label.main();
+ remove_unused_local_variable.main();
rename_to_camel_case.main();
replace_boolean_with_bool.main();
replace_colon_with_equals.main();
@@ -223,11 +237,13 @@
replace_var_with_dynamic.main();
replace_with_brackets.main();
replace_with_conditional_assignment.main();
+ replace_with_extension_name.main();
replace_with_identifier.main();
replace_with_is_empty.main();
replace_with_is_not_empty.main();
replace_with_null_aware.main();
replace_with_tear_off.main();
+ sort_properties_last.main();
update_sdk_constraints.main();
use_const.main();
use_effective_integer_division.main();
diff --git a/pkg/analysis_server/tool/spec/generated/java/AnalysisServer.java b/pkg/analysis_server/tool/spec/generated/java/AnalysisServer.java
index 4132f31..f4e3170 100644
--- a/pkg/analysis_server/tool/spec/generated/java/AnalysisServer.java
+++ b/pkg/analysis_server/tool/spec/generated/java/AnalysisServer.java
@@ -498,8 +498,12 @@
* @param excludedFixes A list of names indicating which fixes should not be applied. If a name is
* specified that does not match the name of a known fix, an error of type UNKNOWN_FIX will
* be generated.
+ * @param outputDir The absolute and normalized path to a directory to which non-nullability
+ * migration output will be written. The output is only produced if the non-nullable fix is
+ * included. Files in the directory might be overwritten, but no previously existing files
+ * will be deleted.
*/
- public void edit_dartfix(List<String> included, List<String> includedFixes, boolean includePedanticFixes, boolean includeRequiredFixes, List<String> excludedFixes, DartfixConsumer consumer);
+ public void edit_dartfix(List<String> included, List<String> includedFixes, boolean includePedanticFixes, boolean includeRequiredFixes, List<String> excludedFixes, String outputDir, DartfixConsumer consumer);
/**
* {@code edit.format}
diff --git a/pkg/analysis_server/tool/spec/spec_input.html b/pkg/analysis_server/tool/spec/spec_input.html
index 712bdc4..f74c90d 100644
--- a/pkg/analysis_server/tool/spec/spec_input.html
+++ b/pkg/analysis_server/tool/spec/spec_input.html
@@ -2235,6 +2235,16 @@
an error of type <tt>UNKNOWN_FIX</tt> will be generated.
</p>
</field>
+ <field name="outputDir" optional="true">
+ <ref>FilePath</ref>
+ <p>
+ The absolute and normalized path to a directory to which
+ non-nullability migration output will be written. The output is only
+ produced if the non-nullable fix is included. Files in the directory
+ might be overwritten, but no previously existing files will be
+ deleted.
+ </p>
+ </field>
</params>
<result>
<field name="suggestions">
diff --git a/pkg/analysis_server_client/lib/src/protocol/protocol_constants.dart b/pkg/analysis_server_client/lib/src/protocol/protocol_constants.dart
index 686011c..55a6571 100644
--- a/pkg/analysis_server_client/lib/src/protocol/protocol_constants.dart
+++ b/pkg/analysis_server_client/lib/src/protocol/protocol_constants.dart
@@ -172,6 +172,7 @@
'includePedanticFixes';
const String EDIT_REQUEST_DARTFIX_INCLUDE_REQUIRED_FIXES =
'includeRequiredFixes';
+const String EDIT_REQUEST_DARTFIX_OUTPUT_DIR = 'outputDir';
const String EDIT_REQUEST_FORMAT = 'edit.format';
const String EDIT_REQUEST_FORMAT_FILE = 'file';
const String EDIT_REQUEST_FORMAT_LINE_LENGTH = 'lineLength';
diff --git a/pkg/analysis_server_client/lib/src/protocol/protocol_generated.dart b/pkg/analysis_server_client/lib/src/protocol/protocol_generated.dart
index d0c24a3..e0495b8 100644
--- a/pkg/analysis_server_client/lib/src/protocol/protocol_generated.dart
+++ b/pkg/analysis_server_client/lib/src/protocol/protocol_generated.dart
@@ -7964,6 +7964,7 @@
* "includePedanticFixes": optional bool
* "includeRequiredFixes": optional bool
* "excludedFixes": optional List<String>
+ * "outputDir": optional FilePath
* }
*
* Clients may not extend, implement or mix-in this class.
@@ -7979,6 +7980,8 @@
List<String> _excludedFixes;
+ String _outputDir;
+
/**
* A list of the files and directories for which edits should be suggested.
*
@@ -8066,16 +8069,36 @@
this._excludedFixes = value;
}
+ /**
+ * The absolute and normalized path to a directory to which non-nullability
+ * migration output will be written. The output is only produced if the
+ * non-nullable fix is included. Files in the directory might be overwritten,
+ * but no previously existing files will be deleted.
+ */
+ String get outputDir => _outputDir;
+
+ /**
+ * The absolute and normalized path to a directory to which non-nullability
+ * migration output will be written. The output is only produced if the
+ * non-nullable fix is included. Files in the directory might be overwritten,
+ * but no previously existing files will be deleted.
+ */
+ void set outputDir(String value) {
+ this._outputDir = value;
+ }
+
EditDartfixParams(List<String> included,
{List<String> includedFixes,
bool includePedanticFixes,
bool includeRequiredFixes,
- List<String> excludedFixes}) {
+ List<String> excludedFixes,
+ String outputDir}) {
this.included = included;
this.includedFixes = includedFixes;
this.includePedanticFixes = includePedanticFixes;
this.includeRequiredFixes = includeRequiredFixes;
this.excludedFixes = excludedFixes;
+ this.outputDir = outputDir;
}
factory EditDartfixParams.fromJson(
@@ -8111,11 +8134,17 @@
excludedFixes = jsonDecoder.decodeList(jsonPath + ".excludedFixes",
json["excludedFixes"], jsonDecoder.decodeString);
}
+ String outputDir;
+ if (json.containsKey("outputDir")) {
+ outputDir = jsonDecoder.decodeString(
+ jsonPath + ".outputDir", json["outputDir"]);
+ }
return new EditDartfixParams(included,
includedFixes: includedFixes,
includePedanticFixes: includePedanticFixes,
includeRequiredFixes: includeRequiredFixes,
- excludedFixes: excludedFixes);
+ excludedFixes: excludedFixes,
+ outputDir: outputDir);
} else {
throw jsonDecoder.mismatch(jsonPath, "edit.dartfix params", json);
}
@@ -8142,6 +8171,9 @@
if (excludedFixes != null) {
result["excludedFixes"] = excludedFixes;
}
+ if (outputDir != null) {
+ result["outputDir"] = outputDir;
+ }
return result;
}
@@ -8163,7 +8195,8 @@
includePedanticFixes == other.includePedanticFixes &&
includeRequiredFixes == other.includeRequiredFixes &&
listEqual(excludedFixes, other.excludedFixes,
- (String a, String b) => a == b);
+ (String a, String b) => a == b) &&
+ outputDir == other.outputDir;
}
return false;
}
@@ -8176,6 +8209,7 @@
hash = JenkinsSmiHash.combine(hash, includePedanticFixes.hashCode);
hash = JenkinsSmiHash.combine(hash, includeRequiredFixes.hashCode);
hash = JenkinsSmiHash.combine(hash, excludedFixes.hashCode);
+ hash = JenkinsSmiHash.combine(hash, outputDir.hashCode);
return JenkinsSmiHash.finish(hash);
}
}
diff --git a/pkg/analyzer/CHANGELOG.md b/pkg/analyzer/CHANGELOG.md
index 6c308d7..04cd0e5 100644
--- a/pkg/analyzer/CHANGELOG.md
+++ b/pkg/analyzer/CHANGELOG.md
@@ -1,3 +1,18 @@
+## 0.38.3
+* Deprecated the following codes from `StaticWarningCode`. Please use the
+ corresponding error codes from `CompileTimeErrorCode` instead:
+ * `EXTRA_POSITIONAL_ARGUMENTS`
+ * `EXTRA_POSITIONAL_ARGUMENTS_COULD_BE_NAMED`
+ * `IMPORT_OF_NON_LIBRARY`
+ * `NOT_ENOUGH_REQUIRED_ARGUMENTS`
+ * `REDIRECT_TO_MISSING_CONSTRUCTOR`
+ * `REDIRECT_TO_NON_CLASS`
+ * `UNDEFINED_CLASS`
+ * `UNDEFINED_NAMED_PARAMETER`
+* Bug fixes: #33749, #35985, #37708, #37857, #37858, #37859, #37945, #38022,
+ #38057, #38071, #38091, #38095, #38105, #38113, #38198, #38202, #38203,
+ #38261, #38282, #38365, #38417, #38448, #38449.
+
## 0.38.2
* The type of `FunctionTypeAlias.declaredElement` has been refined to
`FunctionTypeAliasElement`. Since the new type is a refinement of
diff --git a/pkg/analyzer/lib/dart/analysis/analysis_context.dart b/pkg/analyzer/lib/dart/analysis/analysis_context.dart
index 6c3728f..3a77423 100644
--- a/pkg/analyzer/lib/dart/analysis/analysis_context.dart
+++ b/pkg/analyzer/lib/dart/analysis/analysis_context.dart
@@ -4,7 +4,7 @@
import 'package:analyzer/dart/analysis/context_root.dart';
import 'package:analyzer/dart/analysis/session.dart';
-import 'package:analyzer/src/generated/engine.dart' hide AnalysisResult;
+import 'package:analyzer/src/generated/engine.dart';
/// A representation of a body of code and the context in which the code is to
/// be analyzed.
diff --git a/pkg/analyzer/lib/dart/ast/ast.dart b/pkg/analyzer/lib/dart/ast/ast.dart
index 02fdde9..6bfb473 100644
--- a/pkg/analyzer/lib/dart/ast/ast.dart
+++ b/pkg/analyzer/lib/dart/ast/ast.dart
@@ -3303,6 +3303,9 @@
/// ancestor that is a [CascadeExpression].
bool get isCascaded;
+ /// Whether this index expression is null aware (as opposed to non-null).
+ bool get isNullAware;
+
/// Return the left square bracket.
Token get leftBracket;
@@ -3863,6 +3866,9 @@
/// ancestor that is a [CascadeExpression].
bool get isCascaded;
+ /// Whether this method invocation is null aware (as opposed to non-null).
+ bool get isNullAware;
+
/// Return the name of the method being invoked.
SimpleIdentifier get methodName;
@@ -4411,6 +4417,9 @@
/// ancestor that is a [CascadeExpression].
bool get isCascaded;
+ /// Whether this property access is null aware (as opposed to non-null).
+ bool get isNullAware;
+
/// Return the property access operator.
Token get operator;
@@ -4786,11 +4795,11 @@
/// The expression used to compute the collection being spread.
Expression get expression;
- /// The spread operator, either '...' or '...?'.
- Token get spreadOperator;
-
/// Whether this is a null-aware spread, as opposed to a non-null spread.
bool get isNullAware;
+
+ /// The spread operator, either '...' or '...?'.
+ Token get spreadOperator;
}
/// A node that represents a statement.
diff --git a/pkg/analyzer/lib/dart/element/element.dart b/pkg/analyzer/lib/dart/element/element.dart
index 0eda2b3..8ae0ba1 100644
--- a/pkg/analyzer/lib/dart/element/element.dart
+++ b/pkg/analyzer/lib/dart/element/element.dart
@@ -37,6 +37,7 @@
import 'package:analyzer/dart/analysis/session.dart';
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/constant/value.dart';
+import 'package:analyzer/dart/element/nullability_suffix.dart';
import 'package:analyzer/dart/element/type.dart';
import 'package:analyzer/error/error.dart';
import 'package:analyzer/src/dart/constant/evaluation.dart';
@@ -101,6 +102,10 @@
/// <i>abstract</i> is different from <i>has unimplemented members</i>.
bool get isAbstract;
+ /// Return `true` if this class represents the class 'Object' defined in the
+ /// dart:core library.
+ bool get isDartCoreObject;
+
/// Return `true` if this class is defined by an enum declaration.
bool get isEnum;
@@ -170,6 +175,15 @@
/// guard against infinite loops.
InterfaceType get supertype;
+ /// Return the type of `this` expression for this class.
+ ///
+ /// For a class like `class MyClass<T, U> {}` the returned type is equivalent
+ /// to the type `MyClass<T, U>`. So, the type arguments are the types of the
+ /// type parameters, and either `none` or `star` nullability suffix is used
+ /// for the type arguments, and the returned type depending on the
+ /// nullability status of the declaring library.
+ InterfaceType get thisType;
+
@override
InterfaceType get type;
@@ -210,6 +224,13 @@
/// with the given name.
PropertyAccessorElement getSetter(String name);
+ /// Create the [InterfaceType] for this class with the given [typeArguments]
+ /// and [nullabilitySuffix].
+ InterfaceType instantiate({
+ @required List<DartType> typeArguments,
+ @required NullabilitySuffix nullabilitySuffix,
+ });
+
/// Return the element representing the method that results from looking up
/// the given [methodName] in this class with respect to the given [library],
/// ignoring abstract methods, or `null` if the look up fails. The behavior of
@@ -1187,6 +1208,19 @@
/// then a single type argument should be provided, and it will be substituted
/// for T.
FunctionType instantiate(List<DartType> argumentTypes);
+
+ /// Produces the function type resulting from instantiating this typedef with
+ /// the given [typeArguments] and [nullabilitySuffix].
+ ///
+ /// Note that this always instantiates the typedef itself, so for a
+ /// [GenericTypeAliasElement] the returned [FunctionType] might still be a
+ /// generic function, with type formals. For example, if the typedef is:
+ /// typedef F<T> = void Function<U>(T, U);
+ /// then `F<int>` will produce `void Function<U>(int, U)`.
+ FunctionType instantiate2({
+ @required List<DartType> typeArguments,
+ @required NullabilitySuffix nullabilitySuffix,
+ });
}
/// An element that has a [FunctionType] as its [type].
@@ -1656,6 +1690,12 @@
@override
TypeParameterType get type;
+
+ /// Create the [TypeParameterType] with the given [nullabilitySuffix] for
+ /// this type parameter.
+ TypeParameterType instantiate({
+ @required NullabilitySuffix nullabilitySuffix,
+ });
}
/// An element that has type parameters, such as a class or a typedef. This also
diff --git a/pkg/analyzer/lib/dart/element/nullability_suffix.dart b/pkg/analyzer/lib/dart/element/nullability_suffix.dart
new file mode 100644
index 0000000..59a7759
--- /dev/null
+++ b/pkg/analyzer/lib/dart/element/nullability_suffix.dart
@@ -0,0 +1,27 @@
+// Copyright (c) 2019, 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.
+
+/// Suffix indicating the nullability of a type.
+///
+/// This enum describes whether a `?` or `*` would be used at the end of the
+/// canonical representation of a type. It's subtly different the notions of
+/// "nullable", "non-nullable", "potentially nullable", and "potentially
+/// non-nullable" defined by the spec. For example, the type `Null` is
+/// nullable, even though it lacks a trailing `?`.
+enum NullabilitySuffix {
+ /// An indication that the canonical representation of the type under
+ /// consideration ends with `?`. Types having this nullability suffix should
+ /// be interpreted as being unioned with the Null type.
+ question,
+
+ /// An indication that the canonical representation of the type under
+ /// consideration ends with `*`. Types having this nullability suffix are
+ /// called "legacy types"; it has not yet been determined whether they should
+ /// be unioned with the Null type.
+ star,
+
+ /// An indication that the canonical representation of the type under
+ /// consideration does not end with either `?` or `*`.
+ none
+}
diff --git a/pkg/analyzer/lib/error/error.dart b/pkg/analyzer/lib/error/error.dart
index 94175cc..0dfe3fa 100644
--- a/pkg/analyzer/lib/error/error.dart
+++ b/pkg/analyzer/lib/error/error.dart
@@ -142,6 +142,7 @@
CompileTimeErrorCode.EXTENSION_DECLARES_MEMBER_OF_OBJECT,
CompileTimeErrorCode.EXTENSION_OVERRIDE_ACCESS_TO_STATIC_MEMBER,
CompileTimeErrorCode.EXTENSION_OVERRIDE_ARGUMENT_NOT_ASSIGNABLE,
+ CompileTimeErrorCode.EXTENSION_OVERRIDE_WITH_CASCADE,
CompileTimeErrorCode.EXTENSION_OVERRIDE_WITHOUT_ACCESS,
CompileTimeErrorCode.EXTRA_POSITIONAL_ARGUMENTS,
CompileTimeErrorCode.EXTRA_POSITIONAL_ARGUMENTS_COULD_BE_NAMED,
@@ -304,6 +305,7 @@
CompileTimeErrorCode.UNDEFINED_EXTENSION_METHOD,
CompileTimeErrorCode.UNDEFINED_EXTENSION_SETTER,
CompileTimeErrorCode.UNDEFINED_NAMED_PARAMETER,
+ CompileTimeErrorCode.UNQUALIFIED_REFERENCE_TO_STATIC_MEMBER_OF_EXTENDED_TYPE,
CompileTimeErrorCode.URI_DOES_NOT_EXIST,
CompileTimeErrorCode.URI_HAS_NOT_BEEN_GENERATED,
CompileTimeErrorCode.URI_WITH_INTERPOLATION,
@@ -330,6 +332,7 @@
HintCode.FILE_IMPORT_OUTSIDE_LIB_REFERENCES_FILE_INSIDE,
HintCode.IMPORT_DEFERRED_LIBRARY_WITH_LOAD_FUNCTION,
HintCode.INFERENCE_FAILURE_ON_COLLECTION_LITERAL,
+ HintCode.INFERENCE_FAILURE_ON_FUNCTION_RETURN_TYPE,
HintCode.INFERENCE_FAILURE_ON_INSTANCE_CREATION,
HintCode.INFERENCE_FAILURE_ON_UNINITIALIZED_VARIABLE,
HintCode.INFERENCE_FAILURE_ON_UNTYPED_PARAMETER,
@@ -382,8 +385,6 @@
HintCode.SDK_VERSION_UI_AS_CODE,
HintCode.SDK_VERSION_UI_AS_CODE_IN_CONST_CONTEXT,
HintCode.STRICT_RAW_TYPE,
- HintCode.STRICT_RAW_TYPE_IN_AS,
- HintCode.STRICT_RAW_TYPE_IN_IS,
HintCode.SUBTYPE_OF_SEALED_CLASS,
HintCode.TYPE_CHECK_IS_NOT_NULL,
HintCode.TYPE_CHECK_IS_NULL,
@@ -568,6 +569,7 @@
ParserErrorCode.NON_STRING_LITERAL_AS_URI,
ParserErrorCode.NON_USER_DEFINABLE_OPERATOR,
ParserErrorCode.NORMAL_BEFORE_OPTIONAL_PARAMETERS,
+ ParserErrorCode.NULL_AWARE_CASCADE_OUT_OF_ORDER,
ParserErrorCode.POSITIONAL_AFTER_NAMED_ARGUMENT,
ParserErrorCode.POSITIONAL_PARAMETER_OUTSIDE_GROUP,
ParserErrorCode.PREFIX_AFTER_COMBINATOR,
diff --git a/pkg/analyzer/lib/src/cancelable_future.dart b/pkg/analyzer/lib/src/cancelable_future.dart
deleted file mode 100644
index ff0179b..0000000
--- a/pkg/analyzer/lib/src/cancelable_future.dart
+++ /dev/null
@@ -1,298 +0,0 @@
-// Copyright (c) 2014, 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.
-
-import 'dart:async';
-
-/**
- * Type of callback called when the future returned by a CancelableCompleter
- * is canceled.
- */
-typedef void CancelHandler();
-
-/**
- * A way to produce [CancelableFuture] objects and to complete them later with
- * a value or error.
- *
- * This class behaves like the standard library [Completer] class, except that
- * its [future] getter returns a [CancelableFuture].
- *
- * If the future is canceled before being completed, the [CancelHandler] which
- * was passed to the constructor is invoked, and any further attempt to
- * complete the future has no effect. For example, in the following code:
- *
- * main() {
- * var cc = new CancelableCompleter(() {
- * print('cancelled'); // (2)
- * });
- * cc.future.then((value) {
- * print('completed with value $value');
- * }, onError: (error) {
- * print('completed with error $error'); // (3)
- * });
- * cc.future.cancel(); // (1)
- * }
- *
- * The call at (1) causes (2) to be invoked immediately. (3) will be invoked
- * later (on a microtask), with an error that is an instance of
- * [FutureCanceledError].
- *
- * Note that since the closure passed to then() is executed on a microtask,
- * there is a short window of time between the call to [complete] and the
- * client being informed that the future has completed. During this window,
- * any attempt to cancel the future will have no effect. For example, in the
- * following code:
- *
- * main() {
- * var cc = new CancelableCompleter(() {
- * print('cancelled'); // (3)
- * });
- * cc.future.then((value) {
- * print('completed with value $value'); // (4)
- * }, onError: (error) {
- * print('completed with error $error');
- * });
- * cc.complete(100); // (1)
- * cc.future.cancel(); // (2)
- * }
- *
- * The call at (1) will place the completer in the "completed" state, so the
- * call at (2) will have no effect (in particular, (3) won't ever execute).
- * Later, (4) will be invoked on a microtask.
- */
-class CancelableCompleter<T> implements Completer<T> {
- /**
- * The completer which holds the state of the computation. If the
- * computation is canceled, this completer will remain in the non-completed
- * state.
- */
- final Completer<T> _innerCompleter = new Completer<T>.sync();
-
- /**
- * The completer which holds the future that is exposed to the client
- * through [future]. If the computation is canceled, this completer will
- * be completed with a FutureCanceledError.
- */
- final Completer<T> _outerCompleter = new Completer<T>();
-
- /**
- * The callback to invoke if the 'cancel' method is called on the future
- * returned by [future]. This callback will only be invoked if the future
- * is canceled before being completed.
- */
- final CancelHandler _onCancel;
-
- _CancelableCompleterFuture<T> _future;
-
- /**
- * Create a CancelableCompleter that will invoke the given callback
- * synchronously if its future is canceled. The callback will not be
- * invoked if the future is completed before being canceled.
- */
- CancelableCompleter(this._onCancel) {
- _future = new _CancelableCompleterFuture<T>(this);
-
- // When the client completes the inner completer, we need to check whether
- // the outer completer has been completed. If it has, then the operation
- // was canceled before it finished, and it's too late to un-cancel it, so
- // we just ignore the result from the inner completer. If it hasn't, then
- // we simply pass along the result from the inner completer to the outer
- // completer.
- //
- // Note that the reason it is safe for the inner completer to be
- // synchronous is that we don't expose its future to client code, and we
- // only use it to complete the outer completer (which is asynchronous).
- _innerCompleter.future.then((T value) {
- if (!_outerCompleter.isCompleted) {
- _outerCompleter.complete(value);
- }
- }, onError: (Object error, StackTrace stackTrace) {
- if (!_outerCompleter.isCompleted) {
- _outerCompleter.completeError(error, stackTrace);
- }
- });
- }
-
- /**
- * The [CancelableFuture] that will contain the result provided to this
- * completer.
- */
- @override
- CancelableFuture<T> get future => _future;
-
- /**
- * Whether the future has been completed. This is independent of whether
- * the future has been canceled.
- */
- @override
- bool get isCompleted => _innerCompleter.isCompleted;
-
- /**
- * Complete [future] with the supplied value. If the future has previously
- * been canceled, this will have no effect on [future], however it will
- * still set [isCompleted] to true.
- */
- @override
- void complete([value]) {
- _innerCompleter.complete(value);
- }
-
- /**
- * Complete [future] with an error. If the future has previously been
- * canceled, this will have no effect on [future], however it will still set
- * [isCompleted] to true.
- */
- @override
- void completeError(Object error, [StackTrace stackTrace]) {
- _innerCompleter.completeError(error, stackTrace);
- }
-
- void _cancel() {
- if (!_outerCompleter.isCompleted) {
- _outerCompleter.completeError(new FutureCanceledError());
- _onCancel();
- }
- }
-}
-
-/**
- * An object representing a delayed computation that can be canceled.
- */
-abstract class CancelableFuture<T> implements Future<T> {
- /**
- * A CancelableFuture containing the result of calling [computation]
- * asynchronously. Since the computation is started without delay, calling
- * the future's cancel method will have no effect.
- */
- factory CancelableFuture(computation()) =>
- new _WrappedFuture<T>(new Future<T>(computation));
-
- /**
- * A CancelableFuture containing the result of calling [computation] after
- * [duration] has passed.
- *
- * TODO(paulberry): if the future is canceled before the duration has
- * elapsed, the computation should not be performed.
- */
- factory CancelableFuture.delayed(Duration duration, [computation()]) =>
- new _WrappedFuture<T>(new Future<T>.delayed(duration, computation));
-
- /**
- * A CancelableFuture that completes with error. Since the future is
- * completed without delay, calling the future's cancel method will have no
- * effect.
- */
- factory CancelableFuture.error(Object error, [StackTrace stackTrace]) =>
- new _WrappedFuture<T>(new Future<T>.error(error, stackTrace));
-
- /**
- * A CancelableFuture containing the result of calling [computation]
- * asynchronously with scheduleMicrotask. Since the computation is started
- * without delay, calling the future's cancel method will have no effect.
- */
- factory CancelableFuture.microtask(computation()) =>
- new _WrappedFuture<T>(new Future<T>.microtask(computation));
-
- /**
- * A CancelableFuture containing the result of immediately calling
- * [computation]. Since the computation is started without delay, calling
- * the future's cancel method will have no effect.
- */
- factory CancelableFuture.sync(computation()) =>
- new _WrappedFuture<T>(new Future<T>.sync(computation));
-
- /**
- * A CancelableFuture whose value is available in the next event-loop
- * iteration. Since the value is available without delay, calling the
- * future's cancel method will have no effect.
- */
- factory CancelableFuture.value([value]) =>
- new _WrappedFuture<T>(new Future<T>.value(value));
-
- /**
- * If the delayed computation has not yet completed, attempt to cancel it.
- * Note that the cancellation is not always possible. If the computation
- * could be canceled, the future is completed with a FutureCanceledError.
- * Otherwise it will behave as though cancel() was not called.
- *
- * Note that attempting to cancel a future that has already completed will
- * never succeed--futures that have already completed retain their final
- * state forever.
- */
- void cancel();
-}
-
-/**
- * Error which is used to complete any [CancelableFuture] which has been
- * successfully canceled by calling its 'cancel' method.
- */
-class FutureCanceledError {}
-
-class _CancelableCompleterFuture<T> implements CancelableFuture<T> {
- final CancelableCompleter<T> _completer;
-
- _CancelableCompleterFuture(this._completer);
-
- @override
- Stream<T> asStream() {
- // TODO(paulberry): Implement this in such a way that
- // StreamSubscription.cancel() cancels the future.
- return _completer._outerCompleter.future.asStream();
- }
-
- @override
- void cancel() {
- _completer._cancel();
- }
-
- @override
- Future<T> catchError(Function onError, {bool test(Object error)}) =>
- _completer._outerCompleter.future.catchError(onError, test: test);
-
- @override
- Future<S> then<S>(FutureOr<S> onValue(T value), {Function onError}) =>
- _completer._outerCompleter.future.then(onValue, onError: onError);
-
- @override
- Future<T> timeout(Duration timeLimit, {onTimeout()}) {
- // TODO(paulberry): Implement this in such a way that a timeout cancels
- // the future.
- return _completer._outerCompleter.future
- .timeout(timeLimit, onTimeout: onTimeout);
- }
-
- @override
- Future<T> whenComplete(action()) =>
- _completer._outerCompleter.future.whenComplete(action);
-}
-
-/**
- * A CancelableFuture that wraps an ordinary Future. Attempting to cancel a
- * _WrappedFuture has no effect.
- */
-class _WrappedFuture<T> implements CancelableFuture<T> {
- final Future<T> _future;
-
- _WrappedFuture(this._future);
-
- @override
- Stream<T> asStream() => _future.asStream();
-
- @override
- void cancel() {}
-
- @override
- Future<T> catchError(Function onError, {bool test(Object error)}) =>
- _future.catchError(onError, test: test);
-
- @override
- Future<S> then<S>(FutureOr<S> onValue(T value), {Function onError}) =>
- _future.then(onValue, onError: onError);
-
- @override
- Future<T> timeout(Duration timeLimit, {onTimeout()}) =>
- _future.timeout(timeLimit, onTimeout: onTimeout);
-
- @override
- Future<T> whenComplete(action()) => _future.whenComplete(action);
-}
diff --git a/pkg/analyzer/lib/src/context/builder.dart b/pkg/analyzer/lib/src/context/builder.dart
index 5b69ecb..4a58ff8 100644
--- a/pkg/analyzer/lib/src/context/builder.dart
+++ b/pkg/analyzer/lib/src/context/builder.dart
@@ -160,10 +160,8 @@
InternalAnalysisContext context =
AnalysisEngine.instance.createAnalysisContext();
AnalysisOptionsImpl options = getAnalysisOptions(path);
- context.contentCache = contentCache;
context.sourceFactory = createSourceFactory(path, options);
context.analysisOptions = options;
- context.name = path;
//_processAnalysisOptions(context, optionMap);
declareVariables(context);
return context;
diff --git a/pkg/analyzer/lib/src/context/context.dart b/pkg/analyzer/lib/src/context/context.dart
index 876243d..5e56d1f 100644
--- a/pkg/analyzer/lib/src/context/context.dart
+++ b/pkg/analyzer/lib/src/context/context.dart
@@ -2,34 +2,18 @@
// 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.
-import 'dart:async';
-
-import 'package:analyzer/dart/ast/ast.dart';
-import 'package:analyzer/dart/element/element.dart';
-import 'package:analyzer/error/error.dart';
-import 'package:analyzer/src/cancelable_future.dart';
-import 'package:analyzer/src/context/builder.dart' show EmbedderYamlLocator;
import 'package:analyzer/src/context/cache.dart';
import 'package:analyzer/src/generated/constant.dart';
import 'package:analyzer/src/generated/engine.dart';
import 'package:analyzer/src/generated/resolver.dart';
import 'package:analyzer/src/generated/sdk.dart' show DartSdk;
import 'package:analyzer/src/generated/source.dart';
-import 'package:analyzer/src/plugin/resolver_provider.dart';
-import 'package:analyzer/src/task/api/model.dart';
/**
* An [AnalysisContext] in which analysis can be performed.
*/
class AnalysisContextImpl implements InternalAnalysisContext {
/**
- * A client-provided name used to identify this context, or `null` if the
- * client has not provided a name.
- */
- @override
- String name;
-
- /**
* The set of analysis options controlling the behavior of this context.
*/
AnalysisOptionsImpl _options = new AnalysisOptionsImpl();
@@ -56,47 +40,11 @@
TypeSystem _typeSystem;
/**
- * Determines whether this context should attempt to make use of the global
- * SDK cache partition. Note that if this context is responsible for
- * resynthesizing the SDK element model, this flag should be set to `false`,
- * so that resynthesized elements belonging to this context won't leak into
- * the global SDK cache partition.
- */
- bool useSdkCachePartition = true;
-
- /**
- * The most recently incrementally resolved source, or `null` when it was
- * already validated, or the most recent change was not incrementally resolved.
- */
- Source incrementalResolutionValidation_lastUnitSource;
-
- /**
- * The most recently incrementally resolved library source, or `null` when it
- * was already validated, or the most recent change was not incrementally
- * resolved.
- */
- Source incrementalResolutionValidation_lastLibrarySource;
-
- /**
- * The result of incremental resolution result of
- * [incrementalResolutionValidation_lastUnitSource].
- */
- CompilationUnit incrementalResolutionValidation_lastUnit;
-
- @override
- ResolverProvider fileResolverProvider;
-
- /**
* Initialize a newly created analysis context.
*/
AnalysisContextImpl();
@override
- AnalysisCache get analysisCache {
- throw UnimplementedError();
- }
-
- @override
AnalysisOptions get analysisOptions => _options;
@override
@@ -105,20 +53,6 @@
}
@override
- void set analysisPriorityOrder(List<Source> sources) {
- throw UnimplementedError();
- }
-
- CacheConsistencyValidator get cacheConsistencyValidator {
- throw UnimplementedError();
- }
-
- @override
- set contentCache(ContentCache value) {
- throw UnimplementedError();
- }
-
- @override
DeclaredVariables get declaredVariables => _declaredVariables;
/**
@@ -128,72 +62,6 @@
_declaredVariables = variables;
}
- @deprecated
- @override
- EmbedderYamlLocator get embedderYamlLocator {
- throw UnimplementedError();
- }
-
- @override
- List<AnalysisTarget> get explicitTargets {
- throw UnimplementedError();
- }
-
- @override
- List<Source> get htmlSources {
- throw UnimplementedError();
- }
-
- @override
- Stream<ImplicitAnalysisEvent> get implicitAnalysisEvents {
- throw UnimplementedError();
- }
-
- @override
- bool get isActive {
- throw UnimplementedError();
- }
-
- @override
- set isActive(bool active) {
- throw UnimplementedError();
- }
-
- @override
- bool get isDisposed {
- throw UnimplementedError();
- }
-
- @override
- List<Source> get launchableClientLibrarySources {
- throw UnimplementedError();
- }
-
- @override
- List<Source> get launchableServerLibrarySources {
- throw UnimplementedError();
- }
-
- @override
- List<Source> get librarySources {
- throw UnimplementedError();
- }
-
- @override
- List<Source> get prioritySources {
- throw UnimplementedError();
- }
-
- @override
- List<AnalysisTarget> get priorityTargets {
- throw UnimplementedError();
- }
-
- @override
- CachePartition get privateAnalysisCachePartition {
- throw UnimplementedError();
- }
-
@override
SourceFactory get sourceFactory => _sourceFactory;
@@ -203,25 +71,6 @@
}
@override
- List<Source> get sources {
- throw UnimplementedError();
- }
-
- /**
- * Return a list of the sources that would be processed by
- * [performAnalysisTask]. This method duplicates, and must therefore be kept
- * in sync with, [getNextAnalysisTask]. This method is intended to be used for
- * testing purposes only.
- */
- List<Source> get sourcesNeedingProcessing {
- throw UnimplementedError();
- }
-
- List<Source> get test_priorityOrder {
- throw UnimplementedError();
- }
-
- @override
TypeProvider get typeProvider {
return _typeProvider;
}
@@ -240,268 +89,16 @@
}
@override
- void addListener(AnalysisListener listener) {
- throw UnimplementedError();
- }
-
- @override
- void applyAnalysisDelta(AnalysisDelta delta) {
- throw UnimplementedError();
- }
-
- @override
void applyChanges(ChangeSet changeSet) {
throw UnimplementedError();
}
- @override
- String computeDocumentationComment(Element element) {
- throw UnimplementedError();
- }
-
- @override
- List<AnalysisError> computeErrors(Source source) {
- throw UnimplementedError();
- }
-
- @override
- List<Source> computeExportedLibraries(Source source) {
- throw UnimplementedError();
- }
-
- @override
- List<Source> computeImportedLibraries(Source source) {
- throw UnimplementedError();
- }
-
- @override
- SourceKind computeKindOf(Source source) {
- throw UnimplementedError();
- }
-
- @override
- LibraryElement computeLibraryElement(Source source) {
- throw UnimplementedError();
- }
-
- @override
- LineInfo computeLineInfo(Source source) {
- throw UnimplementedError();
- }
-
- @override
- CancelableFuture<CompilationUnit> computeResolvedCompilationUnitAsync(
- Source unitSource, Source librarySource) {
- throw UnimplementedError();
- }
-
/**
* Create an analysis cache based on the given source [factory].
*/
AnalysisCache createCacheFromSourceFactory(SourceFactory factory) {
throw UnimplementedError();
}
-
- @override
- void dispose() {}
-
- @override
- List<CompilationUnit> ensureResolvedDartUnits(Source unitSource) {
- throw UnimplementedError();
- }
-
- @override
- bool exists(Source source) {
- throw UnimplementedError();
- }
-
- @override
- CompilationUnitElement getCompilationUnitElement(
- Source unitSource, Source librarySource) {
- throw UnimplementedError();
- }
-
- @override
- TimestampedData<String> getContents(Source source) {
- throw UnimplementedError();
- }
-
- @override
- InternalAnalysisContext getContextFor(Source source) {
- throw UnimplementedError();
- }
-
- @override
- Element getElement(ElementLocation location) {
- throw UnimplementedError();
- }
-
- @override
- AnalysisErrorInfo getErrors(Source source) {
- throw UnimplementedError();
- }
-
- @override
- List<Source> getHtmlFilesReferencing(Source source) {
- throw UnimplementedError();
- }
-
- @override
- SourceKind getKindOf(Source source) {
- throw UnimplementedError();
- }
-
- @override
- List<Source> getLibrariesContaining(Source source) {
- throw UnimplementedError();
- }
-
- @override
- List<Source> getLibrariesDependingOn(Source librarySource) {
- throw UnimplementedError();
- }
-
- @override
- List<Source> getLibrariesReferencedFromHtml(Source htmlSource) {
- throw UnimplementedError();
- }
-
- @override
- LibraryElement getLibraryElement(Source source) {
- throw UnimplementedError();
- }
-
- @override
- LineInfo getLineInfo(Source source) {
- throw UnimplementedError();
- }
-
- @override
- int getModificationStamp(Source source) {
- throw UnimplementedError();
- }
-
- @override
- ChangeNoticeImpl getNotice(Source source) {
- throw UnimplementedError();
- }
-
- @override
- Namespace getPublicNamespace(LibraryElement library) {
- // TODO(brianwilkerson) Rename this to not start with 'get'.
- // Note that this is not part of the API of the interface.
- // TODO(brianwilkerson) The public namespace used to be cached, but no
- // longer is. Konstantin adds:
- // The only client of this method is NamespaceBuilder._createExportMapping(),
- // and it is not used with tasks - instead we compute export namespace once
- // using BuildExportNamespaceTask and reuse in scopes.
- NamespaceBuilder builder = new NamespaceBuilder();
- return builder.createPublicNamespaceForLibrary(library);
- }
-
- @override
- CompilationUnit getResolvedCompilationUnit(
- Source unitSource, LibraryElement library) {
- throw UnimplementedError();
- }
-
- @override
- CompilationUnit getResolvedCompilationUnit2(
- Source unitSource, Source librarySource) {
- throw UnimplementedError();
- }
-
- @override
- List<Source> getSourcesWithFullName(String path) {
- throw UnimplementedError();
- }
-
- @override
- bool handleContentsChanged(
- Source source, String originalContents, String newContents, bool notify) {
- throw UnimplementedError();
- }
-
- /**
- * Invalidate analysis cache and notify work managers that they have work
- * to do.
- */
- void invalidateCachedResults() {
- throw UnimplementedError();
- }
-
- @override
- void invalidateLibraryHints(Source librarySource) {
- throw UnimplementedError();
- }
-
- @override
- bool isClientLibrary(Source librarySource) {
- throw UnimplementedError();
- }
-
- @override
- bool isServerLibrary(Source librarySource) {
- throw UnimplementedError();
- }
-
- @override
- CompilationUnit parseCompilationUnit(Source source) {
- throw UnimplementedError();
- }
-
- @override
- AnalysisResult performAnalysisTask() {
- throw UnimplementedError();
- }
-
- @override
- void recordLibraryElements(Map<Source, LibraryElement> elementMap) {
- throw UnimplementedError();
- }
-
- @override
- void removeListener(AnalysisListener listener) {
- throw UnimplementedError();
- }
-
- @override
- CompilationUnit resolveCompilationUnit(
- Source unitSource, LibraryElement library) {
- throw UnimplementedError();
- }
-
- @override
- CompilationUnit resolveCompilationUnit2(
- Source unitSource, Source librarySource) {
- throw UnimplementedError();
- }
-
- @override
- void setChangedContents(Source source, String contents, int offset,
- int oldLength, int newLength) {
- throw UnimplementedError();
- }
-
- @override
- void setContents(Source source, String contents) {
- throw UnimplementedError();
- }
-
- @override
- bool shouldErrorsBeAnalyzed(Source source) {
- throw UnimplementedError();
- }
-
- @override
- void test_flushAstStructures(Source source) {
- throw UnimplementedError();
- }
-
- @override
- void visitContentCache(ContentCacheVisitor visitor) {
- throw UnimplementedError();
- }
}
/**
diff --git a/pkg/analyzer/lib/src/dart/analysis/experiments.g.dart b/pkg/analyzer/lib/src/dart/analysis/experiments.g.dart
index 0132454..06b9e65 100644
--- a/pkg/analyzer/lib/src/dart/analysis/experiments.g.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/experiments.g.dart
@@ -16,6 +16,7 @@
EnableString.set_literals: ExperimentalFeatures.set_literals,
EnableString.spread_collections: ExperimentalFeatures.spread_collections,
EnableString.triple_shift: ExperimentalFeatures.triple_shift,
+ EnableString.variance: ExperimentalFeatures.variance,
// ignore: deprecated_member_use_from_same_package
EnableString.bogus_disabled: ExperimentalFeatures.bogus_disabled,
@@ -31,6 +32,7 @@
true, // set-literals
true, // spread-collections
IsEnabledByDefault.triple_shift,
+ IsEnabledByDefault.variance,
false, // bogus-disabled
true, // bogus-enabled
];
@@ -59,6 +61,9 @@
/// String to enable the experiment "triple-shift"
static const String triple_shift = 'triple-shift';
+ /// String to enable the experiment "variance"
+ static const String variance = 'variance';
+
/// String to enable the experiment "bogus-disabled"
@deprecated
static const String bogus_disabled = 'bogus-disabled';
@@ -122,9 +127,12 @@
IsExpired.triple_shift,
'Triple-shift operator');
+ static const variance = const ExperimentalFeature(7, EnableString.variance,
+ IsEnabledByDefault.variance, IsExpired.variance, 'Sound variance.');
+
@deprecated
static const bogus_disabled = const ExperimentalFeature(
- 7,
+ 8,
// ignore: deprecated_member_use_from_same_package
EnableString.bogus_disabled,
IsEnabledByDefault.bogus_disabled,
@@ -133,7 +141,7 @@
@deprecated
static const bogus_enabled = const ExperimentalFeature(
- 8,
+ 9,
// ignore: deprecated_member_use_from_same_package
EnableString.bogus_enabled,
IsEnabledByDefault.bogus_enabled,
@@ -166,6 +174,9 @@
/// Default state of the experiment "triple-shift"
static const bool triple_shift = false;
+ /// Default state of the experiment "variance"
+ static const bool variance = false;
+
/// Default state of the experiment "bogus-disabled"
@deprecated
static const bool bogus_disabled = false;
@@ -200,6 +211,9 @@
/// Expiration status of the experiment "triple-shift"
static const bool triple_shift = false;
+ /// Expiration status of the experiment "variance"
+ static const bool variance = false;
+
/// Expiration status of the experiment "bogus-disabled"
static const bool bogus_disabled = true;
@@ -241,5 +255,8 @@
/// Current state for the flag "triple-shift"
bool get triple_shift => isEnabled(ExperimentalFeatures.triple_shift);
+ /// Current state for the flag "variance"
+ bool get variance => isEnabled(ExperimentalFeatures.variance);
+
bool isEnabled(covariant ExperimentalFeature feature);
}
diff --git a/pkg/analyzer/lib/src/dart/analysis/library_analyzer.dart b/pkg/analyzer/lib/src/dart/analysis/library_analyzer.dart
index a8c8650..013e122 100644
--- a/pkg/analyzer/lib/src/dart/analysis/library_analyzer.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/library_analyzer.dart
@@ -7,6 +7,7 @@
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/ast/visitor.dart';
import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/dart/element/nullability_suffix.dart';
import 'package:analyzer/error/error.dart';
import 'package:analyzer/error/listener.dart';
import 'package:analyzer/file_system/file_system.dart';
@@ -22,7 +23,6 @@
import 'package:analyzer/src/dart/element/element.dart';
import 'package:analyzer/src/dart/element/handle.dart';
import 'package:analyzer/src/dart/element/inheritance_manager3.dart';
-import 'package:analyzer/src/dart/element/type.dart';
import 'package:analyzer/src/dart/element/type_provider.dart';
import 'package:analyzer/src/dart/resolver/ast_rewrite.dart';
import 'package:analyzer/src/dart/resolver/flow_analysis_visitor.dart';
@@ -658,8 +658,6 @@
source, _typeProvider, errorListener,
nameScope: _libraryScope));
- // TODO(scheglov) remove EnumMemberBuilder class
-
new TypeParameterBoundsResolver(_context.typeSystem, _libraryElement,
source, errorListener, unit.featureSet)
.resolveTypeBounds(unit);
diff --git a/pkg/analyzer/lib/src/dart/analysis/session.dart b/pkg/analyzer/lib/src/dart/analysis/session.dart
index 2857311..f090722 100644
--- a/pkg/analyzer/lib/src/dart/analysis/session.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/session.dart
@@ -219,6 +219,7 @@
return _typeSystem ??= Dart2TypeSystem(
typeProvider,
implicitCasts: analysisOptions.implicitCasts,
+ strictInference: analysisOptions.strictInference,
);
}
diff --git a/pkg/analyzer/lib/src/dart/ast/ast.dart b/pkg/analyzer/lib/src/dart/ast/ast.dart
index 0d75a23..9dd4e72 100644
--- a/pkg/analyzer/lib/src/dart/ast/ast.dart
+++ b/pkg/analyzer/lib/src/dart/ast/ast.dart
@@ -5991,6 +5991,10 @@
bool get isCascaded => period != null;
@override
+ bool get isNullAware =>
+ leftBracket.type == TokenType.QUESTION_PERIOD_OPEN_SQUARE_BRACKET;
+
+ @override
Precedence get precedence => Precedence.postfix;
@deprecated
@@ -7185,6 +7189,9 @@
operator.type == TokenType.QUESTION_PERIOD_PERIOD);
@override
+ bool get isNullAware => operator?.type == TokenType.QUESTION_PERIOD;
+
+ @override
SimpleIdentifier get methodName => _methodName;
@override
@@ -8444,6 +8451,10 @@
operator.type == TokenType.QUESTION_PERIOD_PERIOD);
@override
+ bool get isNullAware =>
+ operator != null && operator.type == TokenType.QUESTION_PERIOD;
+
+ @override
Precedence get precedence => Precedence.postfix;
@override
diff --git a/pkg/analyzer/lib/src/dart/constant/constant_verifier.dart b/pkg/analyzer/lib/src/dart/constant/constant_verifier.dart
index 3c2efbf..9f37e6b 100644
--- a/pkg/analyzer/lib/src/dart/constant/constant_verifier.dart
+++ b/pkg/analyzer/lib/src/dart/constant/constant_verifier.dart
@@ -279,8 +279,12 @@
assert(!node.isConst);
return;
}
- _reportErrors(result.errors,
- CompileTimeErrorCode.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE);
+ if (node.isConst) {
+ _reportErrors(result.errors,
+ CompileTimeErrorCode.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE);
+ } else {
+ _reportErrors(result.errors, null);
+ }
_reportErrorIfFromDeferredLibrary(
initializer,
CompileTimeErrorCode
@@ -352,7 +356,7 @@
MethodElement method =
element.lookUpConcreteMethod("==", _currentLibrary);
if (method == null ||
- (method.enclosingElement as ClassElement).type.isObject) {
+ (method.enclosingElement as ClassElement).isDartCoreObject) {
return false;
}
// there is == that we don't like
diff --git a/pkg/analyzer/lib/src/dart/constant/evaluation.dart b/pkg/analyzer/lib/src/dart/constant/evaluation.dart
index dd26599..c8395a2 100644
--- a/pkg/analyzer/lib/src/dart/constant/evaluation.dart
+++ b/pkg/analyzer/lib/src/dart/constant/evaluation.dart
@@ -11,6 +11,7 @@
import 'package:analyzer/dart/ast/visitor.dart';
import 'package:analyzer/dart/constant/value.dart';
import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/dart/element/nullability_suffix.dart';
import 'package:analyzer/dart/element/type.dart';
import 'package:analyzer/error/error.dart';
import 'package:analyzer/error/listener.dart';
@@ -831,7 +832,7 @@
if (!constructor.isFactory) {
return null;
}
- if (constructor.enclosingElement.type == typeProvider.symbolType) {
+ if (constructor.enclosingElement == typeProvider.symbolElement) {
// The dart:core.Symbol has a const factory constructor that redirects
// to dart:_internal.Symbol. That in turn redirects to an external
// const constructor, which we won't be able to evaluate.
@@ -1256,7 +1257,7 @@
nodeType is InterfaceType && nodeType.typeArguments.isNotEmpty
? nodeType.typeArguments[0]
: _typeProvider.dynamicType;
- InterfaceType listType = _typeProvider.listType.instantiate([elementType]);
+ InterfaceType listType = _typeProvider.listType2(elementType);
return new DartObjectImpl(listType, new ListState(list));
}
@@ -1390,8 +1391,7 @@
valueType = typeArguments[1];
}
}
- InterfaceType mapType =
- _typeProvider.mapType.instantiate([keyType, valueType]);
+ InterfaceType mapType = _typeProvider.mapType2(keyType, valueType);
return new DartObjectImpl(mapType, new MapState(map));
} else {
if (!node.isConst) {
@@ -1412,7 +1412,7 @@
nodeType is InterfaceType && nodeType.typeArguments.isNotEmpty
? nodeType.typeArguments[0]
: _typeProvider.dynamicType;
- InterfaceType setType = _typeProvider.setType.instantiate([elementType]);
+ InterfaceType setType = _typeProvider.setType2(elementType);
return new DartObjectImpl(setType, new SetState(set));
}
}
@@ -1640,13 +1640,36 @@
}
return new DartObjectImpl(functionType, new FunctionState(function));
}
- } else if (variableElement is TypeDefiningElement) {
+ } else if (variableElement is ClassElement) {
+ var type = variableElement.instantiate(
+ typeArguments: variableElement.typeParameters
+ .map((t) => _typeProvider.dynamicType)
+ .toList(),
+ nullabilitySuffix: NullabilitySuffix.star,
+ );
+ return DartObjectImpl(_typeProvider.typeType, TypeState(type));
+ } else if (variableElement is DynamicElementImpl) {
+ return DartObjectImpl(
+ _typeProvider.typeType,
+ TypeState(_typeProvider.dynamicType),
+ );
+ } else if (variableElement is FunctionTypeAliasElement) {
+ var type = variableElement.instantiate2(
+ typeArguments: variableElement.typeParameters
+ .map((t) => _typeProvider.dynamicType)
+ .toList(),
+ nullabilitySuffix: NullabilitySuffix.star,
+ );
+ return DartObjectImpl(_typeProvider.typeType, TypeState(type));
+ } else if (variableElement is NeverElementImpl) {
+ return DartObjectImpl(
+ _typeProvider.typeType,
+ TypeState(_typeProvider.neverType),
+ );
+ } else if (variableElement is TypeParameterElement) {
// Constants may not refer to type parameters.
- if (variableElement is! TypeParameterElement) {
- return new DartObjectImpl(
- _typeProvider.typeType, new TypeState(variableElement.type));
- }
}
+
// TODO(brianwilkerson) Figure out which error to report.
_error(node, null);
return null;
diff --git a/pkg/analyzer/lib/src/dart/element/builder.dart b/pkg/analyzer/lib/src/dart/element/builder.dart
index b6c9ab4..4565244 100644
--- a/pkg/analyzer/lib/src/dart/element/builder.dart
+++ b/pkg/analyzer/lib/src/dart/element/builder.dart
@@ -166,7 +166,7 @@
_setCodeRange(enumElement, node);
enumElement.metadata = _createElementAnnotations(node.metadata);
setElementDocumentationComment(enumElement, node);
- InterfaceTypeImpl enumType = enumElement.type;
+ InterfaceTypeImpl enumType = enumElement.thisType;
//
// Build the elements for the constants. These are minimal elements; the
// rest of the constant elements (and elements for other fields) must be
@@ -368,7 +368,6 @@
..parameters = parameters;
element.typeParameters = typeParameters;
_createTypeParameterTypes(typeParameters);
- element.type = new FunctionTypeImpl.forTypedef(element);
_currentHolder.addTypeAlias(element);
aliasName.staticElement = element;
holder.validate();
@@ -387,7 +386,6 @@
setElementDocumentationComment(element, node);
element.typeParameters = typeParameters;
_createTypeParameterTypes(typeParameters);
- element.type = new FunctionTypeImpl.forTypedef(element);
element.function = node.functionType?.type?.element;
_currentHolder.addTypeAlias(element);
aliasName.staticElement = element;
@@ -728,10 +726,7 @@
for (int i = 0; i < typeParameterCount; i++) {
TypeParameterElementImpl typeParameter =
typeParameters[i] as TypeParameterElementImpl;
- TypeParameterTypeImpl typeParameterType =
- new TypeParameterTypeImpl(typeParameter);
- typeParameter.type = typeParameterType;
- typeArguments[i] = typeParameterType;
+ typeArguments[i] = TypeParameterTypeImpl(typeParameter);
}
return typeArguments;
}
@@ -1557,9 +1552,6 @@
new TypeParameterElementImpl.forNode(parameterName);
_setCodeRange(typeParameter, node);
typeParameter.metadata = _createElementAnnotations(node.metadata);
- TypeParameterTypeImpl typeParameterType =
- new TypeParameterTypeImpl(typeParameter);
- typeParameter.type = typeParameterType;
_currentHolder.addTypeParameter(typeParameter);
parameterName.staticElement = typeParameter;
super.visitTypeParameter(node);
diff --git a/pkg/analyzer/lib/src/dart/element/element.dart b/pkg/analyzer/lib/src/dart/element/element.dart
index 59e5cff..98921f2 100644
--- a/pkg/analyzer/lib/src/dart/element/element.dart
+++ b/pkg/analyzer/lib/src/dart/element/element.dart
@@ -10,6 +10,7 @@
import 'package:analyzer/dart/ast/token.dart';
import 'package:analyzer/dart/constant/value.dart';
import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/dart/element/nullability_suffix.dart';
import 'package:analyzer/dart/element/type.dart';
import 'package:analyzer/error/error.dart';
import 'package:analyzer/src/dart/ast/utilities.dart';
@@ -34,6 +35,7 @@
import 'package:analyzer/src/summary2/linked_unit_context.dart';
import 'package:analyzer/src/summary2/reference.dart';
import 'package:analyzer/src/util/comment.dart';
+import 'package:meta/meta.dart';
/// Assert that the given [object] is null, which in the places where this
/// function is called means that the element is not resynthesized.
@@ -48,6 +50,9 @@
/// A concrete implementation of a [ClassElement].
abstract class AbstractClassElementImpl extends ElementImpl
implements ClassElement {
+ /// The type defined by the class.
+ InterfaceType _thisType;
+
/// A list containing all of the accessors (getters and setters) contained in
/// this class.
List<PropertyAccessorElement> _accessors;
@@ -102,6 +107,9 @@
}
@override
+ bool get isDartCoreObject => false;
+
+ @override
bool get isEnum => false;
@override
@@ -114,6 +122,29 @@
List<InterfaceType> get superclassConstraints => const <InterfaceType>[];
@override
+ InterfaceType get thisType {
+ if (_thisType == null) {
+ // TODO(scheglov) `library` is null in low-level unit tests
+ var nullabilitySuffix = library?.isNonNullableByDefault == true
+ ? NullabilitySuffix.none
+ : NullabilitySuffix.star;
+ List<DartType> typeArguments;
+ if (typeParameters.isNotEmpty) {
+ typeArguments = typeParameters.map<DartType>((t) {
+ return t.instantiate(nullabilitySuffix: nullabilitySuffix);
+ }).toList();
+ } else {
+ typeArguments = const <DartType>[];
+ }
+ return _thisType = instantiate(
+ typeArguments: typeArguments,
+ nullabilitySuffix: nullabilitySuffix,
+ );
+ }
+ return _thisType;
+ }
+
+ @override
T accept<T>(ElementVisitor<T> visitor) => visitor.visitClassElement(this);
@deprecated
@@ -189,6 +220,23 @@
}
@override
+ InterfaceType instantiate({
+ @required List<DartType> typeArguments,
+ @required NullabilitySuffix nullabilitySuffix,
+ }) {
+ if (typeArguments.length != typeParameters.length) {
+ var ta = 'typeArguments.length (${typeArguments.length})';
+ var tp = 'typeParameters.length (${typeParameters.length})';
+ throw ArgumentError('$ta != $tp');
+ }
+ return InterfaceTypeImpl.explicit(
+ this,
+ typeArguments,
+ nullabilitySuffix: nullabilitySuffix,
+ );
+ }
+
+ @override
MethodElement lookUpConcreteMethod(
String methodName, LibraryElement library) =>
_first(getImplementationsOfMethod(this, methodName).where(
@@ -511,7 +559,7 @@
@override
List<InterfaceType> get allSupertypes {
List<InterfaceType> list = new List<InterfaceType>();
- collectAllSupertypes(list, type, type);
+ collectAllSupertypes(list, thisType, thisType);
return list;
}
@@ -728,7 +776,7 @@
MethodElement method = lookUpConcreteMethod(
FunctionElement.NO_SUCH_METHOD_METHOD_NAME, library);
ClassElement definingClass = method?.enclosingElement;
- return definingClass != null && !definingClass.type.isObject;
+ return definingClass != null && !definingClass.isDartCoreObject;
}
@override
@@ -826,6 +874,9 @@
}
@override
+ bool get isDartCoreObject => !isMixin && supertype == null;
+
+ @override
bool get isMixinApplication {
if (linkedNode != null) {
return linkedNode is ClassTypeAlias;
@@ -1897,7 +1948,7 @@
}
@override
- String get identifier => source.encoding;
+ String get identifier => '${source.uri}';
@override
ElementKind get kind => ElementKind.COMPILATION_UNIT;
@@ -2392,7 +2443,7 @@
}
@override
- InterfaceType get type => _enum.type;
+ InterfaceType get type => _enum.thisType;
}
/// The synthetic `values` field of an enum.
@@ -2423,8 +2474,7 @@
@override
InterfaceType get type {
if (_type == null) {
- InterfaceType listType = context.typeProvider.listType;
- return _type = listType.instantiate(<DartType>[_enum.type]);
+ return _type = context.typeProvider.listType2(_enum.thisType);
}
return _type;
}
@@ -2744,7 +2794,7 @@
}
@override
- DartType get returnType => enclosingElement.type;
+ DartType get returnType => enclosingElement.thisType;
void set returnType(DartType returnType) {
assert(false);
@@ -3006,9 +3056,6 @@
static DynamicElementImpl get instance =>
DynamicTypeImpl.instance.element as DynamicElementImpl;
- @override
- DynamicTypeImpl type;
-
/// Initialize a newly created instance of this class. Instances of this class
/// should <b>not</b> be created except as part of creating the type
/// associated with this element. The single instance of this class should be
@@ -3021,6 +3068,9 @@
ElementKind get kind => ElementKind.DYNAMIC;
@override
+ DartType get type => DynamicTypeImpl.instance;
+
+ @override
T accept<T>(ElementVisitor<T> visitor) => null;
}
@@ -3709,7 +3759,9 @@
@deprecated
@override
- CompilationUnit get unit => context.resolveCompilationUnit(source, library);
+ CompilationUnit get unit {
+ throw UnimplementedError();
+ }
@override
bool operator ==(Object object) {
@@ -6379,6 +6431,18 @@
}
@override
+ FunctionType instantiate2({
+ @required List<DartType> typeArguments,
+ @required NullabilitySuffix nullabilitySuffix,
+ }) {
+ // TODO(scheglov) Replace with strict function type.
+ return FunctionTypeImpl.forTypedef(
+ this,
+ nullabilitySuffix: nullabilitySuffix,
+ ).instantiate(typeArguments);
+ }
+
+ @override
void visitChildren(ElementVisitor visitor) {
super.visitChildren(visitor);
safelyVisitChildren(typeParameters, visitor);
@@ -6412,7 +6476,7 @@
if (typeArguments == null ||
parameterElements.length != typeArguments.length) {
- DartType dynamicType = DynamicElementImpl.instance.type;
+ DartType dynamicType = element.context.typeProvider.dynamicType;
typeArguments = new List<DartType>.filled(parameterCount, dynamicType);
}
@@ -7182,7 +7246,7 @@
}
@override
- String get identifier => _definingCompilationUnit.source.encoding;
+ String get identifier => '${_definingCompilationUnit.source.uri}';
@override
List<LibraryElement> get importedLibraries {
@@ -8368,9 +8432,6 @@
static NeverElementImpl get instance =>
BottomTypeImpl.instance.element as NeverElementImpl;
- @override
- BottomTypeImpl type;
-
/// Initialize a newly created instance of this class. Instances of this class
/// should <b>not</b> be created except as part of creating the type
/// associated with this element. The single instance of this class should be
@@ -8383,7 +8444,26 @@
ElementKind get kind => ElementKind.NEVER;
@override
+ DartType get type {
+ throw StateError('Should not be accessed.');
+ }
+
+ @override
T accept<T>(ElementVisitor<T> visitor) => null;
+
+ DartType instantiate({
+ @required NullabilitySuffix nullabilitySuffix,
+ }) {
+ switch (nullabilitySuffix) {
+ case NullabilitySuffix.question:
+ return BottomTypeImpl.instanceNullable;
+ case NullabilitySuffix.star:
+ return BottomTypeImpl.instanceLegacy;
+ case NullabilitySuffix.none:
+ return BottomTypeImpl.instance;
+ }
+ throw StateError('Unsupported nullability: $nullabilitySuffix');
+ }
}
/// A [VariableElementImpl], which is not a parameter.
@@ -10158,6 +10238,13 @@
buffer.write(bound);
}
}
+
+ @override
+ TypeParameterType instantiate({
+ @required NullabilitySuffix nullabilitySuffix,
+ }) {
+ return TypeParameterTypeImpl(this, nullabilitySuffix: nullabilitySuffix);
+ }
}
/// Mixin representing an element which can have type parameters.
@@ -10222,7 +10309,8 @@
/// element's type parameters.
List<TypeParameterType> get typeParameterTypes {
return _typeParameterTypes ??= typeParameters
- .map((TypeParameterElement e) => e.type)
+ .map((TypeParameterElement e) =>
+ e.instantiate(nullabilitySuffix: NullabilitySuffix.star))
.toList(growable: false);
}
diff --git a/pkg/analyzer/lib/src/dart/element/handle.dart b/pkg/analyzer/lib/src/dart/element/handle.dart
index e13d565..534b44f 100644
--- a/pkg/analyzer/lib/src/dart/element/handle.dart
+++ b/pkg/analyzer/lib/src/dart/element/handle.dart
@@ -6,6 +6,7 @@
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/constant/value.dart';
import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/dart/element/nullability_suffix.dart';
import 'package:analyzer/dart/element/type.dart';
import 'package:analyzer/src/dart/element/element.dart';
import 'package:analyzer/src/generated/engine.dart';
@@ -13,6 +14,7 @@
import 'package:analyzer/src/generated/resolver.dart';
import 'package:analyzer/src/generated/source.dart';
import 'package:analyzer/src/generated/utilities_dart.dart';
+import 'package:meta/meta.dart';
/**
* A handle to a [ClassElement].
@@ -70,6 +72,9 @@
bool get isAbstract => actualElement.isAbstract;
@override
+ bool get isDartCoreObject => actualElement.isDartCoreObject;
+
+ @override
bool get isEnum => actualElement.isEnum;
@override
@@ -113,6 +118,9 @@
InterfaceType get supertype => actualElement.supertype;
@override
+ InterfaceType get thisType => actualElement.thisType;
+
+ @override
InterfaceType get type => actualElement.type;
@override
@@ -145,6 +153,17 @@
actualElement.getSetter(setterName);
@override
+ InterfaceType instantiate({
+ @required List<DartType> typeArguments,
+ @required NullabilitySuffix nullabilitySuffix,
+ }) {
+ return actualElement.instantiate(
+ typeArguments: typeArguments,
+ nullabilitySuffix: nullabilitySuffix,
+ );
+ }
+
+ @override
MethodElement lookUpConcreteMethod(
String methodName, LibraryElement library) =>
actualElement.lookUpConcreteMethod(methodName, library);
@@ -763,6 +782,17 @@
@override
FunctionType instantiate(List<DartType> argumentTypes) =>
actualElement.instantiate(argumentTypes);
+
+ @override
+ FunctionType instantiate2({
+ @required List<DartType> typeArguments,
+ @required NullabilitySuffix nullabilitySuffix,
+ }) {
+ return actualElement.instantiate2(
+ typeArguments: typeArguments,
+ nullabilitySuffix: nullabilitySuffix,
+ );
+ }
}
/**
@@ -810,6 +840,17 @@
@override
FunctionType instantiate(List<DartType> argumentTypes) =>
actualElement.instantiate(argumentTypes);
+
+ @override
+ FunctionType instantiate2({
+ @required List<DartType> typeArguments,
+ @required NullabilitySuffix nullabilitySuffix,
+ }) {
+ return actualElement.instantiate2(
+ typeArguments: typeArguments,
+ nullabilitySuffix: nullabilitySuffix,
+ );
+ }
}
/**
@@ -1234,6 +1275,13 @@
@override
TypeParameterType get type => actualElement.type;
+
+ @override
+ TypeParameterType instantiate({
+ @required NullabilitySuffix nullabilitySuffix,
+ }) {
+ return actualElement.instantiate(nullabilitySuffix: nullabilitySuffix);
+ }
}
/**
diff --git a/pkg/analyzer/lib/src/dart/element/member.dart b/pkg/analyzer/lib/src/dart/element/member.dart
index fda6a4d..fc66691 100644
--- a/pkg/analyzer/lib/src/dart/element/member.dart
+++ b/pkg/analyzer/lib/src/dart/element/member.dart
@@ -6,6 +6,7 @@
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/constant/value.dart';
import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/dart/element/nullability_suffix.dart';
import 'package:analyzer/dart/element/type.dart';
import 'package:analyzer/src/dart/element/element.dart';
import 'package:analyzer/src/dart/element/type.dart';
@@ -14,6 +15,7 @@
import 'package:analyzer/src/generated/java_engine.dart';
import 'package:analyzer/src/generated/source.dart';
import 'package:analyzer/src/generated/utilities_dart.dart';
+import 'package:meta/meta.dart';
/**
* A constructor element defined in a parameterized type where the values of the
@@ -55,7 +57,7 @@
@override
ConstructorElement get redirectedConstructor {
- var definingType = _substitution.substituteType(enclosingElement.type);
+ var definingType = _substitution.substituteType(enclosingElement.thisType);
return from(baseElement.redirectedConstructor, definingType);
}
@@ -251,6 +253,10 @@
@override
FieldElement get field {
var field = (baseElement as FieldFormalParameterElement).field;
+ if (field == null) {
+ return null;
+ }
+
return FieldMember(field, _substitution);
}
@@ -932,6 +938,13 @@
}
@override
+ TypeParameterType instantiate({
+ @required NullabilitySuffix nullabilitySuffix,
+ }) {
+ return baseElement.instantiate(nullabilitySuffix: nullabilitySuffix);
+ }
+
+ @override
String toString() {
var buffer = StringBuffer();
appendTo(buffer);
@@ -958,6 +971,10 @@
List<TypeParameterElement> formals,
MapSubstitution substitution,
) {
+ if (substitution.map.isEmpty) {
+ return formals;
+ }
+
// Create type formals with specialized bounds.
// For example `<U extends T>` where T comes from an outer scope.
var newElements = formals.toList(growable: false);
diff --git a/pkg/analyzer/lib/src/dart/element/type.dart b/pkg/analyzer/lib/src/dart/element/type.dart
index 3c1e839..ca2c1e5 100644
--- a/pkg/analyzer/lib/src/dart/element/type.dart
+++ b/pkg/analyzer/lib/src/dart/element/type.dart
@@ -6,6 +6,7 @@
import 'package:analyzer/dart/ast/token.dart';
import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/dart/element/nullability_suffix.dart';
import 'package:analyzer/dart/element/type.dart';
import 'package:analyzer/src/dart/element/element.dart';
import 'package:analyzer/src/dart/element/member.dart';
@@ -92,11 +93,7 @@
* Prevent the creation of instances of this class.
*/
BottomTypeImpl._(this.nullabilitySuffix)
- : super(new NeverElementImpl(), "Never") {
- if (nullabilitySuffix == NullabilitySuffix.none) {
- (element as NeverElementImpl).type = this;
- }
- }
+ : super(new NeverElementImpl(), "Never");
@override
int get hashCode => 0;
@@ -393,10 +390,7 @@
/**
* Prevent the creation of instances of this class.
*/
- DynamicTypeImpl._()
- : super(new DynamicElementImpl(), Keyword.DYNAMIC.lexeme) {
- (element as DynamicElementImpl).type = this;
- }
+ DynamicTypeImpl._() : super(new DynamicElementImpl(), Keyword.DYNAMIC.lexeme);
/**
* Constructor used by [CircularTypeImpl].
@@ -529,7 +523,6 @@
var freshElement =
new TypeParameterElementImpl.synthetic(typeParamElement.name);
var freshTypeVar = new TypeParameterTypeImpl(freshElement);
- freshElement.type = freshTypeVar;
typeVars.add(typeParamElement.type);
freshTypeVars.add(freshTypeVar);
@@ -1407,20 +1400,7 @@
@override
List<InterfaceType> get interfaces {
- ClassElement classElement = element;
- List<InterfaceType> interfaces = classElement.interfaces;
- List<TypeParameterElement> typeParameters = classElement.typeParameters;
- List<DartType> parameterTypes = classElement.type.typeArguments;
- if (typeParameters.isEmpty) {
- return interfaces;
- }
- int count = interfaces.length;
- List<InterfaceType> typedInterfaces = new List<InterfaceType>(count);
- for (int i = 0; i < count; i++) {
- typedInterfaces[i] =
- interfaces[i].substitute2(typeArguments, parameterTypes);
- }
- return typedInterfaces;
+ return _instantiateSuperTypes(element.interfaces);
}
@override
@@ -1574,17 +1554,12 @@
@override
InterfaceType get superclass {
- ClassElement classElement = element;
- InterfaceType supertype = classElement.supertype;
+ InterfaceType supertype = element.supertype;
if (supertype == null) {
return null;
}
- List<DartType> typeParameters = classElement.type.typeArguments;
- if (typeArguments.isEmpty ||
- typeArguments.length != typeParameters.length) {
- return supertype;
- }
- return supertype.substitute2(typeArguments, typeParameters);
+
+ return Substitution.fromInterfaceType(this).substituteType(supertype);
}
@override
@@ -2341,17 +2316,17 @@
}
List<InterfaceType> _instantiateSuperTypes(List<InterfaceType> defined) {
- List<TypeParameterElement> typeParameters = element.typeParameters;
- if (typeParameters.isEmpty) {
- return defined;
+ if (defined.isEmpty) return defined;
+
+ var typeParameters = element.typeParameters;
+ if (typeParameters.isEmpty) return defined;
+
+ var substitution = Substitution.fromInterfaceType(this);
+ var result = List<InterfaceType>(defined.length);
+ for (int i = 0; i < defined.length; i++) {
+ result[i] = substitution.substituteType(defined[i]);
}
- List<DartType> instantiated = element.type.typeArguments;
- int count = defined.length;
- List<InterfaceType> typedConstraints = new List<InterfaceType>(count);
- for (int i = 0; i < count; i++) {
- typedConstraints[i] = defined[i].substitute2(typeArguments, instantiated);
- }
- return typedConstraints;
+ return result;
}
/**
@@ -2579,38 +2554,6 @@
}
/**
- * Suffix indicating the nullability of a type.
- *
- * This enum describes whether a `?` or `*` would be used at the end of the
- * canonical representation of a type. It's subtly different the notions of
- * "nullable", "non-nullable", "potentially nullable", and "potentially
- * non-nullable" defined by the spec. For example, the type `Null` is nullable,
- * even though it lacks a trailing `?`.
- */
-enum NullabilitySuffix {
- /**
- * An indication that the canonical representation of the type under
- * consideration ends with `?`. Types having this nullability suffix should
- * be interpreted as being unioned with the Null type.
- */
- question,
-
- /**
- * An indication that the canonical representation of the type under
- * consideration ends with `*`. Types having this nullability suffix are
- * called "legacy types"; it has not yet been determined whether they should
- * be unioned with the Null type.
- */
- star,
-
- /**
- * An indication that the canonical representation of the type under
- * consideration does not end with either `?` or `*`.
- */
- none
-}
-
-/**
* The abstract class `TypeImpl` implements the behavior common to objects
* representing the declared type of elements in the element model.
*/
@@ -3675,7 +3618,6 @@
if (identical(bound, newBound)) return p;
var element = new TypeParameterElementImpl.synthetic(p.name);
element.bound = newBound;
- element.type = new TypeParameterTypeImpl(element);
return element;
}
diff --git a/pkg/analyzer/lib/src/dart/element/type_algebra.dart b/pkg/analyzer/lib/src/dart/element/type_algebra.dart
index f3e234d..bc9e976 100644
--- a/pkg/analyzer/lib/src/dart/element/type_algebra.dart
+++ b/pkg/analyzer/lib/src/dart/element/type_algebra.dart
@@ -201,6 +201,34 @@
return freshElement;
}
+ @override
+ List<TypeParameterElement> freshTypeParameters(
+ List<TypeParameterElement> elements) {
+ if (elements.isEmpty) {
+ return const <TypeParameterElement>[];
+ }
+
+ var freshElements = List<TypeParameterElement>(elements.length);
+ for (var i = 0; i < elements.length; i++) {
+ var element = elements[i];
+ var freshElement = TypeParameterElementImpl(element.name, -1);
+ freshElements[i] = freshElement;
+ var freshType = TypeParameterTypeImpl(freshElement);
+ freshElement.type = freshType;
+ substitution[element] = freshType;
+ }
+
+ for (var i = 0; i < freshElements.length; i++) {
+ var element = elements[i];
+ if (element.bound != null) {
+ TypeParameterElementImpl freshElement = freshElements[i];
+ freshElement.bound = visit(element.bound);
+ }
+ }
+
+ return freshElements;
+ }
+
DartType lookup(TypeParameterElement parameter, bool upperBound) {
return substitution[parameter];
}
@@ -247,8 +275,8 @@
}
}
- @override
- TypeParameterElement freshTypeParameter(TypeParameterElement element) {
+ List<TypeParameterElement> freshTypeParameters(
+ List<TypeParameterElement> parameters) {
throw 'Create a fresh environment first';
}
@@ -283,15 +311,8 @@
target.useCounter++;
}
- TypeParameterElement freshTypeParameter(TypeParameterElement element);
-
List<TypeParameterElement> freshTypeParameters(
- List<TypeParameterElement> parameters) {
- if (parameters.isEmpty) {
- return const <TypeParameterElement>[];
- }
- return parameters.map(freshTypeParameter).toList();
- }
+ List<TypeParameterElement> elements);
DartType getSubstitute(TypeParameterElement parameter) {
var environment = this;
@@ -339,14 +360,18 @@
// any uses, but does not tell if the resulting function type is distinct.
// Our own use counter will get incremented if something from our
// environment has been used inside the function.
- var inner = type.typeFormals.isEmpty ? this : newInnerEnvironment();
int before = this.useCounter;
+ var inner = this;
+ var typeFormals = type.typeFormals;
+ if (typeFormals.isNotEmpty) {
+ inner = newInnerEnvironment();
+ typeFormals = inner.freshTypeParameters(typeFormals);
+ }
+
// Invert the variance when translating parameters.
inner.invertVariance();
- var typeFormals = inner.freshTypeParameters(type.typeFormals);
-
var parameters = type.parameters.map((parameter) {
var type = inner.visit(parameter.type);
return _parameterElement(parameter, type);
@@ -376,14 +401,18 @@
// any uses, but does not tell if the resulting function type is distinct.
// Our own use counter will get incremented if something from our
// environment has been used inside the function.
- var inner = type.typeFormals.isEmpty ? this : newInnerEnvironment();
int before = this.useCounter;
+ var inner = this;
+ var typeFormals = type.typeFormals;
+ if (typeFormals.isNotEmpty) {
+ inner = newInnerEnvironment();
+ typeFormals = inner.freshTypeParameters(typeFormals);
+ }
+
// Invert the variance when translating parameters.
inner.invertVariance();
- var typeFormals = inner.freshTypeParameters(type.typeFormals);
-
var parameters = type.parameters.map((parameter) {
var type = inner.visit(parameter.type);
return _parameterElement(parameter, type);
diff --git a/pkg/analyzer/lib/src/dart/element/type_provider.dart b/pkg/analyzer/lib/src/dart/element/type_provider.dart
index 0f4a101..952e495 100644
--- a/pkg/analyzer/lib/src/dart/element/type_provider.dart
+++ b/pkg/analyzer/lib/src/dart/element/type_provider.dart
@@ -3,6 +3,7 @@
// BSD-style license that can be found in the LICENSE file.
import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/dart/element/nullability_suffix.dart';
import 'package:analyzer/dart/element/type.dart';
import 'package:analyzer/src/dart/constant/value.dart';
import 'package:analyzer/src/dart/element/type.dart';
@@ -44,6 +45,15 @@
final LibraryElement _coreLibrary;
final LibraryElement _asyncLibrary;
+ ClassElement _futureElement;
+ ClassElement _futureOrElement;
+ ClassElement _iterableElement;
+ ClassElement _listElement;
+ ClassElement _mapElement;
+ ClassElement _setElement;
+ ClassElement _streamElement;
+ ClassElement _symbolElement;
+
InterfaceType _boolType;
InterfaceType _deprecatedType;
InterfaceType _doubleType;
@@ -119,19 +129,39 @@
@override
InterfaceType get futureDynamicType {
- _futureDynamicType ??= futureType.instantiate(<DartType>[dynamicType]);
+ _futureDynamicType ??= InterfaceTypeImpl.explicit(
+ futureElement,
+ [dynamicType],
+ nullabilitySuffix: _nullabilitySuffix,
+ );
return _futureDynamicType;
}
+ ClassElement get futureElement {
+ return _futureElement ??= _getClassElement(_asyncLibrary, 'Future');
+ }
+
@override
InterfaceType get futureNullType {
- _futureNullType ??= futureType.instantiate(<DartType>[nullType]);
+ _futureNullType ??= InterfaceTypeImpl.explicit(
+ futureElement,
+ [nullType],
+ nullabilitySuffix: _nullabilitySuffix,
+ );
return _futureNullType;
}
+ ClassElement get futureOrElement {
+ return _futureOrElement ??= _getClassElement(_asyncLibrary, 'FutureOr');
+ }
+
@override
InterfaceType get futureOrNullType {
- _futureOrNullType ??= futureOrType.instantiate(<DartType>[nullType]);
+ _futureOrNullType ??= InterfaceTypeImpl.explicit(
+ futureOrElement,
+ [nullType],
+ nullabilitySuffix: _nullabilitySuffix,
+ );
return _futureOrNullType;
}
@@ -155,13 +185,26 @@
@override
InterfaceType get iterableDynamicType {
- _iterableDynamicType ??= iterableType.instantiate(<DartType>[dynamicType]);
+ _iterableDynamicType ??= InterfaceTypeImpl.explicit(
+ iterableElement,
+ [dynamicType],
+ nullabilitySuffix: _nullabilitySuffix,
+ );
return _iterableDynamicType;
}
@override
+ ClassElement get iterableElement {
+ return _iterableElement ??= _getClassElement(_coreLibrary, 'Iterable');
+ }
+
+ @override
InterfaceType get iterableObjectType {
- _iterableObjectType ??= iterableType.instantiate(<DartType>[objectType]);
+ _iterableObjectType ??= InterfaceTypeImpl.explicit(
+ iterableElement,
+ [objectType],
+ nullabilitySuffix: _nullabilitySuffix,
+ );
return _iterableObjectType;
}
@@ -172,15 +215,29 @@
}
@override
+ ClassElement get listElement {
+ return _listElement ??= _getClassElement(_coreLibrary, 'List');
+ }
+
+ @override
InterfaceType get listType {
_listType ??= _getType(_coreLibrary, "List");
return _listType;
}
@override
+ ClassElement get mapElement {
+ return _mapElement ??= _getClassElement(_coreLibrary, 'Map');
+ }
+
+ @override
InterfaceType get mapObjectObjectType {
- return _mapObjectObjectType ??=
- mapType.instantiate(<DartType>[objectType, objectType]);
+ _mapObjectObjectType ??= InterfaceTypeImpl.explicit(
+ mapElement,
+ [objectType, objectType],
+ nullabilitySuffix: _nullabilitySuffix,
+ );
+ return _mapObjectObjectType;
}
@override
@@ -219,6 +276,11 @@
}
@override
+ ClassElement get setElement {
+ return _setElement ??= _getClassElement(_coreLibrary, 'Set');
+ }
+
+ @override
InterfaceType get setType {
return _setType ??= _getType(_coreLibrary, "Set");
}
@@ -231,11 +293,20 @@
@override
InterfaceType get streamDynamicType {
- _streamDynamicType ??= streamType.instantiate(<DartType>[dynamicType]);
+ _streamDynamicType ??= InterfaceTypeImpl.explicit(
+ streamElement,
+ [dynamicType],
+ nullabilitySuffix: _nullabilitySuffix,
+ );
return _streamDynamicType;
}
@override
+ ClassElement get streamElement {
+ return _streamElement ??= _getClassElement(_asyncLibrary, 'Stream');
+ }
+
+ @override
InterfaceType get streamType {
_streamType ??= _getType(_asyncLibrary, "Stream");
return _streamType;
@@ -248,6 +319,11 @@
}
@override
+ ClassElement get symbolElement {
+ return _symbolElement ??= _getClassElement(_coreLibrary, 'Symbol');
+ }
+
+ @override
InterfaceType get symbolType {
_symbolType ??= _getType(_coreLibrary, "Symbol");
return _symbolType;
@@ -262,6 +338,62 @@
@override
VoidType get voidType => VoidTypeImpl.instance;
+ @override
+ InterfaceType futureOrType2(DartType valueType) {
+ return futureOrElement.instantiate(
+ typeArguments: [valueType],
+ nullabilitySuffix: _nullabilitySuffix,
+ );
+ }
+
+ @override
+ InterfaceType futureType2(DartType valueType) {
+ return futureElement.instantiate(
+ typeArguments: [valueType],
+ nullabilitySuffix: _nullabilitySuffix,
+ );
+ }
+
+ @override
+ InterfaceType iterableType2(DartType elementType) {
+ return iterableElement.instantiate(
+ typeArguments: [elementType],
+ nullabilitySuffix: _nullabilitySuffix,
+ );
+ }
+
+ @override
+ InterfaceType listType2(DartType elementType) {
+ return listElement.instantiate(
+ typeArguments: [elementType],
+ nullabilitySuffix: _nullabilitySuffix,
+ );
+ }
+
+ @override
+ InterfaceType mapType2(DartType keyType, DartType valueType) {
+ return mapElement.instantiate(
+ typeArguments: [keyType, valueType],
+ nullabilitySuffix: _nullabilitySuffix,
+ );
+ }
+
+ @override
+ InterfaceType setType2(DartType elementType) {
+ return setElement.instantiate(
+ typeArguments: [elementType],
+ nullabilitySuffix: _nullabilitySuffix,
+ );
+ }
+
+ @override
+ InterfaceType streamType2(DartType elementType) {
+ return streamElement.instantiate(
+ typeArguments: [elementType],
+ nullabilitySuffix: _nullabilitySuffix,
+ );
+ }
+
TypeProviderImpl withNullability(NullabilitySuffix nullabilitySuffix) {
if (_nullabilitySuffix == nullabilitySuffix) {
return this;
@@ -270,13 +402,20 @@
nullabilitySuffix: nullabilitySuffix);
}
- /// Return the type with the given [name] from the given [library], or
+ /// Return the class with the given [name] from the given [library], or
/// throw a [StateError] if there is no class with the given name.
- InterfaceType _getType(LibraryElement library, String name) {
+ ClassElement _getClassElement(LibraryElement library, String name) {
var element = library.getType(name);
if (element == null) {
throw StateError('No definition of type $name');
}
+ return element;
+ }
+
+ /// Return the type with the given [name] from the given [library], or
+ /// throw a [StateError] if there is no class with the given name.
+ InterfaceType _getType(LibraryElement library, String name) {
+ var element = _getClassElement(library, name);
var typeArguments = const <DartType>[];
var typeParameters = element.typeParameters;
diff --git a/pkg/analyzer/lib/src/dart/error/hint_codes.dart b/pkg/analyzer/lib/src/dart/error/hint_codes.dart
index 0d8b1c2..4548218 100644
--- a/pkg/analyzer/lib/src/dart/error/hint_codes.dart
+++ b/pkg/analyzer/lib/src/dart/error/hint_codes.dart
@@ -57,6 +57,21 @@
"or removing the unreachable catch clause.");
/**
+ * Users should not create a class named `Function` anymore.
+ */
+ static const HintCode DEPRECATED_FUNCTION_CLASS_DECLARATION = const HintCode(
+ 'DEPRECATED_FUNCTION_CLASS_DECLARATION',
+ "Declaring a class named 'Function' is deprecated.",
+ correction: "Try renaming the class.");
+
+ /**
+ * `Function` should not be extended anymore.
+ */
+ static const HintCode DEPRECATED_EXTENDS_FUNCTION = const HintCode(
+ 'DEPRECATED_EXTENDS_FUNCTION', "Extending 'Function' is deprecated.",
+ correction: "Try removing 'Function' from the 'extends' clause.");
+
+ /**
* Parameters:
* 0: the name of the member
*/
@@ -118,21 +133,6 @@
hasPublishedDocs: true);
/**
- * Users should not create a class named `Function` anymore.
- */
- static const HintCode DEPRECATED_FUNCTION_CLASS_DECLARATION = const HintCode(
- 'DEPRECATED_FUNCTION_CLASS_DECLARATION',
- "Declaring a class named 'Function' is deprecated.",
- correction: "Try renaming the class.");
-
- /**
- * `Function` should not be extended anymore.
- */
- static const HintCode DEPRECATED_EXTENDS_FUNCTION = const HintCode(
- 'DEPRECATED_EXTENDS_FUNCTION', "Extending 'Function' is deprecated.",
- correction: "Try removing 'Function' from the 'extends' clause.");
-
- /**
* `Function` should not be mixed in anymore.
*/
static const HintCode DEPRECATED_MIXIN_FUNCTION = const HintCode(
@@ -220,6 +220,18 @@
correction: "Use explicit type argument(s) for '{0}'.");
/**
+ * When "strict-inference" is enabled, recursive local functions, top-level
+ * functions, methods, and function-typed function parameters must all
+ * specify a return type. See the strict-inference resource:
+ *
+ * https://github.com/dart-lang/language/blob/master/resources/type-system/strict-inference.md
+ */
+ static const HintCode INFERENCE_FAILURE_ON_FUNCTION_RETURN_TYPE = HintCode(
+ 'INFERENCE_FAILURE_ON_FUNCTION_RETURN_TYPE',
+ "The return type of '{0}' cannot be inferred.",
+ correction: "Declare the return type of '{0}'.");
+
+ /**
* When "strict-inference" is enabled, types in instance creation
* (constructor calls) must be inferred via the context type, or have type
* arguments.
@@ -298,6 +310,8 @@
// The following code produces this diagnostic:
//
// ```dart
+ // import 'package:meta/meta.dart';
+ //
// [!@literal!]
// var x;
// ```
@@ -510,7 +524,7 @@
*/
// #### Description
//
- // Any function or method that doesn’t end with either an explicit return or a
+ // Any function or method that doesn't end with either an explicit return or a
// throw implicitly returns `null`. This is rarely the desired behavior. The
// analyzer produces this diagnostic when it finds an implicit return.
//
@@ -683,10 +697,52 @@
"A package import shouldn't contain '..'.");
/**
- * A class defined in `dart:async` that was not exported from `dart:core`
- * before version 2.1 is being referenced via `dart:core` in code that is
- * expected to run on earlier versions.
+ * No parameters.
*/
+ // #### Description
+ //
+ // The analyzer produces this diagnostic when either the class `Future` or
+ // `Stream` is referenced in a library that doesn't import `dart:async` in
+ // code that has an SDK constraint whose lower bound is less than 2.1.0. In
+ // earlier versions, these classes weren't defined in `dart:core`, so the
+ // import was necessary.
+ //
+ // #### Example
+ //
+ // Here's an example of a pubspec that defines an SDK constraint with a lower
+ // bound of less than 2.1.0:
+ //
+ // ```yaml
+ // %uri="pubspec.yaml"
+ // environment:
+ // sdk: '>=2.0.0 <2.4.0'
+ // ```
+ //
+ // In the package that has that pubspec, code like the following produces this
+ // diagnostic:
+ //
+ // ```dart
+ // void f([!Future!] f) {}
+ // ```
+ //
+ // #### Common fixes
+ //
+ // If you don't need to support older versions of the SDK, then you can
+ // increase the SDK constraint to allow the classes to be referenced:
+ //
+ // ```yaml
+ // environment:
+ // sdk: '>=2.1.0 <2.4.0'
+ // ```
+ //
+ // If you need to support older versions of the SDK, then import the
+ // `dart:async` library.
+ //
+ // ```dart
+ // import 'dart:async';
+ //
+ // void f(Future f) {}
+ // ```
static const HintCode SDK_VERSION_ASYNC_EXPORTED_FROM_CORE = const HintCode(
'SDK_VERSION_ASYNC_EXPORTED_FROM_CORE',
"The class '{0}' wasn't exported from 'dart:core' until version 2.1, "
@@ -695,9 +751,54 @@
"Try either importing 'dart:async' or updating the SDK constraints.");
/**
- * An as expression being used in a const context is expected to run on
- * versions of the SDK that did not support them.
+ * No parameters.
*/
+ // #### Description
+ //
+ // The analyzer produces this diagnostic when an as expression inside a
+ // [constant context](#constant-context) is found in code that has an SDK
+ // constraint whose lower bound is less than 2.3.2. Using an as expression in
+ // a [constant context](#constant-context) wasn't supported in earlier
+ // versions, so this code won't be able to run against earlier versions of the
+ // SDK.
+ //
+ // #### Example
+ //
+ // Here's an example of a pubspec that defines an SDK constraint with a lower
+ // bound of less than 2.3.2:
+ //
+ // ```yaml
+ // %uri="pubspec.yaml"
+ // environment:
+ // sdk: '>=2.1.0 <2.4.0'
+ // ```
+ //
+ // In the package that has that pubspec, code like the following generates
+ // this diagnostic:
+ //
+ // ```dart
+ // const num n = 3;
+ // const int i = [!n as int!];
+ // ```
+ //
+ // #### Common fixes
+ //
+ // If you don't need to support older versions of the SDK, then you can
+ // ncrease the SDK constraint to allow the expression to be used:
+ //
+ // ```yaml
+ // environment:
+ // sdk: '>=2.3.2 <2.4.0'
+ // ```
+ //
+ // If you need to support older versions of the SDK, then either rewrite the
+ // code to not use an as expression, or change the code so that the as
+ // expression is not in a [constant context](#constant-context).:
+ //
+ // ```dart
+ // num x = 3;
+ // int y = x as int;
+ // ```
static const HintCode SDK_VERSION_AS_EXPRESSION_IN_CONST_CONTEXT = const HintCode(
'SDK_VERSION_AS_EXPRESSION_IN_CONST_CONTEXT',
"The use of an as expression in a constant expression wasn't "
@@ -706,20 +807,116 @@
correction: "Try updating the SDK constraints.");
/**
- * The operator '&', '|' or '^' is being used on boolean values in code that
- * is expected to run on versions of the SDK that did not support it.
+ * No parameters.
*/
+ // #### Description
+ //
+ // The analyzer produces this diagnostic when any use of the `&`, `|` or `^`
+ // operators on the class `bool` inside a
+ // [constant context](#constant-context) is found in code that has an SDK
+ // constraint whose lower bound is less than 2.3.2. Using these operators in a
+ // [constant context](#constant-context) wasn't supported in earlier versions,
+ // so this code won't be able to run against earlier versions of the SDK.
+ //
+ // #### Example
+ //
+ // Here's an example of a pubspec that defines an SDK constraint with a lower
+ // bound of less than 2.3.2:
+ //
+ // ```yaml
+ // %uri="pubspec.yaml"
+ // environment:
+ // sdk: '>=2.1.0 <2.4.0'
+ // ```
+ //
+ // In the package that has that pubspec, code like the following produces this
+ // diagnostic:
+ //
+ // ```dart
+ // const bool a = true;
+ // const bool b = false;
+ // const bool c = a [!&!] b;
+ // ```
+ //
+ // #### Common fixes
+ //
+ // If you don't need to support older versions of the SDK, then you can
+ // increase the SDK constraint to allow the operators to be used:
+ //
+ // ```yaml
+ // environment:
+ // sdk: '>=2.3.2 <2.4.0'
+ // ```
+ //
+ // If you need to support older versions of the SDK, then either rewrite the
+ // code to not use these operators, or change the code so that the expression
+ // is not in a [constant context](#constant-context).:
+ //
+ // ```dart
+ // const bool a = true;
+ // const bool b = false;
+ // bool c = a & b;
+ // ```
static const HintCode SDK_VERSION_BOOL_OPERATOR_IN_CONST_CONTEXT = const HintCode(
'SDK_VERSION_BOOL_OPERATOR_IN_CONST_CONTEXT',
- "Using the operator '{0}' for 'bool's in a constant expression wasn't "
- "supported until version 2.3.2, but this code is required to be able "
- "to run on earlier versions.",
+ "The use of the operator '{0}' for 'bool' operands in a constant context "
+ "wasn't supported until version 2.3.2, but this code is required to "
+ "be able to run on earlier versions.",
correction: "Try updating the SDK constraints.");
/**
- * The operator '==' is being used on non-primitive values in code that
- * is expected to run on versions of the SDK that did not support it.
+ * No parameters.
*/
+ // #### Description
+ //
+ // The analyzer produces this diagnostic when the operator `==` is used on a
+ // non-primitive type inside a [constant context](#constant-context) is found
+ // in code that has an SDK constraint whose lower bound is less than 2.3.2.
+ // Using this operator in a [constant context](#constant-context) wasn't
+ // supported in earlier versions, so this code won't be able to run against
+ // earlier versions of the SDK.
+ //
+ // #### Example
+ //
+ // Here's an example of a pubspec that defines an SDK constraint with a lower
+ // bound of less than 2.3.2:
+ //
+ // ```yaml
+ // %uri="pubspec.yaml"
+ // environment:
+ // sdk: '>=2.1.0 <2.4.0'
+ // ```
+ //
+ // In the package that has that pubspec, code like the following produces this
+ // diagnostic:
+ //
+ // ```dart
+ // class C {}
+ // const C a = null;
+ // const C b = null;
+ // const bool same = a [!==!] b;
+ // ```
+ //
+ // #### Common fixes
+ //
+ // If you don't need to support older versions of the SDK, then you can
+ // increase the SDK constraint to allow the operator to be used:
+ //
+ // ```yaml
+ // environment:
+ // sdk: '>=2.3.2 <2.4.0'
+ // ```
+ //
+ // If you need to support older versions of the SDK, then either rewrite the
+ // code to not use the `==` operator, or change the code so that the
+ // expression is not in a [constant context](#constant-context).:
+ //
+ // ```dart
+ // class C {}
+ // const C a = null;
+ // const C b = null;
+ // bool same = a == b;
+ // ```
static const HintCode SDK_VERSION_EQ_EQ_OPERATOR_IN_CONST_CONTEXT =
const HintCode(
'SDK_VERSION_EQ_EQ_OPERATOR_IN_CONST_CONTEXT',
@@ -729,9 +926,58 @@
correction: "Try updating the SDK constraints.");
/**
- * Extension method features are being used in code that is expected to run
- * on versions of the SDK that did not support them.
+ * No parameters.
*/
+ // #### Description
+ //
+ // The analyzer produces this diagnostic when an extension declaration or an
+ // extension override is found in code that has an SDK constraint whose lower
+ // bound is less than 2.6.0. Using extensions wasn't supported in earlier
+ // versions, so this code won't be able to run against earlier versions of the
+ // SDK.
+ //
+ // #### Example
+ //
+ // Here's an example of a pubspec that defines an SDK constraint with a lower
+ // bound of less than 2.6.0:
+ //
+ // ```yaml
+ // %uri="pubspec.yaml"
+ // environment:
+ // sdk: '>=2.4.0 <2.7.0'
+ // ```
+ //
+ // In the package that has that pubspec, code like the following generates
+ // this diagnostic:
+ //
+ // ```dart
+ // [!extension!] E on String {
+ // void sayHello() {
+ // print('Hello $this');
+ // }
+ // }
+ // ```
+ //
+ // #### Common fixes
+ //
+ // If you don't need to support older versions of the SDK, then you can
+ // increase the SDK constraint to allow the syntax to be used:
+ //
+ // ```yaml
+ // environment:
+ // sdk: '>=2.6.0 <2.7.0'
+ // ```
+ //
+ // If you need to support older versions of the SDK, then rewrite the code to
+ // not make use of extensions. The most common way to do this is to rewrite
+ // the members of the extension as top-level functions (or methods) that take
+ // the value that would have been bound to `this` as a parameter:
+ //
+ // ```dart
+ // void sayHello(String s) {
+ // print('Hello $s');
+ // }
+ // ```
static const HintCode SDK_VERSION_EXTENSION_METHODS = const HintCode(
'SDK_VERSION_EXTENSION_METHODS',
"Extension methods weren't supported until version 2.6.0, "
@@ -739,9 +985,57 @@
correction: "Try updating the SDK constraints.");
/**
- * The operator '>>>' is being used in code that is expected to run on
- * versions of the SDK that did not support it.
+ * No parameters.
*/
+ /* // #### Description
+ //
+ // The analyzer produces this diagnostic when the operator `>>>` is used in
+ // code that has an SDK constraint whose lower bound is less than 2.X.0. This
+ // operator wasn't supported in earlier versions, so this code won't be able
+ // to run against earlier versions of the SDK.
+ //
+ // #### Example
+ //
+ // Here's an example of a pubspec that defines an SDK constraint with a lower
+ // bound of less than 2.X.0:
+ //
+ // ```yaml
+ // %uri="pubspec.yaml"
+ // environment:
+ // sdk: '>=2.0.0 <2.4.0'
+ // ```
+ //
+ // In the package that has that pubspec, code like the following produces this
+ // diagnostic:
+ //
+ // ```dart
+ // int x = 3 [!>>>!] 4;
+ // ```
+ //
+ // #### Common fixes
+ //
+ // If you don't need to support older versions of the SDK, then you can
+ // increase the SDK constraint to allow the operator to be used:
+ //
+ // ```yaml
+ // environment:
+ // sdk: '>=2.3.2 <2.4.0'
+ // ```
+ //
+ // If you need to support older versions of the SDK, then rewrite the code to
+ // not use the `>>>` operator:
+ //
+ // ```dart
+ // int x = logicalShiftRight(3, 4);
+ //
+ // int logicalShiftRight(int leftOperand, int rightOperand) {
+ // int divisor = 1 << rightOperand;
+ // if (divisor == 0) {
+ // return 0;
+ // }
+ // return leftOperand ~/ divisor;
+ // }
+ // ``` */
static const HintCode SDK_VERSION_GT_GT_GT_OPERATOR = const HintCode(
'SDK_VERSION_GT_GT_GT_OPERATOR',
"The operator '>>>' wasn't supported until version 2.3.2, but this code "
@@ -749,12 +1043,58 @@
correction: "Try updating the SDK constraints.");
/**
- * An is expression being used in a const context is expected to run on
- * versions of the SDK that did not support them.
+ * No parameters.
*/
+ // #### Description
+ //
+ // The analyzer produces this diagnostic when an is expression inside a
+ // [constant context](#constant-context) is found in code that has an SDK
+ // constraint whose lower bound is less than 2.3.2. Using an is expression in
+ // a [constant context](#constant-context) wasn't supported in earlier
+ // versions, so this code won't be able to run against earlier versions of the
+ // SDK.
+ //
+ // #### Example
+ //
+ // Here's an example of a pubspec that defines an SDK constraint with a lower
+ // bound of less than 2.3.2:
+ //
+ // ```yaml
+ // %uri="pubspec.yaml"
+ // environment:
+ // sdk: '>=2.1.0 <2.4.0'
+ // ```
+ //
+ // In the package that has that pubspec, code like the following generates
+ // this diagnostic:
+ //
+ // ```dart
+ // const x = 4;
+ // const y = [!x is int!] ? 0 : 1;
+ // ```
+ //
+ // #### Common fixes
+ //
+ // If you don't need to support older versions of the SDK, then you can
+ // increase the SDK constraint to allow the expression to be used:
+ //
+ // ```yaml
+ // environment:
+ // sdk: '>=2.3.2 <2.4.0'
+ // ```
+ //
+ // If you need to support older versions of the SDK, then either rewrite the
+ // code to not use the is operator, or, if that's not possible, change the
+ // code so that the is expression is not in a
+ // [constant context](#constant-context).:
+ //
+ // ```dart
+ // const x = 4;
+ // var y = x is int ? 0 : 1;
+ // ```
static const HintCode SDK_VERSION_IS_EXPRESSION_IN_CONST_CONTEXT = const HintCode(
'SDK_VERSION_IS_EXPRESSION_IN_CONST_CONTEXT',
- "The use of an is expression in a constant expression wasn't supported "
+ "The use of an is expression in a constant context wasn't supported "
"until version 2.3.2, but this code is required to be able to run on "
"earlier versions.",
correction: "Try updating the SDK constraints.");
@@ -765,21 +1105,23 @@
// #### Description
//
// The analyzer produces this diagnostic when a set literal is found in code
- // that has an SDK constraint whose lower bound is less than 2.2. Set literals
- // weren't supported in earlier versions, so this code won't be able to run
- // against earlier versions of the SDK.
+ // that has an SDK constraint whose lower bound is less than 2.2.0. Set
+ // literals weren't supported in earlier versions, so this code won't be able
+ // to run against earlier versions of the SDK.
//
// #### Example
//
- // In a package that defines the SDK constraint (in the pubspec.yaml file),
- // with a lower bound of less than 2.2. For example:
+ // Here's an example of a pubspec that defines an SDK constraint with a lower
+ // bound of less than 2.2.0:
//
// ```yaml
+ // %uri="pubspec.yaml"
// environment:
// sdk: '>=2.1.0 <2.4.0'
// ```
//
- // The following code generates this diagnostic:
+ // In the package that has that pubspec, code like the following produces this
+ // diagnostic:
//
// ```dart
// var s = [!<int>{}!];
@@ -809,16 +1151,110 @@
hasPublishedDocs: true);
/**
- * The type Never is being used in code that is expected to run on versions of
- * the SDK that did not support it.
+ * No parameters.
*/
+ /* // #### Description
+ //
+ // The analyzer produces this diagnostic when a reference to the class `Never`
+ // is found in code that has an SDK constraint whose lower bound is less than
+ // 2.X.0. This class wasn't defined in earlier versions, so this code won't be
+ // able to run against earlier versions of the SDK.
+ //
+ // #### Example
+ //
+ // Here's an example of a pubspec that defines an SDK constraint with a lower
+ // bound of less than 2.X.0:
+ //
+ // ```yaml
+ // %uri="pubspec.yaml"
+ // environment:
+ // sdk: '>=2.5.0 <2.6.0'
+ // ```
+ //
+ // In the package that has that pubspec, code like the following produces this
+ // diagnostic:
+ //
+ // ```dart
+ // [!Never!] n;
+ // ```
+ //
+ // #### Common fixes
+ //
+ // If you don't need to support older versions of the SDK, then you can
+ // increase the SDK constraint to allow the type to be used:
+ //
+ // ```yaml
+ // environment:
+ // sdk: '>=2.X.0 <2.7.0'
+ // ```
+ //
+ // If you need to support older versions of the SDK, then rewrite the code to
+ // not reference this class:
+ //
+ // ```dart
+ // dynamic x;
+ // ``` */
static const HintCode SDK_VERSION_NEVER = const HintCode(
- 'SDK_VERSION_NEVER', "The type Never is not yet supported.");
+ // TODO(brianwilkerson) Replace the message with the following when we know
+ // when this feature will ship:
+ // The type 'Never' wasn't supported until version 2.X.0, but this code
+ // is required to be able to run on earlier versions.
+ 'SDK_VERSION_NEVER',
+ "The type Never is not yet supported.");
/**
- * The for, if or spread element is being used in code that is expected to run
- * on versions of the SDK that did not support them.
+ * No parameters.
*/
+ // #### Description
+ //
+ // The analyzer produces this diagnostic when a for, if, or spread element is
+ // found in code that has an SDK constraint whose lower bound is less than
+ // 2.3.0. Using a for, if, or spread element wasn't supported in earlier
+ // versions, so this code won't be able to run against earlier versions of the
+ // SDK.
+ //
+ // #### Example
+ //
+ // Here's an example of a pubspec that defines an SDK constraint with a lower
+ // bound of less than 2.3.0:
+ //
+ // ```yaml
+ // %uri="pubspec.yaml"
+ // environment:
+ // sdk: '>=2.2.0 <2.4.0'
+ // ```
+ //
+ // In the package that has that pubspec, code like the following generates
+ // this diagnostic:
+ //
+ // ```dart
+ // var digits = [[!for (int i = 0; i < 10; i++) i!]];
+ // ```
+ //
+ // #### Common fixes
+ //
+ // If you don't need to support older versions of the SDK, then you can
+ // increase the SDK constraint to allow the syntax to be used:
+ //
+ // ```yaml
+ // environment:
+ // sdk: '>=2.3.0 <2.4.0'
+ // ```
+ //
+ // If you need to support older versions of the SDK, then rewrite the code to
+ // not make use of those elements:
+ //
+ // ```dart
+ // var digits = _initializeDigits();
+ //
+ // List<int> _initializeDigits() {
+ // var digits = <int>[];
+ // for (int i = 0; i < 10; i++) {
+ // digits.add(i);
+ // }
+ // return digits;
+ // }
+ // ```
static const HintCode SDK_VERSION_UI_AS_CODE = const HintCode(
'SDK_VERSION_UI_AS_CODE',
"The for, if, and spread elements weren't supported until version 2.2.2, "
@@ -826,14 +1262,66 @@
correction: "Try updating the SDK constraints.");
/**
- * The for, if or spread element is being used in a const context that is
- * expected to run on versions of the SDK that did not support them.
+ * No parameters.
*/
+ // #### Description
+ //
+ // The analyzer produces this diagnostic when an if or spread element inside
+ // a [constant context](#constant-context) is found in code that has an
+ // SDK constraint whose lower bound is less than 2.5.0. Using an if or
+ // spread element inside a [constant context](#constant-context) wasn't
+ // supported in earlier versions, so this code won't be able to run against
+ // earlier versions of the SDK.
+ //
+ // #### Example
+ //
+ // Here's an example of a pubspec that defines an SDK constraint with a lower
+ // bound of less than 2.5.0:
+ //
+ // ```yaml
+ // %uri="pubspec.yaml"
+ // environment:
+ // sdk: '>=2.4.0 <2.6.0'
+ // ```
+ //
+ // In the package that has that pubspec, code like the following generates
+ // this diagnostic:
+ //
+ // ```dart
+ // const a = [1, 2];
+ // const b = [[!...a!]];
+ // ```
+ //
+ // #### Common fixes
+ //
+ // If you don't need to support older versions of the SDK, then you can
+ // increase the SDK constraint to allow the syntax to be used:
+ //
+ // ```yaml
+ // environment:
+ // sdk: '>=2.5.0 <2.6.0'
+ // ```
+ //
+ // If you need to support older versions of the SDK, then rewrite the code to
+ // not make use of those elements:
+ //
+ // ```dart
+ // const a = [1, 2];
+ // const b = [1, 2];
+ // ```
+ //
+ // If that's not possible, change the code so that the element is not in a
+ // [constant context](#constant-context).:
+ //
+ // ```dart
+ // const a = [1, 2];
+ // var b = [...a];
+ // ```
static const HintCode SDK_VERSION_UI_AS_CODE_IN_CONST_CONTEXT = const HintCode(
'SDK_VERSION_UI_AS_CODE_IN_CONST_CONTEXT',
- "The for, if and spread elements weren't supported in constant "
- "expressions until version 2.5.0, but this code is required to be "
- "able to run on earlier versions.",
+ "The if and spread elements weren't supported in constant expressions "
+ "until version 2.5.0, but this code is required to be able to run on "
+ "earlier versions.",
correction: "Try updating the SDK constraints.");
/**
@@ -845,24 +1333,6 @@
correction: "Use explicit type arguments for '{0}'.");
/**
- * When "strict-raw-types" is enabled, raw types must be inferred via the
- * context type, or have type arguments.
- */
- static const HintCode STRICT_RAW_TYPE_IN_AS = HintCode(
- 'STRICT_RAW_TYPE_IN_AS',
- "The generic type '{0}' should have explicit type arguments but doesn't.",
- correction: "Use explicit type arguments for '{0}'.");
-
- /**
- * When "strict-raw-types" is enabled, raw types must be inferred via the
- * context type, or have type arguments.
- */
- static const HintCode STRICT_RAW_TYPE_IN_IS = HintCode(
- 'STRICT_RAW_TYPE_IN_IS',
- "The generic type '{0}' should have explicit type arguments but doesn't.",
- correction: "Use explicit type arguments for '{0}'.");
-
- /**
* This hint is generated anywhere where a `@sealed` class or mixin is used as
* a super-type of a class.
*/
diff --git a/pkg/analyzer/lib/src/dart/error/syntactic_errors.dart b/pkg/analyzer/lib/src/dart/error/syntactic_errors.dart
index 5ad92c2..dbcc657 100644
--- a/pkg/analyzer/lib/src/dart/error/syntactic_errors.dart
+++ b/pkg/analyzer/lib/src/dart/error/syntactic_errors.dart
@@ -207,12 +207,79 @@
static const ParserErrorCode EXPORT_DIRECTIVE_AFTER_PART_DIRECTIVE =
_EXPORT_DIRECTIVE_AFTER_PART_DIRECTIVE;
+ /**
+ * No parameters.
+ */
+ // #### Description
+ //
+ // The analyzer produces this diagnostic when an abstract declaration is
+ // declared in an extension. Extensions can declare only concrete members.
+ //
+ // #### Example
+ //
+ // The following code produces this diagnostic:
+ //
+ // ```dart
+ // extension E on String {
+ // int [!a!]();
+ // }
+ // ```
+ //
+ // #### Common fixes
+ //
+ // Either provide an implementation for the member or remove it.
static const ParserErrorCode EXTENSION_DECLARES_ABSTRACT_MEMBER =
_EXTENSION_DECLARES_ABSTRACT_MEMBER;
+ /**
+ * No parameters.
+ */
+ // #### Description
+ //
+ // The analyzer produces this diagnostic when a constructor declaration is
+ // found in an extension. It isn't valid to define a constructor because
+ // extensions aren't classes, and it isn't possible to create an instance of
+ // an extension.
+ //
+ // #### Example
+ //
+ // The following code produces this diagnostic:
+ //
+ // ```dart
+ // extension E on String {
+ // [!E!]() : super();
+ // }
+ // ```
+ //
+ // #### Common fixes
+ //
+ // Remove the constructor or replace it with a static method.
static const ParserErrorCode EXTENSION_DECLARES_CONSTRUCTOR =
_EXTENSION_DECLARES_CONSTRUCTOR;
+ /**
+ * No parameters.
+ */
+ // #### Description
+ //
+ // The analyzer produces this diagnostic when an instance field declaration is
+ // found in an extension. It isn't valid to define an instance field because
+ // extensions can only add behavior, not state.
+ //
+ // #### Example
+ //
+ // The following code produces this diagnostic:
+ //
+ // ```dart
+ // extension E on String {
+ // String [!s!];
+ // }
+ // ```
+ //
+ // #### Common fixes
+ //
+ // Remove the field, make it a static field, or convert it to be a getter,
+ // setter, or method.
static const ParserErrorCode EXTENSION_DECLARES_INSTANCE_FIELD =
_EXTENSION_DECLARES_INSTANCE_FIELD;
@@ -652,6 +719,9 @@
correction:
"Try moving all of the normal parameters before the optional parameters.");
+ static const ErrorCode NULL_AWARE_CASCADE_OUT_OF_ORDER =
+ _NULL_AWARE_CASCADE_OUT_OF_ORDER;
+
static const ParserErrorCode POSITIONAL_AFTER_NAMED_ARGUMENT =
const ParserErrorCode('POSITIONAL_AFTER_NAMED_ARGUMENT',
"Positional arguments must occur before named arguments.",
diff --git a/pkg/analyzer/lib/src/dart/error/syntactic_errors.g.dart b/pkg/analyzer/lib/src/dart/error/syntactic_errors.g.dart
index abde3d8..9653453 100644
--- a/pkg/analyzer/lib/src/dart/error/syntactic_errors.g.dart
+++ b/pkg/analyzer/lib/src/dart/error/syntactic_errors.g.dart
@@ -103,6 +103,7 @@
_EXTENSION_DECLARES_INSTANCE_FIELD,
_EXTENSION_DECLARES_ABSTRACT_MEMBER,
_MIXIN_DECLARES_CONSTRUCTOR,
+ _NULL_AWARE_CASCADE_OUT_OF_ORDER,
];
const ParserErrorCode _ABSTRACT_CLASS_MEMBER = const ParserErrorCode(
@@ -481,6 +482,12 @@
correction:
"Try removing this native clause and adding @native() or @native('native-name') before the declaration.");
+const ParserErrorCode _NULL_AWARE_CASCADE_OUT_OF_ORDER = const ParserErrorCode(
+ 'NULL_AWARE_CASCADE_OUT_OF_ORDER',
+ r"The '?..' cascade operator must be first in the cascade sequence.",
+ correction:
+ "Try moving the '?..' operator to be the first cascade operator in the sequence.");
+
const ParserErrorCode _PREFIX_AFTER_COMBINATOR = const ParserErrorCode(
'PREFIX_AFTER_COMBINATOR',
r"The prefix ('as' clause) should come before any show/hide combinators.",
diff --git a/pkg/analyzer/lib/src/dart/resolver/ast_rewrite.dart b/pkg/analyzer/lib/src/dart/resolver/ast_rewrite.dart
index 58353ea5..cf5639a 100644
--- a/pkg/analyzer/lib/src/dart/resolver/ast_rewrite.dart
+++ b/pkg/analyzer/lib/src/dart/resolver/ast_rewrite.dart
@@ -71,7 +71,7 @@
}
} else if (target is SimpleIdentifier) {
// Possible cases: C.n(), p.C() or p.C<>()
- if (node.operator.type == TokenType.QUESTION_PERIOD) {
+ if (node.isNullAware) {
// This isn't a constructor invocation because a null aware operator is
// being used.
}
diff --git a/pkg/analyzer/lib/src/dart/resolver/exit_detector.dart b/pkg/analyzer/lib/src/dart/resolver/exit_detector.dart
index 0b10058..5e43500 100644
--- a/pkg/analyzer/lib/src/dart/resolver/exit_detector.dart
+++ b/pkg/analyzer/lib/src/dart/resolver/exit_detector.dart
@@ -48,8 +48,7 @@
operatorType == TokenType.QUESTION_QUESTION_EQ) {
return false;
}
- if (leftHandSide is PropertyAccess &&
- leftHandSide.operator.type == TokenType.QUESTION_PERIOD) {
+ if (leftHandSide is PropertyAccess && leftHandSide.isNullAware) {
return false;
}
return _nodeExits(node.rightHandSide);
@@ -419,7 +418,7 @@
if (target.accept(this)) {
return true;
}
- if (node.operator.type == TokenType.QUESTION_PERIOD) {
+ if (node.isNullAware) {
return false;
}
}
diff --git a/pkg/analyzer/lib/src/dart/resolver/extension_member_resolver.dart b/pkg/analyzer/lib/src/dart/resolver/extension_member_resolver.dart
index 931287a..2e6c7f7 100644
--- a/pkg/analyzer/lib/src/dart/resolver/extension_member_resolver.dart
+++ b/pkg/analyzer/lib/src/dart/resolver/extension_member_resolver.dart
@@ -418,6 +418,7 @@
static bool _isValidContext(ExtensionOverride node) {
AstNode parent = node.parent;
return parent is BinaryExpression && parent.leftOperand == node ||
+ parent is CascadeExpression && parent.target == node ||
parent is FunctionExpressionInvocation && parent.function == node ||
parent is IndexExpression && parent.target == node ||
parent is MethodInvocation && parent.target == node ||
diff --git a/pkg/analyzer/lib/src/dart/resolver/flow_analysis_visitor.dart b/pkg/analyzer/lib/src/dart/resolver/flow_analysis_visitor.dart
index 8fc4935..a7a4a3e 100644
--- a/pkg/analyzer/lib/src/dart/resolver/flow_analysis_visitor.dart
+++ b/pkg/analyzer/lib/src/dart/resolver/flow_analysis_visitor.dart
@@ -244,9 +244,9 @@
return false;
}
- void loopVariable(DeclaredIdentifier loopVariable) {
- if (loopVariable != null) {
- flow.add(loopVariable.declaredElement, assigned: true);
+ void loopVariable(DeclaredIdentifier declaredVariable) {
+ if (declaredVariable != null) {
+ flow.add(declaredVariable.declaredElement, assigned: false);
}
}
@@ -427,6 +427,16 @@
iterable.accept(this);
assignedVariables.beginNode();
+ if (forLoopParts is ForEachPartsWithIdentifier) {
+ var element = forLoopParts.identifier.staticElement;
+ if (element is VariableElement) {
+ assignedVariables.write(element);
+ }
+ } else if (forLoopParts is ForEachPartsWithDeclaration) {
+ assignedVariables.write(forLoopParts.loopVariable.declaredElement);
+ } else {
+ throw new StateError('Unrecognized for loop parts');
+ }
body.accept(this);
assignedVariables.endNode(node);
} else {
diff --git a/pkg/analyzer/lib/src/dart/resolver/inheritance_manager.dart b/pkg/analyzer/lib/src/dart/resolver/inheritance_manager.dart
index 266d3cd..16e1ba9 100644
--- a/pkg/analyzer/lib/src/dart/resolver/inheritance_manager.dart
+++ b/pkg/analyzer/lib/src/dart/resolver/inheritance_manager.dart
@@ -275,7 +275,7 @@
ExecutableElement value = map[memberName];
ClassElement definingClass = value
.getAncestor((Element element) => element is ClassElement);
- if (!definingClass.type.isObject) {
+ if (!definingClass.isDartCoreObject) {
ExecutableElement existingValue = resultMap[memberName];
if (existingValue == null ||
(existingValue != null && !_isAbstract(value))) {
diff --git a/pkg/analyzer/lib/src/dart/resolver/legacy_type_asserter.dart b/pkg/analyzer/lib/src/dart/resolver/legacy_type_asserter.dart
index cd09795..f7286de 100644
--- a/pkg/analyzer/lib/src/dart/resolver/legacy_type_asserter.dart
+++ b/pkg/analyzer/lib/src/dart/resolver/legacy_type_asserter.dart
@@ -8,6 +8,7 @@
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/ast/visitor.dart';
import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/dart/element/nullability_suffix.dart';
import 'package:analyzer/dart/element/type.dart';
import 'package:analyzer/src/dart/element/type.dart';
@@ -49,12 +50,6 @@
}
@override
- visitClassDeclaration(ClassDeclaration node) {
- _assertLegacyType(node.declaredElement?.type);
- super.visitClassDeclaration(node);
- }
-
- @override
visitClassMember(ClassMember node) {
final element = node.declaredElement;
if (element is ExecutableElement) {
@@ -77,12 +72,6 @@
}
@override
- visitEnumDeclaration(EnumDeclaration node) {
- _assertLegacyType(node.declaredElement?.type);
- super.visitEnumDeclaration(node);
- }
-
- @override
visitExpression(Expression e) {
_assertLegacyType(e.staticType);
super.visitExpression(e);
@@ -146,12 +135,16 @@
_assertLegacyType(type.bound);
} else if (type is InterfaceType) {
type.typeArguments.forEach(_assertLegacyType);
- type.typeParameters.map((param) => param.type).forEach(_assertLegacyType);
+ type.typeParameters
+ .map((param) => param.bound)
+ .forEach(_assertLegacyType);
} else if (type is FunctionType) {
_assertLegacyType(type.returnType);
type.parameters.map((param) => param.type).forEach(_assertLegacyType);
type.typeArguments.forEach(_assertLegacyType);
- type.typeParameters.map((param) => param.type).forEach(_assertLegacyType);
+ type.typeParameters
+ .map((param) => param.bound)
+ .forEach(_assertLegacyType);
}
if ((type as TypeImpl).nullabilitySuffix == NullabilitySuffix.star) {
diff --git a/pkg/analyzer/lib/src/dart/resolver/method_invocation_resolver.dart b/pkg/analyzer/lib/src/dart/resolver/method_invocation_resolver.dart
index 39a27a4..9244efd 100644
--- a/pkg/analyzer/lib/src/dart/resolver/method_invocation_resolver.dart
+++ b/pkg/analyzer/lib/src/dart/resolver/method_invocation_resolver.dart
@@ -3,7 +3,6 @@
// BSD-style license that can be found in the LICENSE file.
import 'package:analyzer/dart/ast/ast.dart';
-import 'package:analyzer/dart/ast/token.dart';
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/dart/element/type.dart';
import 'package:analyzer/src/dart/ast/ast.dart';
@@ -411,8 +410,9 @@
}
if (node.isCascaded) {
- // TODO(brianwilkerson) Report this error and decide how to recover.
- throw new UnsupportedError('cascaded extension override');
+ // Report this error and recover by treating it like a non-cascade.
+ _resolver.errorReporter.reportErrorForToken(
+ CompileTimeErrorCode.EXTENSION_OVERRIDE_WITH_CASCADE, node.operator);
}
nameNode.staticElement = member;
@@ -552,7 +552,7 @@
}
enclosingClass = receiverType.element;
} else {
- receiverType = enclosingClass.type;
+ receiverType = enclosingClass.thisType;
}
var target = _inheritance.getMember(receiverType, _currentName);
@@ -566,11 +566,19 @@
if (targetElement != null && targetElement.isStatic) {
nameNode.staticElement = targetElement;
_setDynamicResolution(node);
- _resolver.errorReporter.reportErrorForNode(
- StaticTypeWarningCode.UNQUALIFIED_REFERENCE_TO_NON_LOCAL_STATIC_MEMBER,
- nameNode,
- [receiverType.displayName],
- );
+ if (_resolver.enclosingExtension != null) {
+ _resolver.errorReporter.reportErrorForNode(
+ CompileTimeErrorCode
+ .UNQUALIFIED_REFERENCE_TO_STATIC_MEMBER_OF_EXTENDED_TYPE,
+ nameNode,
+ [targetElement.enclosingElement.displayName]);
+ } else {
+ _resolver.errorReporter.reportErrorForNode(
+ StaticTypeWarningCode
+ .UNQUALIFIED_REFERENCE_TO_NON_LOCAL_STATIC_MEMBER,
+ nameNode,
+ [targetElement.enclosingElement.displayName]);
+ }
return;
}
@@ -590,9 +598,7 @@
void _resolveReceiverPrefix(MethodInvocation node, SimpleIdentifier receiver,
PrefixElement prefix, SimpleIdentifier nameNode, String name) {
- if (node.operator.type == TokenType.QUESTION_PERIOD) {
- _reportPrefixIdentifierNotFollowedByDot(receiver);
- }
+ // Note: prefix?.bar is reported as an error in ElementResolver.
if (name == FunctionElement.LOAD_LIBRARY_NAME) {
var imports = _definingLibrary.getImportsWithPrefix(prefix);
@@ -633,7 +639,7 @@
return;
}
- var receiverType = enclosingClass.type;
+ var receiverType = enclosingClass.thisType;
var target = _inheritance.getMember(
receiverType,
_currentName,
diff --git a/pkg/analyzer/lib/src/error/codes.dart b/pkg/analyzer/lib/src/error/codes.dart
index 49aa71d..11e27cf 100644
--- a/pkg/analyzer/lib/src/error/codes.dart
+++ b/pkg/analyzer/lib/src/error/codes.dart
@@ -146,14 +146,70 @@
"explicitly hiding the name in one of the export directives.");
/**
- * It is a compile time error if there are two applicable extensions defining
- * the same member and neither is more specific than the other.
- *
* Parameters:
* 0: the name of the member
* 1: the name of the first declaring extension
* 2: the name of the second declaring extension
*/
+ // #### Description
+ //
+ // When code refers to a member of an object (for example, `o.m()` or `o.m` or
+ // `o[i]`) where the static type of `o` doesn't declare the member (`m` or
+ // `[]`, for example), then the analyzer tries to find the member in an
+ // extension. For example, if the member is `m`, then the analyzer looks for
+ // extensions that declare a member named `m` and have an extended type that
+ // the static type of `o` can be assigned to. When there's more than one such
+ // extension in scope, the extension whose extended type is most specific is
+ // selected.
+ //
+ // The analyzer produces this diagnostic when none of the extensions has an
+ // extended type that's more specific than the extended types of all of the
+ // other extensions, making the reference to the member ambiguous.
+ //
+ // #### Example
+ //
+ // The following code produces this diagnostic because there's no way to
+ // choose between the member in `E1` and the member in `E2`:
+ //
+ // ```dart
+ // extension E1 on String {
+ // int get charCount => 1;
+ // }
+ //
+ // extension E2 on String {
+ // int get charCount => 2;
+ // }
+ //
+ // void f(String s) {
+ // print(s.[!charCount!]);
+ // }
+ // ```
+ //
+ // #### Common fixes
+ //
+ // If you don't need both extensions, then you can delete or hide one of them.
+ //
+ // If you need both, then explicitly select the one you want to use by using
+ // an extension override:
+ //
+ // ```dart
+ // extension E1 on String {
+ // int get charCount => length;
+ // }
+ //
+ // extension E2 on String {
+ // int get charCount => length;
+ // }
+ //
+ // void f(String s) {
+ // print(E2(s).charCount);
+ // }
+ // ```
+ /*
+ * TODO(brianwilkerson) This message doesn't handle the possible case where
+ * there are more than 2 extensions, nor does it handle well the case where
+ * one or more of the extensions is unnamed.
+ */
static const CompileTimeErrorCode AMBIGUOUS_EXTENSION_MEMBER_ACCESS =
const CompileTimeErrorCode(
'AMBIGUOUS_EXTENSION_MEMBER_ACCESS',
@@ -282,7 +338,7 @@
//
// ```dart
// union(a, b) {
- // var x = {...a, ...b};
+ // var x = [!{...a, ...b}!];
// return x;
// }
// ```
@@ -661,6 +717,86 @@
"changing the import to not be deferred.");
/**
+ * 16.12.2 Const: An expression of one of the forms !e, e1 && e2 or e1 || e2,
+ * where e, e1 and e2 are constant expressions that evaluate to a boolean
+ * value.
+ */
+ static const CompileTimeErrorCode CONST_EVAL_TYPE_BOOL =
+ const CompileTimeErrorCode(
+ 'CONST_EVAL_TYPE_BOOL',
+ "In constant expressions, operands of this operator must be of type "
+ "'bool'.");
+
+ /**
+ * 16.12.2 Const: An expression of one of the forms !e, e1 && e2 or e1 || e2,
+ * where e, e1 and e2 are constant expressions that evaluate to a boolean
+ * value.
+ */
+ static const CompileTimeErrorCode CONST_EVAL_TYPE_BOOL_INT =
+ const CompileTimeErrorCode(
+ 'CONST_EVAL_TYPE_BOOL_INT',
+ "In constant expressions, operands of this operator must be of type "
+ "'bool' or 'int'.");
+
+ /**
+ * 16.12.2 Const: An expression of one of the forms e1 == e2 or e1 != e2 where
+ * e1 and e2 are constant expressions that evaluate to a numeric, string or
+ * boolean value or to null.
+ */
+ static const CompileTimeErrorCode CONST_EVAL_TYPE_BOOL_NUM_STRING =
+ const CompileTimeErrorCode(
+ 'CONST_EVAL_TYPE_BOOL_NUM_STRING',
+ "In constant expressions, operands of this operator must be of type "
+ "'bool', 'num', 'String' or 'null'.");
+
+ /**
+ * 16.12.2 Const: An expression of one of the forms ~e, e1 ^ e2, e1 & e2,
+ * e1 | e2, e1 >> e2 or e1 << e2, where e, e1 and e2 are constant expressions
+ * that evaluate to an integer value or to null.
+ */
+ static const CompileTimeErrorCode CONST_EVAL_TYPE_INT =
+ const CompileTimeErrorCode(
+ 'CONST_EVAL_TYPE_INT',
+ "In constant expressions, operands of this operator must be of type "
+ "'int'.");
+
+ /**
+ * 16.12.2 Const: An expression of one of the forms e, e1 + e2, e1 - e2, e1 *
+ * e2, e1 / e2, e1 ~/ e2, e1 > e2, e1 < e2, e1 >= e2, e1 <= e2 or e1 % e2,
+ * where e, e1 and e2 are constant expressions that evaluate to a numeric
+ * value or to null.
+ */
+ static const CompileTimeErrorCode CONST_EVAL_TYPE_NUM =
+ const CompileTimeErrorCode(
+ 'CONST_EVAL_TYPE_NUM',
+ "In constant expressions, operands of this operator must be of type "
+ "'num'.");
+
+ static const CompileTimeErrorCode CONST_EVAL_TYPE_TYPE =
+ const CompileTimeErrorCode(
+ 'CONST_EVAL_TYPE_TYPE',
+ "In constant expressions, operands of this operator must be of type "
+ "'Type'.");
+
+ /**
+ * 16.12.2 Const: It is a compile-time error if evaluation of a constant
+ * object results in an uncaught exception being thrown.
+ */
+ static const CompileTimeErrorCode CONST_EVAL_THROWS_EXCEPTION =
+ const CompileTimeErrorCode('CONST_EVAL_THROWS_EXCEPTION',
+ "Evaluation of this constant expression throws an exception.");
+
+ /**
+ * 16.12.2 Const: It is a compile-time error if evaluation of a constant
+ * object results in an uncaught exception being thrown.
+ */
+ static const CompileTimeErrorCode CONST_EVAL_THROWS_IDBZE =
+ const CompileTimeErrorCode(
+ 'CONST_EVAL_THROWS_IDBZE',
+ "Evaluation of this constant expression throws an "
+ "IntegerDivisionByZeroException.");
+
+ /**
* 6.2 Formal Parameters: It is a compile-time error if a formal parameter is
* declared as a constant variable.
*/
@@ -740,14 +876,6 @@
correction: "Try declaring the field as final, or adding the keyword "
"'static'.");
- static const CompileTimeErrorCode CONST_SPREAD_EXPECTED_LIST_OR_SET =
- const CompileTimeErrorCode('CONST_SPREAD_EXPECTED_LIST_OR_SET',
- "A list or a set is expected in this spread.");
-
- static const CompileTimeErrorCode CONST_SPREAD_EXPECTED_MAP =
- const CompileTimeErrorCode(
- 'CONST_SPREAD_EXPECTED_MAP', "A map is expected in this spread.");
-
/**
* 12.8 Maps: It is a compile-time error if the key of an entry in a constant
* map literal is an instance of a class that implements the operator
@@ -789,85 +917,13 @@
correction: "Try using a different value for the element, or "
"removing the keyword 'const' from the set.");
- /**
- * 16.12.2 Const: An expression of one of the forms !e, e1 && e2 or e1 || e2,
- * where e, e1 and e2 are constant expressions that evaluate to a boolean
- * value.
- */
- static const CompileTimeErrorCode CONST_EVAL_TYPE_BOOL =
- const CompileTimeErrorCode(
- 'CONST_EVAL_TYPE_BOOL',
- "In constant expressions, operands of this operator must be of type "
- "'bool'.");
+ static const CompileTimeErrorCode CONST_SPREAD_EXPECTED_LIST_OR_SET =
+ const CompileTimeErrorCode('CONST_SPREAD_EXPECTED_LIST_OR_SET',
+ "A list or a set is expected in this spread.");
- /**
- * 16.12.2 Const: An expression of one of the forms !e, e1 && e2 or e1 || e2,
- * where e, e1 and e2 are constant expressions that evaluate to a boolean
- * value.
- */
- static const CompileTimeErrorCode CONST_EVAL_TYPE_BOOL_INT =
+ static const CompileTimeErrorCode CONST_SPREAD_EXPECTED_MAP =
const CompileTimeErrorCode(
- 'CONST_EVAL_TYPE_BOOL_INT',
- "In constant expressions, operands of this operator must be of type "
- "'bool' or 'int'.");
-
- /**
- * 16.12.2 Const: An expression of one of the forms e1 == e2 or e1 != e2 where
- * e1 and e2 are constant expressions that evaluate to a numeric, string or
- * boolean value or to null.
- */
- static const CompileTimeErrorCode CONST_EVAL_TYPE_BOOL_NUM_STRING =
- const CompileTimeErrorCode(
- 'CONST_EVAL_TYPE_BOOL_NUM_STRING',
- "In constant expressions, operands of this operator must be of type "
- "'bool', 'num', 'String' or 'null'.");
-
- /**
- * 16.12.2 Const: An expression of one of the forms ~e, e1 ^ e2, e1 & e2,
- * e1 | e2, e1 >> e2 or e1 << e2, where e, e1 and e2 are constant expressions
- * that evaluate to an integer value or to null.
- */
- static const CompileTimeErrorCode CONST_EVAL_TYPE_INT =
- const CompileTimeErrorCode(
- 'CONST_EVAL_TYPE_INT',
- "In constant expressions, operands of this operator must be of type "
- "'int'.");
-
- /**
- * 16.12.2 Const: An expression of one of the forms e, e1 + e2, e1 - e2, e1 *
- * e2, e1 / e2, e1 ~/ e2, e1 > e2, e1 < e2, e1 >= e2, e1 <= e2 or e1 % e2,
- * where e, e1 and e2 are constant expressions that evaluate to a numeric
- * value or to null.
- */
- static const CompileTimeErrorCode CONST_EVAL_TYPE_NUM =
- const CompileTimeErrorCode(
- 'CONST_EVAL_TYPE_NUM',
- "In constant expressions, operands of this operator must be of type "
- "'num'.");
-
- static const CompileTimeErrorCode CONST_EVAL_TYPE_TYPE =
- const CompileTimeErrorCode(
- 'CONST_EVAL_TYPE_TYPE',
- "In constant expressions, operands of this operator must be of type "
- "'Type'.");
-
- /**
- * 16.12.2 Const: It is a compile-time error if evaluation of a constant
- * object results in an uncaught exception being thrown.
- */
- static const CompileTimeErrorCode CONST_EVAL_THROWS_EXCEPTION =
- const CompileTimeErrorCode('CONST_EVAL_THROWS_EXCEPTION',
- "Evaluation of this constant expression throws an exception.");
-
- /**
- * 16.12.2 Const: It is a compile-time error if evaluation of a constant
- * object results in an uncaught exception being thrown.
- */
- static const CompileTimeErrorCode CONST_EVAL_THROWS_IDBZE =
- const CompileTimeErrorCode(
- 'CONST_EVAL_THROWS_IDBZE',
- "Evaluation of this constant expression throws an "
- "IntegerDivisionByZeroException.");
+ 'CONST_SPREAD_EXPECTED_MAP', "A map is expected in this spread.");
/**
* 16.12.2 Const: If <i>T</i> is a parameterized type <i>S<U<sub>1</sub>,
@@ -968,15 +1024,6 @@
correction: "Try calling a different constructor.");
/**
- * 15.3.1 Typedef: It is a compile-time error if any default values are
- * specified in the signature of a function type alias.
- */
- static const CompileTimeErrorCode DEFAULT_VALUE_IN_FUNCTION_TYPE_ALIAS =
- const CompileTimeErrorCode('DEFAULT_VALUE_IN_FUNCTION_TYPE_ALIAS',
- "Default parameter values aren't allowed in typedefs.",
- correction: "Try removing the default value.");
-
- /**
* It is an error to call the default List constructor with a length argument
* and a type argument which is potentially non-nullable.
*/
@@ -988,6 +1035,15 @@
correction: "Try removing the argument or using 'List.filled'.");
/**
+ * 15.3.1 Typedef: It is a compile-time error if any default values are
+ * specified in the signature of a function type alias.
+ */
+ static const CompileTimeErrorCode DEFAULT_VALUE_IN_FUNCTION_TYPE_ALIAS =
+ const CompileTimeErrorCode('DEFAULT_VALUE_IN_FUNCTION_TYPE_ALIAS',
+ "Default parameter values aren't allowed in typedefs.",
+ correction: "Try removing the default value.");
+
+ /**
* 6.2.1 Required Formals: By means of a function signature that names the
* parameter and describes its type as a function type. It is a compile-time
* error if any default values are specified in the signature of such a
@@ -1116,6 +1172,14 @@
"parameter.");
/**
+ * 16.11 Sets: It is a compile-time error if two elements of a constant set
+ * literal are equal according to their `==` operator (16.27).
+ */
+ static const CompileTimeErrorCode EQUAL_ELEMENTS_IN_CONST_SET =
+ const CompileTimeErrorCode('EQUAL_ELEMENTS_IN_CONST_SET',
+ "Two values in a constant set can't be equal.");
+
+ /**
* No parameters.
*/
// #### Description
@@ -1153,14 +1217,6 @@
hasPublishedDocs: true);
/**
- * 16.11 Sets: It is a compile-time error if two elements of a constant set
- * literal are equal according to their `==` operator (16.27).
- */
- static const CompileTimeErrorCode EQUAL_ELEMENTS_IN_CONST_SET =
- const CompileTimeErrorCode('EQUAL_ELEMENTS_IN_CONST_SET',
- "Two values in a constant set can't be equal.");
-
- /**
* SDK implementation libraries can be exported only by other SDK libraries.
*
* Parameters:
@@ -1198,7 +1254,7 @@
// var map = <String, int>{'a': 0, 'b': 1, [!'c'!]};
// ```
//
- // #### Common fix
+ // #### Common fixes
//
// If the expression is intended to compute either a key or a value in an
// entry, fix the issue by replacing the expression with the key or the value.
@@ -1216,21 +1272,6 @@
hasPublishedDocs: true);
/**
- * 7.9 Superclasses: It is a compile-time error if the extends clause of a
- * class <i>C</i> includes a type expression that does not denote a class
- * available in the lexical scope of <i>C</i>.
- *
- * Parameters:
- * 0: the name of the superclass that was not found
- */
- static const CompileTimeErrorCode EXTENDS_NON_CLASS =
- const CompileTimeErrorCode(
- 'EXTENDS_NON_CLASS', "Classes can only extend other classes.",
- correction:
- "Try specifying a different superclass, or removing the extends "
- "clause.");
-
- /**
* 12.2 Null: It is a compile-time error for a class to attempt to extend or
* implement Null.
*
@@ -1280,6 +1321,21 @@
"removing the extends clause.");
/**
+ * 7.9 Superclasses: It is a compile-time error if the extends clause of a
+ * class <i>C</i> includes a type expression that does not denote a class
+ * available in the lexical scope of <i>C</i>.
+ *
+ * Parameters:
+ * 0: the name of the superclass that was not found
+ */
+ static const CompileTimeErrorCode EXTENDS_NON_CLASS =
+ const CompileTimeErrorCode(
+ 'EXTENDS_NON_CLASS', "Classes can only extend other classes.",
+ correction:
+ "Try specifying a different superclass, or removing the extends "
+ "clause.");
+
+ /**
* Parameters:
* 0: the name of the extension
*/
@@ -1289,17 +1345,43 @@
correction: "Try replacing it with a valid expression.");
/**
- * It is for an extension to define a static member and an instance member
- * with the same base name.
- *
* Parameters:
* 0: the name of the extension defining the conflicting member
* 1: the name of the conflicting static member
*/
+ // #### Description
+ //
+ // The analyzer produces this diagnostic when an extension declaration
+ // contains both an instance member and a static member that have the same
+ // name. The instance member and the static member can't have the same name
+ // because it's unclear which member is being referenced by an unqualified use
+ // of the name within the body of the extension.
+ //
+ // #### Example
+ //
+ // The following code produces this diagnostic:
+ //
+ // ```dart
+ // extension E on Object {
+ // int get a => 0;
+ // static int [!a!]() => 0;
+ // }
+ // ```
+ //
+ // #### Common fixes
+ //
+ // Rename or remove one of the members:
+ //
+ // ```dart
+ // extension E on Object {
+ // int get a => 0;
+ // static int b() => 0;
+ // }
+ // ```
static const CompileTimeErrorCode EXTENSION_CONFLICTING_STATIC_AND_INSTANCE =
const CompileTimeErrorCode(
'EXTENSION_CONFLICTING_STATIC_AND_INSTANCE',
- "Extension '{0}' can't define static member '{1}' and instance "
+ "Extension '{0}' can't define static member '{1}' and an instance "
"member with the same name.",
correction:
"Try renaming the member to a name that doesn't conflict.");
@@ -1307,6 +1389,33 @@
/**
* No parameters.
*/
+ // #### Description
+ //
+ // The analyzer produces this diagnostic when an extension declaration
+ // declares a member with the same name as a member declared in the class
+ // `Object`. Such a member can never be used because the member in `Object` is
+ // always found first.
+ //
+ // #### Example
+ //
+ // The following code produces this diagnostic:
+ //
+ // ```dart
+ // extension E on String {
+ // String [!toString!]() => this;
+ // }
+ // ```
+ //
+ // #### Common fixes
+ //
+ // Remove the member or rename it so that the name doesn't conflict with the
+ // member in `Object`:
+ //
+ // ```dart
+ // extension E on String {
+ // String displayString() => this;
+ // }
+ // ```
static const CompileTimeErrorCode EXTENSION_DECLARES_MEMBER_OF_OBJECT =
const CompileTimeErrorCode(
'EXTENSION_DECLARES_MEMBER_OF_OBJECT',
@@ -1317,6 +1426,40 @@
/**
* No parameters.
*/
+ // #### Description
+ //
+ // The analyzer produces this diagnostic when an extension override is the
+ // target of the invocation of a static member. Similar to static members in
+ // classes, the static members of an extension should be accessed using the
+ // name of the extension, not an extension override.
+ //
+ // #### Example
+ //
+ // The following code produces this diagnostic:
+ //
+ // ```dart
+ // extension E on String {
+ // static void staticMethod() {}
+ // }
+ //
+ // void f() {
+ // E('').[!staticMethod!]();
+ // }
+ // ```
+ //
+ // #### Common fixes
+ //
+ // Replace the extension override with the name of the extension:
+ //
+ // ```dart
+ // extension E on String {
+ // static void staticMethod() {}
+ // }
+ //
+ // void f() {
+ // E.staticMethod();
+ // }
+ // ```
static const CompileTimeErrorCode EXTENSION_OVERRIDE_ACCESS_TO_STATIC_MEMBER =
const CompileTimeErrorCode(
'EXTENSION_OVERRIDE_ACCESS_TO_STATIC_MEMBER',
@@ -1329,6 +1472,43 @@
* 0: the type of the argument
* 1: the extended type
*/
+ // #### Description
+ //
+ // The analyzer produces this diagnostic when the argument to an extension
+ // override isn't assignable to the type being extended by the extension.
+ //
+ // #### Example
+ //
+ // The following code produces this diagnostic:
+ //
+ // ```dart
+ // extension E on String {
+ // void method() {}
+ // }
+ //
+ // void f() {
+ // E([!3!]).method();
+ // }
+ // ```
+ //
+ // #### Common fixes
+ //
+ // If you're using the correct extension, then update the argument to have the
+ // correct type:
+ //
+ // ```dart
+ // extension E on String {
+ // void method() {}
+ // }
+ //
+ // void f() {
+ // E(3.toString()).method();
+ // }
+ // ```
+ //
+ // If there's a different extension that's valid for the type of the argument,
+ // then either replace the name of the extension or unwrap the target so that
+ // the correct extension is found.
static const CompileTimeErrorCode EXTENSION_OVERRIDE_ARGUMENT_NOT_ASSIGNABLE =
const CompileTimeErrorCode(
'EXTENSION_OVERRIDE_ARGUMENT_NOT_ASSIGNABLE',
@@ -1338,6 +1518,63 @@
/**
* No parameters.
*/
+ static const CompileTimeErrorCode EXTENSION_OVERRIDE_WITH_CASCADE =
+ const CompileTimeErrorCode(
+ 'EXTENSION_OVERRIDE_WITH_CASCADE',
+ "Extension overrides have no value so they can't be used as the "
+ "target of a cascade expression.",
+ correction: "Try using '.' instead of '..'.");
+
+ /**
+ * No parameters.
+ */
+ // #### Description
+ //
+ // The analyzer produces this diagnostic when an extension override is found
+ // that isn't being used to access one of the members of the extension. The
+ // extension override syntax doesn't have any runtime semantics; it only
+ // controls which member is selected at compile time.
+ //
+ // #### Example
+ //
+ // The following code produces this diagnostic:
+ //
+ // ```dart
+ // extension E on int {
+ // int get a => 0;
+ // }
+ //
+ // void f(int i) {
+ // print([!E(i)!]);
+ // }
+ // ```
+ //
+ // #### Common fixes
+ //
+ // If you want to invoke one of the members of the extension, then add the
+ // invocation:
+ //
+ // ```dart
+ // extension E on int {
+ // int get a => 0;
+ // }
+ //
+ // void f(int i) {
+ // print(E(i).a);
+ // }
+ // ```
+ //
+ // If you don't want to invoke a member, then unwrap the target:
+ //
+ // ```dart
+ // extension E on int {
+ // int get a => 0;
+ // }
+ //
+ // void f(int i) {
+ // print(i);
+ // }
+ // ```
static const CompileTimeErrorCode EXTENSION_OVERRIDE_WITHOUT_ACCESS =
const CompileTimeErrorCode('EXTENSION_OVERRIDE_WITHOUT_ACCESS',
"An extension override can only be used to access instance members.",
@@ -1404,19 +1641,6 @@
correction: "Try removing one of the initializations.");
/**
- * 5 Variables: It is a compile-time error if a final instance variable that
- * has is initialized by means of an initializing formal of a constructor is
- * also initialized elsewhere in the same constructor.
- *
- * Parameters:
- * 0: the name of the field in question
- */
- static const CompileTimeErrorCode FINAL_INITIALIZED_MULTIPLE_TIMES =
- const CompileTimeErrorCode('FINAL_INITIALIZED_MULTIPLE_TIMES',
- "'{0}' is a final field and so can only be set once.",
- correction: "Try removing all but one of the initializations.");
-
- /**
* 7.6.1 Generative Constructors: It is a compile-time error if an
* initializing formal is used by a function other than a non-redirecting
* generative constructor.
@@ -1452,6 +1676,47 @@
correction: "Try using a normal parameter.");
/**
+ * 5 Variables: It is a compile-time error if a final instance variable that
+ * has is initialized by means of an initializing formal of a constructor is
+ * also initialized elsewhere in the same constructor.
+ *
+ * Parameters:
+ * 0: the name of the field in question
+ */
+ static const CompileTimeErrorCode FINAL_INITIALIZED_MULTIPLE_TIMES =
+ const CompileTimeErrorCode('FINAL_INITIALIZED_MULTIPLE_TIMES',
+ "'{0}' is a final field and so can only be set once.",
+ correction: "Try removing all but one of the initializations.");
+
+ static const CompileTimeErrorCode FOR_IN_WITH_CONST_VARIABLE =
+ const CompileTimeErrorCode('FOR_IN_WITH_CONST_VARIABLE',
+ "A for-in loop-variable can't be 'const'.",
+ correction: "Try removing the 'const' modifier from the variable, or "
+ "use a different variable.");
+
+ /**
+ * It is a compile-time error if a generic function type is used as a bound
+ * for a formal type parameter of a class or a function.
+ */
+ static const CompileTimeErrorCode GENERIC_FUNCTION_TYPE_CANNOT_BE_BOUND =
+ const CompileTimeErrorCode('GENERIC_FUNCTION_TYPE_CANNOT_BE_BOUND',
+ "Generic function types can't be used as type parameter bounds",
+ correction: "Try making the free variable in the function type part"
+ " of the larger declaration signature");
+
+ /**
+ * It is a compile-time error if a generic function type is used as an actual
+ * type argument.
+ */
+ static const CompileTimeErrorCode
+ GENERIC_FUNCTION_TYPE_CANNOT_BE_TYPE_ARGUMENT =
+ const CompileTimeErrorCode(
+ 'GENERIC_FUNCTION_TYPE_CANNOT_BE_TYPE_ARGUMENT',
+ "A generic function type can't be a type argument.",
+ correction: "Try removing type parameters from the generic function "
+ "type, or using 'dynamic' as the type argument here.");
+
+ /**
* Temporary error to work around dartbug.com/28515.
*
* We cannot yet properly summarize function-typed parameters with generic
@@ -1814,24 +2079,6 @@
correction: "Try using a top-level variable or a field.");
/**
- * 9. Functions: It is a compile-time error if an async, async* or sync*
- * modifier is attached to the body of a setter or constructor.
- */
- static const CompileTimeErrorCode INVALID_MODIFIER_ON_CONSTRUCTOR =
- const CompileTimeErrorCode('INVALID_MODIFIER_ON_CONSTRUCTOR',
- "The modifier '{0}' can't be applied to the body of a constructor.",
- correction: "Try removing the modifier.");
-
- /**
- * 9. Functions: It is a compile-time error if an async, async* or sync*
- * modifier is attached to the body of a setter or constructor.
- */
- static const CompileTimeErrorCode INVALID_MODIFIER_ON_SETTER =
- const CompileTimeErrorCode('INVALID_MODIFIER_ON_SETTER',
- "The modifier '{0}' can't be applied to the body of a setter.",
- correction: "Try removing the modifier.");
-
- /**
* TODO(brianwilkerson) Remove this when we have decided on how to report
* errors in compile-time constants. Until then, this acts as a placeholder
* for more informative errors.
@@ -1852,6 +2099,53 @@
/**
* No parameters.
*/
+ // #### Description
+ //
+ // The analyzer produces this diagnostic when an extension override doesn't
+ // have exactly one argument. The argument is the expression used to compute
+ // the value of `this` within the extension method, so there must be one
+ // argument.
+ //
+ // #### Example
+ //
+ // The following code produces this diagnostic because there are no arguments:
+ //
+ // ```dart
+ // extension E on String {
+ // String join(String other) => '$this $other';
+ // }
+ //
+ // void f() {
+ // E[!()!].join('b');
+ // }
+ // ```
+ //
+ // And, the following code produces this diagnostic because there's more than
+ // one argument:
+ //
+ // ```dart
+ // extension E on String {
+ // String join(String other) => '$this $other';
+ // }
+ //
+ // void f() {
+ // E[!('a', 'b')!].join('c');
+ // }
+ // ```
+ //
+ // #### Common fixes
+ //
+ // Provide one argument for the extension override:
+ //
+ // ```dart
+ // extension E on String {
+ // String join(String other) => '$this $other';
+ // }
+ //
+ // void f() {
+ // E('a').join('b');
+ // }
+ // ```
static const CompileTimeErrorCode INVALID_EXTENSION_ARGUMENT_COUNT =
const CompileTimeErrorCode(
'INVALID_EXTENSION_ARGUMENT_COUNT',
@@ -1878,6 +2172,24 @@
"(returnType 'Function(' parameters ')').");
/**
+ * 9. Functions: It is a compile-time error if an async, async* or sync*
+ * modifier is attached to the body of a setter or constructor.
+ */
+ static const CompileTimeErrorCode INVALID_MODIFIER_ON_CONSTRUCTOR =
+ const CompileTimeErrorCode('INVALID_MODIFIER_ON_CONSTRUCTOR',
+ "The modifier '{0}' can't be applied to the body of a constructor.",
+ correction: "Try removing the modifier.");
+
+ /**
+ * 9. Functions: It is a compile-time error if an async, async* or sync*
+ * modifier is attached to the body of a setter or constructor.
+ */
+ static const CompileTimeErrorCode INVALID_MODIFIER_ON_SETTER =
+ const CompileTimeErrorCode('INVALID_MODIFIER_ON_SETTER',
+ "The modifier '{0}' can't be applied to the body of a setter.",
+ correction: "Try removing the modifier.");
+
+ /**
* It is an error if an optional parameter (named or otherwise) with no
* default value has a potentially non-nullable type. This is produced in
* cases where there is no valid default value.
@@ -1972,9 +2284,35 @@
/**
* No parameters.
*/
+ // #### Description
+ //
+ // The analyzer produces this diagnostic when a member declared inside an
+ // extension uses the keyword `covariant` in the declaration of a parameter.
+ // Extensions aren't classes and don't have subclasses, so the keyword serves
+ // no purpose.
+ //
+ // #### Example
+ //
+ // The following code produces this diagnostic:
+ //
+ // ```dart
+ // extension E on String {
+ // void a([!covariant!] int i) {}
+ // }
+ // ```
+ //
+ // #### Common fixes
+ //
+ // Remove the 'covariant' keyword:
+ //
+ // ```dart
+ // extension E on String {
+ // void a(int i) {}
+ // }
+ // ```
static const CompileTimeErrorCode INVALID_USE_OF_COVARIANT_IN_EXTENSION =
const CompileTimeErrorCode('INVALID_USE_OF_COVARIANT_IN_EXTENSION',
- "The 'covariant' keyword can't be used in extensions.",
+ "The 'covariant' keyword can't be used in an extension.",
correction: "Try removing the 'covariant' keyword.");
/**
@@ -2513,8 +2851,8 @@
// even though it appears in an implicitly constant list literal:
//
// ```dart
- // int x = 2;
- // const y = <int>[0, 1, [!x!]];
+ // var x = 2;
+ // var y = const <int>[0, 1, [!x!]];
// ```
//
// #### Common fixes
@@ -2524,17 +2862,17 @@
// declaration of `x`:
//
// ```dart
- // const int x = 2;
- // const y = <int>[0, 1, x];
+ // const x = 2;
+ // var y = const <int>[0, 1, x];
// ```
//
// If the expression can't be made a constant, then the list can't be a
// constant either, so you must change the code so that the list isn't a
- // constant. In the example above this means removing the `const` keyword from
- // the declaration of `y`:
+ // constant. In the example above this means removing the `const` keyword
+ // before the list literal:
//
// ```dart
- // int x = 2;
+ // var x = 2;
// var y = <int>[0, 1, x];
// ```
static const CompileTimeErrorCode NON_CONSTANT_LIST_ELEMENT =
@@ -2643,6 +2981,20 @@
"Initializer expressions in constant constructors must be "
"constants.");
+ /**
+ * 7.6.1 Generative Constructors: Let <i>C</i> be the class in which the
+ * superinitializer appears and let <i>S</i> be the superclass of <i>C</i>.
+ * Let <i>k</i> be a generative constructor. It is a compile-time error if
+ * class <i>S</i> does not declare a generative constructor named <i>S</i>
+ * (respectively <i>S.id</i>)
+ */
+ static const CompileTimeErrorCode NON_GENERATIVE_CONSTRUCTOR =
+ const CompileTimeErrorCode('NON_GENERATIVE_CONSTRUCTOR',
+ "The generative constructor '{0}' expected, but factory found.",
+ correction:
+ "Try calling a different constructor in the superclass, or "
+ "making the called constructor not be a factory constructor.");
+
static const CompileTimeErrorCode NON_SYNC_FACTORY =
const CompileTimeErrorCode('NON_SYNC_FACTORY',
"Factory bodies can't use 'async', 'async*', or 'sync*'.");
@@ -2746,7 +3098,7 @@
// var s = <String>{...[!m!]};
// ```
//
- // #### Common fix
+ // #### Common fixes
//
// The most common fix is to replace the expression with one that produces an
// iterable object:
@@ -2771,20 +3123,6 @@
"spread.");
/**
- * 7.6.1 Generative Constructors: Let <i>C</i> be the class in which the
- * superinitializer appears and let <i>S</i> be the superclass of <i>C</i>.
- * Let <i>k</i> be a generative constructor. It is a compile-time error if
- * class <i>S</i> does not declare a generative constructor named <i>S</i>
- * (respectively <i>S.id</i>)
- */
- static const CompileTimeErrorCode NON_GENERATIVE_CONSTRUCTOR =
- const CompileTimeErrorCode('NON_GENERATIVE_CONSTRUCTOR',
- "The generative constructor '{0}' expected, but factory found.",
- correction:
- "Try calling a different constructor in the superclass, or "
- "making the called constructor not be a factory constructor.");
-
- /**
* It is an error if the type `T` in the on-catch clause `on T catch` is
* potentially nullable.
*/
@@ -3053,6 +3391,29 @@
"'{0}' can't use itself as a mixin.");
/**
+ * 7.6.1 Generative constructors: A generative constructor may be
+ * <i>redirecting</i>, in which case its only action is to invoke another
+ * generative constructor.
+ */
+ static const CompileTimeErrorCode REDIRECT_GENERATIVE_TO_MISSING_CONSTRUCTOR =
+ const CompileTimeErrorCode('REDIRECT_GENERATIVE_TO_MISSING_CONSTRUCTOR',
+ "The constructor '{0}' couldn't be found in '{1}'.",
+ correction: "Try redirecting to a different constructor, or "
+ "defining the constructor named '{0}'.");
+
+ /**
+ * 7.6.1 Generative constructors: A generative constructor may be
+ * <i>redirecting</i>, in which case its only action is to invoke another
+ * generative constructor.
+ */
+ static const CompileTimeErrorCode
+ REDIRECT_GENERATIVE_TO_NON_GENERATIVE_CONSTRUCTOR =
+ const CompileTimeErrorCode(
+ 'REDIRECT_GENERATIVE_TO_NON_GENERATIVE_CONSTRUCTOR',
+ "Generative constructor can't redirect to a factory constructor.",
+ correction: "Try redirecting to a different constructor.");
+
+ /**
* 7.6.2 Factories: It is a compile-time error if <i>k</i> is prefixed with
* the const modifier but <i>k'</i> is not a constant constructor.
*/
@@ -3078,7 +3439,7 @@
// The following code produces this diagnostic because `f` is a function:
//
// ```dart
- // C f() {}
+ // C f() => null;
//
// class C {
// factory C() = [!f!];
@@ -3097,7 +3458,7 @@
// the constructor to return the value from the constructor's body:
//
// ```dart
- // C f() {}
+ // C f() => null;
//
// class C {
// factory C() => f();
@@ -3123,29 +3484,6 @@
correction: "Try redirecting to a different constructor.");
/**
- * 7.6.1 Generative constructors: A generative constructor may be
- * <i>redirecting</i>, in which case its only action is to invoke another
- * generative constructor.
- */
- static const CompileTimeErrorCode REDIRECT_GENERATIVE_TO_MISSING_CONSTRUCTOR =
- const CompileTimeErrorCode('REDIRECT_GENERATIVE_TO_MISSING_CONSTRUCTOR',
- "The constructor '{0}' couldn't be found in '{1}'.",
- correction: "Try redirecting to a different constructor, or "
- "defining the constructor named '{0}'.");
-
- /**
- * 7.6.1 Generative constructors: A generative constructor may be
- * <i>redirecting</i>, in which case its only action is to invoke another
- * generative constructor.
- */
- static const CompileTimeErrorCode
- REDIRECT_GENERATIVE_TO_NON_GENERATIVE_CONSTRUCTOR =
- const CompileTimeErrorCode(
- 'REDIRECT_GENERATIVE_TO_NON_GENERATIVE_CONSTRUCTOR',
- "Generative constructor can't redirect to a factory constructor.",
- correction: "Try redirecting to a different constructor.");
-
- /**
* 5 Variables: A local variable may only be referenced at a source code
* location that is after its initializer, if any, is complete, or a
* compile-time error occurs.
@@ -3219,11 +3557,36 @@
/**
* No parameters.
*/
+ // #### Description
+ //
+ // The analyzer produces this diagnostic when a member declared inside an
+ // extension uses the `super` keyword . Extensions aren't classes and don't
+ // have superclasses, so the `super` keyword serves no purpose.
+ //
+ // #### Example
+ //
+ // The following code produces this diagnostic:
+ //
+ // ```dart
+ // extension E on Object {
+ // String get displayString => [!super!].toString();
+ // }
+ // ```
+ //
+ // #### Common fixes
+ //
+ // Remove the `super` keyword :
+ //
+ // ```dart
+ // extension E on Object {
+ // String get displayString => toString();
+ // }
+ // ```
static const CompileTimeErrorCode SUPER_IN_EXTENSION =
const CompileTimeErrorCode(
'SUPER_IN_EXTENSION',
- "You can't reference 'super' in an extension because extensions do "
- "not have a superclass.");
+ "The 'super' keyword can't be used in an extension because an "
+ "extension doesn't have a superclass.");
/**
* 12.15.4 Super Invocation: A super method invocation <i>i</i> has the form
@@ -3292,34 +3655,6 @@
hasPublishedDocs: true);
/**
- * It is a compile-time error if a generic function type is used as a bound
- * for a formal type parameter of a class or a function.
- */
- static const CompileTimeErrorCode GENERIC_FUNCTION_TYPE_CANNOT_BE_BOUND =
- const CompileTimeErrorCode('GENERIC_FUNCTION_TYPE_CANNOT_BE_BOUND',
- "Generic function types can't be used as type parameter bounds",
- correction: "Try making the free variable in the function type part"
- " of the larger declaration signature");
-
- static const CompileTimeErrorCode FOR_IN_WITH_CONST_VARIABLE =
- const CompileTimeErrorCode('FOR_IN_WITH_CONST_VARIABLE',
- "A for-in loop-variable can't be 'const'.",
- correction: "Try removing the 'const' modifier from the variable, or "
- "use a different variable.");
-
- /**
- * It is a compile-time error if a generic function type is used as an actual
- * type argument.
- */
- static const CompileTimeErrorCode
- GENERIC_FUNCTION_TYPE_CANNOT_BE_TYPE_ARGUMENT =
- const CompileTimeErrorCode(
- 'GENERIC_FUNCTION_TYPE_CANNOT_BE_TYPE_ARGUMENT',
- "A generic function type can't be a type argument.",
- correction: "Try removing type parameters from the generic function "
- "type, or using 'dynamic' as the type argument here.");
-
- /**
* 15.3.1 Typedef: Any self reference, either directly, or recursively via
* another typedef, is a compile time error.
*/
@@ -3364,9 +3699,7 @@
// ```dart
// class Point {}
//
- // void main() {
- // [!Piont!] p;
- // }
+ // void f([!Piont!] p) {}
// ```
//
// #### Common fixes
@@ -3378,9 +3711,7 @@
// ```dart
// class Point {}
//
- // void main() {
- // Point p;
- // }
+ // void f(Point p) {}
// ```
//
// If the class is defined but isn't visible, then you probably need to add an
@@ -3432,6 +3763,94 @@
* 0: the name of the getter that is undefined
* 1: the name of the extension that was explicitly specified
*/
+ // #### Description
+ //
+ // The analyzer produces this diagnostic when an extension override is used to
+ // invoke a getter, but the getter isn't defined by the specified extension.
+ // The analyzer also produces this diagnostic when a static getter is
+ // referenced but isn't defined by the specified extension.
+ //
+ // #### Example
+ //
+ // The following code produces this diagnostic because the extension `E`
+ // doesn't declare an instance getter named `b`:
+ //
+ // ```dart
+ // extension E on String {
+ // String get a => 'a';
+ // }
+ //
+ // extension F on String {
+ // String get b => 'b';
+ // }
+ //
+ // void f() {
+ // E('c').[!b!];
+ // }
+ // ```
+ //
+ // The following code produces this diagnostic because the extension `E`
+ // doesn't declare a static getter named `a`:
+ //
+ // ```dart
+ // extension E on String {}
+ //
+ // var x = E.[!a!];
+ // ```
+ //
+ // #### Common fixes
+ //
+ // If the name of the getter is incorrect, then change it to the name of an
+ // existing getter:
+ //
+ // ```dart
+ // extension E on String {
+ // String get a => 'a';
+ // }
+ //
+ // extension F on String {
+ // String get b => 'b';
+ // }
+ //
+ // void f() {
+ // E('c').a;
+ // }
+ // ```
+ //
+ // If the name of the getter is correct but the name of the extension is
+ // wrong, then change the name of the extension to the correct name:
+ //
+ // ```dart
+ // extension E on String {
+ // String get a => 'a';
+ // }
+ //
+ // extension F on String {
+ // String get b => 'b';
+ // }
+ //
+ // void f() {
+ // F('c').b;
+ // }
+ // ```
+ //
+ // If the name of the getter and extension are both correct, but the getter
+ // isn't defined, then define the getter:
+ //
+ // ```dart
+ // extension E on String {
+ // String get a => 'a';
+ // String get b => 'z';
+ // }
+ //
+ // extension F on String {
+ // String get b => 'b';
+ // }
+ //
+ // void f() {
+ // E('c').b;
+ // }
+ // ```
static const CompileTimeErrorCode UNDEFINED_EXTENSION_GETTER =
const CompileTimeErrorCode('UNDEFINED_EXTENSION_GETTER',
"The getter '{0}' isn't defined for the extension '{1}'.",
@@ -3444,6 +3863,94 @@
* 0: the name of the method that is undefined
* 1: the name of the extension that was explicitly specified
*/
+ // #### Description
+ //
+ // The analyzer produces this diagnostic when an extension override is used to
+ // invoke a method, but the method isn't defined by the specified extension.
+ // The analyzer also produces this diagnostic when a static method is
+ // referenced but isn't defined by the specified extension.
+ //
+ // #### Example
+ //
+ // The following code produces this diagnostic because the extension `E`
+ // doesn't declare an instance method named `b`:
+ //
+ // ```dart
+ // extension E on String {
+ // String a() => 'a';
+ // }
+ //
+ // extension F on String {
+ // String b() => 'b';
+ // }
+ //
+ // void f() {
+ // E('c').[!b!]();
+ // }
+ // ```
+ //
+ // The following code produces this diagnostic because the extension `E`
+ // doesn't declare a static method named `a`:
+ //
+ // ```dart
+ // extension E on String {}
+ //
+ // var x = E.[!a!]();
+ // ```
+ //
+ // #### Common fixes
+ //
+ // If the name of the method is incorrect, then change it to the name of an
+ // existing method:
+ //
+ // ```dart
+ // extension E on String {
+ // String a() => 'a';
+ // }
+ //
+ // extension F on String {
+ // String b() => 'b';
+ // }
+ //
+ // void f() {
+ // E('c').a();
+ // }
+ // ```
+ //
+ // If the name of the method is correct, but the name of the extension is
+ // wrong, then change the name of the extension to the correct name:
+ //
+ // ```dart
+ // extension E on String {
+ // String a() => 'a';
+ // }
+ //
+ // extension F on String {
+ // String b() => 'b';
+ // }
+ //
+ // void f() {
+ // F('c').b();
+ // }
+ // ```
+ //
+ // If the name of the method and extension are both correct, but the method
+ // isn't defined, then define the method:
+ //
+ // ```dart
+ // extension E on String {
+ // String a() => 'a';
+ // String b() => 'z';
+ // }
+ //
+ // extension F on String {
+ // String b() => 'b';
+ // }
+ //
+ // void f() {
+ // E('c').b();
+ // }
+ // ```
static const CompileTimeErrorCode UNDEFINED_EXTENSION_METHOD =
const CompileTimeErrorCode('UNDEFINED_EXTENSION_METHOD',
"The method '{0}' isn't defined for the extension '{1}'.",
@@ -3456,6 +3963,96 @@
* 0: the name of the setter that is undefined
* 1: the name of the extension that was explicitly specified
*/
+ // #### Description
+ //
+ // The analyzer produces this diagnostic when an extension override is used to
+ // invoke a setter, but the setter isn't defined by the specified extension.
+ // The analyzer also produces this diagnostic when a static setter is
+ // referenced but isn't defined by the specified extension.
+ //
+ // #### Example
+ //
+ // The following code produces this diagnostic because the extension `E`
+ // doesn't declare an instance setter named `b`:
+ //
+ // ```dart
+ // extension E on String {
+ // set a(String v) {}
+ // }
+ //
+ // extension F on String {
+ // set b(String v) {}
+ // }
+ //
+ // void f() {
+ // E('c').[!b!] = 'd';
+ // }
+ // ```
+ //
+ // The following code produces this diagnostic because the extension `E`
+ // doesn't declare a static setter named `a`:
+ //
+ // ```dart
+ // extension E on String {}
+ //
+ // void f() {
+ // E.[!a!] = 3;
+ // }
+ // ```
+ //
+ // #### Common fixes
+ //
+ // If the name of the setter is incorrect, then change it to the name of an
+ // existing setter:
+ //
+ // ```dart
+ // extension E on String {
+ // set a(String v) {}
+ // }
+ //
+ // extension F on String {
+ // set b(String v) {}
+ // }
+ //
+ // void f() {
+ // E('c').a = 'd';
+ // }
+ // ```
+ //
+ // If the name of the setter is correct, but the name of the extension is
+ // wrong, then change the name of the extension to the correct name:
+ //
+ // ```dart
+ // extension E on String {
+ // set a(String v) {}
+ // }
+ //
+ // extension F on String {
+ // set b(String v) {}
+ // }
+ //
+ // void f() {
+ // F('c').b = 'd';
+ // }
+ // ```
+ //
+ // If the name of the setter and extension are both correct, but the setter
+ // isn't defined, then define the setter:
+ //
+ // ```dart
+ // extension E on String {
+ // set a(String v) {}
+ // set b(String v) {}
+ // }
+ //
+ // extension F on String {
+ // set b(String v) {}
+ // }
+ //
+ // void f() {
+ // E('c').b = 'd';
+ // }
+ // ```
static const CompileTimeErrorCode UNDEFINED_EXTENSION_SETTER =
const CompileTimeErrorCode('UNDEFINED_EXTENSION_SETTER',
"The setter '{0}' isn't defined for the extension '{1}'.",
@@ -3470,7 +4067,7 @@
// #### Description
//
// The analyzer produces this diagnostic when a method or function invocation
- // has a named argument, but the method or function being invoked doesn’t
+ // has a named argument, but the method or function being invoked doesn't
// define a parameter with the same name.
//
// #### Example
@@ -3540,6 +4137,18 @@
/**
* Parameters:
+ * 0: the name of the defining type
+ */
+ static const CompileTimeErrorCode
+ UNQUALIFIED_REFERENCE_TO_STATIC_MEMBER_OF_EXTENDED_TYPE =
+ const CompileTimeErrorCode(
+ 'UNQUALIFIED_REFERENCE_TO_STATIC_MEMBER_OF_EXTENDED_TYPE',
+ "Static members from the extended type or one of its superclasses must "
+ "be qualified by the name of the defining type.",
+ correction: "Try adding '{0}.' before the name.");
+
+ /**
+ * Parameters:
* 0: the URI pointing to a non-existent file
*/
// #### Description
@@ -4111,7 +4720,7 @@
// int f(String s) => s.[!len!];
// ```
//
- // #### Common fix
+ // #### Common fixes
//
// If the identifier isn't defined, then either define it or replace it with
// the name of a getter that is defined. The example above can be corrected by
@@ -4149,7 +4758,7 @@
// int f(List<int> l) => l.[!removeMiddle!]();
// ```
//
- // #### Common fix
+ // #### Common fixes
//
// If the identifier isn't defined, then either define it or replace it with
// the name of a method that is defined. The example above can be corrected by
@@ -4216,31 +4825,25 @@
// The following code produces this diagnostic:
//
// ```dart
- // class Point {
- // int x;
- // int y;
- // Point(this.x, this.y);
- // void shiftBy(Point other) {
- // this.x += other.x;
- // this.[!z!] += other.y;
+ // class C {
+ // int x = 0;
+ // void m(int y) {
+ // this.[!z!] = y;
// }
// }
// ```
//
- // #### Common fix
+ // #### Common fixes
//
// If the identifier isn't defined, then either define it or replace it with
// the name of a setter that is defined. The example above can be corrected by
// fixing the spelling of the setter:
//
// ```dart
- // class Point {
- // int x;
- // int y;
- // Point(this.x, this.y);
- // void shiftBy(Point other) {
- // this.x += other.x;
- // this.y += other.y;
+ // class C {
+ // int x = 0;
+ // void m(int y) {
+ // this.x = y;
// }
// }
// ```
@@ -4509,8 +5112,8 @@
// The following code produces this diagnostic:
//
// ```dart
- // int f(int x) => x;
- // num g(num y) => f([!y!]);
+ // String f(String x) => x;
+ // String g(num y) => f([!y!]);
// ```
//
// #### Common fixes
@@ -4519,8 +5122,8 @@
// example above you might be able to change the type of the parameter `y`:
//
// ```dart
- // int f(int x) => x;
- // int g(int y) => f(y);
+ // String f(String x) => x;
+ // String g(String y) => f(y);
// ```
//
// If that fix isn't possible, then add code to handle the case where the
@@ -4528,15 +5131,15 @@
// types to the required type:
//
// ```dart
- // int f(int x) => x;
- // num g(num y) => f(y.floor());
+ // String f(String x) => x;
+ // String g(num y) => f(y.toString());
// ```
//
// Another approach is to add explicit type tests and fallback code:
//
// ```dart
- // int f(int x) => x;
- // num g(num y) => f(y is int ? y : 0);
+ // String f(String x) => x;
+ // String g(num y) => f(y is String ? y : '');
// ```
//
// If you believe that the runtime type of the argument will always be the
@@ -4544,8 +5147,8 @@
// an exception thrown at runtime if you're wrong, then add an explicit cast:
//
// ```dart
- // int f(int x) => x;
- // num g(num y) => f(y as int);
+ // String f(String x) => x;
+ // String g(num y) => f(y as String);
// ```
static const StaticWarningCode ARGUMENT_TYPE_NOT_ASSIGNABLE =
const StaticWarningCode(
@@ -4832,10 +5435,8 @@
* 2: the number of additional not initialized variables that aren't listed
*/
static const StaticWarningCode FINAL_NOT_INITIALIZED_CONSTRUCTOR_3_PLUS =
- const StaticWarningCode(
- 'FINAL_NOT_INITIALIZED_CONSTRUCTOR_3',
- "The final variables '{0}', '{1}' and '{2}' more must be "
- "initialized.",
+ const StaticWarningCode('FINAL_NOT_INITIALIZED_CONSTRUCTOR_3',
+ "The final variables '{0}', '{1}' and {2} more must be initialized.",
correction: "Try adding initializers for the fields.");
/**
@@ -5264,9 +5865,7 @@
//
// ```dart
// f() {}
- // main() {
- // [!f!] v = null;
- // }
+ // g([!f!] v) {}
// ```
//
// #### Common fixes
@@ -5550,7 +6149,7 @@
"dynamic.");
/**
- * It is an error to call a method or getter on an expression of type [Never],
+ * It is an error to call a method or getter on an expression of type `Never`,
* or to invoke it as if it were a function.
*
* Go out of our way to provide a *little* more information here because many
@@ -5588,7 +6187,7 @@
'USE_OF_VOID_RESULT',
"The expression here has a type of 'void', and therefore can't be used.",
correction:
- "Try checking to see if you are using the correct API; there might "
+ "Try checking to see if you're using the correct API; there might "
"be a function or call that returns void you didn't expect. Also "
"check type parameters and variables which might also be void.");
diff --git a/pkg/analyzer/lib/src/error/duplicate_definition_verifier.dart b/pkg/analyzer/lib/src/error/duplicate_definition_verifier.dart
index 0dfad29..2638c00 100644
--- a/pkg/analyzer/lib/src/error/duplicate_definition_verifier.dart
+++ b/pkg/analyzer/lib/src/error/duplicate_definition_verifier.dart
@@ -343,6 +343,9 @@
void _checkDuplicateIdentifier(
Map<String, Element> getterScope, SimpleIdentifier identifier,
{Element element, Map<String, Element> setterScope}) {
+ if (identifier.isSynthetic) {
+ return;
+ }
element ??= identifier.staticElement;
// Fields define getters and setters, so check them separately.
diff --git a/pkg/analyzer/lib/src/error/inheritance_override.dart b/pkg/analyzer/lib/src/error/inheritance_override.dart
index af4dc3a..8ece3f2 100644
--- a/pkg/analyzer/lib/src/error/inheritance_override.dart
+++ b/pkg/analyzer/lib/src/error/inheritance_override.dart
@@ -135,7 +135,7 @@
return;
}
- InterfaceTypeImpl type = classElement.type;
+ InterfaceTypeImpl type = classElement.thisType;
// Add all superinterfaces of the direct supertype.
if (type.superclass != null) {
@@ -169,11 +169,11 @@
var fieldList = member.fields;
for (var field in fieldList.variables) {
FieldElement fieldElement = field.declaredElement;
- _checkDeclaredMember(fieldList, libraryUri, fieldElement.getter);
- _checkDeclaredMember(fieldList, libraryUri, fieldElement.setter);
+ _checkDeclaredMember(field.name, libraryUri, fieldElement.getter);
+ _checkDeclaredMember(field.name, libraryUri, fieldElement.setter);
}
} else if (member is MethodDeclaration) {
- _checkDeclaredMember(member, libraryUri, member.declaredElement,
+ _checkDeclaredMember(member.name, libraryUri, member.declaredElement,
methodParameterNodes: member.parameters?.parameters);
}
}
@@ -221,6 +221,13 @@
// 2. if the class contains no member named `m`, and the class member
// for `noSuchMethod` is the one declared in `Object`, then it's a
// compile-time error.
+ // TODO(brianwilkerson) This code catches some cases not caught in
+ // _checkDeclaredMember, but also duplicates the diagnostic reported
+ // there in some other cases.
+ // TODO(brianwilkerson) In the case of methods inherited via mixins, the
+ // diagnostic should be reported on the name of the mixin defining the
+ // method. In other cases, it should be reported on the name of the
+ // overriding method. The classNameNode is always wrong.
if (!typeSystem.isOverrideSubtypeOf(
concreteElement.type, interfaceElement.type)) {
reporter.reportErrorForNode(
@@ -228,10 +235,10 @@
classNameNode,
[
name.name,
- concreteElement.enclosingElement.name,
- concreteElement.displayName,
interfaceElement.enclosingElement.name,
- interfaceElement.displayName,
+ interfaceElement.type.displayName,
+ concreteElement.enclosingElement.name,
+ concreteElement.type.displayName,
],
);
}
@@ -284,7 +291,7 @@
member.enclosingElement.name,
member.type.displayName,
superMember.enclosingElement.name,
- superMember.displayName
+ superMember.type.displayName
],
);
}
diff --git a/pkg/analyzer/lib/src/error/literal_element_verifier.dart b/pkg/analyzer/lib/src/error/literal_element_verifier.dart
index fb2cced..66fa754 100644
--- a/pkg/analyzer/lib/src/error/literal_element_verifier.dart
+++ b/pkg/analyzer/lib/src/error/literal_element_verifier.dart
@@ -4,6 +4,7 @@
import 'package:analyzer/dart/analysis/features.dart';
import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer/dart/element/nullability_suffix.dart';
import 'package:analyzer/dart/element/type.dart';
import 'package:analyzer/error/listener.dart';
import 'package:analyzer/src/dart/element/type.dart';
diff --git a/pkg/analyzer/lib/src/error/type_arguments_verifier.dart b/pkg/analyzer/lib/src/error/type_arguments_verifier.dart
index 3d1dfab..4592e91 100644
--- a/pkg/analyzer/lib/src/error/type_arguments_verifier.dart
+++ b/pkg/analyzer/lib/src/error/type_arguments_verifier.dart
@@ -10,6 +10,7 @@
import 'package:analyzer/error/error.dart';
import 'package:analyzer/error/listener.dart';
import 'package:analyzer/src/dart/element/type.dart';
+import 'package:analyzer/src/dart/element/type_algebra.dart';
import 'package:analyzer/src/error/codes.dart';
import 'package:analyzer/src/generated/engine.dart' show AnalysisOptionsImpl;
import 'package:analyzer/src/generated/resolver.dart';
@@ -80,10 +81,8 @@
void checkTypeName(TypeName node) {
_checkForTypeArgumentNotMatchingBounds(node);
- if (node.parent is ConstructorName &&
- node.parent.parent is InstanceCreationExpression) {
- _checkForInferenceFailureOnInstanceCreation(node, node.parent.parent);
- } else {
+ if (node.parent is! ConstructorName ||
+ node.parent.parent is! InstanceCreationExpression) {
_checkForRawTypeName(node);
}
}
@@ -147,27 +146,6 @@
}
}
- /// Checks a type on an instance creation expression for an inference
- /// failure, and reports the appropriate error if
- /// [AnalysisOptionsImpl.strictInference] is set.
- ///
- /// This checks if [node] refers to a generic type and does not have explicit
- /// or inferred type arguments. When that happens, it reports a
- /// HintMode.INFERENCE_FAILURE_ON_INSTANCE_CREATION error.
- void _checkForInferenceFailureOnInstanceCreation(
- TypeName node, InstanceCreationExpression inferenceContextNode) {
- if (!_options.strictInference || node == null) return;
- if (node.typeArguments != null) {
- // Type has explicit type arguments.
- return;
- }
- if (_isMissingTypeArguments(
- node, node.type, node.name.staticElement, inferenceContextNode)) {
- _errorReporter.reportErrorForNode(
- HintCode.INFERENCE_FAILURE_ON_INSTANCE_CREATION, node, [node.type]);
- }
- }
-
/// Checks a type annotation for a raw generic type, and reports the
/// appropriate error if [AnalysisOptionsImpl.strictRawTypes] is set.
///
@@ -194,12 +172,9 @@
if (_isMissingTypeArguments(
node, node.type, node.name.staticElement, null)) {
AstNode unwrappedParent = parentEscapingTypeArguments(node);
- if (unwrappedParent is AsExpression) {
- _errorReporter.reportErrorForNode(
- HintCode.STRICT_RAW_TYPE_IN_AS, node, [node.type]);
- } else if (unwrappedParent is IsExpression) {
- _errorReporter.reportErrorForNode(
- HintCode.STRICT_RAW_TYPE_IN_IS, node, [node.type]);
+ if (unwrappedParent is AsExpression || unwrappedParent is IsExpression) {
+ // Do not report a "Strict raw type" error in this case; too noisy.
+ // See https://github.com/dart-lang/language/blob/master/resources/type-system/strict-raw-types.md#conditions-for-a-raw-type-hint
} else {
_errorReporter
.reportErrorForNode(HintCode.STRICT_RAW_TYPE, node, [node.type]);
@@ -238,8 +213,6 @@
'Unexpected element associated with parameterized type: '
'${element.runtimeType}');
}
- var parameterTypes =
- parameterElements.map<DartType>((p) => p.type).toList();
List<DartType> arguments = type.typeArguments;
// iterate over each bounded type parameter and corresponding argument
NodeList<TypeAnnotation> argumentNodes =
@@ -248,7 +221,7 @@
int loopThroughIndex =
math.min(typeArguments.length, parameterElements.length);
bool shouldSubstitute =
- arguments.isNotEmpty && arguments.length == parameterTypes.length;
+ arguments.isNotEmpty && arguments.length == parameterElements.length;
for (int i = 0; i < loopThroughIndex; i++) {
DartType argType = typeArguments[i];
TypeAnnotation argumentNode =
@@ -265,7 +238,8 @@
DartType boundType = parameterElements[i].bound;
if (argType != null && boundType != null) {
if (shouldSubstitute) {
- boundType = boundType.substitute2(arguments, parameterTypes);
+ boundType = Substitution.fromPairs(parameterElements, arguments)
+ .substituteType(boundType);
}
if (!_typeSystem.isSubtypeOf(argType, boundType)) {
diff --git a/pkg/analyzer/lib/src/fasta/ast_builder.dart b/pkg/analyzer/lib/src/fasta/ast_builder.dart
index fa944a9..5d94e1b 100644
--- a/pkg/analyzer/lib/src/fasta/ast_builder.dart
+++ b/pkg/analyzer/lib/src/fasta/ast_builder.dart
@@ -23,7 +23,6 @@
Message,
MessageCode,
messageConstConstructorWithBody,
- messageConstMethod,
messageConstructorWithReturnType,
messageConstructorWithTypeParameters,
messageDirectiveAfterDeclaration,
@@ -1607,11 +1606,6 @@
throw new UnimplementedError();
}
- if (modifiers?.constKeyword != null) {
- // This error is also reported in OutlineBuilder.endMethod
- handleRecoverableError(
- messageConstMethod, modifiers.constKeyword, modifiers.constKeyword);
- }
checkFieldFormalParameters(parameters);
currentDeclarationMembers.add(ast.methodDeclaration(
comment,
diff --git a/pkg/analyzer/lib/src/generated/declaration_resolver.dart b/pkg/analyzer/lib/src/generated/declaration_resolver.dart
index 6184e13..25b6dcc 100644
--- a/pkg/analyzer/lib/src/generated/declaration_resolver.dart
+++ b/pkg/analyzer/lib/src/generated/declaration_resolver.dart
@@ -462,7 +462,6 @@
// Work around dartbug.com/28515.
// TODO(paulberry): remove this once dartbug.com/28515 is fixed.
var element = new TypeParameterElementImpl.forNode(node.name);
- element.type = new TypeParameterTypeImpl(element);
node.name?.staticElement = element;
} else {
TypeParameterElement element =
diff --git a/pkg/analyzer/lib/src/generated/element_resolver.dart b/pkg/analyzer/lib/src/generated/element_resolver.dart
index e91190e..6e95ad6 100644
--- a/pkg/analyzer/lib/src/generated/element_resolver.dart
+++ b/pkg/analyzer/lib/src/generated/element_resolver.dart
@@ -645,6 +645,7 @@
AstNode parent = node.parent;
if (parent is Annotation) {
_resolveAnnotationElement(parent);
+ return;
}
//
// Otherwise, the prefix is really an expression that happens to be a simple
@@ -692,8 +693,10 @@
return;
} else if (target is ExtensionOverride) {
if (node.isCascaded) {
- // TODO(brianwilkerson) Report this error and decide how to recover.
- throw new UnsupportedError('cascaded extension override');
+ // Report this error and recover by treating it like a non-cascade.
+ _resolver.errorReporter.reportErrorForToken(
+ CompileTimeErrorCode.EXTENSION_OVERRIDE_WITH_CASCADE,
+ node.operator);
}
ExtensionElement element = target.extensionName.staticElement;
SimpleIdentifier propertyName = node.propertyName;
@@ -860,7 +863,7 @@
if (node.inSetterContext() &&
node.inGetterContext() &&
enclosingClass != null) {
- InterfaceType enclosingType = enclosingClass.type;
+ InterfaceType enclosingType = enclosingClass.thisType;
var propertyResolver = _newPropertyResolver();
propertyResolver.resolve(null, enclosingType, node.name, node);
node.auxiliaryElements = AuxiliaryElements(
@@ -956,6 +959,20 @@
resolveMetadata(node);
}
+ /// If the [element] is not static, report the error on the [identifier].
+ void _checkForStaticAccessToInstanceMember(
+ SimpleIdentifier identifier,
+ ExecutableElement element,
+ ) {
+ if (element.isStatic) return;
+
+ _resolver.errorReporter.reportErrorForNode(
+ StaticWarningCode.STATIC_ACCESS_TO_INSTANCE_MEMBER,
+ identifier,
+ [identifier.name],
+ );
+ }
+
/**
* Check that the given index [expression] was resolved, otherwise a
* [StaticTypeWarningCode.UNDEFINED_OPERATOR] is generated. The [target] is
@@ -1132,18 +1149,6 @@
}
/**
- * Return `true` if the given [element] is a static element.
- */
- bool _isStatic(Element element) {
- if (element is ExecutableElement) {
- return element.isStatic;
- } else if (element is PropertyInducingElement) {
- return element.isStatic;
- }
- return false;
- }
-
- /**
* Return `true` if the given [node] can validly be resolved to a prefix:
* * it is the prefix in an import directive, or
* * it is the prefix in a prefixed identifier.
@@ -1155,7 +1160,8 @@
} else if (parent is PrefixedIdentifier) {
return true;
} else if (parent is MethodInvocation) {
- return identical(parent.target, node);
+ return identical(parent.target, node) &&
+ parent.operator?.type == TokenType.PERIOD;
}
return false;
}
@@ -1501,34 +1507,6 @@
}
/**
- * Given that we are accessing a property of the given [classElement] with the
- * given [propertyName], return the element that represents the property.
- */
- ResolutionResult _resolveElement(
- ClassElement classElement, SimpleIdentifier propertyName) {
- String name = propertyName.name;
- if (propertyName.inSetterContext()) {
- var element = classElement.getSetter(name);
- if (element != null && element.isAccessibleIn(_definingLibrary)) {
- return ResolutionResult(property: element.variable);
- }
- }
- {
- var element = classElement.getGetter(name);
- if (element != null && element.isAccessibleIn(_definingLibrary)) {
- return ResolutionResult(property: element.variable);
- }
- }
- {
- var element = classElement.getMethod(name);
- if (element != null && element.isAccessibleIn(_definingLibrary)) {
- return ResolutionResult(function: element);
- }
- }
- return ResolutionResult.none;
- }
-
- /**
* Given a [node] that can have annotations associated with it, resolve the
* annotations in the element model representing annotations to the node.
*/
@@ -1536,195 +1514,256 @@
_resolveAnnotations(node.metadata);
}
- /**
- * Given that we are accessing a property of the given [targetType] with the
- * given [propertyName], return the element that represents the property. The
- * [target] is the target of the invocation ('e').
- */
- ResolutionResult _resolveProperty(
- Expression target, DartType targetType, SimpleIdentifier propertyName) {
- var propertyResolver = _newPropertyResolver();
- propertyResolver.resolve(
- target, targetType, propertyName.name, propertyName);
- ResolutionResult result = ResolutionResult.none;
- if (propertyName.inSetterContext()) {
- result = propertyResolver.setterResult;
- }
- if (result.isNone) {
- result = propertyResolver.getterResult;
- }
- return result;
- }
-
void _resolvePropertyAccess(
Expression target, SimpleIdentifier propertyName, bool isCascaded) {
DartType staticType = _getStaticType(target);
+
//
// If this property access is of the form 'E.m' where 'E' is an extension,
// then look for the member in the extension. This does not apply to
// conditional property accesses (i.e. 'C?.m').
//
- ResolutionResult result = ResolutionResult.none;
if (target is Identifier && target.staticElement is ExtensionElement) {
- ExecutableElement staticElement;
ExtensionElement extension = target.staticElement;
String memberName = propertyName.name;
- if (propertyName.inSetterContext()) {
- staticElement = extension.getSetter(memberName);
- }
- staticElement ??= extension.getGetter(memberName);
- staticElement ??= extension.getMethod(memberName);
- if (staticElement == null) {
- if (propertyName.inSetterContext()) {
- _resolver.errorReporter.reportErrorForNode(
- CompileTimeErrorCode.UNDEFINED_EXTENSION_SETTER,
- propertyName,
- [memberName, extension.name]);
+
+ if (propertyName.inGetterContext()) {
+ ExecutableElement element;
+ element ??= extension.getGetter(memberName);
+ element ??= extension.getMethod(memberName);
+ if (element != null) {
+ propertyName.staticElement = element;
+ _checkForStaticAccessToInstanceMember(propertyName, element);
} else {
_resolver.errorReporter.reportErrorForNode(
- CompileTimeErrorCode.UNDEFINED_EXTENSION_GETTER,
- propertyName,
- [memberName, extension.name]);
- }
- } else if (!staticElement.isStatic) {
- _resolver.errorReporter.reportErrorForNode(
- StaticWarningCode.STATIC_ACCESS_TO_INSTANCE_MEMBER,
+ CompileTimeErrorCode.UNDEFINED_EXTENSION_GETTER,
propertyName,
- [memberName]);
- }
- if (staticElement != null) {
- if (staticElement is PropertyAccessorElement) {
- result = ResolutionResult(property: staticElement.variable);
- } else if (staticElement is MethodElement) {
- result = ResolutionResult(function: staticElement);
+ [memberName, extension.name],
+ );
}
}
+
+ if (propertyName.inSetterContext()) {
+ var element = extension.getSetter(memberName);
+ if (element != null) {
+ propertyName.staticElement = element;
+ _checkForStaticAccessToInstanceMember(propertyName, element);
+ } else {
+ _resolver.errorReporter.reportErrorForNode(
+ CompileTimeErrorCode.UNDEFINED_EXTENSION_SETTER,
+ propertyName,
+ [memberName, extension.name],
+ );
+ }
+ }
+
+ return;
}
+
//
// If this property access is of the form 'C.m' where 'C' is a class,
// then we don't call resolveProperty(...) which walks up the class
// hierarchy, instead we just look for the member in the type only. This
// does not apply to conditional property accesses (i.e. 'C?.m').
//
- if (result.isNone) {
- ClassElement typeReference = getTypeReference(target);
- if (typeReference != null) {
- if (isCascaded) {
- typeReference = _typeType.element;
+ ClassElement typeReference = getTypeReference(target);
+ if (typeReference != null) {
+ if (isCascaded) {
+ typeReference = _typeType.element;
+ }
+
+ if (propertyName.inGetterContext()) {
+ ExecutableElement element;
+
+ if (element == null) {
+ var getter = typeReference.getGetter(propertyName.name);
+ if (getter != null && getter.isAccessibleIn(_definingLibrary)) {
+ element = getter;
+ }
}
- result = _resolveElement(typeReference, propertyName);
- } else {
- if (target is SuperExpression) {
- ExecutableElement staticElement;
- if (staticType is InterfaceTypeImpl) {
- staticElement = staticType.lookUpInheritedMember(
- propertyName.name, _definingLibrary,
- setter: propertyName.inSetterContext(),
- concrete: true,
- forSuperInvocation: true);
+
+ if (element == null) {
+ var method = typeReference.getMethod(propertyName.name);
+ if (method != null && method.isAccessibleIn(_definingLibrary)) {
+ element = method;
+ }
+ }
+
+ if (element != null) {
+ propertyName.staticElement = element;
+ _checkForStaticAccessToInstanceMember(propertyName, element);
+ } else {
+ _resolver.errorReporter.reportErrorForNode(
+ StaticTypeWarningCode.UNDEFINED_GETTER,
+ propertyName,
+ [propertyName.name, typeReference.name],
+ );
+ }
+ }
+
+ if (propertyName.inSetterContext()) {
+ ExecutableElement element;
+
+ var setter = typeReference.getSetter(propertyName.name);
+ if (setter != null && setter.isAccessibleIn(_definingLibrary)) {
+ element = setter;
+ }
+
+ if (element != null) {
+ propertyName.staticElement = element;
+ _checkForStaticAccessToInstanceMember(propertyName, element);
+ } else {
+ var getter = typeReference.getGetter(propertyName.name);
+ if (getter != null) {
+ propertyName.staticElement = getter;
+ // The error will be reported in ErrorVerifier.
+ } else {
+ _resolver.errorReporter.reportErrorForNode(
+ StaticTypeWarningCode.UNDEFINED_SETTER,
+ propertyName,
+ [propertyName.name, typeReference.name],
+ );
+ }
+ }
+ }
+
+ return;
+ }
+
+ if (target is SuperExpression) {
+ if (staticType is InterfaceTypeImpl) {
+ if (propertyName.inGetterContext()) {
+ var element = staticType.lookUpInheritedMember(
+ propertyName.name, _definingLibrary,
+ setter: false, concrete: true, forSuperInvocation: true);
+
+ if (element != null) {
+ propertyName.staticElement = element;
+ } else {
// We were not able to find the concrete dispatch target.
// But we would like to give the user at least some resolution.
// So, we retry without the "concrete" requirement.
- if (staticElement == null) {
- staticElement = staticType.lookUpInheritedMember(
- propertyName.name, _definingLibrary,
- setter: propertyName.inSetterContext(), concrete: false);
- if (staticElement != null) {
- ClassElementImpl receiverSuperClass =
- AbstractClassElementImpl.getImpl(
- staticType.element.supertype.element,
+ element = staticType.lookUpInheritedMember(
+ propertyName.name, _definingLibrary,
+ setter: false, concrete: false);
+ if (element != null) {
+ propertyName.staticElement = element;
+ ClassElementImpl receiverSuperClass =
+ AbstractClassElementImpl.getImpl(
+ staticType.element.supertype.element,
+ );
+ if (!receiverSuperClass.hasNoSuchMethod) {
+ _resolver.errorReporter.reportErrorForNode(
+ CompileTimeErrorCode.ABSTRACT_SUPER_MEMBER_REFERENCE,
+ propertyName,
+ [element.kind.displayName, propertyName.name],
);
- if (!receiverSuperClass.hasNoSuchMethod) {
- _resolver.errorReporter.reportErrorForNode(
- CompileTimeErrorCode.ABSTRACT_SUPER_MEMBER_REFERENCE,
- propertyName,
- [staticElement.kind.displayName, propertyName.name]);
- }
}
+ } else {
+ _resolver.errorReporter.reportErrorForNode(
+ StaticTypeWarningCode.UNDEFINED_SUPER_GETTER,
+ propertyName,
+ [propertyName.name, staticType.displayName],
+ );
}
}
- if (staticElement is PropertyAccessorElement) {
- result = ResolutionResult(property: staticElement.variable);
- } else if (staticElement is MethodElement) {
- result = ResolutionResult(function: staticElement);
+ }
+
+ if (propertyName.inSetterContext()) {
+ var element = staticType.lookUpInheritedMember(
+ propertyName.name, _definingLibrary,
+ setter: true, concrete: true, forSuperInvocation: true);
+
+ if (element != null) {
+ propertyName.staticElement = element;
+ } else {
+ // We were not able to find the concrete dispatch target.
+ // But we would like to give the user at least some resolution.
+ // So, we retry without the "concrete" requirement.
+ element = staticType.lookUpInheritedMember(
+ propertyName.name, _definingLibrary,
+ setter: true, concrete: false);
+ if (element != null) {
+ propertyName.staticElement = element;
+ ClassElementImpl receiverSuperClass =
+ AbstractClassElementImpl.getImpl(
+ staticType.element.supertype.element,
+ );
+ if (!receiverSuperClass.hasNoSuchMethod) {
+ _resolver.errorReporter.reportErrorForNode(
+ CompileTimeErrorCode.ABSTRACT_SUPER_MEMBER_REFERENCE,
+ propertyName,
+ [element.kind.displayName, propertyName.name],
+ );
+ }
+ } else {
+ _resolver.errorReporter.reportErrorForNode(
+ StaticTypeWarningCode.UNDEFINED_SUPER_SETTER,
+ propertyName,
+ [propertyName.name, staticType.displayName],
+ );
+ }
}
- } else {
- result = _resolveProperty(target, staticType, propertyName);
}
}
- }
- // Might be part of an annotation, record property element only if exists.
- // Error was already reported in validateAnnotationElement().
- if (target.parent.parent is Annotation) {
- if (result.isSingle) {
- propertyName.staticElement = result.getter;
- }
+
return;
}
- propertyName.staticElement =
- (propertyName.inSetterContext() ? result.setter : null) ??
- result.getter;
- if (_shouldReportInvalidMember(staticType, result)) {
- if (staticType is FunctionType &&
- propertyName.name == FunctionElement.CALL_METHOD_NAME) {
- return;
- }
- Element enclosingElement = staticType.element;
- bool isStaticProperty = _isStatic(enclosingElement);
- // Special getter cases.
- if (propertyName.inGetterContext()) {
- if (!isStaticProperty && enclosingElement is ClassElement) {
- InterfaceType targetType = enclosingElement.type;
- if (targetType != null &&
- targetType.isDartCoreFunction &&
- propertyName.name == FunctionElement.CALL_METHOD_NAME) {
- return;
- } else if (enclosingElement.isEnum && propertyName.name == "_name") {
- _resolver.errorReporter.reportErrorForNode(
- CompileTimeErrorCode.ACCESS_PRIVATE_ENUM_FIELD,
- propertyName,
- [propertyName.name]);
- return;
- }
- }
- }
- Element declaringElement = staticType.isVoid ? null : enclosingElement;
- if (propertyName.inSetterContext()) {
- ErrorCode errorCode;
- var arguments = [propertyName.name, staticType.displayName];
- if (target is SuperExpression) {
- errorCode = StaticTypeWarningCode.UNDEFINED_SUPER_SETTER;
+
+ if (staticType == null || staticType.isDynamic) {
+ return;
+ }
+
+ if (staticType.isVoid) {
+ _resolver.errorReporter.reportErrorForNode(
+ StaticWarningCode.USE_OF_VOID_RESULT,
+ propertyName,
+ );
+ return;
+ }
+
+ var propertyResolver = _newPropertyResolver();
+ propertyResolver.resolve(
+ target, staticType, propertyName.name, propertyName);
+
+ if (propertyName.inGetterContext()) {
+ var getterResult = propertyResolver.getterResult;
+ if (getterResult.isSingle) {
+ propertyName.staticElement = getterResult.getter;
+ } else if (getterResult.isNone) {
+ if (staticType is FunctionType &&
+ propertyName.name == FunctionElement.CALL_METHOD_NAME) {
+ // Referencing `.call` on a `Function` type is OK.
+ } else if (staticType is InterfaceType &&
+ staticType.isDartCoreFunction &&
+ propertyName.name == FunctionElement.CALL_METHOD_NAME) {
+ // Referencing `.call` on a `Function` type is OK.
} else {
- if (staticType.isVoid) {
- errorCode = StaticWarningCode.USE_OF_VOID_RESULT;
- arguments = [];
- } else {
- errorCode = StaticTypeWarningCode.UNDEFINED_SETTER;
- }
- }
- _recordUndefinedNode(
- declaringElement, errorCode, propertyName, arguments);
- } else if (propertyName.inGetterContext()) {
- ErrorCode errorCode;
- var arguments = [propertyName.name, staticType.displayName];
- if (target is SuperExpression) {
- errorCode = StaticTypeWarningCode.UNDEFINED_SUPER_GETTER;
- } else {
- if (staticType.isVoid) {
- errorCode = StaticWarningCode.USE_OF_VOID_RESULT;
- arguments = [];
- } else {
- errorCode = StaticTypeWarningCode.UNDEFINED_GETTER;
- }
- }
- _recordUndefinedNode(
- declaringElement, errorCode, propertyName, arguments);
- } else {
- _recordUndefinedNode(
- declaringElement,
- StaticWarningCode.UNDEFINED_IDENTIFIER,
+ _resolver.errorReporter.reportErrorForNode(
+ StaticTypeWarningCode.UNDEFINED_GETTER,
propertyName,
- [propertyName.name]);
+ [propertyName.name, staticType.displayName],
+ );
+ }
+ }
+ }
+
+ if (propertyName.inSetterContext()) {
+ var setterResult = propertyResolver.setterResult;
+ if (setterResult.isSingle) {
+ propertyName.staticElement = setterResult.setter;
+ } else if (setterResult.isNone) {
+ var getter = propertyResolver.getterResult.getter;
+ if (getter != null) {
+ propertyName.staticElement = getter;
+ // A more specific error will be reported in ErrorVerifier.
+ } else {
+ _resolver.errorReporter.reportErrorForNode(
+ StaticTypeWarningCode.UNDEFINED_SETTER,
+ propertyName,
+ [propertyName.name, staticType.displayName],
+ );
+ }
}
}
}
@@ -1750,7 +1789,7 @@
if (enclosingClass != null) {
var propertyResolver = _newPropertyResolver();
propertyResolver.resolve(
- null, enclosingClass.type, identifier.name, identifier);
+ null, enclosingClass.thisType, identifier.name, identifier);
setter = propertyResolver.setterResult.setter;
}
}
@@ -1783,7 +1822,7 @@
return null;
}
} else {
- enclosingType = enclosingClass.type;
+ enclosingType = enclosingClass.thisType;
}
if (element == null && enclosingType != null) {
var propertyResolver = _newPropertyResolver();
@@ -2019,8 +2058,8 @@
if (result.isSingle) {
if (result.getter != null) {
getterResult = result;
- } else {
- assert(result.setter != null);
+ }
+ if (result.setter != null) {
setterResult = result;
}
} else if (result.isAmbiguous) {
diff --git a/pkg/analyzer/lib/src/generated/engine.dart b/pkg/analyzer/lib/src/generated/engine.dart
index dd79796..ec27a69 100644
--- a/pkg/analyzer/lib/src/generated/engine.dart
+++ b/pkg/analyzer/lib/src/generated/engine.dart
@@ -2,34 +2,23 @@
// 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.
-import 'dart:async';
import 'dart:collection';
import 'dart:typed_data';
import 'package:analyzer/dart/analysis/features.dart';
-import 'package:analyzer/dart/ast/ast.dart';
-import 'package:analyzer/dart/ast/visitor.dart';
-import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/error/error.dart';
import 'package:analyzer/exception/exception.dart';
import 'package:analyzer/instrumentation/instrumentation.dart';
import 'package:analyzer/source/error_processor.dart';
-import 'package:analyzer/src/cancelable_future.dart';
-import 'package:analyzer/src/context/builder.dart' show EmbedderYamlLocator;
-import 'package:analyzer/src/context/cache.dart';
import 'package:analyzer/src/context/context.dart';
import 'package:analyzer/src/dart/analysis/experiments.dart';
-import 'package:analyzer/src/dart/ast/ast.dart';
import 'package:analyzer/src/generated/constant.dart';
import 'package:analyzer/src/generated/java_engine.dart';
import 'package:analyzer/src/generated/resolver.dart';
import 'package:analyzer/src/generated/source.dart';
-import 'package:analyzer/src/generated/timestamped_data.dart';
import 'package:analyzer/src/generated/utilities_general.dart';
-import 'package:analyzer/src/plugin/resolver_provider.dart';
import 'package:analyzer/src/services/lint.dart';
import 'package:analyzer/src/summary/api_signature.dart';
-import 'package:analyzer/src/task/api/model.dart';
import 'package:front_end/src/fasta/scanner/token.dart';
import 'package:path/path.dart' as pathos;
import 'package:pub_semver/pub_semver.dart';
@@ -80,10 +69,6 @@
/// also be used to perform an analysis based on a proposed future state, such as
/// the state after a refactoring.
abstract class AnalysisContext {
- /// The file resolver provider used to override the way file URI's are
- /// resolved in some contexts.
- ResolverProvider fileResolverProvider;
-
/// Return the set of analysis options controlling the behavior of this
/// context. Clients should not modify the returned set of options.
AnalysisOptions get analysisOptions;
@@ -93,56 +78,9 @@
/// results have been invalidated.
void set analysisOptions(AnalysisOptions options);
- /// Set the order in which sources will be analyzed by [performAnalysisTask] to
- /// match the order of the sources in the given list of [sources]. If a source
- /// that needs to be analyzed is not contained in the list, then it will be
- /// treated as if it were at the end of the list. If the list is empty (or
- /// `null`) then no sources will be given priority over other sources.
- ///
- /// Changes made to the list after this method returns will <b>not</b> be
- /// reflected in the priority order.
- void set analysisPriorityOrder(List<Source> sources);
-
/// Return the set of declared variables used when computing constant values.
DeclaredVariables get declaredVariables;
- /// Return a list containing all of the sources known to this context that
- /// represent HTML files. The contents of the list can be incomplete.
- List<Source> get htmlSources;
-
- /// The stream that is notified when a source either starts or stops being
- /// analyzed implicitly.
- Stream<ImplicitAnalysisEvent> get implicitAnalysisEvents;
-
- /// Returns `true` if this context was disposed using [dispose].
- bool get isDisposed;
-
- /// Return a list containing all of the sources known to this context that
- /// represent the defining compilation unit of a library that can be run within
- /// a browser. The sources that are returned represent libraries that have a
- /// 'main' method and are either referenced by an HTML file or import, directly
- /// or indirectly, a client-only library. The contents of the list can be
- /// incomplete.
- List<Source> get launchableClientLibrarySources;
-
- /// Return a list containing all of the sources known to this context that
- /// represent the defining compilation unit of a library that can be run
- /// outside of a browser. The contents of the list can be incomplete.
- List<Source> get launchableServerLibrarySources;
-
- /// Return a list containing all of the sources known to this context that
- /// represent the defining compilation unit of a library. The contents of the
- /// list can be incomplete.
- List<Source> get librarySources;
-
- /// Return a client-provided name used to identify this context, or `null` if
- /// the client has not provided a name.
- String get name;
-
- /// Set the client-provided name used to identify this context to the given
- /// [name].
- set name(String name);
-
/// Return the source factory used to create the sources that can be analyzed
/// in this context.
SourceFactory get sourceFactory;
@@ -152,9 +90,6 @@
/// all analysis results have been invalidated.
void set sourceFactory(SourceFactory factory);
- /// Return a list containing all of the sources known to this context.
- List<Source> get sources;
-
/// Return a type provider for this context or throw [AnalysisException] if
/// either `dart:core` or `dart:async` cannot be resolved.
TypeProvider get typeProvider;
@@ -162,364 +97,11 @@
/// Return a type system for this context.
TypeSystem get typeSystem;
- /// Add the given [listener] to the list of objects that are to be notified
- /// when various analysis results are produced in this context.
- void addListener(AnalysisListener listener);
-
- /// Apply the given [delta] to change the level of analysis that will be
- /// performed for the sources known to this context.
- void applyAnalysisDelta(AnalysisDelta delta);
-
/// Apply the changes specified by the given [changeSet] to this context. Any
/// analysis results that have been invalidated by these changes will be
/// removed.
+ /// TODO(scheglov) This method is referenced by the internal indexer tool.
void applyChanges(ChangeSet changeSet);
-
- /// Return the documentation comment for the given [element] as it appears in
- /// the original source (complete with the beginning and ending delimiters) for
- /// block documentation comments, or lines starting with `"///"` and separated
- /// with `"\n"` characters for end-of-line documentation comments, or `null` if
- /// the element does not have a documentation comment associated with it. This
- /// can be a long-running operation if the information needed to access the
- /// comment is not cached.
- ///
- /// Throws an [AnalysisException] if the documentation comment could not be
- /// determined because the analysis could not be performed.
- ///
- /// <b>Note:</b> This method cannot be used in an async environment.
- String computeDocumentationComment(Element element);
-
- /// Return a list containing all of the errors associated with the given
- /// [source]. If the errors are not already known then the source will be
- /// analyzed in order to determine the errors associated with it.
- ///
- /// Throws an [AnalysisException] if the errors could not be determined because
- /// the analysis could not be performed.
- ///
- /// <b>Note:</b> This method cannot be used in an async environment.
- ///
- /// See [getErrors].
- List<AnalysisError> computeErrors(Source source);
-
- /// Return the kind of the given [source], computing it's kind if it is not
- /// already known. Return [SourceKind.UNKNOWN] if the source is not contained
- /// in this context.
- ///
- /// <b>Note:</b> This method cannot be used in an async environment.
- ///
- /// See [getKindOf].
- SourceKind computeKindOf(Source source);
-
- /// Return the element model corresponding to the library defined by the given
- /// [source]. If the element model does not yet exist it will be created. The
- /// process of creating an element model for a library can long-running,
- /// depending on the size of the library and the number of libraries that are
- /// imported into it that also need to have a model built for them.
- ///
- /// Throws an [AnalysisException] if the element model could not be determined
- /// because the analysis could not be performed.
- ///
- /// <b>Note:</b> This method cannot be used in an async environment.
- ///
- /// See [getLibraryElement].
- LibraryElement computeLibraryElement(Source source);
-
- /// Return the line information for the given [source], or `null` if the source
- /// is not of a recognized kind (neither a Dart nor HTML file). If the line
- /// information was not previously known it will be created. The line
- /// information is used to map offsets from the beginning of the source to line
- /// and column pairs.
- ///
- /// Throws an [AnalysisException] if the line information could not be
- /// determined because the analysis could not be performed.
- ///
- /// <b>Note:</b> This method cannot be used in an async environment.
- ///
- /// See [getLineInfo].
- LineInfo computeLineInfo(Source source);
-
- /// Return a future which will be completed with the fully resolved AST for a
- /// single compilation unit within the given library, once that AST is up to
- /// date.
- ///
- /// If the resolved AST can't be computed for some reason, the future will be
- /// completed with an error. One possible error is AnalysisNotScheduledError,
- /// which means that the resolved AST can't be computed because the given
- /// source file is not scheduled to be analyzed within the context of the
- /// given library.
- CancelableFuture<CompilationUnit> computeResolvedCompilationUnitAsync(
- Source source, Source librarySource);
-
- /// Notifies the context that the client is going to stop using this context.
- void dispose();
-
- /// Return `true` if the given [source] exists.
- ///
- /// This method should be used rather than the method [Source.exists] because
- /// contexts can have local overrides of the content of a source that the
- /// source is not aware of and a source with local content is considered to
- /// exist even if there is no file on disk.
- bool exists(Source source);
-
- /// Return the element model corresponding to the compilation unit defined by
- /// the given [unitSource] in the library defined by the given [librarySource],
- /// or `null` if the element model does not currently exist or if the library
- /// cannot be analyzed for some reason.
- CompilationUnitElement getCompilationUnitElement(
- Source unitSource, Source librarySource);
-
- /// Return the contents and timestamp of the given [source].
- ///
- /// This method should be used rather than the method [Source.getContents]
- /// because contexts can have local overrides of the content of a source that
- /// the source is not aware of.
- TimestampedData<String> getContents(Source source);
-
- /// Return the element referenced by the given [location], or `null` if the
- /// element is not immediately available or if there is no element with the
- /// given location. The latter condition can occur, for example, if the
- /// location describes an element from a different context or if the element
- /// has been removed from this context as a result of some change since it was
- /// originally obtained.
- Element getElement(ElementLocation location);
-
- /// Return an analysis error info containing the list of all of the errors and
- /// the line info associated with the given [source]. The list of errors will
- /// be empty if the source is not known to this context or if there are no
- /// errors in the source. The errors contained in the list can be incomplete.
- ///
- /// See [computeErrors].
- AnalysisErrorInfo getErrors(Source source);
-
- /// Return the sources for the HTML files that reference the compilation unit
- /// with the given [source]. If the source does not represent a Dart source or
- /// is not known to this context, the returned list will be empty. The contents
- /// of the list can be incomplete.
- List<Source> getHtmlFilesReferencing(Source source);
-
- /// Return the kind of the given [source], or `null` if the kind is not known
- /// to this context.
- ///
- /// See [computeKindOf].
- SourceKind getKindOf(Source source);
-
- /// Return the sources for the defining compilation units of any libraries of
- /// which the given [source] is a part. The list will normally contain a single
- /// library because most Dart sources are only included in a single library,
- /// but it is possible to have a part that is contained in multiple identically
- /// named libraries. If the source represents the defining compilation unit of
- /// a library, then the returned list will contain the given source as its only
- /// element. If the source does not represent a Dart source or is not known to
- /// this context, the returned list will be empty. The contents of the list can
- /// be incomplete.
- List<Source> getLibrariesContaining(Source source);
-
- /// Return the sources for the defining compilation units of any libraries that
- /// depend on the library defined by the given [librarySource]. One library
- /// depends on another if it either imports or exports that library.
- List<Source> getLibrariesDependingOn(Source librarySource);
-
- /// Return the sources for the defining compilation units of any libraries that
- /// are referenced from the HTML file defined by the given [htmlSource].
- List<Source> getLibrariesReferencedFromHtml(Source htmlSource);
-
- /// Return the element model corresponding to the library defined by the given
- /// [source], or `null` if the element model does not currently exist or if the
- /// library cannot be analyzed for some reason.
- LibraryElement getLibraryElement(Source source);
-
- /// Return the line information for the given [source], or `null` if the line
- /// information is not known. The line information is used to map offsets from
- /// the beginning of the source to line and column pairs.
- ///
- /// See [computeLineInfo].
- LineInfo getLineInfo(Source source);
-
- /// Return the modification stamp for the [source], or a negative value if the
- /// source does not exist. A modification stamp is a non-negative integer with
- /// the property that if the contents of the source have not been modified
- /// since the last time the modification stamp was accessed then the same value
- /// will be returned, but if the contents of the source have been modified one
- /// or more times (even if the net change is zero) the stamps will be different.
- ///
- /// This method should be used rather than the method
- /// [Source.getModificationStamp] because contexts can have local overrides of
- /// the content of a source that the source is not aware of.
- int getModificationStamp(Source source);
-
- /// Return a fully resolved AST for the compilation unit defined by the given
- /// [unitSource] within the given [library], or `null` if the resolved AST is
- /// not already computed.
- ///
- /// See [resolveCompilationUnit].
- CompilationUnit getResolvedCompilationUnit(
- Source unitSource, LibraryElement library);
-
- /// Return a fully resolved AST for the compilation unit defined by the given
- /// [unitSource] within the library defined by the given [librarySource], or
- /// `null` if the resolved AST is not already computed.
- ///
- /// See [resolveCompilationUnit2].
- CompilationUnit getResolvedCompilationUnit2(
- Source unitSource, Source librarySource);
-
- /// Return a list of the sources being analyzed in this context whose full path
- /// is equal to the given [path].
- List<Source> getSourcesWithFullName(String path);
-
- /// Invalidates hints in the given [librarySource] and included parts.
- void invalidateLibraryHints(Source librarySource);
-
- /// Return `true` if the given [librarySource] is known to be the defining
- /// compilation unit of a library that can be run on a client (references
- /// 'dart:html', either directly or indirectly).
- ///
- /// <b>Note:</b> In addition to the expected case of returning `false` if the
- /// source is known to be a library that cannot be run on a client, this method
- /// will also return `false` if the source is not known to be a library or if
- /// we do not know whether it can be run on a client.
- bool isClientLibrary(Source librarySource);
-
- /// Return `true` if the given [librarySource] is known to be the defining
- /// compilation unit of a library that can be run on the server (does not
- /// reference 'dart:html', either directly or indirectly).
- ///
- /// <b>Note:</b> In addition to the expected case of returning `false` if the
- /// source is known to be a library that cannot be run on the server, this
- /// method will also return `false` if the source is not known to be a library
- /// or if we do not know whether it can be run on the server.
- bool isServerLibrary(Source librarySource);
-
- /// Parse the content of the given [source] to produce an AST structure. The
- /// resulting AST structure may or may not be resolved, and may have a slightly
- /// different structure depending upon whether it is resolved.
- ///
- /// Throws an [AnalysisException] if the analysis could not be performed
- ///
- /// <b>Note:</b> This method cannot be used in an async environment.
- CompilationUnit parseCompilationUnit(Source source);
-
- /// Perform the next unit of work required to keep the analysis results
- /// up-to-date and return information about the consequent changes to the
- /// analysis results. This method can be long running.
- ///
- /// The implementation that uses the task model notifies subscribers of
- /// [onResultChanged] about computed results.
- ///
- /// The following results are computed for Dart sources.
- ///
- /// 1. For explicit and implicit sources:
- /// [PARSED_UNIT]
- /// [RESOLVED_UNIT]
- ///
- /// 2. For explicit sources:
- /// [DART_ERRORS].
- ///
- /// 3. For explicit and implicit library sources:
- /// [LIBRARY_ELEMENT].
- AnalysisResult performAnalysisTask();
-
- /// Remove the given [listener] from the list of objects that are to be
- /// notified when various analysis results are produced in this context.
- void removeListener(AnalysisListener listener);
-
- /// Return a fully resolved AST for the compilation unit defined by the given
- /// [unitSource] within the given [library].
- ///
- /// Throws an [AnalysisException] if the analysis could not be performed.
- ///
- /// <b>Note:</b> This method cannot be used in an async environment.
- ///
- /// See [getResolvedCompilationUnit].
- CompilationUnit resolveCompilationUnit(
- Source unitSource, LibraryElement library);
-
- /// Return a fully resolved AST for the compilation unit defined by the given
- /// [unitSource] within the library defined by the given [librarySource].
- ///
- /// Throws an [AnalysisException] if the analysis could not be performed.
- ///
- /// <b>Note:</b> This method cannot be used in an async environment.
- ///
- /// See [getResolvedCompilationUnit2].
- CompilationUnit resolveCompilationUnit2(
- Source unitSource, Source librarySource);
-
- /// Set the contents of the given [source] to the given [contents] and mark the
- /// source as having changed. The additional [offset] and [length] information
- /// is used by the context to determine what reanalysis is necessary.
- void setChangedContents(
- Source source, String contents, int offset, int oldLength, int newLength);
-
- /// Set the contents of the given [source] to the given [contents] and mark the
- /// source as having changed. This has the effect of overriding the default
- /// contents of the source. If the contents are `null` the override is removed
- /// so that the default contents will be returned.
- void setContents(Source source, String contents);
-}
-
-/// A representation of changes to the types of analysis that should be
-/// performed.
-class AnalysisDelta {
- /// A mapping from source to what type of analysis should be performed on that
- /// source.
- Map<Source, AnalysisLevel> _analysisMap =
- new HashMap<Source, AnalysisLevel>();
-
- /// Return a collection of the sources that have been added. This is equivalent
- /// to calling [getAnalysisLevels] and collecting all sources that do not have
- /// an analysis level of [AnalysisLevel.NONE].
- List<Source> get addedSources {
- List<Source> result = new List<Source>();
- _analysisMap.forEach((Source source, AnalysisLevel level) {
- if (level != AnalysisLevel.NONE) {
- result.add(source);
- }
- });
- return result;
- }
-
- /// Return a mapping of sources to the level of analysis that should be
- /// performed.
- Map<Source, AnalysisLevel> get analysisLevels => _analysisMap;
-
- /// Record that the given [source] should be analyzed at the given [level].
- void setAnalysisLevel(Source source, AnalysisLevel level) {
- _analysisMap[source] = level;
- }
-
- @override
- String toString() {
- StringBuffer buffer = new StringBuffer();
- bool needsSeparator = _appendSources(buffer, false, AnalysisLevel.ALL);
- needsSeparator =
- _appendSources(buffer, needsSeparator, AnalysisLevel.RESOLVED);
- _appendSources(buffer, needsSeparator, AnalysisLevel.NONE);
- return buffer.toString();
- }
-
- /// Append to the given [buffer] all sources with the given analysis [level],
- /// prefixed with a label and a separator if [needsSeparator] is `true`.
- bool _appendSources(
- StringBuffer buffer, bool needsSeparator, AnalysisLevel level) {
- bool first = true;
- _analysisMap.forEach((Source source, AnalysisLevel sourceLevel) {
- if (sourceLevel == level) {
- if (first) {
- first = false;
- if (needsSeparator) {
- buffer.write("; ");
- }
- buffer.write(level);
- buffer.write(" ");
- } else {
- buffer.write(", ");
- }
- buffer.write(source.fullName);
- }
- });
- return needsSeparator || !first;
- }
}
/// The entry point for the functionality provided by the analysis engine. There
@@ -662,79 +244,6 @@
AnalysisErrorInfoImpl(this.errors, this.lineInfo);
}
-/// The levels at which a source can be analyzed.
-class AnalysisLevel implements Comparable<AnalysisLevel> {
- /// Indicates a source should be fully analyzed.
- static const AnalysisLevel ALL = const AnalysisLevel('ALL', 0);
-
- /// Indicates a source should be resolved and that errors, warnings and hints
- /// are needed.
- static const AnalysisLevel ERRORS = const AnalysisLevel('ERRORS', 1);
-
- /// Indicates a source should be resolved, but that errors, warnings and hints
- /// are not needed.
- static const AnalysisLevel RESOLVED = const AnalysisLevel('RESOLVED', 2);
-
- /// Indicates a source is not of interest to the client.
- static const AnalysisLevel NONE = const AnalysisLevel('NONE', 3);
-
- static const List<AnalysisLevel> values = const [ALL, ERRORS, RESOLVED, NONE];
-
- /// The name of this analysis level.
- final String name;
-
- /// The ordinal value of the analysis level.
- final int ordinal;
-
- const AnalysisLevel(this.name, this.ordinal);
-
- @override
- int get hashCode => ordinal;
-
- @override
- int compareTo(AnalysisLevel other) => ordinal - other.ordinal;
-
- @override
- String toString() => name;
-}
-
-/// An object that is listening for results being produced by an analysis
-/// context.
-abstract class AnalysisListener {
- /// Reports that a task, described by the given [taskDescription] is about to
- /// be performed by the given [context].
- void aboutToPerformTask(AnalysisContext context, String taskDescription);
-
- /// Reports that the [errors] associated with the given [source] in the given
- /// [context] has been updated to the given errors. The [lineInfo] is the line
- /// information associated with the source.
- void computedErrors(AnalysisContext context, Source source,
- List<AnalysisError> errors, LineInfo lineInfo);
-
- /// Reports that the given [source] is no longer included in the set of sources
- /// that are being analyzed by the given analysis [context].
- void excludedSource(AnalysisContext context, Source source);
-
- /// Reports that the given [source] is now included in the set of sources that
- /// are being analyzed by the given analysis [context].
- void includedSource(AnalysisContext context, Source source);
-
- /// Reports that the given Dart [source] was parsed in the given [context],
- /// producing the given [unit].
- void parsedDart(AnalysisContext context, Source source, CompilationUnit unit);
-
- /// Reports that the given Dart [source] was resolved in the given [context].
- void resolvedDart(
- AnalysisContext context, Source source, CompilationUnit unit);
-}
-
-/// Futures returned by [AnalysisContext] for pending analysis results will
-/// complete with this error if it is determined that analysis results will
-/// never become available (e.g. because the requested source is not subject to
-/// analysis, or because the requested source is a part file which is not a part
-/// of any known library).
-class AnalysisNotScheduledError implements Exception {}
-
/// A set of analysis options used to control the behavior of an analysis
/// context.
abstract class AnalysisOptions {
@@ -1366,213 +875,6 @@
static bool _analyzeNoFunctionBodies(Source _) => false;
}
-///
-class AnalysisResult {
- /// The change notices associated with this result, or `null` if there were no
- /// changes and there is no more work to be done.
- final List<ChangeNotice> _notices;
-
- /// The number of milliseconds required to determine which task was to be
- /// performed.
- final int getTime;
-
- /// The name of the class of the task that was performed.
- final String taskClassName;
-
- /// The number of milliseconds required to perform the task.
- final int performTime;
-
- /// Initialize a newly created analysis result to have the given values. The
- /// [notices] is the change notices associated with this result. The [getTime]
- /// is the number of milliseconds required to determine which task was to be
- /// performed. The [taskClassName] is the name of the class of the task that
- /// was performed. The [performTime] is the number of milliseconds required to
- /// perform the task.
- AnalysisResult(
- this._notices, this.getTime, this.taskClassName, this.performTime);
-
- /// Return the change notices associated with this result, or `null` if there
- /// were no changes and there is no more work to be done.
- List<ChangeNotice> get changeNotices => _notices;
-
- /// Return `true` if there is more to be performed after the task that was
- /// performed.
- bool get hasMoreWork => _notices != null;
-}
-
-/// Statistics about cache consistency validation.
-class CacheConsistencyValidationStatistics {
- /// Number of sources which were changed, but the context was not notified
- /// about it, so this fact was detected only during cache consistency
- /// validation.
- int numOfChanged = 0;
-
- /// Number of sources which stopped existing, but the context was not notified
- /// about it, so this fact was detected only during cache consistency
- /// validation.
- int numOfRemoved = 0;
-
- /// Reset all counters.
- void reset() {
- numOfChanged = 0;
- numOfRemoved = 0;
- }
-}
-
-/// Interface for cache consistency validation in an [InternalAnalysisContext].
-abstract class CacheConsistencyValidator {
- /// Return sources for which the contexts needs to know modification times.
- List<Source> getSourcesToComputeModificationTimes();
-
- /// Notify the validator that modification [times] were computed for [sources].
- /// If a source does not exist, its modification time is `-1`.
- ///
- /// It's up to the validator and the context how to use this information,
- /// the list of sources the context has might have been changed since the
- /// previous invocation of [getSourcesToComputeModificationTimes].
- ///
- /// Check the cache for any invalid entries (entries whose modification time
- /// does not match the modification time of the source associated with the
- /// entry). Invalid entries will be marked as invalid so that the source will
- /// be re-analyzed. Return `true` if at least one entry was invalid.
- bool sourceModificationTimesComputed(List<Source> sources, List<int> times);
-}
-
-/// The possible states of cached data.
-class CacheState implements Comparable<CacheState> {
- /// The data is not in the cache and the last time an attempt was made to
- /// compute the data an exception occurred, making it pointless to attempt to
- /// compute the data again.
- ///
- /// Valid Transitions:
- /// * [INVALID] if a source was modified that might cause the data to be
- /// computable
- static const CacheState ERROR = const CacheState('ERROR', 0);
-
- /// The data is not in the cache because it was flushed from the cache in order
- /// to control memory usage. If the data is recomputed, results do not need to
- /// be reported.
- ///
- /// Valid Transitions:
- /// * [IN_PROCESS] if the data is being recomputed
- /// * [INVALID] if a source was modified that causes the data to need to be
- /// recomputed
- static const CacheState FLUSHED = const CacheState('FLUSHED', 1);
-
- /// The data might or might not be in the cache but is in the process of being
- /// recomputed.
- ///
- /// Valid Transitions:
- /// * [ERROR] if an exception occurred while trying to compute the data
- /// * [VALID] if the data was successfully computed and stored in the cache
- static const CacheState IN_PROCESS = const CacheState('IN_PROCESS', 2);
-
- /// The data is not in the cache and needs to be recomputed so that results can
- /// be reported.
- ///
- /// Valid Transitions:
- /// * [IN_PROCESS] if an attempt is being made to recompute the data
- static const CacheState INVALID = const CacheState('INVALID', 3);
-
- /// The data is in the cache and up-to-date.
- ///
- /// Valid Transitions:
- /// * [FLUSHED] if the data is removed in order to manage memory usage
- /// * [INVALID] if a source was modified in such a way as to invalidate the
- /// previous data
- static const CacheState VALID = const CacheState('VALID', 4);
-
- static const List<CacheState> values = const [
- ERROR,
- FLUSHED,
- IN_PROCESS,
- INVALID,
- VALID
- ];
-
- /// The name of this cache state.
- final String name;
-
- /// The ordinal value of the cache state.
- final int ordinal;
-
- const CacheState(this.name, this.ordinal);
-
- @override
- int get hashCode => ordinal;
-
- @override
- int compareTo(CacheState other) => ordinal - other.ordinal;
-
- @override
- String toString() => name;
-}
-
-/// An object that represents a change to the analysis results associated with a
-/// given source.
-abstract class ChangeNotice implements AnalysisErrorInfo {
- /// The parsed, but maybe not resolved Dart AST that changed as a result of
- /// the analysis, or `null` if the AST was not changed.
- CompilationUnit get parsedDartUnit;
-
- /// The fully resolved Dart AST that changed as a result of the analysis, or
- /// `null` if the AST was not changed.
- CompilationUnit get resolvedDartUnit;
-
- /// Return the source for which the result is being reported.
- Source get source;
-}
-
-/// An implementation of a [ChangeNotice].
-class ChangeNoticeImpl implements ChangeNotice {
- /// The source for which the result is being reported.
- @override
- final Source source;
-
- /// The parsed, but maybe not resolved Dart AST that changed as a result of
- /// the analysis, or `null` if the AST was not changed.
- @override
- CompilationUnit parsedDartUnit;
-
- /// The fully resolved Dart AST that changed as a result of the analysis, or
- /// `null` if the AST was not changed.
- @override
- CompilationUnit resolvedDartUnit;
-
- /// The errors that changed as a result of the analysis, or `null` if errors
- /// were not changed.
- List<AnalysisError> _errors;
-
- /// The line information associated with the source, or `null` if errors were
- /// not changed.
- LineInfo _lineInfo;
-
- /// Initialize a newly created notice associated with the given source.
- ///
- /// @param source the source for which the change is being reported
- ChangeNoticeImpl(this.source);
-
- @override
- List<AnalysisError> get errors => _errors;
-
- @override
- LineInfo get lineInfo => _lineInfo;
-
- /// Set the errors that changed as a result of the analysis to the given
- /// [errors] and set the line information to the given [lineInfo].
- void setErrors(List<AnalysisError> errors, LineInfo lineInfo) {
- this._errors = errors;
- this._lineInfo = lineInfo;
- if (lineInfo == null) {
- AnalysisEngine.instance.logger.logInformation("No line info: $source",
- new CaughtException(new AnalysisException(), null));
- }
- }
-
- @override
- String toString() => "Changes for ${source.fullName}";
-}
-
/// An indication of which sources have been added, changed, removed, or deleted.
/// In the case of a changed source, there are multiple ways of indicating the
/// nature of the change.
@@ -1760,131 +1062,11 @@
this.contents, this.offset, this.oldLength, this.newLength);
}
-/// An event indicating when a source either starts or stops being implicitly
-/// analyzed.
-class ImplicitAnalysisEvent {
- /// The source whose status has changed.
- final Source source;
-
- /// A flag indicating whether the source is now being analyzed.
- final bool isAnalyzed;
-
- /// Initialize a newly created event to indicate that the given [source] has
- /// changed it status to match the [isAnalyzed] flag.
- ImplicitAnalysisEvent(this.source, this.isAnalyzed);
-
- @override
- String toString() =>
- '${isAnalyzed ? '' : 'not '}analyzing ${source.fullName}';
-}
-
/// Additional behavior for an analysis context that is required by internal
/// users of the context.
abstract class InternalAnalysisContext implements AnalysisContext {
- /// A table mapping the sources known to the context to the information known
- /// about the source.
- AnalysisCache get analysisCache;
-
- /// The cache consistency validator for this context.
- CacheConsistencyValidator get cacheConsistencyValidator;
-
- /// Allow the client to supply its own content cache. This will take the
- /// place of the content cache created by default, allowing clients to share
- /// the content cache between contexts.
- set contentCache(ContentCache value);
-
- /// Get the [EmbedderYamlLocator] for this context.
- @deprecated
- EmbedderYamlLocator get embedderYamlLocator;
-
- /// Return a list of the explicit targets being analyzed by this context.
- List<AnalysisTarget> get explicitTargets;
-
- /// Return `true` if the context is active, i.e. is being analyzed now.
- bool get isActive;
-
- /// Specify whether the context is active, i.e. is being analyzed now.
- set isActive(bool value);
-
- /// Return a list containing all of the sources that have been marked as
- /// priority sources. Clients must not modify the returned list.
- List<Source> get prioritySources;
-
- /// Return a list of the priority targets being analyzed by this context.
- List<AnalysisTarget> get priorityTargets;
-
- /// The partition that contains analysis results that are not shared with other
- /// contexts.
- CachePartition get privateAnalysisCachePartition;
-
/// Sets the [TypeProvider] for this context.
void set typeProvider(TypeProvider typeProvider);
-
- /// Return a list containing the sources of the libraries that are exported by
- /// the library with the given [source]. The list will be empty if the given
- /// source is invalid, if the given source does not represent a library, or if
- /// the library does not export any other libraries.
- ///
- /// Throws an [AnalysisException] if the exported libraries could not be
- /// computed.
- List<Source> computeExportedLibraries(Source source);
-
- /// Return a list containing the sources of the libraries that are imported by
- /// the library with the given [source]. The list will be empty if the given
- /// source is invalid, if the given source does not represent a library, or if
- /// the library does not import any other libraries.
- ///
- /// Throws an [AnalysisException] if the imported libraries could not be
- /// computed.
- List<Source> computeImportedLibraries(Source source);
-
- /// Return all the resolved [CompilationUnit]s for the given [source] if not
- /// flushed, otherwise return `null` and ensures that the [CompilationUnit]s
- /// will be eventually returned to the client from [performAnalysisTask].
- List<CompilationUnit> ensureResolvedDartUnits(Source source);
-
- /// Return context that owns the given [source].
- InternalAnalysisContext getContextFor(Source source);
-
- /// Return a change notice for the given [source], creating one if one does not
- /// already exist.
- ChangeNoticeImpl getNotice(Source source);
-
- /// Return a namespace containing mappings for all of the public names defined
- /// by the given [library].
- Namespace getPublicNamespace(LibraryElement library);
-
- /// Respond to a change which has been made to the given [source] file.
- /// [originalContents] is the former contents of the file, and [newContents]
- /// is the updated contents. If [notify] is true, a source changed event is
- /// triggered.
- ///
- /// Normally it should not be necessary for clients to call this function,
- /// since it will be automatically invoked in response to a call to
- /// [applyChanges] or [setContents]. However, if this analysis context is
- /// sharing its content cache with other contexts, then the client must
- /// manually update the content cache and call this function for each context.
- ///
- /// Return `true` if the change was significant to this context (i.e. [source]
- /// is either implicitly or explicitly analyzed by this context, and a change
- /// actually occurred).
- bool handleContentsChanged(
- Source source, String originalContents, String newContents, bool notify);
-
- /// Given an [elementMap] mapping the source for the libraries represented by
- /// the corresponding elements to the elements representing the libraries,
- /// record those mappings.
- void recordLibraryElements(Map<Source, LibraryElement> elementMap);
-
- /// Return `true` if errors should be produced for the given [source].
- bool shouldErrorsBeAnalyzed(Source source);
-
- /// For testing only: flush all representations of the AST (both resolved and
- /// unresolved) for the given [source] out of the cache.
- void test_flushAstStructures(Source source);
-
- /// Visit all entries of the content cache.
- void visitContentCache(ContentCacheVisitor visitor);
}
/// An object that can be used to receive information about errors within the
@@ -1916,25 +1098,6 @@
void logInformation(String message, [CaughtException exception]) {}
}
-/// An exception created when an analysis attempt fails because a source was
-/// deleted between the time the analysis started and the time the results of the
-/// analysis were ready to be recorded.
-class ObsoleteSourceAnalysisException extends AnalysisException {
- /// The source that was removed while it was being analyzed.
- Source _source;
-
- /// Initialize a newly created exception to represent the removal of the given
- /// [source].
- ObsoleteSourceAnalysisException(Source source)
- : super(
- "The source '${source.fullName}' was removed while it was being analyzed") {
- this._source = source;
- }
-
- /// Return the source that was removed while it was being analyzed.
- Source get source => _source;
-}
-
/// Container with global [AnalysisContext] performance statistics.
class PerformanceStatistics {
/// The [PerformanceTag] for `package:analyzer`.
@@ -1969,143 +1132,4 @@
/// The [PerformanceTag] for time spent in summaries support.
static PerformanceTag summary = analyzer.createChild('summary');
-
- /// Statistics about cache consistency validation.
- static final CacheConsistencyValidationStatistics
- cacheConsistencyValidationStatistics =
- new CacheConsistencyValidationStatistics();
-}
-
-/// An visitor that removes any resolution information from an AST structure when
-/// used to visit that structure.
-class ResolutionEraser extends GeneralizingAstVisitor<void> {
- /// A flag indicating whether the elements associated with declarations should
- /// be erased.
- bool eraseDeclarations = true;
-
- @override
- void visitAssignmentExpression(AssignmentExpression node) {
- node.staticElement = null;
- super.visitAssignmentExpression(node);
- }
-
- @override
- void visitBinaryExpression(BinaryExpression node) {
- node.staticElement = null;
- super.visitBinaryExpression(node);
- }
-
- @override
- void visitBreakStatement(BreakStatement node) {
- node.target = null;
- super.visitBreakStatement(node);
- }
-
- @override
- void visitCompilationUnit(CompilationUnit node) {
- if (eraseDeclarations) {
- node.element = null;
- }
- super.visitCompilationUnit(node);
- }
-
- @override
- void visitConstructorDeclaration(ConstructorDeclaration node) {
- if (eraseDeclarations) {
- (node as ConstructorDeclarationImpl).declaredElement = null;
- }
- super.visitConstructorDeclaration(node);
- }
-
- @override
- void visitConstructorName(ConstructorName node) {
- node.staticElement = null;
- super.visitConstructorName(node);
- }
-
- @override
- void visitContinueStatement(ContinueStatement node) {
- node.target = null;
- super.visitContinueStatement(node);
- }
-
- @override
- void visitDirective(Directive node) {
- if (eraseDeclarations) {
- node.element = null;
- }
- super.visitDirective(node);
- }
-
- @override
- void visitExpression(Expression node) {
- node.staticType = null;
- super.visitExpression(node);
- }
-
- @override
- void visitFunctionExpression(FunctionExpression node) {
- if (eraseDeclarations) {
- (node as FunctionExpressionImpl).declaredElement = null;
- }
- super.visitFunctionExpression(node);
- }
-
- @override
- void visitFunctionExpressionInvocation(FunctionExpressionInvocation node) {
- node.staticElement = null;
- super.visitFunctionExpressionInvocation(node);
- }
-
- @override
- void visitIndexExpression(IndexExpression node) {
- node.staticElement = null;
- super.visitIndexExpression(node);
- }
-
- @override
- void visitInstanceCreationExpression(InstanceCreationExpression node) {
- node.staticElement = null;
- super.visitInstanceCreationExpression(node);
- }
-
- @override
- void visitPostfixExpression(PostfixExpression node) {
- node.staticElement = null;
- super.visitPostfixExpression(node);
- }
-
- @override
- void visitPrefixExpression(PrefixExpression node) {
- node.staticElement = null;
- super.visitPrefixExpression(node);
- }
-
- @override
- void visitRedirectingConstructorInvocation(
- RedirectingConstructorInvocation node) {
- node.staticElement = null;
- super.visitRedirectingConstructorInvocation(node);
- }
-
- @override
- void visitSimpleIdentifier(SimpleIdentifier node) {
- if (eraseDeclarations || !node.inDeclarationContext()) {
- node.staticElement = null;
- }
- super.visitSimpleIdentifier(node);
- }
-
- @override
- void visitSuperConstructorInvocation(SuperConstructorInvocation node) {
- node.staticElement = null;
- super.visitSuperConstructorInvocation(node);
- }
-
- /// Remove any resolution information from the given AST structure.
- static void erase(AstNode node, {bool eraseDeclarations: true}) {
- ResolutionEraser eraser = new ResolutionEraser();
- eraser.eraseDeclarations = eraseDeclarations;
- node.accept(eraser);
- }
}
diff --git a/pkg/analyzer/lib/src/generated/error_verifier.dart b/pkg/analyzer/lib/src/generated/error_verifier.dart
index 3b1fd26..566e931 100644
--- a/pkg/analyzer/lib/src/generated/error_verifier.dart
+++ b/pkg/analyzer/lib/src/generated/error_verifier.dart
@@ -996,8 +996,7 @@
@override
void visitIndexExpression(IndexExpression node) {
_checkForArgumentTypeNotAssignableForArgument(node.index);
- if (node.leftBracket.type !=
- TokenType.QUESTION_PERIOD_OPEN_SQUARE_BRACKET) {
+ if (!node.isNullAware) {
_checkForNullableDereference(node.target);
}
super.visitIndexExpression(node);
@@ -1106,7 +1105,7 @@
_typeArgumentsVerifier.checkMethodInvocation(node);
_checkForNullableDereference(methodName);
_requiredParametersVerifier.visitMethodInvocation(node);
- if (node.operator?.type != TokenType.QUESTION_PERIOD &&
+ if (!node.isNullAware &&
methodName.name != 'toString' &&
methodName.name != 'noSuchMethod') {
_checkForNullableDereference(target);
@@ -1219,7 +1218,7 @@
_checkForStaticAccessToInstanceMember(typeReference, propertyName);
_checkForInstanceAccessToStaticMember(
typeReference, node.target, propertyName);
- if (node.operator?.type != TokenType.QUESTION_PERIOD &&
+ if (!node.isNullAware &&
!_objectPropertyNames.contains(propertyName.name)) {
_checkForNullableDereference(node.target);
}
@@ -2245,7 +2244,7 @@
if (_enclosingClass == null) {
return;
}
- InterfaceType enclosingType = _enclosingClass.type;
+ InterfaceType enclosingType = _enclosingClass.thisType;
Uri libraryUri = _currentLibrary.source.uri;
// method declared in the enclosing class vs. inherited getter/setter
@@ -2329,7 +2328,7 @@
visitedClasses.removeLast();
}
- visit(_enclosingClass.type);
+ visit(_enclosingClass.thisType);
}
/**
@@ -2726,9 +2725,6 @@
} else if (parent is ForElement) {
awaitKeyword = parent.awaitKeyword;
}
- DartType loopType = awaitKeyword != null
- ? _typeProvider.streamType
- : _typeProvider.iterableType;
// Use an explicit string instead of [loopType] to remove the "<E>".
String loopTypeName = awaitKeyword != null ? "Stream" : "Iterable";
@@ -2737,13 +2733,23 @@
// is assignable to the variable's type.
// TODO(rnystrom): Move this into mostSpecificTypeArgument()?
iterableType = iterableType.resolveToBound(_typeProvider.objectType);
- DartType bestIterableType =
- _typeSystem.mostSpecificTypeArgument(iterableType, loopType);
+
+ ClassElement sequenceElement = awaitKeyword != null
+ ? _typeProvider.streamElement
+ : _typeProvider.iterableElement;
+
+ DartType bestIterableType;
+ if (iterableType is InterfaceTypeImpl) {
+ var sequenceType = iterableType.asInstanceOf(sequenceElement);
+ if (sequenceType != null) {
+ bestIterableType = sequenceType.typeArguments[0];
+ }
+ }
// Allow it to be a supertype of Iterable<T> (basically just Object) and do
// an implicit downcast to Iterable<dynamic>.
if (bestIterableType == null) {
- if (_typeSystem.isSubtypeOf(loopType, iterableType)) {
+ if (iterableType == _typeProvider.objectType) {
bestIterableType = DynamicTypeImpl.instance;
}
}
@@ -3906,7 +3912,7 @@
return false;
}
- InterfaceTypeImpl enclosingType = _enclosingClass.type;
+ InterfaceTypeImpl enclosingType = _enclosingClass.thisType;
Uri mixinLibraryUri = mixinElement.librarySource.uri;
for (var name in mixinElementImpl.superInvokedNames) {
var nameObject = new Name(mixinLibraryUri, name);
@@ -4782,9 +4788,8 @@
}
}
if (!expectedType.isVoid && !fromType.isVoid) {
- var checkWithType = (!_inAsync)
- ? fromType
- : _typeProvider.futureType.instantiate(<DartType>[fromType]);
+ var checkWithType =
+ !_inAsync ? fromType : _typeProvider.futureType2(fromType);
if (_typeSystem.isAssignableTo(checkWithType, expectedType,
featureSet: _featureSet)) {
return;
@@ -5074,10 +5079,24 @@
if (element is ExecutableElement && !element.isStatic) {
return;
}
- _errorReporter.reportErrorForNode(
- StaticTypeWarningCode.UNQUALIFIED_REFERENCE_TO_NON_LOCAL_STATIC_MEMBER,
- name,
- [enclosingElement.name]);
+ if (element is MethodElement) {
+ // Invalid methods are reported in
+ // [MethodInvocationResolver._resolveReceiverNull].
+ return;
+ }
+ if (_enclosingExtension != null) {
+ _errorReporter.reportErrorForNode(
+ CompileTimeErrorCode
+ .UNQUALIFIED_REFERENCE_TO_STATIC_MEMBER_OF_EXTENDED_TYPE,
+ name,
+ [enclosingElement.displayName]);
+ } else {
+ _errorReporter.reportErrorForNode(
+ StaticTypeWarningCode
+ .UNQUALIFIED_REFERENCE_TO_NON_LOCAL_STATIC_MEMBER,
+ name,
+ [enclosingElement.displayName]);
+ }
}
/**
@@ -5311,11 +5330,9 @@
if (isYieldEach) {
impliedReturnType = staticYieldedType;
} else if (_enclosingFunction.isAsynchronous) {
- impliedReturnType =
- _typeProvider.streamType.instantiate(<DartType>[staticYieldedType]);
+ impliedReturnType = _typeProvider.streamType2(staticYieldedType);
} else {
- impliedReturnType =
- _typeProvider.iterableType.instantiate(<DartType>[staticYieldedType]);
+ impliedReturnType = _typeProvider.iterableType2(staticYieldedType);
}
if (!_checkForAssignableExpressionAtType(yieldExpression, impliedReturnType,
declaredReturnType, StaticTypeWarningCode.YIELD_OF_INVALID_TYPE)) {
@@ -5375,7 +5392,7 @@
return;
}
ClassElement classElement = node.declaredElement;
- var type = classElement.type;
+ var type = classElement.thisType;
var supertype = classElement.supertype;
List<InterfaceType> supertypesForMixinInference = <InterfaceType>[];
ClassElementImpl.collectAllSupertypes(
diff --git a/pkg/analyzer/lib/src/generated/resolver.dart b/pkg/analyzer/lib/src/generated/resolver.dart
index 3f2e838..2f1a57f 100644
--- a/pkg/analyzer/lib/src/generated/resolver.dart
+++ b/pkg/analyzer/lib/src/generated/resolver.dart
@@ -10,6 +10,7 @@
import 'package:analyzer/dart/ast/token.dart';
import 'package:analyzer/dart/ast/visitor.dart';
import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/dart/element/nullability_suffix.dart';
import 'package:analyzer/dart/element/type.dart';
import 'package:analyzer/error/error.dart';
import 'package:analyzer/error/listener.dart';
@@ -91,6 +92,9 @@
/// Is `true` if NNBD is enabled for the library being analyzed.
final bool _isNonNullable;
+ /// True if inference failures should be reported, otherwise false.
+ final bool _strictInference;
+
/// Create a new instance of the [BestPracticesVerifier].
///
/// @param errorReporter the error reporter
@@ -108,6 +112,8 @@
}) : _nullType = typeProvider.nullType,
_typeSystem = typeSystem ?? new Dart2TypeSystem(typeProvider),
_isNonNullable = unit.featureSet.isEnabled(Feature.non_nullable),
+ _strictInference =
+ (analysisOptions as AnalysisOptionsImpl).strictInference,
_inheritanceManager = inheritanceManager,
_invalidAccessVerifier =
new _InvalidAccessVerifier(_errorReporter, _currentLibrary) {
@@ -305,6 +311,11 @@
try {
_checkForMissingReturn(
node.returnType, node.functionExpression.body, element, node);
+
+ // Return types are inferred only on non-recursive local functions.
+ if (node.parent is CompilationUnit) {
+ _checkStrictInferenceReturnType(node.returnType, node, node.name.name);
+ }
super.visitFunctionDeclaration(node);
} finally {
_inDeprecatedMember = wasInDeprecatedMember;
@@ -312,6 +323,13 @@
}
@override
+ void visitFunctionDeclarationStatement(FunctionDeclarationStatement node) {
+ // TODO(srawlins): Check strict-inference return type on recursive
+ // local functions.
+ super.visitFunctionDeclarationStatement(node);
+ }
+
+ @override
void visitFunctionExpression(FunctionExpression node) {
if (node.parent is! FunctionDeclaration) {
_checkForMissingReturn(null, node.body, node.declaredElement, node);
@@ -320,6 +338,13 @@
}
@override
+ void visitFunctionTypedFormalParameter(FunctionTypedFormalParameter node) {
+ _checkStrictInferenceReturnType(
+ node.returnType, node, node.identifier.name);
+ super.visitFunctionTypedFormalParameter(node);
+ }
+
+ @override
void visitImportDirective(ImportDirective node) {
_checkForDeprecatedMemberUse(node.uriElement, node);
ImportElement importElement = node.element;
@@ -360,6 +385,7 @@
//checkForOverridingPrivateMember(node);
_checkForMissingReturn(node.returnType, node.body, element, node);
_checkForUnnecessaryNoSuchMethod(node);
+ _checkStrictInferenceReturnType(node.returnType, node, node.name.name);
super.visitMethodDeclaration(node);
} finally {
_inDeprecatedMember = wasInDeprecatedMember;
@@ -934,7 +960,7 @@
// CAN_BE_NULL_AFTER_NULL_AWARE
if (parent is MethodInvocation &&
- parent.operator.type != TokenType.QUESTION_PERIOD &&
+ !parent.isNullAware &&
_nullType.lookUpMethod(parent.methodName.name, _currentLibrary) ==
null) {
_errorReporter.reportErrorForNode(
@@ -942,7 +968,7 @@
return;
}
if (parent is PropertyAccess &&
- parent.operator.type != TokenType.QUESTION_PERIOD &&
+ !parent.isNullAware &&
_nullType.lookUpGetter(parent.propertyName.name, _currentLibrary) ==
null) {
_errorReporter.reportErrorForNode(
@@ -1056,7 +1082,7 @@
Element classElement = methodElement?.enclosingElement;
return methodElement is MethodElement &&
classElement is ClassElement &&
- !classElement.type.isObject;
+ !classElement.isDartCoreObject;
}
}
return false;
@@ -1110,6 +1136,20 @@
}
}
+ /// In "strict-inference" mode, check that [returnNode]'s return type is specified.
+ void _checkStrictInferenceReturnType(
+ AstNode returnType, AstNode reportNode, String displayName) {
+ if (!_strictInference) {
+ return;
+ }
+ if (returnType == null) {
+ _errorReporter.reportErrorForNode(
+ HintCode.INFERENCE_FAILURE_ON_FUNCTION_RETURN_TYPE,
+ reportNode,
+ [displayName]);
+ }
+ }
+
bool _isLibraryInWorkspacePackage(LibraryElement library) {
if (_workspacePackage == null || library == null) {
// Better to not make a big claim that they _are_ in the same package,
@@ -2246,95 +2286,6 @@
}
}
-/// Instances of the class `EnumMemberBuilder` build the members in enum
-/// declarations.
-class EnumMemberBuilder extends RecursiveAstVisitor<void> {
- /// The type provider used to access the types needed to build an element
- /// model for enum declarations.
- final TypeProvider _typeProvider;
-
- /// Initialize a newly created enum member builder.
- ///
- /// @param typeProvider the type provider used to access the types needed to
- /// build an element model for enum declarations
- EnumMemberBuilder(this._typeProvider);
-
- @override
- void visitEnumDeclaration(EnumDeclaration node) {
- //
- // Finish building the enum.
- //
- EnumElementImpl enumElement = node.name.staticElement as EnumElementImpl;
- InterfaceType enumType = enumElement.type;
- //
- // Populate the fields.
- //
- List<FieldElement> fields = new List<FieldElement>();
- List<PropertyAccessorElement> getters = new List<PropertyAccessorElement>();
- InterfaceType intType = _typeProvider.intType;
- String indexFieldName = "index";
- FieldElementImpl indexField = new FieldElementImpl(indexFieldName, -1);
- indexField.isFinal = true;
- indexField.isSynthetic = true;
- indexField.type = intType;
- fields.add(indexField);
- getters.add(_createGetter(indexField));
- ConstFieldElementImpl valuesField = new ConstFieldElementImpl("values", -1);
- valuesField.isStatic = true;
- valuesField.isConst = true;
- valuesField.isSynthetic = true;
- valuesField.type = _typeProvider.listType.instantiate(<DartType>[enumType]);
- fields.add(valuesField);
- getters.add(_createGetter(valuesField));
- //
- // Build the enum constants.
- //
- NodeList<EnumConstantDeclaration> constants = node.constants;
- List<DartObjectImpl> constantValues = new List<DartObjectImpl>();
- int constantCount = constants.length;
- for (int i = 0; i < constantCount; i++) {
- EnumConstantDeclaration constant = constants[i];
- FieldElementImpl constantField = constant.name.staticElement;
- //
- // Create a value for the constant.
- //
- Map<String, DartObjectImpl> fieldMap =
- new HashMap<String, DartObjectImpl>();
- fieldMap[indexFieldName] = new DartObjectImpl(intType, new IntState(i));
- DartObjectImpl value =
- new DartObjectImpl(enumType, new GenericState(fieldMap));
- constantValues.add(value);
- constantField.evaluationResult = new EvaluationResultImpl(value);
- fields.add(constantField);
- getters.add(constantField.getter);
- }
- //
- // Build the value of the 'values' field.
- //
- valuesField.evaluationResult = new EvaluationResultImpl(
- new DartObjectImpl(valuesField.type, new ListState(constantValues)));
- // Update toString() return type.
- {
- MethodElementImpl toStringMethod = enumElement.methods[0];
- toStringMethod.returnType = _typeProvider.stringType;
- toStringMethod.type = new FunctionTypeImpl(toStringMethod);
- }
- //
- // Finish building the enum.
- //
- enumElement.fields = fields;
- enumElement.accessors = getters;
- // Client code isn't allowed to invoke the constructor, so we do not model
- // it.
- super.visitEnumDeclaration(node);
- }
-
- /// Create a getter that corresponds to the given [field].
- PropertyAccessorElement _createGetter(FieldElementImpl field) {
- return new PropertyAccessorElementImpl_ImplicitGetter(field);
- }
-}
-
/// An [AstVisitor] that fills [UsedLocalElements].
class GatherUsedLocalElementsVisitor extends RecursiveAstVisitor {
final UsedLocalElements usedElements = new UsedLocalElements();
@@ -2715,7 +2666,7 @@
Scope outerScope = nameScope;
try {
enclosingClass = node.declaredElement;
- typeAnalyzer.thisType = enclosingClass?.type;
+ typeAnalyzer.thisType = enclosingClass?.thisType;
if (enclosingClass == null) {
AnalysisEngine.instance.logger.logInformation(
"Missing element for class declaration ${node.name.name} in ${definingLibrary.source.fullName}",
@@ -2735,7 +2686,7 @@
}
} finally {
nameScope = outerScope;
- typeAnalyzer.thisType = outerType?.type;
+ typeAnalyzer.thisType = outerType?.thisType;
enclosingClass = outerType;
_enclosingClassDeclaration = null;
}
@@ -2780,7 +2731,7 @@
@override
visitClassDeclaration(ClassDeclaration node) {
- _currentType = node.declaredElement.type;
+ _currentType = node.declaredElement.thisType;
super.visitClassDeclaration(node);
_currentType = null;
}
@@ -2831,7 +2782,7 @@
@override
visitMixinDeclaration(MixinDeclaration node) {
- _currentType = node.declaredElement.type;
+ _currentType = node.declaredElement.thisType;
super.visitMixinDeclaration(node);
_currentType = null;
}
@@ -2843,7 +2794,7 @@
}
}
-/// An AST visitor that is used to resolve the some of the nodes within a single
+/// An AST visitor that is used to resolve some of the nodes within a single
/// compilation unit. The nodes that are skipped are those that are within
/// function bodies.
class PartialResolverVisitor extends ResolverVisitor {
@@ -3008,7 +2959,7 @@
StaticTypeAnalyzer typeAnalyzer;
/// The type system in use during resolution.
- TypeSystem typeSystem;
+ Dart2TypeSystem typeSystem;
/// The class declaration representing the class containing the current node,
/// or `null` if the current node is not contained in a class.
@@ -3227,7 +3178,7 @@
}) {
_enclosingClassDeclaration = null;
enclosingClass = enclosingClassElement;
- typeAnalyzer.thisType = enclosingClass?.type;
+ typeAnalyzer.thisType = enclosingClass?.thisType;
_enclosingFunction = enclosingExecutableElement;
}
@@ -3235,7 +3186,7 @@
void prepareToResolveMembersInClass(ClassDeclaration node) {
_enclosingClassDeclaration = node;
enclosingClass = node.declaredElement;
- typeAnalyzer.thisType = enclosingClass?.type;
+ typeAnalyzer.thisType = enclosingClass?.thisType;
}
/// Visit the given [comment] if it is not `null`.
@@ -3495,12 +3446,12 @@
ClassElement outerType = enclosingClass;
try {
enclosingClass = node.declaredElement;
- typeAnalyzer.thisType = enclosingClass?.type;
+ typeAnalyzer.thisType = enclosingClass?.thisType;
super.visitClassDeclaration(node);
node.accept(elementResolver);
node.accept(typeAnalyzer);
} finally {
- typeAnalyzer.thisType = outerType?.type;
+ typeAnalyzer.thisType = outerType?.thisType;
enclosingClass = outerType;
_enclosingClassDeclaration = null;
}
@@ -3717,12 +3668,12 @@
ClassElement outerType = enclosingClass;
try {
enclosingClass = node.declaredElement;
- typeAnalyzer.thisType = enclosingClass?.type;
+ typeAnalyzer.thisType = enclosingClass?.thisType;
super.visitEnumDeclaration(node);
node.accept(elementResolver);
node.accept(typeAnalyzer);
} finally {
- typeAnalyzer.thisType = outerType?.type;
+ typeAnalyzer.thisType = outerType?.thisType;
enclosingClass = outerType;
_enclosingClassDeclaration = null;
}
@@ -3810,27 +3761,28 @@
Expression iterable = forLoopParts.iterable;
DeclaredIdentifier loopVariable;
DartType valueType;
+ Element identifierElement;
if (forLoopParts is ForEachPartsWithDeclaration) {
loopVariable = forLoopParts.loopVariable;
valueType = loopVariable?.type?.type ?? UnknownInferredType.instance;
} else if (forLoopParts is ForEachPartsWithIdentifier) {
SimpleIdentifier identifier = forLoopParts.identifier;
identifier?.accept(this);
- Element element = identifier?.staticElement;
- if (element is VariableElement) {
- valueType = element.type;
- } else if (element is PropertyAccessorElement) {
- if (element.parameters.isNotEmpty) {
- valueType = element.parameters[0].type;
+ identifierElement = identifier?.staticElement;
+ if (identifierElement is VariableElement) {
+ valueType = identifierElement.type;
+ } else if (identifierElement is PropertyAccessorElement) {
+ if (identifierElement.parameters.isNotEmpty) {
+ valueType = identifierElement.parameters[0].type;
}
}
}
if (valueType != null) {
InterfaceType targetType = (node.awaitKeyword == null)
- ? typeProvider.iterableType
- : typeProvider.streamType;
- InferenceContext.setType(iterable, targetType.instantiate([valueType]));
+ ? typeProvider.iterableType2(valueType)
+ : typeProvider.streamType2(valueType);
+ InferenceContext.setType(iterable, targetType);
}
//
// We visit the iterator before the loop variable because the loop
@@ -3840,7 +3792,10 @@
_flowAnalysis?.loopVariable(loopVariable);
loopVariable?.accept(this);
_flowAnalysis?.flow?.forEach_bodyBegin(
- _flowAnalysis.assignedVariables.writtenInNode(node));
+ _flowAnalysis.assignedVariables.writtenInNode(node),
+ identifierElement is VariableElement
+ ? identifierElement
+ : loopVariable.declaredElement);
node.body?.accept(this);
_flowAnalysis?.flow?.forEach_end();
@@ -3880,6 +3835,7 @@
Expression iterable = forLoopParts.iterable;
DeclaredIdentifier loopVariable;
SimpleIdentifier identifier;
+ Element identifierElement;
if (forLoopParts is ForEachPartsWithDeclaration) {
loopVariable = forLoopParts.loopVariable;
} else if (forLoopParts is ForEachPartsWithIdentifier) {
@@ -3893,20 +3849,20 @@
valueType = typeAnnotation?.type ?? UnknownInferredType.instance;
}
if (identifier != null) {
- Element element = identifier.staticElement;
- if (element is VariableElement) {
- valueType = element.type;
- } else if (element is PropertyAccessorElement) {
- if (element.parameters.isNotEmpty) {
- valueType = element.parameters[0].type;
+ identifierElement = identifier.staticElement;
+ if (identifierElement is VariableElement) {
+ valueType = identifierElement.type;
+ } else if (identifierElement is PropertyAccessorElement) {
+ if (identifierElement.parameters.isNotEmpty) {
+ valueType = identifierElement.parameters[0].type;
}
}
}
if (valueType != null) {
InterfaceType targetType = (node.awaitKeyword == null)
- ? typeProvider.iterableType
- : typeProvider.streamType;
- InferenceContext.setType(iterable, targetType.instantiate([valueType]));
+ ? typeProvider.iterableType2(valueType)
+ : typeProvider.streamType2(valueType);
+ InferenceContext.setType(iterable, targetType);
}
//
// We visit the iterator before the loop variable because the loop variable
@@ -3917,8 +3873,10 @@
loopVariable?.accept(this);
_flowAnalysis?.flow?.forEach_bodyBegin(
- _flowAnalysis.assignedVariables.writtenInNode(node),
- );
+ _flowAnalysis.assignedVariables.writtenInNode(node),
+ identifierElement is VariableElement
+ ? identifierElement
+ : loopVariable.declaredElement);
Statement body = node.body;
if (body != null) {
@@ -4124,7 +4082,7 @@
if (typeArguments.arguments.length == 1) {
DartType elementType = typeArguments.arguments[0].type;
if (!elementType.isDynamic) {
- listType = typeProvider.listType.instantiate([elementType]);
+ listType = typeProvider.listType2(elementType);
}
}
} else {
@@ -4132,8 +4090,7 @@
}
if (listType != null) {
DartType elementType = listType.typeArguments[0];
- DartType iterableType =
- typeProvider.iterableType.instantiate([elementType]);
+ DartType iterableType = typeProvider.iterableType2(elementType);
_pushCollectionTypesDownToAll(node.elements,
elementType: elementType, iterableType: iterableType);
InferenceContext.setType(node, listType);
@@ -4192,12 +4149,12 @@
ClassElement outerType = enclosingClass;
try {
enclosingClass = node.declaredElement;
- typeAnalyzer.thisType = enclosingClass?.type;
+ typeAnalyzer.thisType = enclosingClass?.thisType;
super.visitMixinDeclaration(node);
node.accept(elementResolver);
node.accept(typeAnalyzer);
} finally {
- typeAnalyzer.thisType = outerType?.type;
+ typeAnalyzer.thisType = outerType?.thisType;
enclosingClass = outerType;
_enclosingMixinDeclaration = null;
}
@@ -4300,7 +4257,7 @@
if (literalResolution.kind == _LiteralResolutionKind.set) {
if (typeArguments != null && typeArguments.length == 1) {
var elementType = typeArguments[0].type;
- literalType = typeProvider.setType.instantiate([elementType]);
+ literalType = typeProvider.setType2(elementType);
} else {
literalType = typeAnalyzer.inferSetTypeDownwards(
node, literalResolution.contextType);
@@ -4309,7 +4266,7 @@
if (typeArguments != null && typeArguments.length == 2) {
var keyType = typeArguments[0].type;
var valueType = typeArguments[1].type;
- literalType = typeProvider.mapType.instantiate([keyType, valueType]);
+ literalType = typeProvider.mapType2(keyType, valueType);
} else {
literalType = typeAnalyzer.inferMapTypeDownwards(
node, literalResolution.contextType);
@@ -4322,8 +4279,7 @@
List<DartType> typeArguments = literalType.typeArguments;
if (typeArguments.length == 1) {
DartType elementType = literalType.typeArguments[0];
- DartType iterableType =
- typeProvider.iterableType.instantiate([elementType]);
+ DartType iterableType = typeProvider.iterableType2(elementType);
_pushCollectionTypesDownToAll(node.elements,
elementType: elementType, iterableType: iterableType);
if (!_uiAsCodeEnabled &&
@@ -4561,10 +4517,9 @@
if (node.star != null) {
// If this is a yield*, then we wrap the element return type
// If it's synchronous, we expect Iterable<T>, otherwise Stream<T>
- InterfaceType wrapperType = _enclosingFunction.isSynchronous
- ? typeProvider.iterableType
- : typeProvider.streamType;
- type = wrapperType.instantiate(<DartType>[type]);
+ type = _enclosingFunction.isSynchronous
+ ? typeProvider.iterableType2(type)
+ : typeProvider.streamType2(type);
}
InferenceContext.setType(e, type);
}
@@ -4575,12 +4530,12 @@
if (node.star != null) {
// If this is a yield*, then we unwrap the element return type
// If it's synchronous, we expect Iterable<T>, otherwise Stream<T>
- InterfaceType wrapperType = _enclosingFunction.isSynchronous
- ? typeProvider.iterableType
- : typeProvider.streamType;
if (type is InterfaceType) {
+ ClassElement wrapperElement = _enclosingFunction.isSynchronous
+ ? typeProvider.iterableElement
+ : typeProvider.streamElement;
var asInstanceType =
- (type as InterfaceTypeImpl).asInstanceOf(wrapperType.element);
+ (type as InterfaceTypeImpl).asInstanceOf(wrapperElement);
if (asInstanceType != null) {
type = asInstanceType.typeArguments[0];
}
@@ -4607,13 +4562,19 @@
if (isGenerator) {
// If it's sync* we expect Iterable<T>
// If it's async* we expect Stream<T>
- InterfaceType rawType = isAsynchronous
- ? typeProvider.streamType
- : typeProvider.iterableType;
// Match the types to instantiate the type arguments if possible
List<DartType> targs = declaredType.typeArguments;
- if (targs.length == 1 && rawType.instantiate(targs) == declaredType) {
- return targs[0];
+ if (targs.length == 1) {
+ var arg = targs[0];
+ if (isAsynchronous) {
+ if (typeProvider.streamType2(arg) == declaredType) {
+ return arg;
+ }
+ } else {
+ if (typeProvider.iterableType2(arg) == declaredType) {
+ return arg;
+ }
+ }
}
}
// async functions expect `Future<T> | T`
@@ -4673,8 +4634,8 @@
} else if (literal.elements.isEmpty) {
return _LiteralResolution(
_LiteralResolutionKind.map,
- typeProvider.mapType.instantiate(
- [typeProvider.dynamicType, typeProvider.dynamicType]));
+ typeProvider.mapType2(
+ typeProvider.dynamicType, typeProvider.dynamicType));
}
return _LiteralResolution(_LiteralResolutionKind.ambiguous, null);
}
@@ -4691,7 +4652,7 @@
if (type.isDartAsyncFutureOr) {
return type;
}
- return typeProvider.futureOrType.instantiate([type]);
+ return typeProvider.futureOrType2(type);
}
/// If [contextType] is defined and is a subtype of `Iterable<Object>` and
@@ -4736,12 +4697,10 @@
NodeList<TypeAnnotation> arguments = typeArgumentList.arguments;
if (arguments.length == 1) {
return _LiteralResolution(_LiteralResolutionKind.set,
- typeProvider.setType.instantiate([arguments[0].type]));
+ typeProvider.setType2(arguments[0].type));
} else if (arguments.length == 2) {
- return _LiteralResolution(
- _LiteralResolutionKind.map,
- typeProvider.mapType
- .instantiate([arguments[0].type, arguments[1].type]));
+ return _LiteralResolution(_LiteralResolutionKind.map,
+ typeProvider.mapType2(arguments[0].type, arguments[1].type));
}
}
return _LiteralResolution(_LiteralResolutionKind.ambiguous, null);
@@ -4765,20 +4724,23 @@
DartType uninstantiatedType, TypeArgumentList typeArguments,
{AstNode errorNode, bool isConst: false}) {
errorNode ??= inferenceNode;
- TypeSystem ts = typeSystem;
if (typeArguments == null &&
uninstantiatedType is FunctionType &&
- uninstantiatedType.typeFormals.isNotEmpty &&
- ts is Dart2TypeSystem) {
- return ts.inferGenericFunctionOrType<FunctionType>(
- uninstantiatedType,
- const <ParameterElement>[],
- const <DartType>[],
- InferenceContext.getContext(inferenceNode),
- downwards: true,
- isConst: isConst,
- errorReporter: errorReporter,
- errorNode: errorNode);
+ uninstantiatedType.typeFormals.isNotEmpty) {
+ var typeArguments = typeSystem.inferGenericFunctionOrType(
+ typeParameters: uninstantiatedType.typeFormals,
+ parameters: const <ParameterElement>[],
+ declaredReturnType: uninstantiatedType.returnType,
+ argumentTypes: const <DartType>[],
+ contextReturnType: InferenceContext.getContext(inferenceNode),
+ downwards: true,
+ isConst: isConst,
+ errorReporter: errorReporter,
+ errorNode: errorNode,
+ );
+ if (typeArguments != null) {
+ return uninstantiatedType.instantiate(typeArguments);
+ }
}
return null;
}
@@ -5809,7 +5771,7 @@
///
/// The client must set [nameScope] before calling [resolveTypeName].
class TypeNameResolver {
- final TypeSystem typeSystem;
+ final Dart2TypeSystem typeSystem;
final DartType dynamicType;
final bool isNonNullableUnit;
final AnalysisOptionsImpl analysisOptions;
@@ -6064,7 +6026,9 @@
type = DynamicTypeImpl.instance;
} else if (element is NeverElementImpl) {
_setElement(typeName, element);
- type = element.type;
+ type = element.instantiate(
+ nullabilitySuffix: _getNullability(node.question != null),
+ );
} else if (element is FunctionTypeAliasElement) {
_setElement(typeName, element);
type = element.type as TypeImpl;
@@ -6141,9 +6105,8 @@
}
} else {
if (element is GenericTypeAliasElementImpl) {
- var ts = typeSystem as Dart2TypeSystem;
List<DartType> typeArguments =
- ts.instantiateTypeFormalsToBounds2(element);
+ typeSystem.instantiateTypeFormalsToBounds2(element);
type = GenericTypeAliasElementImpl.typeAfterSubstitution(
element, typeArguments) ??
dynamicType;
@@ -6255,24 +6218,25 @@
/// If the [node] is the type name in a redirected factory constructor,
/// infer type arguments using the enclosing class declaration. Return `null`
/// otherwise.
- InterfaceTypeImpl _inferTypeArgumentsForRedirectedConstructor(
- TypeName node, DartType type) {
+ List<DartType> _inferTypeArgumentsForRedirectedConstructor(
+ TypeName node, ClassElement typeElement) {
AstNode constructorName = node.parent;
AstNode enclosingConstructor = constructorName?.parent;
- TypeSystem ts = typeSystem;
if (constructorName is ConstructorName &&
enclosingConstructor is ConstructorDeclaration &&
- enclosingConstructor.redirectedConstructor == constructorName &&
- type is InterfaceType &&
- ts is Dart2TypeSystem) {
+ enclosingConstructor.redirectedConstructor == constructorName) {
ClassOrMixinDeclaration enclosingClassNode = enclosingConstructor.parent;
- ClassElement enclosingClassElement = enclosingClassNode.declaredElement;
- if (enclosingClassElement == type.element) {
- return type;
+ var enclosingClassElement = enclosingClassNode.declaredElement;
+ if (enclosingClassElement == typeElement) {
+ return typeElement.thisType.typeArguments;
} else {
- InterfaceType contextType = enclosingClassElement.type;
- return ts.inferGenericFunctionOrType(
- type, const <ParameterElement>[], const <DartType>[], contextType);
+ return typeSystem.inferGenericFunctionOrType(
+ typeParameters: typeElement.typeParameters,
+ parameters: const [],
+ declaredReturnType: typeElement.thisType,
+ argumentTypes: const [],
+ contextReturnType: enclosingClassElement.thisType,
+ );
}
}
return null;
@@ -6382,13 +6346,10 @@
} else if (parameterCount == 0) {
typeArguments = const <DartType>[];
} else {
- var redirectedType =
- _inferTypeArgumentsForRedirectedConstructor(node, element.type);
- if (redirectedType != null) {
- typeArguments = redirectedType.typeArguments;
- } else {
- var ts = typeSystem as Dart2TypeSystem;
- typeArguments = ts.instantiateTypeFormalsToBounds2(element);
+ typeArguments =
+ _inferTypeArgumentsForRedirectedConstructor(node, element);
+ if (typeArguments == null) {
+ typeArguments = typeSystem.instantiateTypeFormalsToBounds2(element);
}
}
@@ -6618,16 +6579,24 @@
/// Return the type representing 'Future<dynamic>'.
InterfaceType get futureDynamicType;
+ /// Return the element representing the built-in class 'Future'.
+ ClassElement get futureElement;
+
/// Return the type representing 'Future<Null>'.
InterfaceType get futureNullType;
+ /// Return the element representing the built-in class 'FutureOr'.
+ ClassElement get futureOrElement;
+
/// Return the type representing 'FutureOr<Null>'.
InterfaceType get futureOrNullType;
/// Return the type representing the built-in type 'FutureOr'.
+ @Deprecated('Use futureOrType2() instead.')
InterfaceType get futureOrType;
/// Return the type representing the built-in type 'Future'.
+ @Deprecated('Use futureType2() instead.')
InterfaceType get futureType;
/// Return the type representing the built-in type 'int'.
@@ -6636,19 +6605,31 @@
/// Return the type representing the type 'Iterable<dynamic>'.
InterfaceType get iterableDynamicType;
+ /// Return the element representing the built-in class 'Iterable'.
+ ClassElement get iterableElement;
+
/// Return the type representing the type 'Iterable<Object>'.
InterfaceType get iterableObjectType;
/// Return the type representing the built-in type 'Iterable'.
+ @Deprecated('Use iterableType2() instead.')
InterfaceType get iterableType;
+ /// Return the element representing the built-in class 'List'.
+ ClassElement get listElement;
+
/// Return the type representing the built-in type 'List'.
+ @Deprecated('Use listType2() instead.')
InterfaceType get listType;
+ /// Return the element representing the built-in class 'Map'.
+ ClassElement get mapElement;
+
/// Return the type representing 'Map<Object, Object>'.
InterfaceType get mapObjectObjectType;
/// Return the type representing the built-in type 'Map'.
+ @Deprecated('Use mapType2() instead.')
InterfaceType get mapType;
/// Return the type representing the built-in type 'Never'.
@@ -6670,7 +6651,11 @@
/// Return the type representing the built-in type 'Object'.
InterfaceType get objectType;
+ /// Return the element representing the built-in class 'Set'.
+ ClassElement get setElement;
+
/// Return the type representing the built-in type 'Set'.
+ @Deprecated('Use setType2() instead.')
InterfaceType get setType;
/// Return the type representing the built-in type 'StackTrace'.
@@ -6679,12 +6664,19 @@
/// Return the type representing 'Stream<dynamic>'.
InterfaceType get streamDynamicType;
+ /// Return the element representing the built-in class 'Stream'.
+ ClassElement get streamElement;
+
/// Return the type representing the built-in type 'Stream'.
+ @Deprecated('Use streamType2() instead.')
InterfaceType get streamType;
/// Return the type representing the built-in type 'String'.
InterfaceType get stringType;
+ /// Return the element representing the built-in class 'Symbol'.
+ ClassElement get symbolElement;
+
/// Return the type representing the built-in type 'Symbol'.
InterfaceType get symbolType;
@@ -6694,6 +6686,14 @@
/// Return the type representing the built-in type `void`.
VoidType get voidType;
+ /// Return the instantiation of the built-in class 'FutureOr' with the
+ /// given [valueType]. The type has the nullability suffix of this provider.
+ InterfaceType futureOrType2(DartType valueType);
+
+ /// Return the instantiation of the built-in class 'Future' with the
+ /// given [valueType]. The type has the nullability suffix of this provider.
+ InterfaceType futureType2(DartType valueType);
+
/// Return 'true' if [id] is the name of a getter on
/// the Object type.
bool isObjectGetter(String id);
@@ -6705,6 +6705,27 @@
/// Return 'true' if [id] is the name of a method on
/// the Object type.
bool isObjectMethod(String id);
+
+ /// Return the instantiation of the built-in class 'Iterable' with the
+ /// given [elementType]. The type has the nullability suffix of this provider.
+ InterfaceType iterableType2(DartType elementType);
+
+ /// Return the instantiation of the built-in class 'List' with the
+ /// given [elementType]. The type has the nullability suffix of this provider.
+ InterfaceType listType2(DartType elementType);
+
+ /// Return the instantiation of the built-in class 'List' with the
+ /// given [keyType] and [valueType]. The type has the nullability suffix of
+ /// this provider.
+ InterfaceType mapType2(DartType keyType, DartType valueType);
+
+ /// Return the instantiation of the built-in class 'Set' with the
+ /// given [elementType]. The type has the nullability suffix of this provider.
+ InterfaceType setType2(DartType elementType);
+
+ /// Return the instantiation of the built-in class 'Stream' with the
+ /// given [elementType]. The type has the nullability suffix of this provider.
+ InterfaceType streamType2(DartType elementType);
}
/// Modes in which [TypeResolverVisitor] works.
diff --git a/pkg/analyzer/lib/src/generated/source.dart b/pkg/analyzer/lib/src/generated/source.dart
index 1152e24..dd872c2 100644
--- a/pkg/analyzer/lib/src/generated/source.dart
+++ b/pkg/analyzer/lib/src/generated/source.dart
@@ -33,7 +33,7 @@
String get encoding => uri.toString();
@override
- String get fullName => encoding;
+ String get fullName => '$uri';
@override
int get hashCode => uri.hashCode;
@@ -50,6 +50,8 @@
/**
* A cache used to override the default content of a [Source].
+ *
+ * TODO(scheglov) Remove it.
*/
class ContentCache {
/**
@@ -388,6 +390,7 @@
* @return an encoded representation of this source
* See [SourceFactory.fromEncoding].
*/
+ @deprecated
String get encoding;
/**
@@ -595,7 +598,6 @@
* @param encoding the encoding of a source object
* @return a source object that is described by the given encoding
* @throws IllegalArgumentException if the argument is not a valid encoding
- * See [Source.encoding].
*/
Source fromEncoding(String encoding);
diff --git a/pkg/analyzer/lib/src/generated/static_type_analyzer.dart b/pkg/analyzer/lib/src/generated/static_type_analyzer.dart
index 3a98084..91b6336 100644
--- a/pkg/analyzer/lib/src/generated/static_type_analyzer.dart
+++ b/pkg/analyzer/lib/src/generated/static_type_analyzer.dart
@@ -7,6 +7,7 @@
import 'package:analyzer/dart/ast/token.dart';
import 'package:analyzer/dart/ast/visitor.dart';
import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/dart/element/nullability_suffix.dart';
import 'package:analyzer/dart/element/type.dart';
import 'package:analyzer/src/dart/analysis/driver.dart';
import 'package:analyzer/src/dart/ast/ast.dart';
@@ -51,7 +52,7 @@
/**
* The type system in use for static type analysis.
*/
- TypeSystem _typeSystem;
+ Dart2TypeSystem _typeSystem;
/**
* The type representing the type 'dynamic'.
@@ -90,6 +91,12 @@
_strictInference = analysisOptions.strictInference;
}
+ NullabilitySuffix get _noneOrStarSuffix {
+ return _nonNullableEnabled
+ ? NullabilitySuffix.none
+ : NullabilitySuffix.star;
+ }
+
/**
* Return `true` if NNBD is enabled for this compilation unit.
*/
@@ -117,12 +124,11 @@
FormalParameterList node, DartType functionType) {
bool inferred = false;
if (node != null && functionType is FunctionType) {
- var ts = _typeSystem as Dart2TypeSystem;
void inferType(ParameterElementImpl p, DartType inferredType) {
// Check that there is no declared type, and that we have not already
// inferred a type in some fashion.
if (p.hasImplicitType && (p.type == null || p.type.isDynamic)) {
- inferredType = ts.upperBoundForType(inferredType);
+ inferredType = _typeSystem.upperBoundForType(inferredType);
if (inferredType.isDartCoreNull) {
inferredType = _typeProvider.objectType;
}
@@ -162,7 +168,12 @@
DartType inferListType(ListLiteral node, {bool downwards: false}) {
DartType contextType = InferenceContext.getContext(node);
- var ts = _typeSystem as Dart2TypeSystem;
+ var element = _typeProvider.listElement;
+ var typeParameters = element.typeParameters;
+ var genericElementType = typeParameters[0].instantiate(
+ nullabilitySuffix: _noneOrStarSuffix,
+ );
+
List<DartType> elementTypes;
List<ParameterElement> parameters;
@@ -178,12 +189,9 @@
.map((element) => _computeElementType(element))
.where((t) => t != null)
.toList();
- TypeParameterType listTypeParam =
- _typeProvider.listType.typeParameters[0].type;
- ParameterElementImpl syntheticParamElement =
- new ParameterElementImpl.synthetic(
- 'element', listTypeParam, ParameterKind.POSITIONAL);
- parameters = new List.filled(elementTypes.length, syntheticParamElement);
+ var syntheticParameter = ParameterElementImpl.synthetic(
+ 'element', genericElementType, ParameterKind.POSITIONAL);
+ parameters = List.filled(elementTypes.length, syntheticParameter);
}
if (_strictInference && parameters.isEmpty && contextType == null) {
// We cannot infer the type of a collection literal with no elements, and
@@ -192,13 +200,22 @@
_resolver.errorReporter.reportErrorForNode(
HintCode.INFERENCE_FAILURE_ON_COLLECTION_LITERAL, node, ['List']);
}
- InterfaceType inferred = ts.inferGenericFunctionOrType<InterfaceType>(
- _typeProvider.listType, parameters, elementTypes, contextType,
- downwards: downwards,
- isConst: node.isConst,
- errorReporter: _resolver.errorReporter,
- errorNode: node);
- return inferred;
+
+ var typeArguments = _typeSystem.inferGenericFunctionOrType(
+ typeParameters: typeParameters,
+ parameters: parameters,
+ declaredReturnType: element.thisType,
+ argumentTypes: elementTypes,
+ contextReturnType: contextType,
+ downwards: downwards,
+ isConst: node.isConst,
+ errorReporter: _resolver.errorReporter,
+ errorNode: node,
+ );
+ return element.instantiate(
+ typeArguments: typeArguments,
+ nullabilitySuffix: _noneOrStarSuffix,
+ );
}
ParameterizedType inferMapTypeDownwards(
@@ -207,14 +224,22 @@
return null;
}
- var ts = _typeSystem as Dart2TypeSystem;
- ParameterizedType inferred = ts.inferGenericFunctionOrType(
- _typeProvider.mapType, [], [], contextType,
- downwards: true,
- isConst: node.isConst,
- errorReporter: _resolver.errorReporter,
- errorNode: node);
- return inferred;
+ var element = _typeProvider.mapElement;
+ var typeArguments = _typeSystem.inferGenericFunctionOrType(
+ typeParameters: element.typeParameters,
+ parameters: const [],
+ declaredReturnType: element.thisType,
+ argumentTypes: const [],
+ contextReturnType: contextType,
+ downwards: true,
+ isConst: node.isConst,
+ errorReporter: _resolver.errorReporter,
+ errorNode: node,
+ );
+ return element.instantiate(
+ typeArguments: typeArguments,
+ nullabilitySuffix: _noneOrStarSuffix,
+ );
}
DartType inferSetTypeDownwards(SetOrMapLiteral node, DartType contextType) {
@@ -222,14 +247,22 @@
return null;
}
- var ts = _typeSystem as Dart2TypeSystem;
- DartType inferred = ts.inferGenericFunctionOrType<InterfaceType>(
- _typeProvider.setType, [], [], contextType,
- downwards: true,
- isConst: node.isConst,
- errorReporter: _resolver.errorReporter,
- errorNode: node);
- return inferred;
+ var element = _typeProvider.setElement;
+ var typeArguments = _typeSystem.inferGenericFunctionOrType(
+ typeParameters: element.typeParameters,
+ parameters: const [],
+ declaredReturnType: element.thisType,
+ argumentTypes: const [],
+ contextReturnType: contextType,
+ downwards: true,
+ isConst: node.isConst,
+ errorReporter: _resolver.errorReporter,
+ errorNode: node,
+ );
+ return element.instantiate(
+ typeArguments: typeArguments,
+ nullabilitySuffix: _noneOrStarSuffix,
+ );
}
/**
@@ -593,8 +626,8 @@
@override
void visitFunctionExpressionInvocation(FunctionExpressionInvocation node) {
_inferGenericInvocationExpression(node);
- DartType staticType = _computeInvokeReturnType(node.staticInvokeType,
- isNullableInvoke: false);
+ DartType staticType =
+ _computeInvokeReturnType(node.staticInvokeType, isNullAware: false);
_recordStaticType(node, staticType);
}
@@ -703,14 +736,11 @@
}
}
_recordStaticType(
- node,
- _nonNullable(
- _typeProvider.listType.instantiate(<DartType>[staticType])));
+ node, _nonNullable(_typeProvider.listType2(staticType)));
return;
}
- DartType listDynamicType =
- _typeProvider.listType.instantiate(<DartType>[_dynamicType]);
+ DartType listDynamicType = _typeProvider.listType2(_dynamicType);
// If there are no type arguments, try to infer some arguments.
DartType inferred = inferListType(node);
@@ -777,7 +807,7 @@
if (!inferredStaticType) {
DartType staticStaticType = _computeInvokeReturnType(
node.staticInvokeType,
- isNullableInvoke: node.operator?.type == TokenType.QUESTION_PERIOD);
+ isNullAware: node.isNullAware);
_recordStaticType(node, staticStaticType);
}
}
@@ -1005,18 +1035,14 @@
(node as SetOrMapLiteralImpl).becomeSet();
var elementType = _getType(typeArguments[0]) ?? _dynamicType;
_recordStaticType(
- node,
- _nonNullable(
- _typeProvider.setType.instantiate(<DartType>[elementType])));
+ node, _nonNullable(_typeProvider.setType2(elementType)));
return;
} else if (typeArguments.length == 2) {
(node as SetOrMapLiteralImpl).becomeMap();
var keyType = _getType(typeArguments[0]) ?? _dynamicType;
var valueType = _getType(typeArguments[1]) ?? _dynamicType;
_recordStaticType(
- node,
- _nonNullable(_typeProvider.mapType
- .instantiate(<DartType>[keyType, valueType])));
+ node, _nonNullable(_typeProvider.mapType2(keyType, valueType)));
return;
}
// If we get here, then a nonsense number of type arguments were provided,
@@ -1026,10 +1052,10 @@
if (literalType.isDynamic) {
// The literal is ambiguous, and further analysis won't resolve the
// ambiguity. Leave it as neither a set nor a map.
- } else if (literalType.element == _typeProvider.mapType.element) {
+ } else if (literalType.element == _typeProvider.mapElement) {
(node as SetOrMapLiteralImpl).becomeMap();
} else {
- assert(literalType.element == _typeProvider.setType.element);
+ assert(literalType.element == _typeProvider.setElement);
(node as SetOrMapLiteralImpl).becomeSet();
}
if (_strictInference &&
@@ -1273,7 +1299,7 @@
if (_typeSystem.isSubtypeOf(
expressionType, _typeProvider.iterableObjectType)) {
InterfaceType iterableType = (expressionType as InterfaceTypeImpl)
- .asInstanceOf(_typeProvider.iterableType.element);
+ .asInstanceOf(_typeProvider.iterableElement);
return iterableType.typeArguments[0];
}
} else if (expressionType.isDynamic) {
@@ -1292,7 +1318,7 @@
* type that is being invoked.
*/
DartType /*!*/ _computeInvokeReturnType(DartType type,
- {@required bool isNullableInvoke}) {
+ {@required bool isNullAware}) {
TypeImpl /*!*/ returnType;
if (type is InterfaceType) {
MethodElement callMethod = type.lookUpMethod(
@@ -1304,7 +1330,7 @@
returnType = _dynamicType;
}
- if (isNullableInvoke && _nonNullableEnabled) {
+ if (isNullAware && _nonNullableEnabled) {
returnType = _typeSystem.makeNullable(returnType);
}
@@ -1320,16 +1346,16 @@
*/
DartType _computeReturnTypeOfFunction(FunctionBody body, DartType type) {
if (body.isGenerator) {
- InterfaceType genericType = body.isAsynchronous
- ? _typeProvider.streamType
- : _typeProvider.iterableType;
- return _nonNullable(genericType.instantiate(<DartType>[type]));
+ InterfaceType generatedType = body.isAsynchronous
+ ? _typeProvider.streamType2(type)
+ : _typeProvider.iterableType2(type);
+ return _nonNullable(generatedType);
} else if (body.isAsynchronous) {
if (type.isDartAsyncFutureOr) {
type = (type as InterfaceType).typeArguments[0];
}
- DartType futureType = _typeProvider.futureType
- .instantiate(<DartType>[_typeSystem.flatten(type)]);
+ DartType futureType =
+ _typeProvider.futureType2(_typeSystem.flatten(type));
return _nonNullable(futureType);
} else {
return type;
@@ -1351,10 +1377,10 @@
FunctionType propertyType = element.type;
if (propertyType != null) {
return _computeInvokeReturnType(propertyType.returnType,
- isNullableInvoke: false);
+ isNullAware: false);
}
} else if (element is ExecutableElement) {
- return _computeInvokeReturnType(element.type, isNullableInvoke: false);
+ return _computeInvokeReturnType(element.type, isNullAware: false);
}
return _dynamicType;
}
@@ -1526,7 +1552,7 @@
if (_typeSystem.isSubtypeOf(
expressionType, _typeProvider.iterableObjectType)) {
InterfaceType iterableType = (expressionType as InterfaceTypeImpl)
- .asInstanceOf(_typeProvider.iterableType.element);
+ .asInstanceOf(_typeProvider.iterableElement);
return _InferredCollectionElementTypeInformation(
elementType: iterableType.typeArguments[0],
keyType: null,
@@ -1534,7 +1560,7 @@
} else if (_typeSystem.isSubtypeOf(
expressionType, _typeProvider.mapObjectObjectType)) {
InterfaceType mapType = (expressionType as InterfaceTypeImpl)
- .asInstanceOf(_typeProvider.mapType.element);
+ .asInstanceOf(_typeProvider.mapElement);
List<DartType> typeArguments = mapType.typeArguments;
return _InferredCollectionElementTypeInformation(
elementType: null,
@@ -1590,8 +1616,8 @@
iterableType = iterableType.resolveToBound(_typeProvider.objectType);
ClassElement iteratedElement = (awaitKeyword == null)
- ? _typeProvider.iterableType.element
- : _typeProvider.streamType.element;
+ ? _typeProvider.iterableElement
+ : _typeProvider.streamElement;
InterfaceType iteratedType = iterableType is InterfaceTypeImpl
? iterableType.asInstanceOf(iteratedElement)
@@ -1644,11 +1670,9 @@
ArgumentList argumentList,
AstNode errorNode,
{bool isConst: false}) {
- TypeSystem ts = _typeSystem;
if (typeArguments == null &&
fnType is FunctionType &&
- fnType.typeFormals.isNotEmpty &&
- ts is Dart2TypeSystem) {
+ fnType.typeFormals.isNotEmpty) {
// Get the parameters that correspond to the uninstantiated generic.
List<ParameterElement> rawParameters =
ResolverVisitor.resolveArgumentsToParameters(
@@ -1663,11 +1687,16 @@
argTypes.add(argumentList.arguments[i].staticType);
}
}
- var typeArgs = ts.inferGenericFunctionOrType2<FunctionType>(
- fnType, params, argTypes, InferenceContext.getContext(node),
- isConst: isConst,
- errorReporter: _resolver.errorReporter,
- errorNode: errorNode);
+ var typeArgs = _typeSystem.inferGenericFunctionOrType(
+ typeParameters: fnType.typeFormals,
+ parameters: params,
+ declaredReturnType: fnType.returnType,
+ argumentTypes: argTypes,
+ contextReturnType: InferenceContext.getContext(node),
+ isConst: isConst,
+ errorReporter: _resolver.errorReporter,
+ errorNode: errorNode,
+ );
if (node is InvocationExpressionImpl) {
node.typeArgumentTypes = typeArgs;
}
@@ -1961,12 +1990,9 @@
SimpleIdentifier identifier,
DartType tearOffType,
) {
- TypeSystem ts = _typeSystem;
var context = InferenceContext.getContext(expression);
- if (context is FunctionType &&
- tearOffType is FunctionType &&
- ts is Dart2TypeSystem) {
- var typeArguments = ts.inferFunctionTypeInstantiation(
+ if (context is FunctionType && tearOffType is FunctionType) {
+ var typeArguments = _typeSystem.inferFunctionTypeInstantiation(
context,
tearOffType,
errorReporter: _resolver.errorReporter,
@@ -2078,54 +2104,69 @@
DartType _toMapType(SetOrMapLiteral node, DartType contextType,
List<_InferredCollectionElementTypeInformation> inferredTypes) {
DartType dynamicType = _typeProvider.dynamicType;
- List<DartType> keyTypes = [];
- List<DartType> valueTypes = [];
- for (int i = 0; i < inferredTypes.length; i++) {
- keyTypes.add(inferredTypes[i].keyType ?? dynamicType);
- valueTypes.add(inferredTypes[i].valueType ?? dynamicType);
+
+ var element = _typeProvider.mapElement;
+ var typeParameters = element.typeParameters;
+ var genericKeyType = typeParameters[0].instantiate(
+ nullabilitySuffix: _noneOrStarSuffix,
+ );
+ var genericValueType = typeParameters[1].instantiate(
+ nullabilitySuffix: _noneOrStarSuffix,
+ );
+
+ var parameters = List<ParameterElement>(2 * inferredTypes.length);
+ var argumentTypes = List<DartType>(2 * inferredTypes.length);
+ for (var i = 0; i < inferredTypes.length; i++) {
+ parameters[2 * i + 0] = ParameterElementImpl.synthetic(
+ 'key', genericKeyType, ParameterKind.POSITIONAL);
+ parameters[2 * i + 1] = ParameterElementImpl.synthetic(
+ 'value', genericValueType, ParameterKind.POSITIONAL);
+ argumentTypes[2 * i + 0] = inferredTypes[i].keyType ?? dynamicType;
+ argumentTypes[2 * i + 1] = inferredTypes[i].valueType ?? dynamicType;
}
- TypeParameterType keyTypeParam =
- _typeProvider.mapType.typeParameters[0].type;
- TypeParameterType valueTypeParam =
- _typeProvider.mapType.typeParameters[1].type;
- ParameterElementImpl syntheticKeyParameter =
- new ParameterElementImpl.synthetic(
- 'key', keyTypeParam, ParameterKind.POSITIONAL);
- ParameterElementImpl syntheticValueParameter =
- new ParameterElementImpl.synthetic(
- 'value', valueTypeParam, ParameterKind.POSITIONAL);
- List<ParameterElement> typeParameters =
- new List.filled(keyTypes.length, syntheticKeyParameter, growable: true)
- ..addAll(new List.filled(valueTypes.length, syntheticValueParameter));
- List<DartType> elementTypes = new List<DartType>.from(keyTypes)
- ..addAll(valueTypes);
- return (_typeSystem as Dart2TypeSystem).inferGenericFunctionOrType(
- _typeProvider.mapType, typeParameters, elementTypes, contextType,
- isConst: node.isConst,
- errorReporter: _resolver.errorReporter,
- errorNode: node);
+
+ var typeArguments = _typeSystem.inferGenericFunctionOrType(
+ typeParameters: typeParameters,
+ parameters: parameters,
+ declaredReturnType: element.thisType,
+ argumentTypes: argumentTypes,
+ contextReturnType: contextType,
+ );
+ return element.instantiate(
+ typeArguments: typeArguments,
+ nullabilitySuffix: _noneOrStarSuffix,
+ );
}
DartType _toSetType(SetOrMapLiteral node, DartType contextType,
List<_InferredCollectionElementTypeInformation> inferredTypes) {
DartType dynamicType = _typeProvider.dynamicType;
- List<DartType> elementTypes = [];
- for (int i = 0; i < inferredTypes.length; i++) {
- elementTypes.add(inferredTypes[i].elementType ?? dynamicType);
+
+ var element = _typeProvider.setElement;
+ var typeParameters = element.typeParameters;
+ var genericElementType = typeParameters[0].instantiate(
+ nullabilitySuffix: _noneOrStarSuffix,
+ );
+
+ var parameters = List<ParameterElement>(inferredTypes.length);
+ var argumentTypes = List<DartType>(inferredTypes.length);
+ for (var i = 0; i < inferredTypes.length; i++) {
+ parameters[i] = ParameterElementImpl.synthetic(
+ 'element', genericElementType, ParameterKind.POSITIONAL);
+ argumentTypes[i] = inferredTypes[i].elementType ?? dynamicType;
}
- TypeParameterType elementTypeParam =
- _typeProvider.setType.typeParameters[0].type;
- ParameterElementImpl syntheticElementParameter =
- new ParameterElementImpl.synthetic(
- 'key', elementTypeParam, ParameterKind.POSITIONAL);
- List<ParameterElement> parameters = new List.filled(
- elementTypes.length, syntheticElementParameter,
- growable: true);
- return (_typeSystem as Dart2TypeSystem).inferGenericFunctionOrType(
- _typeProvider.setType, parameters, elementTypes, contextType,
- isConst: node.isConst,
- errorReporter: _resolver.errorReporter,
- errorNode: node);
+
+ var typeArguments = _typeSystem.inferGenericFunctionOrType(
+ typeParameters: typeParameters,
+ parameters: parameters,
+ declaredReturnType: element.thisType,
+ argumentTypes: argumentTypes,
+ contextReturnType: contextType,
+ );
+ return element.instantiate(
+ typeArguments: typeArguments,
+ nullabilitySuffix: _noneOrStarSuffix,
+ );
}
/**
@@ -2182,13 +2223,10 @@
return _hasNullShorting(node.leftHandSide);
}
if (node is IndexExpression) {
- return node.leftBracket.type ==
- TokenType.QUESTION_PERIOD_OPEN_SQUARE_BRACKET ||
- _hasNullShorting(node.target);
+ return node.isNullAware || _hasNullShorting(node.target);
}
if (node is PropertyAccess) {
- return node.operator.type == TokenType.QUESTION_PERIOD ||
- _hasNullShorting(node.target);
+ return node.isNullAware || _hasNullShorting(node.target);
}
return false;
}
diff --git a/pkg/analyzer/lib/src/generated/testing/ast_test_factory.dart b/pkg/analyzer/lib/src/generated/testing/ast_test_factory.dart
index a7d934a..f6687b4 100644
--- a/pkg/analyzer/lib/src/generated/testing/ast_test_factory.dart
+++ b/pkg/analyzer/lib/src/generated/testing/ast_test_factory.dart
@@ -777,10 +777,11 @@
[List<Combinator> combinators]) =>
importDirective(null, uri, false, prefix, combinators);
- static IndexExpression indexExpression(Expression array, Expression index) =>
+ static IndexExpression indexExpression(Expression array, Expression index,
+ [TokenType leftBracket = TokenType.OPEN_SQUARE_BRACKET]) =>
astFactory.indexExpressionForTarget(
array,
- TokenFactory.tokenFromType(TokenType.OPEN_SQUARE_BRACKET),
+ TokenFactory.tokenFromType(leftBracket),
index,
TokenFactory.tokenFromType(TokenType.CLOSE_SQUARE_BRACKET));
diff --git a/pkg/analyzer/lib/src/generated/testing/element_factory.dart b/pkg/analyzer/lib/src/generated/testing/element_factory.dart
index c0ea183..0ed4131 100644
--- a/pkg/analyzer/lib/src/generated/testing/element_factory.dart
+++ b/pkg/analyzer/lib/src/generated/testing/element_factory.dart
@@ -170,7 +170,7 @@
FieldElementImpl valuesField = new FieldElementImpl("values", -1);
valuesField.isStatic = true;
valuesField.isConst = true;
- valuesField.type = typeProvider.listType.instantiate(<DartType>[enumType]);
+ valuesField.type = typeProvider.listType2(enumType);
fields.add(valuesField);
//
// Build the enum constants.
@@ -404,7 +404,6 @@
element.function = new GenericFunctionTypeElementImpl.forOffset(-1)
..parameters = parameters
..returnType = returnType ?? DynamicTypeImpl.instance;
- element.type = new FunctionTypeImpl.forTypedef(element);
return element;
}
@@ -586,6 +585,7 @@
setter.parameters = <ParameterElement>[parameter];
setter.returnType = VoidTypeImpl.instance;
setter.type = new FunctionTypeImpl(setter);
+ setter.isStatic = isStatic;
field.setter = setter;
return setter;
}
@@ -628,9 +628,7 @@
}
static TypeParameterElementImpl typeParameterElement(String name) {
- TypeParameterElementImpl element = new TypeParameterElementImpl(name, 0);
- element.type = new TypeParameterTypeImpl(element);
- return element;
+ return new TypeParameterElementImpl(name, 0);
}
static List<TypeParameterElement> typeParameters(List<String> names) {
@@ -649,7 +647,6 @@
static TypeParameterElementImpl typeParameterWithType(String name,
[DartType bound]) {
TypeParameterElementImpl typeParameter = typeParameterElement(name);
- typeParameter.type = new TypeParameterTypeImpl(typeParameter);
typeParameter.bound = bound;
return typeParameter;
}
diff --git a/pkg/analyzer/lib/src/generated/testing/test_type_provider.dart b/pkg/analyzer/lib/src/generated/testing/test_type_provider.dart
index 5d27b81..9538549 100644
--- a/pkg/analyzer/lib/src/generated/testing/test_type_provider.dart
+++ b/pkg/analyzer/lib/src/generated/testing/test_type_provider.dart
@@ -3,7 +3,7 @@
// BSD-style license that can be found in the LICENSE file.
import 'package:analyzer/dart/element/element.dart';
-import 'package:analyzer/src/dart/element/type.dart';
+import 'package:analyzer/dart/element/nullability_suffix.dart';
import 'package:analyzer/src/dart/element/type_provider.dart';
import 'package:analyzer/src/generated/engine.dart' show AnalysisContext;
import 'package:analyzer/src/generated/source.dart' show Source;
@@ -23,13 +23,17 @@
context ??= _MockAnalysisContext();
var sdkElements = MockSdkElements(context, nullabilitySuffix);
return TestTypeProvider._(
+ nullabilitySuffix,
sdkElements.coreLibrary,
sdkElements.asyncLibrary,
);
}
- TestTypeProvider._(LibraryElement coreLibrary, LibraryElement asyncLibrary)
- : super(coreLibrary, asyncLibrary);
+ TestTypeProvider._(
+ NullabilitySuffix nullabilitySuffix,
+ LibraryElement coreLibrary,
+ LibraryElement asyncLibrary,
+ ) : super(coreLibrary, asyncLibrary, nullabilitySuffix: nullabilitySuffix);
}
class _MockAnalysisContext implements AnalysisContext {
diff --git a/pkg/analyzer/lib/src/generated/type_system.dart b/pkg/analyzer/lib/src/generated/type_system.dart
index 85a737b..5f384f0 100644
--- a/pkg/analyzer/lib/src/generated/type_system.dart
+++ b/pkg/analyzer/lib/src/generated/type_system.dart
@@ -6,9 +6,10 @@
import 'dart:math' as math;
import 'package:analyzer/dart/analysis/features.dart';
-import 'package:analyzer/dart/ast/ast.dart' show AstNode;
+import 'package:analyzer/dart/ast/ast.dart' show AstNode, ConstructorName;
import 'package:analyzer/dart/ast/token.dart' show Keyword, TokenType;
import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/dart/element/nullability_suffix.dart';
import 'package:analyzer/dart/element/type.dart';
import 'package:analyzer/dart/element/type_system.dart' as public;
import 'package:analyzer/error/listener.dart' show ErrorReporter;
@@ -17,7 +18,7 @@
import 'package:analyzer/src/dart/element/member.dart' show TypeParameterMember;
import 'package:analyzer/src/dart/element/type.dart';
import 'package:analyzer/src/dart/element/type_algebra.dart';
-import 'package:analyzer/src/error/codes.dart' show StrongModeCode;
+import 'package:analyzer/src/error/codes.dart' show HintCode, StrongModeCode;
import 'package:analyzer/src/generated/engine.dart'
show AnalysisContext, AnalysisOptionsImpl;
import 'package:analyzer/src/generated/resolver.dart' show TypeProvider;
@@ -106,9 +107,15 @@
*/
final bool implicitCasts;
+ /// A flag indicating whether inference failures are allowed, off by default.
+ ///
+ /// This option is experimental and subject to change.
+ final bool strictInference;
+
final TypeProvider typeProvider;
- Dart2TypeSystem(this.typeProvider, {this.implicitCasts: true});
+ Dart2TypeSystem(this.typeProvider,
+ {this.implicitCasts: true, this.strictInference: false});
/// Returns true iff the type [t] accepts function types, and requires an
/// implicit coercion if interface types with a `call` method are passed in.
@@ -202,7 +209,7 @@
* Given a generic function type `F<T0, T1, ... Tn>` and a context type C,
* infer an instantiation of F, such that `F<S0, S1, ..., Sn>` <: C.
*
- * This is similar to [inferGenericFunctionOrType2], but the return type is
+ * This is similar to [inferGenericFunctionOrType], but the return type is
* also considered as part of the solution.
*
* If this function is called with a [contextType] that is also
@@ -231,49 +238,6 @@
);
}
- /// Infers a generic type, function, method, or list/map literal
- /// instantiation, using the downward context type as well as the argument
- /// types if available.
- ///
- /// For example, given a function type with generic type parameters, this
- /// infers the type parameters from the actual argument types, and returns the
- /// instantiated function type.
- ///
- /// Concretely, given a function type with parameter types P0, P1, ... Pn,
- /// result type R, and generic type parameters T0, T1, ... Tm, use the
- /// argument types A0, A1, ... An to solve for the type parameters.
- ///
- /// For each parameter Pi, we want to ensure that Ai <: Pi. We can do this by
- /// running the subtype algorithm, and when we reach a type parameter Tj,
- /// recording the lower or upper bound it must satisfy. At the end, all
- /// constraints can be combined to determine the type.
- ///
- /// All constraints on each type parameter Tj are tracked, as well as where
- /// they originated, so we can issue an error message tracing back to the
- /// argument values, type parameter "extends" clause, or the return type
- /// context.
- T inferGenericFunctionOrType<T extends ParameterizedType>(
- T genericType,
- List<ParameterElement> parameters,
- List<DartType> argumentTypes,
- DartType returnContextType,
- {ErrorReporter errorReporter,
- AstNode errorNode,
- bool downwards: false,
- bool isConst: false}) {
- var inferredTypes = inferGenericFunctionOrType2(
- genericType,
- parameters,
- argumentTypes,
- returnContextType,
- errorReporter: errorReporter,
- errorNode: errorNode,
- downwards: downwards,
- isConst: isConst,
- );
- return genericType.instantiate(inferredTypes);
- }
-
/// Infers type arguments for a generic type, function, method, or
/// list/map literal, using the downward context type as well as the
/// argument types if available.
@@ -295,18 +259,19 @@
/// they originated, so we can issue an error message tracing back to the
/// argument values, type parameter "extends" clause, or the return type
/// context.
- List<DartType> inferGenericFunctionOrType2<T extends ParameterizedType>(
- T genericType,
- List<ParameterElement> parameters,
- List<DartType> argumentTypes,
- DartType returnContextType,
- {ErrorReporter errorReporter,
- AstNode errorNode,
- bool downwards: false,
- bool isConst: false}) {
- // TODO(jmesserly): expose typeFormals on ParameterizedType.
- List<TypeParameterElement> typeFormals = typeFormalsAsElements(genericType);
- if (typeFormals.isEmpty) {
+ List<DartType> inferGenericFunctionOrType({
+ ClassElement genericClass,
+ @required List<TypeParameterElement> typeParameters,
+ @required List<ParameterElement> parameters,
+ @required DartType declaredReturnType,
+ @required List<DartType> argumentTypes,
+ @required DartType contextReturnType,
+ ErrorReporter errorReporter,
+ AstNode errorNode,
+ bool downwards: false,
+ bool isConst: false,
+ }) {
+ if (typeParameters.isEmpty) {
return null;
}
@@ -314,30 +279,32 @@
// inferred. It will optimistically assume these type parameters can be
// subtypes (or supertypes) as necessary, and track the constraints that
// are implied by this.
- var inferrer = new GenericInferrer(typeProvider, this, typeFormals);
+ var inferrer = new GenericInferrer(typeProvider, this, typeParameters);
- DartType declaredReturnType =
- genericType is FunctionType ? genericType.returnType : genericType;
-
- if (returnContextType != null) {
+ if (contextReturnType != null) {
if (isConst) {
- returnContextType = _eliminateTypeVariables(returnContextType);
+ contextReturnType = _eliminateTypeVariables(contextReturnType);
}
- inferrer.constrainReturnType(declaredReturnType, returnContextType);
+ inferrer.constrainReturnType(declaredReturnType, contextReturnType);
}
for (int i = 0; i < argumentTypes.length; i++) {
// Try to pass each argument to each parameter, recording any type
// parameter bounds that were implied by this assignment.
inferrer.constrainArgument(
- argumentTypes[i], parameters[i].type, parameters[i].name,
- genericType: genericType);
+ argumentTypes[i],
+ parameters[i].type,
+ parameters[i].name,
+ genericClass: genericClass,
+ );
}
- return inferrer.infer(typeFormals,
- errorReporter: errorReporter,
- errorNode: errorNode,
- downwardsInferPhase: downwards);
+ return inferrer.infer(
+ typeParameters,
+ errorReporter: errorReporter,
+ errorNode: errorNode,
+ downwardsInferPhase: downwards,
+ );
}
/**
@@ -351,7 +318,7 @@
* and generic functions; compute lazily and cache.
*/
DartType instantiateToBounds(DartType type,
- {List<bool> hasError, Map<TypeParameterType, DartType> knownTypes}) {
+ {List<bool> hasError, Map<TypeParameterElement, DartType> knownTypes}) {
List<TypeParameterElement> typeFormals = typeFormalsAsElements(type);
List<DartType> arguments = instantiateTypeFormalsToBounds(typeFormals,
hasError: hasError, knownTypes: knownTypes);
@@ -371,20 +338,19 @@
List<DartType> instantiateTypeFormalsToBounds(
List<TypeParameterElement> typeFormals,
{List<bool> hasError,
- Map<TypeParameterType, DartType> knownTypes}) {
+ Map<TypeParameterElement, DartType> knownTypes}) {
int count = typeFormals.length;
if (count == 0) {
return const <DartType>[];
}
- Set<TypeParameterType> all = new Set<TypeParameterType>();
+ Set<TypeParameterElement> all = new Set<TypeParameterElement>();
// all ground
- Map<TypeParameterType, DartType> defaults = knownTypes ?? {};
+ Map<TypeParameterElement, DartType> defaults = knownTypes ?? {};
// not ground
- Map<TypeParameterType, DartType> partials = {};
+ Map<TypeParameterElement, DartType> partials = {};
- for (TypeParameterElement typeParameterElement in typeFormals) {
- TypeParameterType typeParameter = typeParameterElement.type;
+ for (TypeParameterElement typeParameter in typeFormals) {
all.add(typeParameter);
if (!defaults.containsKey(typeParameter)) {
if (typeParameter.bound == null) {
@@ -395,8 +361,8 @@
}
}
- List<TypeParameterType> getFreeParameters(DartType rootType) {
- List<TypeParameterType> parameters = null;
+ List<TypeParameterElement> getFreeParameters(DartType rootType) {
+ List<TypeParameterElement> parameters = null;
Set<DartType> visitedTypes = new HashSet<DartType>();
void appendParameters(DartType type) {
@@ -407,9 +373,12 @@
return;
}
visitedTypes.add(type);
- if (type is TypeParameterType && all.contains(type)) {
- parameters ??= <TypeParameterType>[];
- parameters.add(type);
+ if (type is TypeParameterType) {
+ var element = type.element;
+ if (all.contains(element)) {
+ parameters ??= <TypeParameterElement>[];
+ parameters.add(element);
+ }
} else if (AnalysisDriver.useSummary2) {
if (type is FunctionType) {
appendParameters(type.returnType);
@@ -429,17 +398,17 @@
bool hasProgress = true;
while (hasProgress) {
hasProgress = false;
- for (TypeParameterType parameter in partials.keys) {
+ for (TypeParameterElement parameter in partials.keys) {
DartType value = partials[parameter];
- List<TypeParameterType> freeParameters = getFreeParameters(value);
+ List<TypeParameterElement> freeParameters = getFreeParameters(value);
if (freeParameters == null) {
defaults[parameter] = value;
partials.remove(parameter);
hasProgress = true;
break;
} else if (freeParameters.every(defaults.containsKey)) {
- defaults[parameter] = value.substitute2(
- defaults.values.toList(), defaults.keys.toList());
+ defaults[parameter] =
+ Substitution.fromMap(defaults).substituteType(value);
partials.remove(parameter);
hasProgress = true;
break;
@@ -459,19 +428,20 @@
var range = defaults.values.toList();
// Build a substitution Phi mapping each uncompleted type variable to
// dynamic, and each completed type variable to its default.
- for (TypeParameterType parameter in partials.keys) {
+ for (TypeParameterElement parameter in partials.keys) {
domain.add(parameter);
range.add(DynamicTypeImpl.instance);
}
// Set the default for an uncompleted type variable (T extends B)
// to be Phi(B)
- for (TypeParameterType parameter in partials.keys) {
- defaults[parameter] = partials[parameter].substitute2(range, domain);
+ for (TypeParameterElement parameter in partials.keys) {
+ defaults[parameter] = Substitution.fromPairs(domain, range)
+ .substituteType(partials[parameter]);
}
}
List<DartType> orderedArguments =
- typeFormals.map((p) => defaults[p.type]).toList();
+ typeFormals.map((p) => defaults[p]).toList();
return orderedArguments;
}
@@ -705,7 +675,7 @@
// given t1 is Future<A> | A, then:
// (Future<A> | A) <: t2 iff Future<A> <: t2 and A <: t2.
- var t1Future = typeProvider.futureType.instantiate([t1TypeArg]);
+ var t1Future = typeProvider.futureType2(t1TypeArg);
return isSubtypeOf(t1Future, t2) && isSubtypeOf(t1TypeArg, t2);
}
@@ -713,7 +683,7 @@
// given t2 is Future<A> | A, then:
// t1 <: (Future<A> | A) iff t1 <: Future<A> or t1 <: A
var t2TypeArg = t2.typeArguments[0];
- var t2Future = typeProvider.futureType.instantiate([t2TypeArg]);
+ var t2Future = typeProvider.futureType2(t2TypeArg);
return isSubtypeOf(t1, t2Future) || isSubtypeOf(t1, t2TypeArg);
}
@@ -1250,7 +1220,7 @@
class GenericInferrer {
final Dart2TypeSystem _typeSystem;
final TypeProvider typeProvider;
- final Map<TypeParameterElement, List<_TypeConstraint>> constraints;
+ final Map<TypeParameterElement, List<_TypeConstraint>> constraints = {};
/// Buffer recording constraints recorded while performing a recursive call to
/// [_matchSubtypeOf] that might fail, so that any constraints recorded during
@@ -1258,10 +1228,7 @@
final _undoBuffer = <_TypeConstraint>[];
GenericInferrer(this.typeProvider, this._typeSystem,
- Iterable<TypeParameterElement> typeFormals)
- : constraints = new HashMap(
- equals: (x, y) => x.location == y.location,
- hashCode: (x) => x.location.hashCode) {
+ Iterable<TypeParameterElement> typeFormals) {
for (var formal in typeFormals) {
constraints[formal] = [];
}
@@ -1271,10 +1238,10 @@
/// is a subtype of the [parameterType].
void constrainArgument(
DartType argumentType, DartType parameterType, String parameterName,
- {DartType genericType}) {
+ {ClassElement genericClass}) {
var origin = new _TypeConstraintFromArgument(
argumentType, parameterType, parameterName,
- genericType: genericType);
+ genericClass: genericClass);
tryMatchSubtypeOf(argumentType, parameterType, origin, covariant: false);
}
@@ -1313,30 +1280,29 @@
AstNode errorNode,
bool failAtError: false,
bool downwardsInferPhase: false}) {
- var fnTypeParams = TypeParameterTypeImpl.getTypes(typeFormals);
-
// Initialize the inferred type array.
//
// In the downwards phase, they all start as `?` to offer reasonable
// degradation for f-bounded type parameters.
var inferredTypes = new List<DartType>.filled(
- fnTypeParams.length, UnknownInferredType.instance);
+ typeFormals.length, UnknownInferredType.instance);
var _inferTypeParameter = downwardsInferPhase
? _inferTypeParameterFromContext
: _inferTypeParameterFromAll;
- for (int i = 0; i < fnTypeParams.length; i++) {
- TypeParameterType typeParam = fnTypeParams[i];
+ for (int i = 0; i < typeFormals.length; i++) {
+ TypeParameterElement typeParam = typeFormals[i];
- var typeParamBound = typeParam.bound;
_TypeConstraint extendsClause;
- if (considerExtendsClause && !typeParamBound.isDynamic) {
- extendsClause = new _TypeConstraint.fromExtends(typeParam,
- typeParam.bound.substitute2(inferredTypes, fnTypeParams));
+ if (considerExtendsClause && typeParam.bound != null) {
+ extendsClause = new _TypeConstraint.fromExtends(
+ typeParam,
+ Substitution.fromPairs(typeFormals, inferredTypes)
+ .substituteType(typeParam.bound));
}
inferredTypes[i] =
- _inferTypeParameter(constraints[typeParam.element], extendsClause);
+ _inferTypeParameter(constraints[typeParam], extendsClause);
}
// If the downwards infer phase has failed, we'll catch this in the upwards
@@ -1346,14 +1312,14 @@
}
// Check the inferred types against all of the constraints.
- var knownTypes = new HashMap<TypeParameterType, DartType>(
- equals: (x, y) => x.element == y.element,
- hashCode: (x) => x.element.hashCode);
- for (int i = 0; i < fnTypeParams.length; i++) {
- TypeParameterType typeParam = fnTypeParams[i];
- var constraints = this.constraints[typeParam.element];
- var typeParamBound =
- typeParam.bound.substitute2(inferredTypes, fnTypeParams);
+ var knownTypes = <TypeParameterElement, DartType>{};
+ for (int i = 0; i < typeFormals.length; i++) {
+ TypeParameterElement typeParam = typeFormals[i];
+ var constraints = this.constraints[typeParam];
+ var typeParamBound = typeParam.bound != null
+ ? Substitution.fromPairs(typeFormals, inferredTypes)
+ .substituteType(typeParam.bound)
+ : typeProvider.dynamicType;
var inferred = inferredTypes[i];
bool success =
@@ -1371,7 +1337,7 @@
errorReporter?.reportErrorForNode(
StrongModeCode.COULD_NOT_INFER,
errorNode,
- [typeParam, _formatError(typeParam, inferred, constraints)]);
+ [typeParam.name, _formatError(typeParam, inferred, constraints)]);
// Heuristic: even if we failed, keep the erroneous type.
// It should satisfy at least some of the constraints (e.g. the return
@@ -1383,7 +1349,7 @@
if (failAtError) return null;
errorReporter
?.reportErrorForNode(StrongModeCode.COULD_NOT_INFER, errorNode, [
- typeParam,
+ typeParam.name,
' Inferred candidate type $inferred has type parameters'
' ${(inferred as FunctionType).typeFormals}, but a function with'
' type parameters cannot be used as a type argument.'
@@ -1398,11 +1364,25 @@
if (UnknownInferredType.isKnown(inferred)) {
knownTypes[typeParam] = inferred;
+ } else if (_typeSystem.strictInference) {
+ // [typeParam] could not be inferred. A result will still be returned
+ // by [infer], with [typeParam] filled in as its bounds. This is
+ // considered a failure of inference, under the "strict-inference"
+ // mode.
+ if (errorNode is ConstructorName) {
+ String constructorName = '${errorNode.type}.${errorNode.name}';
+ errorReporter?.reportTypeErrorForNode(
+ HintCode.INFERENCE_FAILURE_ON_INSTANCE_CREATION,
+ errorNode,
+ [constructorName]);
+ }
+ // TODO(srawlins): More inference failure cases, like functions, and
+ // function expressions.
}
}
// Use instantiate to bounds to finish things off.
- var hasError = new List<bool>.filled(fnTypeParams.length, false);
+ var hasError = new List<bool>.filled(typeFormals.length, false);
var result = _typeSystem.instantiateTypeFormalsToBounds(typeFormals,
hasError: hasError, knownTypes: knownTypes);
@@ -1410,13 +1390,13 @@
for (int i = 0; i < hasError.length; i++) {
if (hasError[i]) {
if (failAtError) return null;
- TypeParameterType typeParam = fnTypeParams[i];
- var typeParamBound =
- typeParam.bound.substitute2(inferredTypes, fnTypeParams);
+ TypeParameterElement typeParam = typeFormals[i];
+ var typeParamBound = Substitution.fromPairs(typeFormals, inferredTypes)
+ .substituteType(typeParam.bound ?? typeProvider.objectType);
// TODO(jmesserly): improve this error message.
errorReporter
?.reportErrorForNode(StrongModeCode.COULD_NOT_INFER, errorNode, [
- typeParam,
+ typeParam.name,
"\nRecursive bound cannot be instantiated: '$typeParamBound'."
"\nConsider passing explicit type argument(s) "
"to the generic.\n\n'"
@@ -1504,9 +1484,9 @@
return lower;
}
- String _formatError(TypeParameterType typeParam, DartType inferred,
+ String _formatError(TypeParameterElement typeParam, DartType inferred,
Iterable<_TypeConstraint> constraints) {
- var intro = "Tried to infer '$inferred' for '$typeParam'"
+ var intro = "Tried to infer '$inferred' for '${typeParam.name}'"
" which doesn't work:";
var constraintsByOrigin = <_TypeConstraintOrigin, List<_TypeConstraint>>{};
@@ -1552,14 +1532,14 @@
// GLB(FutureOr<A>, FutureOr<B>) == FutureOr<GLB(A, B)>
if (t2.isDartAsyncFutureOr) {
var t2TypeArg = t2.typeArguments[0];
- return typeProvider.futureOrType
- .instantiate([_getGreatestLowerBound(t1TypeArg, t2TypeArg)]);
+ return typeProvider
+ .futureOrType2(_getGreatestLowerBound(t1TypeArg, t2TypeArg));
}
// GLB(FutureOr<A>, Future<B>) == Future<GLB(A, B)>
if (t2.isDartAsyncFuture) {
var t2TypeArg = t2.typeArguments[0];
- return typeProvider.futureType
- .instantiate([_getGreatestLowerBound(t1TypeArg, t2TypeArg)]);
+ return typeProvider
+ .futureType2(_getGreatestLowerBound(t1TypeArg, t2TypeArg));
}
}
// GLB(FutureOr<A>, B) == GLB(A, B)
@@ -1699,7 +1679,7 @@
var constraints = this.constraints[t1.element];
if (constraints != null) {
if (!identical(t2, UnknownInferredType.instance)) {
- var constraint = new _TypeConstraint(origin, t1, upper: t2);
+ var constraint = new _TypeConstraint(origin, t1.element, upper: t2);
constraints.add(constraint);
_undoBuffer.add(constraint);
}
@@ -1710,7 +1690,7 @@
var constraints = this.constraints[t2.element];
if (constraints != null) {
if (!identical(t1, UnknownInferredType.instance)) {
- var constraint = new _TypeConstraint(origin, t2, lower: t1);
+ var constraint = new _TypeConstraint(origin, t2.element, lower: t1);
constraints.add(constraint);
_undoBuffer.add(constraint);
}
@@ -1738,7 +1718,7 @@
// given t1 is Future<A> | A, then:
// (Future<A> | A) <: t2 iff Future<A> <: t2 and A <: t2.
- var t1Future = typeProvider.futureType.instantiate([t1TypeArg]);
+ var t1Future = typeProvider.futureType2(t1TypeArg);
return matchSubtype(t1Future, t2) && matchSubtype(t1TypeArg, t2);
}
@@ -1746,7 +1726,7 @@
// given t2 is Future<A> | A, then:
// t1 <: (Future<A> | A) iff t1 <: Future<A> or t1 <: A
var t2TypeArg = t2.typeArguments[0];
- var t2Future = typeProvider.futureType.instantiate([t2TypeArg]);
+ var t2Future = typeProvider.futureType2(t2TypeArg);
// First we try matching `t1 <: Future<A>`. If that succeeds *and*
// records at least one constraint, then we proceed using that constraint.
@@ -1850,7 +1830,7 @@
void _rewindConstraints(int previousRewindBufferLength) {
while (_undoBuffer.length > previousRewindBufferLength) {
var constraint = _undoBuffer.removeLast();
- var element = constraint.typeParameter.element;
+ var element = constraint.typeParameter;
assert(identical(constraints[element].last, constraint));
constraints[element].removeLast();
}
@@ -2874,7 +2854,8 @@
static TypeSystem create(AnalysisContext context) {
var options = context.analysisOptions as AnalysisOptionsImpl;
return new Dart2TypeSystem(context.typeProvider,
- implicitCasts: options.implicitCasts);
+ implicitCasts: options.implicitCasts,
+ strictInference: options.strictInference);
}
}
@@ -3003,7 +2984,7 @@
/// A constraint on a type parameter that we're inferring.
class _TypeConstraint extends _TypeRange {
/// The type parameter that is constrained by [lowerBound] or [upperBound].
- final TypeParameterType typeParameter;
+ final TypeParameterElement typeParameter;
/// Where this constraint comes from, used for error messages.
///
@@ -3014,8 +2995,10 @@
{DartType upper, DartType lower})
: super(upper: upper, lower: lower);
- _TypeConstraint.fromExtends(TypeParameterType type, DartType extendsType)
- : this(new _TypeConstraintFromExtendsClause(type, extendsType), type,
+ _TypeConstraint.fromExtends(
+ TypeParameterElement element, DartType extendsType)
+ : this(
+ new _TypeConstraintFromExtendsClause(element, extendsType), element,
upper: extendsType);
bool get isDownwards => origin is! _TypeConstraintFromArgument;
@@ -3034,11 +3017,11 @@
final DartType argumentType;
final DartType parameterType;
final String parameterName;
- final DartType genericType;
+ final ClassElement genericClass;
_TypeConstraintFromArgument(
this.argumentType, this.parameterType, this.parameterName,
- {this.genericType});
+ {this.genericClass});
@override
formatError() {
@@ -3046,14 +3029,14 @@
// However in summary code it doesn't look like the AST node with span is
// available.
String prefix;
- if (genericType != null &&
- (genericType.name == "List" || genericType.name == "Map") &&
- genericType?.element?.library?.isDartCore == true) {
+ if (genericClass != null &&
+ (genericClass.name == "List" || genericClass.name == "Map") &&
+ genericClass.library.isDartCore == true) {
// This will become:
// "List element"
// "Map key"
// "Map value"
- prefix = "${genericType.name} $parameterName";
+ prefix = "${genericClass.name} $parameterName";
} else {
prefix = "Parameter '$parameterName'";
}
@@ -3067,7 +3050,7 @@
}
class _TypeConstraintFromExtendsClause extends _TypeConstraintOrigin {
- final TypeParameterType typeParam;
+ final TypeParameterElement typeParam;
final DartType extendsType;
_TypeConstraintFromExtendsClause(this.typeParam, this.extendsType);
@@ -3075,7 +3058,7 @@
@override
formatError() {
return [
- "Type parameter '$typeParam'",
+ "Type parameter '${typeParam.name}'",
"declared to extend '$extendsType'."
];
}
diff --git a/pkg/analyzer/lib/src/hint/sdk_constraint_verifier.dart b/pkg/analyzer/lib/src/hint/sdk_constraint_verifier.dart
index cfb7917..2e9c37f 100644
--- a/pkg/analyzer/lib/src/hint/sdk_constraint_verifier.dart
+++ b/pkg/analyzer/lib/src/hint/sdk_constraint_verifier.dart
@@ -246,8 +246,8 @@
}
Element element = node.staticElement;
if (checkFutureAndStream &&
- (element == _typeProvider.futureType.element ||
- element == _typeProvider.streamType.element)) {
+ (element == _typeProvider.futureElement ||
+ element == _typeProvider.streamElement)) {
for (LibraryElement importedLibrary
in _containingLibrary.importedLibraries) {
if (!importedLibrary.isDartCore) {
diff --git a/pkg/analyzer/lib/src/lint/analysis.dart b/pkg/analyzer/lib/src/lint/analysis.dart
index e3dae80..0ec27b9 100644
--- a/pkg/analyzer/lib/src/lint/analysis.dart
+++ b/pkg/analyzer/lib/src/lint/analysis.dart
@@ -18,7 +18,7 @@
import 'package:analyzer/src/dart/analysis/performance_logger.dart';
import 'package:analyzer/src/dart/sdk/sdk.dart';
import 'package:analyzer/src/file_system/file_system.dart';
-import 'package:analyzer/src/generated/engine.dart' hide AnalysisResult;
+import 'package:analyzer/src/generated/engine.dart';
import 'package:analyzer/src/generated/sdk.dart';
import 'package:analyzer/src/generated/source.dart';
import 'package:analyzer/src/generated/source_io.dart';
diff --git a/pkg/analyzer/lib/src/summary/expr_builder.dart b/pkg/analyzer/lib/src/summary/expr_builder.dart
index f34a7ba..ed9493b 100644
--- a/pkg/analyzer/lib/src/summary/expr_builder.dart
+++ b/pkg/analyzer/lib/src/summary/expr_builder.dart
@@ -895,7 +895,7 @@
var typeArg = typeArguments == null
? resynthesizer.typeProvider.dynamicType
: typeArguments.arguments[0].type;
- var staticType = resynthesizer.typeProvider.listType.instantiate([typeArg]);
+ var staticType = resynthesizer.typeProvider.listType2(typeArg);
_push(AstTestFactory.listLiteral2(Keyword.CONST, typeArguments, elements)
..staticType = staticType);
}
@@ -960,8 +960,7 @@
var valueType = typeArguments == null
? resynthesizer.typeProvider.dynamicType
: typeArguments.arguments[1].type;
- var staticType =
- resynthesizer.typeProvider.mapType.instantiate([keyType, valueType]);
+ var staticType = resynthesizer.typeProvider.mapType2(keyType, valueType);
SetOrMapLiteralImpl literal =
AstTestFactory.setOrMapLiteral(Keyword.CONST, typeArguments, entries);
literal.becomeMap();
@@ -1013,15 +1012,13 @@
if (typeArguments.arguments.length == 2) {
var keyType = typeArguments.arguments[0].type;
var valueType = typeArguments.arguments[1].type;
- staticType = resynthesizer.typeProvider.mapType
- .instantiate([keyType, valueType]);
+ staticType = resynthesizer.typeProvider.mapType2(keyType, valueType);
} else if (typeArguments.arguments.length == 1) {
isMap = false;
var valueType = typeArguments == null
? resynthesizer.typeProvider.dynamicType
: typeArguments.arguments[0].type;
- staticType =
- resynthesizer.typeProvider.setType.instantiate([valueType]);
+ staticType = resynthesizer.typeProvider.setType2(valueType);
}
} else {
for (var i = 0; i < elements.length; ++i) {
diff --git a/pkg/analyzer/lib/src/summary/format.dart b/pkg/analyzer/lib/src/summary/format.dart
index 00c787a..4260806 100644
--- a/pkg/analyzer/lib/src/summary/format.dart
+++ b/pkg/analyzer/lib/src/summary/format.dart
@@ -5022,6 +5022,7 @@
double _variantField_21;
LinkedNodeTypeBuilder _variantField_25;
String _variantField_20;
+ List<LinkedNodeTypeBuilder> _variantField_39;
int _flags;
String _variantField_1;
int _variantField_36;
@@ -5065,6 +5066,12 @@
}
@override
+ LinkedNodeTypeBuilder get extensionOverride_extendedType {
+ assert(kind == idl.LinkedNodeKind.extensionOverride);
+ return _variantField_24;
+ }
+
+ @override
LinkedNodeTypeBuilder get invocationExpression_invokeType {
assert(kind == idl.LinkedNodeKind.functionExpressionInvocation ||
kind == idl.LinkedNodeKind.methodInvocation);
@@ -5094,6 +5101,11 @@
_variantField_24 = value;
}
+ set extensionOverride_extendedType(LinkedNodeTypeBuilder value) {
+ assert(kind == idl.LinkedNodeKind.extensionOverride);
+ _variantField_24 = value;
+ }
+
set invocationExpression_invokeType(LinkedNodeTypeBuilder value) {
assert(kind == idl.LinkedNodeKind.functionExpressionInvocation ||
kind == idl.LinkedNodeKind.methodInvocation);
@@ -5155,6 +5167,12 @@
}
@override
+ List<LinkedNodeBuilder> get extensionOverride_arguments {
+ assert(kind == idl.LinkedNodeKind.extensionOverride);
+ return _variantField_2 ??= <LinkedNodeBuilder>[];
+ }
+
+ @override
List<LinkedNodeBuilder> get formalParameterList_parameters {
assert(kind == idl.LinkedNodeKind.formalParameterList);
return _variantField_2 ??= <LinkedNodeBuilder>[];
@@ -5297,6 +5315,11 @@
_variantField_2 = value;
}
+ set extensionOverride_arguments(List<LinkedNodeBuilder> value) {
+ assert(kind == idl.LinkedNodeKind.extensionOverride);
+ _variantField_2 = value;
+ }
+
set formalParameterList_parameters(List<LinkedNodeBuilder> value) {
assert(kind == idl.LinkedNodeKind.formalParameterList);
_variantField_2 = value;
@@ -6419,6 +6442,12 @@
}
@override
+ LinkedNodeBuilder get extensionOverride_extensionName {
+ assert(kind == idl.LinkedNodeKind.extensionOverride);
+ return _variantField_7;
+ }
+
+ @override
LinkedNodeBuilder get fieldFormalParameter_typeParameters {
assert(kind == idl.LinkedNodeKind.fieldFormalParameter);
return _variantField_7;
@@ -6677,6 +6706,11 @@
_variantField_7 = value;
}
+ set extensionOverride_extensionName(LinkedNodeBuilder value) {
+ assert(kind == idl.LinkedNodeKind.extensionOverride);
+ _variantField_7 = value;
+ }
+
set fieldFormalParameter_typeParameters(LinkedNodeBuilder value) {
assert(kind == idl.LinkedNodeKind.fieldFormalParameter);
_variantField_7 = value;
@@ -6890,6 +6924,12 @@
}
@override
+ LinkedNodeBuilder get extensionOverride_typeArguments {
+ assert(kind == idl.LinkedNodeKind.extensionOverride);
+ return _variantField_8;
+ }
+
+ @override
LinkedNodeBuilder get fieldFormalParameter_formalParameters {
assert(kind == idl.LinkedNodeKind.fieldFormalParameter);
return _variantField_8;
@@ -6978,6 +7018,11 @@
_variantField_8 = value;
}
+ set extensionOverride_typeArguments(LinkedNodeBuilder value) {
+ assert(kind == idl.LinkedNodeKind.extensionOverride);
+ _variantField_8 = value;
+ }
+
set fieldFormalParameter_formalParameters(LinkedNodeBuilder value) {
assert(kind == idl.LinkedNodeKind.fieldFormalParameter);
_variantField_8 = value;
@@ -7739,6 +7784,17 @@
}
@override
+ List<LinkedNodeTypeBuilder> get extensionOverride_typeArgumentTypes {
+ assert(kind == idl.LinkedNodeKind.extensionOverride);
+ return _variantField_39 ??= <LinkedNodeTypeBuilder>[];
+ }
+
+ set extensionOverride_typeArgumentTypes(List<LinkedNodeTypeBuilder> value) {
+ assert(kind == idl.LinkedNodeKind.extensionOverride);
+ _variantField_39 = value;
+ }
+
+ @override
int get flags => _flags ??= 0;
set flags(int value) {
@@ -8387,6 +8443,19 @@
_variantField_20 = extensionDeclaration_refName,
_variantField_36 = informativeId;
+ LinkedNodeBuilder.extensionOverride({
+ LinkedNodeTypeBuilder extensionOverride_extendedType,
+ List<LinkedNodeBuilder> extensionOverride_arguments,
+ LinkedNodeBuilder extensionOverride_extensionName,
+ LinkedNodeBuilder extensionOverride_typeArguments,
+ List<LinkedNodeTypeBuilder> extensionOverride_typeArgumentTypes,
+ }) : _kind = idl.LinkedNodeKind.extensionOverride,
+ _variantField_24 = extensionOverride_extendedType,
+ _variantField_2 = extensionOverride_arguments,
+ _variantField_7 = extensionOverride_extensionName,
+ _variantField_8 = extensionOverride_typeArguments,
+ _variantField_39 = extensionOverride_typeArgumentTypes;
+
LinkedNodeBuilder.fieldDeclaration({
List<LinkedNodeBuilder> annotatedNode_metadata,
LinkedNodeBuilder fieldDeclaration_fields,
@@ -9245,6 +9314,12 @@
extensionDeclaration_extendedType?.flushInformative();
extensionDeclaration_members?.forEach((b) => b.flushInformative());
informativeId = null;
+ } else if (kind == idl.LinkedNodeKind.extensionOverride) {
+ extensionOverride_extendedType?.flushInformative();
+ extensionOverride_arguments?.forEach((b) => b.flushInformative());
+ extensionOverride_extensionName?.flushInformative();
+ extensionOverride_typeArguments?.flushInformative();
+ extensionOverride_typeArgumentTypes?.forEach((b) => b.flushInformative());
} else if (kind == idl.LinkedNodeKind.fieldDeclaration) {
annotatedNode_metadata?.forEach((b) => b.flushInformative());
fieldDeclaration_fields?.flushInformative();
@@ -10056,6 +10131,32 @@
signature.addInt(this.flags ?? 0);
signature.addString(this.extensionDeclaration_refName ?? '');
signature.addString(this.name ?? '');
+ } else if (kind == idl.LinkedNodeKind.extensionOverride) {
+ signature.addInt(this.kind == null ? 0 : this.kind.index);
+ if (this.extensionOverride_arguments == null) {
+ signature.addInt(0);
+ } else {
+ signature.addInt(this.extensionOverride_arguments.length);
+ for (var x in this.extensionOverride_arguments) {
+ x?.collectApiSignature(signature);
+ }
+ }
+ signature.addBool(this.extensionOverride_extensionName != null);
+ this.extensionOverride_extensionName?.collectApiSignature(signature);
+ signature.addBool(this.extensionOverride_typeArguments != null);
+ this.extensionOverride_typeArguments?.collectApiSignature(signature);
+ signature.addInt(this.flags ?? 0);
+ signature.addBool(this.extensionOverride_extendedType != null);
+ this.extensionOverride_extendedType?.collectApiSignature(signature);
+ signature.addString(this.name ?? '');
+ if (this.extensionOverride_typeArgumentTypes == null) {
+ signature.addInt(0);
+ } else {
+ signature.addInt(this.extensionOverride_typeArgumentTypes.length);
+ for (var x in this.extensionOverride_typeArgumentTypes) {
+ x?.collectApiSignature(signature);
+ }
+ }
} else if (kind == idl.LinkedNodeKind.fieldDeclaration) {
signature.addInt(this.kind == null ? 0 : this.kind.index);
if (this.annotatedNode_metadata == null) {
@@ -11146,6 +11247,7 @@
fb.Offset offset_variantField_10;
fb.Offset offset_variantField_25;
fb.Offset offset_variantField_20;
+ fb.Offset offset_variantField_39;
fb.Offset offset_variantField_1;
fb.Offset offset_variantField_30;
fb.Offset offset_variantField_14;
@@ -11208,6 +11310,10 @@
if (_variantField_20 != null) {
offset_variantField_20 = fbBuilder.writeString(_variantField_20);
}
+ if (!(_variantField_39 == null || _variantField_39.isEmpty)) {
+ offset_variantField_39 = fbBuilder
+ .writeList(_variantField_39.map((b) => b.finish(fbBuilder)).toList());
+ }
if (_variantField_1 != null) {
offset_variantField_1 = fbBuilder.writeString(_variantField_1);
}
@@ -11310,6 +11416,9 @@
if (offset_variantField_20 != null) {
fbBuilder.addOffset(20, offset_variantField_20);
}
+ if (offset_variantField_39 != null) {
+ fbBuilder.addOffset(39, offset_variantField_39);
+ }
if (_flags != null && _flags != 0) {
fbBuilder.addUint32(18, _flags);
}
@@ -11402,6 +11511,7 @@
double _variantField_21;
idl.LinkedNodeType _variantField_25;
String _variantField_20;
+ List<idl.LinkedNodeType> _variantField_39;
int _flags;
String _variantField_1;
int _variantField_36;
@@ -11451,6 +11561,14 @@
}
@override
+ idl.LinkedNodeType get extensionOverride_extendedType {
+ assert(kind == idl.LinkedNodeKind.extensionOverride);
+ _variantField_24 ??=
+ const _LinkedNodeTypeReader().vTableGet(_bc, _bcOffset, 24, null);
+ return _variantField_24;
+ }
+
+ @override
idl.LinkedNodeType get invocationExpression_invokeType {
assert(kind == idl.LinkedNodeKind.functionExpressionInvocation ||
kind == idl.LinkedNodeKind.methodInvocation);
@@ -11541,6 +11659,15 @@
}
@override
+ List<idl.LinkedNode> get extensionOverride_arguments {
+ assert(kind == idl.LinkedNodeKind.extensionOverride);
+ _variantField_2 ??=
+ const fb.ListReader<idl.LinkedNode>(const _LinkedNodeReader())
+ .vTableGet(_bc, _bcOffset, 2, const <idl.LinkedNode>[]);
+ return _variantField_2;
+ }
+
+ @override
List<idl.LinkedNode> get formalParameterList_parameters {
assert(kind == idl.LinkedNodeKind.formalParameterList);
_variantField_2 ??=
@@ -12494,6 +12621,14 @@
}
@override
+ idl.LinkedNode get extensionOverride_extensionName {
+ assert(kind == idl.LinkedNodeKind.extensionOverride);
+ _variantField_7 ??=
+ const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 7, null);
+ return _variantField_7;
+ }
+
+ @override
idl.LinkedNode get fieldFormalParameter_typeParameters {
assert(kind == idl.LinkedNodeKind.fieldFormalParameter);
_variantField_7 ??=
@@ -12798,6 +12933,14 @@
}
@override
+ idl.LinkedNode get extensionOverride_typeArguments {
+ assert(kind == idl.LinkedNodeKind.extensionOverride);
+ _variantField_8 ??=
+ const _LinkedNodeReader().vTableGet(_bc, _bcOffset, 8, null);
+ return _variantField_8;
+ }
+
+ @override
idl.LinkedNode get fieldFormalParameter_formalParameters {
assert(kind == idl.LinkedNodeKind.fieldFormalParameter);
_variantField_8 ??=
@@ -13373,6 +13516,15 @@
}
@override
+ List<idl.LinkedNodeType> get extensionOverride_typeArgumentTypes {
+ assert(kind == idl.LinkedNodeKind.extensionOverride);
+ _variantField_39 ??=
+ const fb.ListReader<idl.LinkedNodeType>(const _LinkedNodeTypeReader())
+ .vTableGet(_bc, _bcOffset, 39, const <idl.LinkedNodeType>[]);
+ return _variantField_39;
+ }
+
+ @override
int get flags {
_flags ??= const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 18, 0);
return _flags;
@@ -13970,6 +14122,26 @@
_result["extensionDeclaration_refName"] = extensionDeclaration_refName;
if (informativeId != 0) _result["informativeId"] = informativeId;
}
+ if (kind == idl.LinkedNodeKind.extensionOverride) {
+ if (extensionOverride_extendedType != null)
+ _result["extensionOverride_extendedType"] =
+ extensionOverride_extendedType.toJson();
+ if (extensionOverride_arguments.isNotEmpty)
+ _result["extensionOverride_arguments"] = extensionOverride_arguments
+ .map((_value) => _value.toJson())
+ .toList();
+ if (extensionOverride_extensionName != null)
+ _result["extensionOverride_extensionName"] =
+ extensionOverride_extensionName.toJson();
+ if (extensionOverride_typeArguments != null)
+ _result["extensionOverride_typeArguments"] =
+ extensionOverride_typeArguments.toJson();
+ if (extensionOverride_typeArgumentTypes.isNotEmpty)
+ _result["extensionOverride_typeArgumentTypes"] =
+ extensionOverride_typeArgumentTypes
+ .map((_value) => _value.toJson())
+ .toList();
+ }
if (kind == idl.LinkedNodeKind.fieldDeclaration) {
if (annotatedNode_metadata.isNotEmpty)
_result["annotatedNode_metadata"] =
@@ -15151,6 +15323,19 @@
"name": name,
};
}
+ if (kind == idl.LinkedNodeKind.extensionOverride) {
+ return {
+ "extensionOverride_extendedType": extensionOverride_extendedType,
+ "extensionOverride_arguments": extensionOverride_arguments,
+ "extensionOverride_extensionName": extensionOverride_extensionName,
+ "extensionOverride_typeArguments": extensionOverride_typeArguments,
+ "extensionOverride_typeArgumentTypes":
+ extensionOverride_typeArgumentTypes,
+ "flags": flags,
+ "kind": kind,
+ "name": name,
+ };
+ }
if (kind == idl.LinkedNodeKind.fieldDeclaration) {
return {
"annotatedNode_metadata": annotatedNode_metadata,
diff --git a/pkg/analyzer/lib/src/summary/format.fbs b/pkg/analyzer/lib/src/summary/format.fbs
index 4ce0eca..25ebd97 100644
--- a/pkg/analyzer/lib/src/summary/format.fbs
+++ b/pkg/analyzer/lib/src/summary/format.fbs
@@ -429,7 +429,9 @@
withClause,
- yieldStatement
+ yieldStatement,
+
+ extensionOverride
}
/// Kinds of [LinkedNodeType]s.
@@ -1961,6 +1963,8 @@
variantField_20:string (id: 20);
+ variantField_39:[LinkedNodeType] (id: 39);
+
flags:uint (id: 18);
variantField_1:string (id: 1);
diff --git a/pkg/analyzer/lib/src/summary/idl.dart b/pkg/analyzer/lib/src/summary/idl.dart
index 0ada341..de1760a 100644
--- a/pkg/analyzer/lib/src/summary/idl.dart
+++ b/pkg/analyzer/lib/src/summary/idl.dart
@@ -1189,6 +1189,21 @@
@VariantId(6, variant: LinkedNodeKind.extensionDeclaration)
LinkedNode get extensionDeclaration_typeParameters;
+ @VariantId(2, variant: LinkedNodeKind.extensionOverride)
+ List<LinkedNode> get extensionOverride_arguments;
+
+ @VariantId(24, variant: LinkedNodeKind.extensionOverride)
+ LinkedNodeType get extensionOverride_extendedType;
+
+ @VariantId(7, variant: LinkedNodeKind.extensionOverride)
+ LinkedNode get extensionOverride_extensionName;
+
+ @VariantId(8, variant: LinkedNodeKind.extensionOverride)
+ LinkedNode get extensionOverride_typeArguments;
+
+ @VariantId(39, variant: LinkedNodeKind.extensionOverride)
+ List<LinkedNodeType> get extensionOverride_typeArgumentTypes;
+
@VariantId(6, variant: LinkedNodeKind.fieldDeclaration)
LinkedNode get fieldDeclaration_fields;
@@ -1914,6 +1929,7 @@
whileStatement,
withClause,
yieldStatement,
+ extensionOverride,
}
/// Information about a single library in a [LinkedNodeBundle].
diff --git a/pkg/analyzer/lib/src/summary/link.dart b/pkg/analyzer/lib/src/summary/link.dart
index b3e3783..db8ae22 100644
--- a/pkg/analyzer/lib/src/summary/link.dart
+++ b/pkg/analyzer/lib/src/summary/link.dart
@@ -61,6 +61,7 @@
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/ast/standard_ast_factory.dart';
import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/dart/element/nullability_suffix.dart';
import 'package:analyzer/dart/element/type.dart';
import 'package:analyzer/error/listener.dart';
import 'package:analyzer/src/dart/ast/ast.dart';
@@ -84,6 +85,7 @@
import 'package:analyzer/src/summary/prelink.dart';
import 'package:analyzer/src/summary/resynthesize.dart';
import 'package:analyzer/src/task/strong_mode.dart';
+import 'package:meta/meta.dart';
final _typesWithImplicitArguments = new Expando();
@@ -486,6 +488,11 @@
@override
String get name;
+ @override
+ InterfaceType get thisType {
+ return type;
+ }
+
DartType get typeWithDefaultBounds => _typeWithDefaultBounds ??=
enclosingElement.library._linker.typeSystem.instantiateToBounds(type);
@@ -541,6 +548,23 @@
return null;
}
+ @override
+ InterfaceType instantiate({
+ @required List<DartType> typeArguments,
+ @required NullabilitySuffix nullabilitySuffix,
+ }) {
+ if (typeArguments.length != typeParameters.length) {
+ var ta = 'typeArguments.length (${typeArguments.length})';
+ var tp = 'typeParameters.length (${typeParameters.length})';
+ throw ArgumentError('$ta != $tp');
+ }
+ return InterfaceTypeImpl.explicit(
+ this,
+ typeArguments,
+ nullabilitySuffix: nullabilitySuffix,
+ );
+ }
+
/// Perform type inference and cycle detection on this class and
/// store the resulting information in [compilationUnit].
void link(CompilationUnitElementInBuildUnit compilationUnit);
@@ -5581,10 +5605,16 @@
_futureDynamicType ??= futureType.instantiate(<DartType>[dynamicType]);
@override
+ ClassElement get futureElement => futureType.element;
+
+ @override
InterfaceType get futureNullType =>
_futureNullType ??= futureType.instantiate(<DartType>[nullType]);
@override
+ ClassElement get futureOrElement => futureOrType.element;
+
+ @override
InterfaceType get futureOrNullType =>
_futureOrNullType ??= futureOrType.instantiate(<DartType>[nullType]);
@@ -5605,6 +5635,9 @@
iterableType.instantiate(<DartType>[dynamicType]);
@override
+ ClassElement get iterableElement => iterableType.element;
+
+ @override
InterfaceType get iterableObjectType =>
_iterableObjectType ??= iterableType.instantiate(<DartType>[objectType]);
@@ -5613,10 +5646,16 @@
_iterableType ??= _buildInterfaceType(_linker.coreLibrary, 'Iterable');
@override
+ ClassElement get listElement => listType.element;
+
+ @override
InterfaceType get listType =>
_listType ??= _buildInterfaceType(_linker.coreLibrary, 'List');
@override
+ ClassElement get mapElement => mapType.element;
+
+ @override
InterfaceType get mapObjectObjectType => _mapObjectObjectType ??=
mapType.instantiate(<DartType>[objectType, objectType]);
@@ -5646,6 +5685,9 @@
_objectType ??= _buildInterfaceType(_linker.coreLibrary, 'Object');
@override
+ ClassElement get setElement => setType.element;
+
+ @override
InterfaceType get setType =>
_setType ??= _buildInterfaceType(_linker.coreLibrary, 'Set');
@@ -5658,6 +5700,9 @@
_streamDynamicType ??= streamType.instantiate(<DartType>[dynamicType]);
@override
+ ClassElement get streamElement => streamType.element;
+
+ @override
InterfaceType get streamType =>
_streamType ??= _buildInterfaceType(_linker.asyncLibrary, 'Stream');
@@ -5666,6 +5711,9 @@
_stringType ??= _buildInterfaceType(_linker.coreLibrary, 'String');
@override
+ ClassElement get symbolElement => symbolType.element;
+
+ @override
InterfaceType get symbolType =>
_symbolType ??= _buildInterfaceType(_linker.coreLibrary, 'Symbol');
@@ -5676,6 +5724,41 @@
@override
VoidType get voidType => VoidTypeImpl.instance;
+ @override
+ InterfaceType futureOrType2(DartType valueType) {
+ return futureOrType.instantiate([valueType]);
+ }
+
+ @override
+ InterfaceType futureType2(DartType valueType) {
+ return futureType.instantiate([valueType]);
+ }
+
+ @override
+ InterfaceType iterableType2(DartType elementType) {
+ return iterableType.instantiate([elementType]);
+ }
+
+ @override
+ InterfaceType listType2(DartType elementType) {
+ return listType.instantiate([elementType]);
+ }
+
+ @override
+ InterfaceType mapType2(DartType keyType, DartType valueType) {
+ return mapType.instantiate([keyType, valueType]);
+ }
+
+ @override
+ InterfaceType setType2(DartType elementType) {
+ return setType.instantiate([elementType]);
+ }
+
+ @override
+ InterfaceType streamType2(DartType elementType) {
+ return streamType.instantiate([elementType]);
+ }
+
InterfaceType _buildInterfaceType(
LibraryElementForLink library, String name) {
return library.getContainedName(name).buildType((int i) {
diff --git a/pkg/analyzer/lib/src/summary/resynthesize.dart b/pkg/analyzer/lib/src/summary/resynthesize.dart
index 4cfe876..0b8c5ac 100644
--- a/pkg/analyzer/lib/src/summary/resynthesize.dart
+++ b/pkg/analyzer/lib/src/summary/resynthesize.dart
@@ -7,6 +7,7 @@
import 'package:analyzer/dart/analysis/session.dart';
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/dart/element/nullability_suffix.dart';
import 'package:analyzer/dart/element/type.dart';
import 'package:analyzer/src/dart/element/element.dart';
import 'package:analyzer/src/dart/element/handle.dart';
diff --git a/pkg/analyzer/lib/src/summary2/ast_binary_reader.dart b/pkg/analyzer/lib/src/summary2/ast_binary_reader.dart
index fef52b3..a0a089c 100644
--- a/pkg/analyzer/lib/src/summary2/ast_binary_reader.dart
+++ b/pkg/analyzer/lib/src/summary2/ast_binary_reader.dart
@@ -619,6 +619,24 @@
}
}
+ ExtensionOverride _read_extensionOverride(LinkedNode data) {
+ var node = astFactory.extensionOverride(
+ extensionName: _readNode(data.extensionOverride_extensionName),
+ argumentList: astFactory.argumentList(
+ _Tokens.OPEN_PAREN,
+ _readNodeList(
+ data.extensionOverride_arguments,
+ ),
+ _Tokens.CLOSE_PAREN,
+ ),
+ typeArguments: _readNode(data.extensionOverride_typeArguments),
+ ) as ExtensionOverrideImpl;
+ node.extendedType = _readType(data.extensionOverride_extendedType);
+ node.typeArgumentTypes =
+ data.extensionOverride_typeArgumentTypes.map(_readType).toList();
+ return node;
+ }
+
FieldDeclaration _read_fieldDeclaration(LinkedNode data) {
var node = astFactory.fieldDeclaration2(
comment: _readDocumentationComment(data),
@@ -1719,6 +1737,8 @@
return _read_extendsClause(data);
case LinkedNodeKind.extensionDeclaration:
return _read_extensionDeclaration(data);
+ case LinkedNodeKind.extensionOverride:
+ return _read_extensionOverride(data);
case LinkedNodeKind.fieldDeclaration:
return _read_fieldDeclaration(data);
case LinkedNodeKind.fieldFormalParameter:
diff --git a/pkg/analyzer/lib/src/summary2/ast_binary_writer.dart b/pkg/analyzer/lib/src/summary2/ast_binary_writer.dart
index 7ee9b12..c85acd5 100644
--- a/pkg/analyzer/lib/src/summary2/ast_binary_writer.dart
+++ b/pkg/analyzer/lib/src/summary2/ast_binary_writer.dart
@@ -520,6 +520,21 @@
}
@override
+ LinkedNodeBuilder visitExtensionOverride(ExtensionOverride node) {
+ var builder = LinkedNodeBuilder.extensionOverride(
+ extensionOverride_arguments: _writeNodeList(
+ node.argumentList.arguments,
+ ),
+ extensionOverride_extensionName: node.extensionName.accept(this),
+ extensionOverride_typeArguments: node.typeArguments?.accept(this),
+ extensionOverride_typeArgumentTypes:
+ node.typeArgumentTypes.map(_writeType).toList(),
+ extensionOverride_extendedType: _writeType(node.extendedType),
+ );
+ return builder;
+ }
+
+ @override
LinkedNodeBuilder visitFieldDeclaration(FieldDeclaration node) {
var builder = LinkedNodeBuilder.fieldDeclaration(
fieldDeclaration_fields: node.fields.accept(this),
diff --git a/pkg/analyzer/lib/src/summary2/function_type_builder.dart b/pkg/analyzer/lib/src/summary2/function_type_builder.dart
index 3153f3b..2a00807 100644
--- a/pkg/analyzer/lib/src/summary2/function_type_builder.dart
+++ b/pkg/analyzer/lib/src/summary2/function_type_builder.dart
@@ -4,6 +4,7 @@
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/dart/element/nullability_suffix.dart';
import 'package:analyzer/dart/element/type.dart';
import 'package:analyzer/src/dart/ast/ast.dart';
import 'package:analyzer/src/dart/element/element.dart';
diff --git a/pkg/analyzer/lib/src/summary2/linked_unit_context.dart b/pkg/analyzer/lib/src/summary2/linked_unit_context.dart
index 823fef5..6e15f41 100644
--- a/pkg/analyzer/lib/src/summary2/linked_unit_context.dart
+++ b/pkg/analyzer/lib/src/summary2/linked_unit_context.dart
@@ -6,6 +6,7 @@
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/ast/standard_ast_factory.dart';
import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/dart/element/nullability_suffix.dart';
import 'package:analyzer/dart/element/type.dart';
import 'package:analyzer/source/line_info.dart';
import 'package:analyzer/src/dart/ast/ast.dart';
diff --git a/pkg/analyzer/lib/src/summary2/linking_bundle_context.dart b/pkg/analyzer/lib/src/summary2/linking_bundle_context.dart
index 48b3541..6f003ab 100644
--- a/pkg/analyzer/lib/src/summary2/linking_bundle_context.dart
+++ b/pkg/analyzer/lib/src/summary2/linking_bundle_context.dart
@@ -3,6 +3,7 @@
// BSD-style license that can be found in the LICENSE file.
import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/dart/element/nullability_suffix.dart';
import 'package:analyzer/dart/element/type.dart';
import 'package:analyzer/src/dart/element/element.dart';
import 'package:analyzer/src/dart/element/member.dart';
diff --git a/pkg/analyzer/lib/src/summary2/named_type_builder.dart b/pkg/analyzer/lib/src/summary2/named_type_builder.dart
index ff94d7d..1aaa1cc 100644
--- a/pkg/analyzer/lib/src/summary2/named_type_builder.dart
+++ b/pkg/analyzer/lib/src/summary2/named_type_builder.dart
@@ -4,6 +4,7 @@
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/dart/element/nullability_suffix.dart';
import 'package:analyzer/dart/element/type.dart';
import 'package:analyzer/src/dart/element/element.dart';
import 'package:analyzer/src/dart/element/type.dart';
@@ -57,17 +58,11 @@
var element = this.element;
if (element is ClassElement) {
var parameters = element.typeParameters;
- if (parameters.isEmpty) {
- var rawType = element.type;
- _type = (rawType as TypeImpl).withNullability(nullabilitySuffix);
- } else {
- var arguments = _buildArguments(parameters);
- _type = InterfaceTypeImpl.explicit(
- element,
- arguments,
- nullabilitySuffix: nullabilitySuffix,
- );
- }
+ var arguments = _buildArguments(parameters);
+ _type = element.instantiate(
+ typeArguments: arguments,
+ nullabilitySuffix: nullabilitySuffix,
+ );
} else if (element is GenericTypeAliasElement) {
// Break a possible recursion.
_type = _dynamicType;
@@ -83,9 +78,12 @@
_type = substitution.substituteType(rawType);
}
} else if (element is NeverElementImpl) {
- _type = element.type.withNullability(nullabilitySuffix);
+ _type = BottomTypeImpl.instance.withNullability(nullabilitySuffix);
} else if (element is TypeParameterElement) {
- _type = TypeParameterTypeImpl(element);
+ _type = TypeParameterTypeImpl(
+ element,
+ nullabilitySuffix: nullabilitySuffix,
+ );
} else {
_type = _dynamicType;
}
@@ -108,7 +106,9 @@
/// Build arguments that correspond to the type [parameters].
List<DartType> _buildArguments(List<TypeParameterElement> parameters) {
- if (arguments.isNotEmpty) {
+ if (parameters.isEmpty) {
+ return const <DartType>[];
+ } else if (arguments.isNotEmpty) {
if (arguments.length == parameters.length) {
var result = List<DartType>(parameters.length);
for (int i = 0; i < result.length; ++i) {
diff --git a/pkg/analyzer/lib/src/summary2/reference_resolver.dart b/pkg/analyzer/lib/src/summary2/reference_resolver.dart
index 6392ba2..e55e10c 100644
--- a/pkg/analyzer/lib/src/summary2/reference_resolver.dart
+++ b/pkg/analyzer/lib/src/summary2/reference_resolver.dart
@@ -6,6 +6,7 @@
import 'package:analyzer/dart/ast/token.dart';
import 'package:analyzer/dart/ast/visitor.dart';
import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/dart/element/nullability_suffix.dart';
import 'package:analyzer/src/dart/ast/ast.dart';
import 'package:analyzer/src/dart/element/element.dart';
import 'package:analyzer/src/dart/element/type.dart';
diff --git a/pkg/analyzer/lib/src/summary2/types_builder.dart b/pkg/analyzer/lib/src/summary2/types_builder.dart
index e7733c3..b60d334 100644
--- a/pkg/analyzer/lib/src/summary2/types_builder.dart
+++ b/pkg/analyzer/lib/src/summary2/types_builder.dart
@@ -342,7 +342,7 @@
void _infer(ClassElementImpl element, WithClause withClause) {
element.linkedMixinInferenceCallback = _callbackWhenLoop;
try {
- _MixinInference(typeSystem, element.type).perform(withClause);
+ _MixinInference(typeSystem, element.thisType).perform(withClause);
} finally {
element.linkedMixinInferenceCallback = null;
}
diff --git a/pkg/analyzer/lib/src/task/strong/checker.dart b/pkg/analyzer/lib/src/task/strong/checker.dart
index 634baf4..ddf6cf8 100644
--- a/pkg/analyzer/lib/src/task/strong/checker.dart
+++ b/pkg/analyzer/lib/src/task/strong/checker.dart
@@ -12,6 +12,7 @@
import 'package:analyzer/dart/ast/token.dart';
import 'package:analyzer/dart/ast/visitor.dart';
import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/dart/element/nullability_suffix.dart';
import 'package:analyzer/dart/element/type.dart';
import 'package:analyzer/error/error.dart';
import 'package:analyzer/error/listener.dart';
@@ -139,6 +140,14 @@
bool get failure => _failure;
+ NullabilitySuffix get _noneOrStarSuffix {
+ return _nonNullableEnabled
+ ? NullabilitySuffix.none
+ : NullabilitySuffix.star;
+ }
+
+ bool get _nonNullableEnabled => _featureSet.isEnabled(Feature.non_nullable);
+
void checkArgument(Expression arg, DartType expectedType) {
// Preserve named argument structure, so their immediate parent is the
// method invocation.
@@ -184,13 +193,12 @@
} else if (element is SpreadElement) {
// Spread expression may be dynamic in which case it's implicitly downcast
// to Iterable<dynamic>
- DartType expressionCastType =
- typeProvider.iterableType.instantiate([DynamicTypeImpl.instance]);
+ DartType expressionCastType = typeProvider.iterableDynamicType;
checkAssignment(element.expression, expressionCastType);
var exprType = element.expression.staticType;
var asIterableType = exprType is InterfaceTypeImpl
- ? exprType.asInstanceOf(typeProvider.iterableType.element)
+ ? exprType.asInstanceOf(typeProvider.iterableElement)
: null;
var elementType =
asIterableType == null ? null : asIterableType.typeArguments[0];
@@ -223,13 +231,13 @@
} else if (element is SpreadElement) {
// Spread expression may be dynamic in which case it's implicitly downcast
// to Map<dynamic, dynamic>
- DartType expressionCastType = typeProvider.mapType
- .instantiate([DynamicTypeImpl.instance, DynamicTypeImpl.instance]);
+ DartType expressionCastType = typeProvider.mapType2(
+ DynamicTypeImpl.instance, DynamicTypeImpl.instance);
checkAssignment(element.expression, expressionCastType);
var exprType = element.expression.staticType;
var asMapType = exprType is InterfaceTypeImpl
- ? exprType.asInstanceOf(typeProvider.mapType.element)
+ ? exprType.asInstanceOf(typeProvider.mapElement)
: null;
var elementKeyType =
@@ -350,6 +358,7 @@
node.visitChildren(this);
}
+ // Check invocations
/// Check constructor declaration to ensure correct super call placement.
@override
void visitConstructorDeclaration(ConstructorDeclaration node) {
@@ -373,7 +382,6 @@
node.visitChildren(this);
}
- // Check invocations
@override
void visitDefaultFormalParameter(DefaultFormalParameter node) {
// Check that defaults have the proper subtype.
@@ -997,22 +1005,22 @@
var type = functionType.returnType;
- InterfaceType expectedType = null;
+ ClassElement expectedElement = null;
if (body.isAsynchronous) {
if (body.isGenerator) {
// Stream<T> -> T
- expectedType = typeProvider.streamType;
+ expectedElement = typeProvider.streamElement;
} else {
// Future<T> -> FutureOr<T>
- var typeArg = (type.element == typeProvider.futureType.element)
+ var typeArg = (type.element == typeProvider.futureElement)
? (type as InterfaceType).typeArguments[0]
: typeProvider.dynamicType;
- return typeProvider.futureOrType.instantiate([typeArg]);
+ return typeProvider.futureOrType2(typeArg);
}
} else {
if (body.isGenerator) {
// Iterable<T> -> T
- expectedType = typeProvider.iterableType;
+ expectedElement = typeProvider.iterableElement;
} else {
// T -> T
return type;
@@ -1021,7 +1029,10 @@
if (yieldStar) {
if (type.isDynamic) {
// Ensure it's at least a Stream / Iterable.
- return expectedType.instantiate([typeProvider.dynamicType]);
+ return expectedElement.instantiate(
+ typeArguments: [typeProvider.dynamicType],
+ nullabilitySuffix: _noneOrStarSuffix,
+ );
} else {
// Analyzer will provide a separate error if expected type
// is not compatible with type.
@@ -1030,7 +1041,7 @@
}
if (type.isDynamic) {
return type;
- } else if (type is InterfaceType && type.element == expectedType.element) {
+ } else if (type is InterfaceType && type.element == expectedElement) {
return type.typeArguments[0];
} else {
// Malformed type - fallback on analyzer error.
@@ -1128,7 +1139,7 @@
// In this case, we're more permissive than assignability.
if (to.isDartAsyncFutureOr) {
var to1 = (to as InterfaceType).typeArguments[0];
- var to2 = typeProvider.futureType.instantiate([to1]);
+ var to2 = typeProvider.futureType2(to1);
return _needsImplicitCast(expr, to1, from: from) == true ||
_needsImplicitCast(expr, to2, from: from) == true;
}
@@ -1353,19 +1364,20 @@
'Unexpected parent of ForEachParts: ${parent.runtimeType}');
}
// Find the element type of the sequence.
- var sequenceInterface = awaitKeyword != null
- ? typeProvider.streamType
- : typeProvider.iterableType;
+ var sequenceElement = awaitKeyword != null
+ ? typeProvider.streamElement
+ : typeProvider.iterableElement;
var iterableType = _getExpressionType(node.iterable);
- var elementType =
- _getInstanceTypeArgument(iterableType, sequenceInterface.element);
+ var elementType = _getInstanceTypeArgument(iterableType, sequenceElement);
// If the sequence is not an Iterable (or Stream for await for) but is a
// supertype of it, do an implicit downcast to Iterable<dynamic>. Then
// we'll do a separate cast of the dynamic element to the variable's type.
if (elementType == null) {
- var sequenceType =
- sequenceInterface.instantiate([DynamicTypeImpl.instance]);
+ var sequenceType = sequenceElement.instantiate(
+ typeArguments: [typeProvider.dynamicType],
+ nullabilitySuffix: _noneOrStarSuffix,
+ );
if (rules.isSubtypeOf(sequenceType, iterableType)) {
_recordImplicitCast(node.iterable, sequenceType, from: iterableType);
@@ -1393,7 +1405,7 @@
void check(Declaration node) {
var element = node.declaredElement as ClassElement;
- if (element.type.isObject) {
+ if (element.isDartCoreObject) {
return;
}
_checkForCovariantGenerics(node, element);
diff --git a/pkg/analyzer/lib/src/task/strong_mode.dart b/pkg/analyzer/lib/src/task/strong_mode.dart
index 7b86364c..21fcc0a 100644
--- a/pkg/analyzer/lib/src/task/strong_mode.dart
+++ b/pkg/analyzer/lib/src/task/strong_mode.dart
@@ -307,7 +307,7 @@
//
// Then infer the types for the members.
//
- this.interfaceType = classElement.type;
+ this.interfaceType = classElement.thisType;
for (FieldElement field in classElement.fields) {
_inferField(field);
}
diff --git a/pkg/analyzer/lib/src/test_utilities/find_node.dart b/pkg/analyzer/lib/src/test_utilities/find_node.dart
index e02ea7e..acef919 100644
--- a/pkg/analyzer/lib/src/test_utilities/find_node.dart
+++ b/pkg/analyzer/lib/src/test_utilities/find_node.dart
@@ -127,6 +127,10 @@
return _node(search, (n) => n is FunctionTypeAlias);
}
+ FunctionTypedFormalParameter functionTypedFormalParameter(String search) {
+ return _node(search, (n) => n is FunctionTypedFormalParameter);
+ }
+
GenericFunctionType genericFunctionType(String search) {
return _node(search, (n) => n is GenericFunctionType);
}
diff --git a/pkg/analyzer/lib/src/test_utilities/mock_sdk.dart b/pkg/analyzer/lib/src/test_utilities/mock_sdk.dart
index 382edb0..176212d 100644
--- a/pkg/analyzer/lib/src/test_utilities/mock_sdk.dart
+++ b/pkg/analyzer/lib/src/test_utilities/mock_sdk.dart
@@ -346,6 +346,7 @@
void addAll(Iterable<E> iterable) {}
void clear() {}
int indexOf(Object element);
+ E removeLast() {}
noSuchMethod(Invocation invocation) => null;
}
@@ -393,6 +394,7 @@
int operator ~/(num other);
num abs();
+ int floor();
int round();
double toDouble();
int toInt();
@@ -498,7 +500,147 @@
'$sdkRoot/lib/html/dart2js/html_dart2js.dart',
'''
library dart.html;
-class HtmlElement {}
+import 'dart:async';
+
+class Event {}
+class MouseEvent extends Event {}
+class FocusEvent extends Event {}
+class KeyEvent extends Event {}
+
+abstract class ElementStream<T extends Event> implements Stream<T> {}
+
+abstract class Element {
+ /// Stream of `cut` events handled by this [Element].
+ ElementStream<Event> get onCut => null;
+
+ String get id => null;
+
+ set id(String value) => null;
+}
+
+class HtmlElement extends Element {
+ int tabIndex;
+ ElementStream<Event> get onChange => null;
+ ElementStream<MouseEvent> get onClick => null;
+ ElementStream<KeyEvent> get onKeyUp => null;
+ ElementStream<KeyEvent> get onKeyDown => null;
+
+ bool get hidden => null;
+ set hidden(bool value) => null;
+
+ void set className(String s){}
+ void set readOnly(bool b){}
+ void set tabIndex(int i){}
+
+ String _innerHtml;
+ String get innerHtml {
+ throw 'not the real implementation';
+ }
+ set innerHtml(String value) {
+ // stuff
+ }
+}
+
+class AnchorElement extends HtmlElement {
+ factory AnchorElement({String href}) {
+ AnchorElement e = JS('returns:AnchorElement;creates:AnchorElement;new:true',
+ '#.createElement(#)', document, "a");
+ if (href != null) e.href = href;
+ return e;
+ }
+
+ String href;
+ String _privateField;
+}
+
+class BodyElement extends HtmlElement {
+ factory BodyElement() => document.createElement("body");
+
+ ElementStream<Event> get onUnload => null;
+}
+
+class ButtonElement extends HtmlElement {
+ factory ButtonElement._() { throw new UnsupportedError("Not supported"); }
+ factory ButtonElement() => document.createElement("button");
+
+ bool autofocus;
+}
+
+class HeadingElement extends HtmlElement {
+ factory HeadingElement._() { throw new UnsupportedError("Not supported"); }
+ factory HeadingElement.h1() => document.createElement("h1");
+ factory HeadingElement.h2() => document.createElement("h2");
+ factory HeadingElement.h3() => document.createElement("h3");
+}
+
+class InputElement extends HtmlElement {
+ factory InputElement._() { throw new UnsupportedError("Not supported"); }
+ factory InputElement() => document.createElement("input");
+
+ String value;
+ String validationMessage;
+}
+
+class IFrameElement extends HtmlElement {
+ factory IFrameElement._() { throw new UnsupportedError("Not supported"); }
+ factory IFrameElement() => JS(
+ 'returns:IFrameElement;creates:IFrameElement;new:true',
+ '#.createElement(#)',
+ document,
+ "iframe");
+
+ String src;
+}
+
+class OptionElement extends HtmlElement {
+ factory OptionElement({String data: '', String value : '', bool selected: false}) {
+ }
+
+ factory OptionElement._([String data, String value, bool defaultSelected, bool selected]) {
+ }
+}
+
+class TableSectionElement extends HtmlElement {
+
+ List<TableRowElement> get rows => null;
+
+ TableRowElement addRow() {
+ }
+
+ TableRowElement insertRow(int index) => null;
+
+ factory TableSectionElement._() { throw new UnsupportedError("Not supported"); }
+
+ @Deprecated("Internal Use Only")
+ external static Type get instanceRuntimeType;
+
+ @Deprecated("Internal Use Only")
+ TableSectionElement.internal_() : super.internal_();
+}
+
+class TemplateElement extends HtmlElement {
+ factory TemplateElement._() { throw new UnsupportedError("Not supported"); }
+ factory TemplateElement() => document.createElement("template");
+}
+
+class AudioElement extends MediaElement {
+ factory AudioElement._([String src]) {
+ if (src != null) {
+ return AudioElement._create_1(src);
+ }
+ return AudioElement._create_2();
+ }
+
+ static AudioElement _create_1(src) => JS('AudioElement', 'new Audio(#)', src);
+ static AudioElement _create_2() => JS('AudioElement', 'new Audio()');
+ AudioElement.created() : super.created();
+
+ factory AudioElement([String src]) => new AudioElement._(src);
+}
+
+class MediaElement extends Element {}
+
+dynamic JS(a, b, c, d) {}
''',
)
],
@@ -510,34 +652,148 @@
'dart:html',
'$sdkRoot/lib/html/dartium/html_dartium.dart',
'''
-library dart.dom.html;
+library dart.html;
+import 'dart:async';
-final HtmlDocument document;
+class Event {}
+class MouseEvent extends Event {}
+class FocusEvent extends Event {}
+class KeyEvent extends Event {}
-abstract class Element {}
+abstract class ElementStream<T extends Event> implements Stream<T> {}
-abstract class HtmlDocument {
- Element query(String relativeSelectors) => null;
+abstract class Element {
+ /// Stream of `cut` events handled by this [Element].
+ ElementStream<Event> get onCut => null;
+
+ String get id => null;
+
+ set id(String value) => null;
}
-abstract class HtmlElement extends Element {}
+class HtmlElement extends Element {
+ int tabIndex;
+ ElementStream<Event> get onChange => null;
+ ElementStream<MouseEvent> get onClick => null;
+ ElementStream<KeyEvent> get onKeyUp => null;
+ ElementStream<KeyEvent> get onKeyDown => null;
-abstract class AnchorElement extends HtmlElement {}
-abstract class BodyElement extends HtmlElement {}
-abstract class ButtonElement extends HtmlElement {}
-abstract class DivElement extends HtmlElement {}
-abstract class InputElement extends HtmlElement {}
-abstract class SelectElement extends HtmlElement {}
+ bool get hidden => null;
+ set hidden(bool value) => null;
+ void set className(String s){}
+ void set readOnly(bool b){}
+ void set tabIndex(int i){}
-abstract class CanvasElement extends HtmlElement {
- Object getContext(String contextId, [Map attributes]);
- CanvasRenderingContext2D get context2D;
+ String _innerHtml;
+ String get innerHtml {
+ throw 'not the real implementation';
+ }
+ set innerHtml(String value) {
+ // stuff
+ }
}
-abstract class CanvasRenderingContext2D {}
+class AnchorElement extends HtmlElement {
+ factory AnchorElement({String href}) {
+ AnchorElement e = JS('returns:AnchorElement;creates:AnchorElement;new:true',
+ '#.createElement(#)', document, "a");
+ if (href != null) e.href = href;
+ return e;
+ }
-Element query(String relativeSelectors) => null;
+ String href;
+ String _privateField;
+}
+
+class BodyElement extends HtmlElement {
+ factory BodyElement() => document.createElement("body");
+
+ ElementStream<Event> get onUnload => null;
+}
+
+class ButtonElement extends HtmlElement {
+ factory ButtonElement._() { throw new UnsupportedError("Not supported"); }
+ factory ButtonElement() => document.createElement("button");
+
+ bool autofocus;
+}
+
+class HeadingElement extends HtmlElement {
+ factory HeadingElement._() { throw new UnsupportedError("Not supported"); }
+ factory HeadingElement.h1() => document.createElement("h1");
+ factory HeadingElement.h2() => document.createElement("h2");
+ factory HeadingElement.h3() => document.createElement("h3");
+}
+
+class InputElement extends HtmlElement {
+ factory InputElement._() { throw new UnsupportedError("Not supported"); }
+ factory InputElement() => document.createElement("input");
+
+ String value;
+ String validationMessage;
+}
+
+class IFrameElement extends HtmlElement {
+ factory IFrameElement._() { throw new UnsupportedError("Not supported"); }
+ factory IFrameElement() => JS(
+ 'returns:IFrameElement;creates:IFrameElement;new:true',
+ '#.createElement(#)',
+ document,
+ "iframe");
+
+ String src;
+}
+
+class OptionElement extends HtmlElement {
+ factory OptionElement({String data: '', String value : '', bool selected: false}) {
+ }
+
+ factory OptionElement._([String data, String value, bool defaultSelected, bool selected]) {
+ }
+}
+
+class TableSectionElement extends HtmlElement {
+
+ List<TableRowElement> get rows => null;
+
+ TableRowElement addRow() {
+ }
+
+ TableRowElement insertRow(int index) => null;
+
+ factory TableSectionElement._() { throw new UnsupportedError("Not supported"); }
+
+ @Deprecated("Internal Use Only")
+ external static Type get instanceRuntimeType;
+
+ @Deprecated("Internal Use Only")
+ TableSectionElement.internal_() : super.internal_();
+}
+
+class TemplateElement extends HtmlElement {
+ factory TemplateElement._() { throw new UnsupportedError("Not supported"); }
+ factory TemplateElement() => document.createElement("template");
+}
+
+class AudioElement extends MediaElement {
+ factory AudioElement._([String src]) {
+ if (src != null) {
+ return AudioElement._create_1(src);
+ }
+ return AudioElement._create_2();
+ }
+
+ static AudioElement _create_1(src) => JS('AudioElement', 'new Audio(#)', src);
+ static AudioElement _create_2() => JS('AudioElement', 'new Audio()');
+ AudioElement.created() : super.created();
+
+ factory AudioElement([String src]) => new AudioElement._(src);
+}
+
+class MediaElement extends Element {}
+
+dynamic JS(a, b, c, d) {}
''',
)
],
diff --git a/pkg/analyzer/lib/src/test_utilities/mock_sdk_elements.dart b/pkg/analyzer/lib/src/test_utilities/mock_sdk_elements.dart
index 856b19b..85d5856 100644
--- a/pkg/analyzer/lib/src/test_utilities/mock_sdk_elements.dart
+++ b/pkg/analyzer/lib/src/test_utilities/mock_sdk_elements.dart
@@ -3,6 +3,7 @@
// BSD-style license that can be found in the LICENSE file.
import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/dart/element/nullability_suffix.dart';
import 'package:analyzer/dart/element/type.dart';
import 'package:analyzer/src/dart/element/element.dart';
import 'package:analyzer/src/dart/element/type.dart';
diff --git a/pkg/analyzer/pubspec.yaml b/pkg/analyzer/pubspec.yaml
index 5314552..67ae027 100644
--- a/pkg/analyzer/pubspec.yaml
+++ b/pkg/analyzer/pubspec.yaml
@@ -1,5 +1,5 @@
name: analyzer
-version: 0.38.2
+version: 0.38.3
author: Dart Team <misc@dartlang.org>
description: This package provides a library that performs static analysis of Dart code.
homepage: https://github.com/dart-lang/sdk/tree/master/pkg/analyzer
@@ -13,10 +13,10 @@
collection: ^1.10.1
convert: ^2.0.0
crypto: '>=1.1.1 <3.0.0'
- front_end: 0.1.24
+ front_end: 0.1.25
glob: ^1.0.3
html: '>=0.13.4+1 <0.15.0'
- kernel: 0.3.24
+ kernel: 0.3.25
meta: ^1.0.2
package_config: '>=0.1.5 <2.0.0'
path: '>=0.9.0 <2.0.0'
diff --git a/pkg/analyzer/test/cancelable_future_test.dart b/pkg/analyzer/test/cancelable_future_test.dart
deleted file mode 100644
index 4f840aa..0000000
--- a/pkg/analyzer/test/cancelable_future_test.dart
+++ /dev/null
@@ -1,425 +0,0 @@
-// Copyright (c) 2014, 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.
-
-import 'dart:async';
-
-import 'package:analyzer/src/cancelable_future.dart';
-import 'package:test/test.dart';
-import 'package:test_reflective_loader/test_reflective_loader.dart';
-
-void main() {
- defineReflectiveSuite(() {
- defineReflectiveTests(CancelableCompleterTests);
- defineReflectiveTests(CancelableFutureTests);
- });
-}
-
-@reflectiveTest
-class CancelableCompleterTests {
- CancelableCompleter<Object> completer;
- int cancelCount = 0;
-
- void setUp() {
- completer = new CancelableCompleter<Object>(() {
- cancelCount++;
- });
- }
-
- Future test_cancel_after_cancel() {
- // It is permissible to cancel multiple times, but only the first
- // cancellation has any effect.
- expect(cancelCount, 0);
- completer.future.cancel();
- expect(cancelCount, 1);
- completer.future.cancel();
- expect(cancelCount, 1);
- // Make sure the future still completes with error.
- return completer.future
- .then((_) {
- fail('Expected error completion');
- }, onError: (error) {
- expect(error, new TypeMatcher<FutureCanceledError>());
- // And make sure nothing else happens.
- })
- .then((_) => pumpEventQueue())
- .then((_) {
- expect(completer.isCompleted, isFalse);
- expect(cancelCount, 1);
- });
- }
-
- Future test_cancel_after_chaining() {
- bool callbackInvoked = false;
- completer.future.then((_) {
- fail('Expected error completion');
- }, onError: (error) {
- expect(callbackInvoked, isFalse);
- expect(error, new TypeMatcher<FutureCanceledError>());
- callbackInvoked = true;
- });
- expect(cancelCount, 0);
- completer.future.cancel();
- // The cancel callback should have been invoked immediately.
- expect(cancelCount, 1);
- // But the completer should remain in the "not completed" state.
- expect(completer.isCompleted, isFalse);
- // The callback should be deferred to a microtask.
- expect(callbackInvoked, isFalse);
- return pumpEventQueue().then((_) {
- expect(callbackInvoked, isTrue);
- expect(completer.isCompleted, isFalse);
- expect(cancelCount, 1);
- });
- }
-
- Future test_cancel_after_complete() {
- Object obj = new Object();
- completer.complete(obj);
- completer.future.cancel();
- // The cancel callback should not have been invoked, because it was too
- // late to cancel.
- expect(cancelCount, 0);
- // Make sure the future still completes with the object.
- return completer.future
- .then((result) {
- expect(result, same(obj));
- // And make sure nothing else happens.
- })
- .then((_) => pumpEventQueue())
- .then((_) {
- expect(completer.isCompleted, isTrue);
- expect(cancelCount, 0);
- });
- }
-
- Future test_cancel_before_chaining() {
- completer.future.cancel();
- // The cancel callback should have been invoked immediately.
- expect(cancelCount, 1);
- // But the completer should remain in the "not completed" state.
- expect(completer.isCompleted, isFalse);
- bool callbackInvoked = false;
- completer.future.then((_) {
- fail('Expected error completion');
- }, onError: (error) {
- expect(callbackInvoked, isFalse);
- expect(error, new TypeMatcher<FutureCanceledError>());
- callbackInvoked = true;
- });
- // The callback should be deferred to a microtask.
- expect(callbackInvoked, isFalse);
- expect(completer.isCompleted, isFalse);
- return pumpEventQueue().then((_) {
- expect(callbackInvoked, isTrue);
- expect(completer.isCompleted, isFalse);
- expect(cancelCount, 1);
- });
- }
-
- Future test_complete_after_cancel() {
- completer.future.cancel();
- // The cancel callback should have been invoked immediately.
- expect(cancelCount, 1);
- // Completing should have no effect other than to set the isCompleted
- // flag.
- expect(completer.isCompleted, isFalse);
- Object obj = new Object();
- completer.complete(obj);
- expect(completer.isCompleted, isTrue);
- // Make sure the future still completer with error.
- return completer.future
- .then((_) {
- fail('Expected error completion');
- }, onError: (error) {
- expect(error, new TypeMatcher<FutureCanceledError>());
- // And make sure nothing else happens.
- })
- .then((_) => pumpEventQueue())
- .then((_) {
- expect(completer.isCompleted, isTrue);
- expect(cancelCount, 1);
- });
- }
-
- Future test_complete_after_chaining() {
- Object obj = new Object();
- bool callbackInvoked = false;
- completer.future.then((result) {
- expect(callbackInvoked, isFalse);
- expect(result, same(obj));
- callbackInvoked = true;
- }, onError: (error) {
- fail('Expected successful completion');
- });
- expect(completer.isCompleted, isFalse);
- // Running the event loop should have no effect since the completer hasn't
- // been completed yet.
- return pumpEventQueue()
- .then((_) {
- completer.complete(obj);
- expect(completer.isCompleted, isTrue);
- // The callback should be deferred to a microtask.
- expect(callbackInvoked, isFalse);
- })
- .then((_) => pumpEventQueue())
- .then((_) {
- expect(callbackInvoked, isTrue);
- expect(completer.isCompleted, isTrue);
- expect(cancelCount, 0);
- });
- }
-
- void test_complete_after_complete() {
- // As with an ordinary Completer, calling complete() (or completeError)
- // after calling complete() should throw an exception.
- completer.complete();
- expect(() {
- completer.complete();
- }, throwsStateError);
- expect(() {
- completer.completeError(new Object());
- }, throwsStateError);
- }
-
- void test_complete_after_completeError() {
- // As with an ordinary Completer, calling complete() (or completeError)
- // after calling completeError() should throw an exception.
- completer.completeError(new Object());
- expect(() {
- completer.complete();
- }, throwsStateError);
- expect(() {
- completer.completeError(new Object());
- }, throwsStateError);
- // Now absorb the error that's in the completer's future.
- completer.future.catchError((_) => null);
- }
-
- Future test_complete_before_chaining() {
- Object obj = new Object();
- completer.complete(obj);
- expect(completer.isCompleted, isTrue);
- bool callbackInvoked = false;
- completer.future.then((result) {
- expect(callbackInvoked, isFalse);
- expect(result, same(obj));
- callbackInvoked = true;
- }, onError: (error) {
- fail('Expected successful completion');
- });
- // The callback should be deferred to a microtask.
- expect(callbackInvoked, isFalse);
- expect(completer.isCompleted, isTrue);
- return pumpEventQueue().then((_) {
- expect(callbackInvoked, isTrue);
- expect(completer.isCompleted, isTrue);
- expect(cancelCount, 0);
- });
- }
-
- Future test_completeError_after_cancel() {
- completer.future.cancel();
- // The cancel callback should have been invoked immediately.
- expect(cancelCount, 1);
- // Completing should have no effect other than to set the isCompleted
- // flag.
- expect(completer.isCompleted, isFalse);
- Object obj = new Object();
- completer.completeError(obj);
- expect(completer.isCompleted, isTrue);
- // Make sure the future still completes with error.
- return completer.future
- .then((_) {
- fail('Expected error completion');
- }, onError: (error) {
- expect(error, new TypeMatcher<FutureCanceledError>());
- // And make sure nothing else happens.
- })
- .then((_) => pumpEventQueue())
- .then((_) {
- expect(completer.isCompleted, isTrue);
- expect(cancelCount, 1);
- });
- }
-
- Future test_completeError_after_chaining() {
- Object obj = new Object();
- bool callbackInvoked = false;
- completer.future.then((_) {
- fail('Expected error completion');
- }, onError: (error) {
- expect(callbackInvoked, isFalse);
- expect(error, same(obj));
- callbackInvoked = true;
- });
- expect(completer.isCompleted, isFalse);
- // Running the event loop should have no effect since the completer hasn't
- // been completed yet.
- return pumpEventQueue()
- .then((_) {
- completer.completeError(obj);
- expect(completer.isCompleted, isTrue);
- // The callback should be deferred to a microtask.
- expect(callbackInvoked, isFalse);
- })
- .then((_) => pumpEventQueue())
- .then((_) {
- expect(callbackInvoked, isTrue);
- expect(completer.isCompleted, isTrue);
- expect(cancelCount, 0);
- });
- }
-
- Future test_completeError_before_chaining() {
- Object obj = new Object();
- completer.completeError(obj);
- expect(completer.isCompleted, isTrue);
- bool callbackInvoked = false;
- completer.future.then((_) {
- fail('Expected error completion');
- }, onError: (error) {
- expect(callbackInvoked, isFalse);
- expect(error, same(obj));
- callbackInvoked = true;
- });
- // The callback should be deferred to a microtask.
- expect(callbackInvoked, isFalse);
- expect(completer.isCompleted, isTrue);
- return pumpEventQueue().then((_) {
- expect(callbackInvoked, isTrue);
- expect(completer.isCompleted, isTrue);
- expect(cancelCount, 0);
- });
- }
-
- void test_initialState() {
- expect(completer.isCompleted, isFalse);
- expect(cancelCount, 0);
- }
-}
-
-@reflectiveTest
-class CancelableFutureTests {
- Future test_defaultConstructor_returnFuture() {
- Object obj = new Object();
- bool callbackInvoked = false;
- new CancelableFuture(() => new Future(() => obj)).then((result) {
- expect(callbackInvoked, isFalse);
- expect(result, same(obj));
- callbackInvoked = true;
- }, onError: (error) {
- fail('Expected successful completion');
- });
- expect(callbackInvoked, isFalse);
- return pumpEventQueue().then((_) {
- expect(callbackInvoked, isTrue);
- });
- }
-
- Future test_defaultConstructor_returnValue() {
- Object obj = new Object();
- bool callbackInvoked = false;
- new CancelableFuture(() => obj).then((result) {
- expect(callbackInvoked, isFalse);
- expect(result, same(obj));
- callbackInvoked = true;
- }, onError: (error) {
- fail('Expected successful completion');
- });
- expect(callbackInvoked, isFalse);
- return pumpEventQueue().then((_) {
- expect(callbackInvoked, isTrue);
- });
- }
-
- Future test_defaultConstructor_throwException() {
- Object obj = new Object();
- bool callbackInvoked = false;
- new CancelableFuture(() {
- throw obj;
- }).then((result) {
- fail('Expected error completion');
- }, onError: (error) {
- expect(callbackInvoked, isFalse);
- expect(error, same(obj));
- callbackInvoked = true;
- });
- expect(callbackInvoked, isFalse);
- return pumpEventQueue().then((_) {
- expect(callbackInvoked, isTrue);
- });
- }
-
- Future test_delayed_noCallback() {
- DateTime start = new DateTime.now();
- return new CancelableFuture.delayed(new Duration(seconds: 1))
- .then((result) {
- DateTime end = new DateTime.now();
- expect(result, isNull);
- expect(end.difference(start).inMilliseconds > 900, isTrue);
- });
- }
-
- Future test_delayed_withCallback() {
- Object obj = new Object();
- DateTime start = new DateTime.now();
- return new CancelableFuture.delayed(new Duration(seconds: 1), () {
- DateTime end = new DateTime.now();
- expect(end.difference(start).inMilliseconds > 900, isTrue);
- return obj;
- }).then((result) {
- expect(result, same(obj));
- });
- }
-
- Future test_error() {
- Object obj = new Object();
- return new CancelableFuture.error(obj).then((result) {
- fail('Expected error completion');
- }, onError: (error) {
- expect(error, same(obj));
- });
- }
-
- Future test_microtask() {
- Object obj = new Object();
- bool callbackInvoked = false;
- new CancelableFuture.microtask(() => obj).then((result) {
- expect(callbackInvoked, isFalse);
- expect(result, same(obj));
- callbackInvoked = true;
- }, onError: (error) {
- fail('Expected successful completion');
- });
- expect(callbackInvoked, isFalse);
- return pumpEventQueue().then((_) {
- expect(callbackInvoked, isTrue);
- });
- }
-
- Future test_sync() {
- Object obj = new Object();
- bool callbackInvoked = false;
- new CancelableFuture.sync(() => obj).then((result) {
- expect(callbackInvoked, isFalse);
- expect(result, same(obj));
- callbackInvoked = true;
- }, onError: (error) {
- fail('Expected successful completion');
- });
- expect(callbackInvoked, isFalse);
- return pumpEventQueue().then((_) {
- expect(callbackInvoked, isTrue);
- });
- }
-
- Future test_value() {
- Object obj = new Object();
- return new CancelableFuture.value(obj).then((result) {
- expect(result, same(obj));
- }, onError: (error) {
- fail('Expected successful completion');
- });
- }
-}
diff --git a/pkg/analyzer/test/dart/ast/ast_test.dart b/pkg/analyzer/test/dart/ast/ast_test.dart
index 9c90698..163cb6c 100644
--- a/pkg/analyzer/test/dart/ast/ast_test.dart
+++ b/pkg/analyzer/test/dart/ast/ast_test.dart
@@ -26,8 +26,10 @@
defineReflectiveTests(FieldFormalParameterTest);
defineReflectiveTests(IndexExpressionTest);
defineReflectiveTests(MethodDeclarationTest);
+ defineReflectiveTests(MethodInvocationTest);
defineReflectiveTests(NodeListTest);
defineReflectiveTests(PreviousTokenTest);
+ defineReflectiveTests(PropertyAccessTest);
defineReflectiveTests(SimpleIdentifierTest);
defineReflectiveTests(SimpleStringLiteralTest);
defineReflectiveTests(SpreadElementTest);
@@ -322,6 +324,22 @@
AstTestFactory.prefixExpression(TokenType.PLUS_PLUS, expression);
expect(expression.inSetterContext(), isTrue);
}
+
+ void test_isNullAware_regularIndex() {
+ final expression = AstTestFactory.indexExpression(
+ AstTestFactory.nullLiteral(),
+ AstTestFactory.nullLiteral(),
+ TokenType.OPEN_SQUARE_BRACKET);
+ expect(expression.isNullAware, isFalse);
+ }
+
+ void test_isNullAware_true() {
+ final expression = AstTestFactory.indexExpression(
+ AstTestFactory.nullLiteral(),
+ AstTestFactory.nullLiteral(),
+ TokenType.QUESTION_PERIOD_OPEN_SQUARE_BRACKET);
+ expect(expression.isNullAware, isTrue);
+ }
}
@reflectiveTest
@@ -363,6 +381,31 @@
}
@reflectiveTest
+class MethodInvocationTest extends ParserTestCase {
+ void test_isNullAware_cascade() {
+ final invocation = AstTestFactory.methodInvocation3(
+ AstTestFactory.nullLiteral(), 'foo', null, [], TokenType.PERIOD_PERIOD);
+ expect(invocation.isNullAware, isFalse);
+ }
+
+ void test_isNullAware_regularInvocation() {
+ final invocation = AstTestFactory.methodInvocation3(
+ AstTestFactory.nullLiteral(), 'foo', null, [], TokenType.PERIOD);
+ expect(invocation.isNullAware, isFalse);
+ }
+
+ void test_isNullAware_true() {
+ final invocation = AstTestFactory.methodInvocation3(
+ AstTestFactory.nullLiteral(),
+ 'foo',
+ null,
+ [],
+ TokenType.QUESTION_PERIOD);
+ expect(invocation.isNullAware, isTrue);
+ }
+}
+
+@reflectiveTest
class NodeListTest extends EngineTestCase {
void test_add() {
AstNode parent = AstTestFactory.argumentList();
@@ -712,6 +755,27 @@
}
@reflectiveTest
+class PropertyAccessTest extends ParserTestCase {
+ void test_isNullAware_cascade() {
+ final invocation = AstTestFactory.propertyAccess2(
+ AstTestFactory.nullLiteral(), 'foo', TokenType.PERIOD_PERIOD);
+ expect(invocation.isNullAware, isFalse);
+ }
+
+ void test_isNullAware_regularPropertyAccess() {
+ final invocation = AstTestFactory.propertyAccess2(
+ AstTestFactory.nullLiteral(), 'foo', TokenType.PERIOD);
+ expect(invocation.isNullAware, isFalse);
+ }
+
+ void test_isNullAware_true() {
+ final invocation = AstTestFactory.propertyAccess2(
+ AstTestFactory.nullLiteral(), 'foo', TokenType.QUESTION_PERIOD);
+ expect(invocation.isNullAware, isTrue);
+ }
+}
+
+@reflectiveTest
class SimpleIdentifierTest extends ParserTestCase {
void test_inGetterContext() {
for (_WrapperKind wrapper in _WrapperKind.values) {
diff --git a/pkg/analyzer/test/dart/element/builder_test.dart b/pkg/analyzer/test/dart/element/builder_test.dart
index adfcf2e..92d475a 100644
--- a/pkg/analyzer/test/dart/element/builder_test.dart
+++ b/pkg/analyzer/test/dart/element/builder_test.dart
@@ -6,6 +6,7 @@
import 'package:analyzer/dart/ast/standard_ast_factory.dart';
import 'package:analyzer/dart/ast/token.dart';
import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/dart/element/nullability_suffix.dart';
import 'package:analyzer/src/dart/ast/ast.dart';
import 'package:analyzer/src/dart/element/builder.dart';
import 'package:analyzer/src/dart/element/element.dart';
@@ -2540,7 +2541,13 @@
expect(alias, isNotNull);
assertHasCodeRange(alias, 50, 31);
expect(alias.name, aliasName);
- expect(alias.type, isNotNull);
+ expect(
+ alias.instantiate2(
+ typeArguments: [],
+ nullabilitySuffix: NullabilitySuffix.none,
+ ),
+ isNotNull,
+ );
expect(alias.isSynthetic, isFalse);
List<VariableElement> parameters = alias.parameters;
expect(parameters, hasLength(2));
@@ -2567,7 +2574,6 @@
GenericTypeAliasElementImpl alias = aliases[0];
expect(alias, isNotNull);
expect(alias.name, aliasName);
- expect(alias.type, isNotNull);
expect(alias.isSynthetic, isFalse);
List<VariableElement> parameters = alias.parameters;
expect(parameters, isNotNull);
diff --git a/pkg/analyzer/test/error/error_reporter_test.dart b/pkg/analyzer/test/error/error_reporter_test.dart
index eeb2468..a796291 100644
--- a/pkg/analyzer/test/error/error_reporter_test.dart
+++ b/pkg/analyzer/test/error/error_reporter_test.dart
@@ -2,6 +2,7 @@
// 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.
+import 'package:analyzer/dart/element/nullability_suffix.dart';
import 'package:analyzer/error/listener.dart';
import 'package:analyzer/src/error/codes.dart';
import 'package:source_span/source_span.dart';
@@ -106,8 +107,14 @@
var aImport = findElement.importFind('package:test/a.dart');
var bImport = findElement.importFind('package:test/b.dart');
- var firstType = aImport.class_('A').type;
- var secondType = bImport.class_('B').type;
+ var firstType = aImport.class_('A').instantiate(
+ typeArguments: [],
+ nullabilitySuffix: NullabilitySuffix.none,
+ );
+ var secondType = bImport.class_('B').instantiate(
+ typeArguments: [],
+ nullabilitySuffix: NullabilitySuffix.none,
+ );
var reporter = ErrorReporter(listener, firstType.element.source);
@@ -137,8 +144,14 @@
var aImport = findElement.importFind('package:test/a.dart');
var bImport = findElement.importFind('package:test/b.dart');
- var firstType = aImport.class_('A').type;
- var secondType = bImport.class_('A').type;
+ var firstType = aImport.class_('A').instantiate(
+ typeArguments: [],
+ nullabilitySuffix: NullabilitySuffix.none,
+ );
+ var secondType = bImport.class_('A').instantiate(
+ typeArguments: [],
+ nullabilitySuffix: NullabilitySuffix.none,
+ );
var reporter = ErrorReporter(listener, firstType.element.source);
reporter.reportTypeErrorForNode(
diff --git a/pkg/analyzer/test/file_system/memory_file_system_test.dart b/pkg/analyzer/test/file_system/memory_file_system_test.dart
index 443e842..76ee1651 100644
--- a/pkg/analyzer/test/file_system/memory_file_system_test.dart
+++ b/pkg/analyzer/test/file_system/memory_file_system_test.dart
@@ -114,10 +114,6 @@
expect(contents.data, defaultFileContent);
}
- test_encoding() {
- expect(source.encoding, new Uri.file(defaultFilePath).toString());
- }
-
test_equals_false_differentFile() {
File fileA = getFile(exists: false, filePath: join(tempPath, 'a.dart'));
File fileB = getFile(exists: false, filePath: join(tempPath, 'b.dart'));
@@ -196,10 +192,6 @@
expect(() => source.contents, throwsA(isFileSystemException));
}
- test_encoding() {
- expect(source.encoding, new Uri.file(defaultFilePath).toString());
- }
-
test_exists() {
expect(source.exists(), isFalse);
}
diff --git a/pkg/analyzer/test/generated/all_the_rest_test.dart b/pkg/analyzer/test/generated/all_the_rest_test.dart
index 7e37544..a0153b8 100644
--- a/pkg/analyzer/test/generated/all_the_rest_test.dart
+++ b/pkg/analyzer/test/generated/all_the_rest_test.dart
@@ -2,24 +2,15 @@
// 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.
-import 'package:analyzer/dart/ast/ast.dart';
-import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/error/error.dart';
import 'package:analyzer/file_system/file_system.dart';
import 'package:analyzer/file_system/physical_file_system.dart';
-import 'package:analyzer/src/dart/element/builder.dart';
-import 'package:analyzer/src/dart/element/element.dart';
import 'package:analyzer/src/dart/sdk/sdk.dart' hide SdkLibrariesReader;
-import 'package:analyzer/src/file_system/file_system.dart';
import 'package:analyzer/src/generated/java_engine_io.dart';
import 'package:analyzer/src/generated/java_io.dart';
-import 'package:analyzer/src/generated/resolver.dart';
import 'package:analyzer/src/generated/sdk.dart';
import 'package:analyzer/src/generated/source.dart';
import 'package:analyzer/src/generated/source_io.dart';
-import 'package:analyzer/src/generated/testing/ast_test_factory.dart';
-import 'package:analyzer/src/generated/testing/test_type_provider.dart';
-import 'package:analyzer/src/generated/testing/token_factory.dart';
import 'package:analyzer/src/generated/utilities_dart.dart';
import 'package:analyzer/src/test_utilities/resource_provider_mixin.dart';
import 'package:test/test.dart';
@@ -33,7 +24,6 @@
// ignore: deprecated_member_use_from_same_package
defineReflectiveTests(CustomUriResolverTest);
defineReflectiveTests(DartUriResolverTest);
- defineReflectiveTests(EnumMemberBuilderTest);
defineReflectiveTests(ErrorSeverityTest);
defineReflectiveTests(FileBasedSourceTest);
defineReflectiveTests(ResolveRelativeUriTest);
@@ -144,100 +134,6 @@
}
@reflectiveTest
-class EnumMemberBuilderTest extends EngineTestCase {
- test_visitEnumDeclaration_multiple() async {
- String firstName = "ONE";
- String secondName = "TWO";
- String thirdName = "THREE";
- EnumDeclaration enumDeclaration = AstTestFactory.enumDeclaration2(
- "E", [firstName, secondName, thirdName]);
-
- ClassElement enumElement = _buildElement(enumDeclaration);
- List<FieldElement> fields = enumElement.fields;
- expect(fields, hasLength(5));
-
- FieldElement constant = fields[2];
- expect(constant, isNotNull);
- expect(constant.name, firstName);
- expect(constant.isStatic, isTrue);
- expect((constant as FieldElementImpl).evaluationResult, isNotNull);
- _assertGetter(constant);
-
- constant = fields[3];
- expect(constant, isNotNull);
- expect(constant.name, secondName);
- expect(constant.isStatic, isTrue);
- expect((constant as FieldElementImpl).evaluationResult, isNotNull);
- _assertGetter(constant);
-
- constant = fields[4];
- expect(constant, isNotNull);
- expect(constant.name, thirdName);
- expect(constant.isStatic, isTrue);
- expect((constant as FieldElementImpl).evaluationResult, isNotNull);
- _assertGetter(constant);
- }
-
- test_visitEnumDeclaration_single() async {
- String firstName = "ONE";
- EnumDeclaration enumDeclaration =
- AstTestFactory.enumDeclaration2("E", [firstName]);
- enumDeclaration.constants[0].documentationComment =
- AstTestFactory.documentationComment(
- [TokenFactory.tokenFromString('/// aaa')..offset = 50], []);
-
- ClassElement enumElement = _buildElement(enumDeclaration);
- List<FieldElement> fields = enumElement.fields;
- expect(fields, hasLength(3));
-
- FieldElement field = fields[0];
- expect(field, isNotNull);
- expect(field.name, "index");
- expect(field.isStatic, isFalse);
- expect(field.isSynthetic, isTrue);
- _assertGetter(field);
-
- field = fields[1];
- expect(field, isNotNull);
- expect(field.name, "values");
- expect(field.isStatic, isTrue);
- expect(field.isSynthetic, isTrue);
- expect((field as FieldElementImpl).evaluationResult, isNotNull);
- _assertGetter(field);
-
- FieldElement constant = fields[2];
- expect(constant, isNotNull);
- expect(constant.name, firstName);
- expect(constant.isStatic, isTrue);
- expect((constant as FieldElementImpl).evaluationResult, isNotNull);
- expect(constant.documentationComment, '/// aaa');
- _assertGetter(constant);
- }
-
- void _assertGetter(FieldElement field) {
- PropertyAccessorElement getter = field.getter;
- expect(getter, isNotNull);
- expect(getter.variable, same(field));
- expect(getter.type, isNotNull);
- }
-
- ClassElement _buildElement(EnumDeclaration enumDeclaration) {
- ElementHolder holder = new ElementHolder();
- ElementBuilder elementBuilder = _makeBuilder(holder);
- enumDeclaration.accept(elementBuilder);
- EnumMemberBuilder memberBuilder =
- new EnumMemberBuilder(new TestTypeProvider());
- enumDeclaration.accept(memberBuilder);
- List<ClassElement> enums = holder.enums;
- expect(enums, hasLength(1));
- return enums[0];
- }
-
- ElementBuilder _makeBuilder(ElementHolder holder) =>
- new ElementBuilder(holder, new CompilationUnitElementImpl());
-}
-
-@reflectiveTest
class ErrorSeverityTest extends EngineTestCase {
test_max_error_error() async {
expect(ErrorSeverity.ERROR.max(ErrorSeverity.ERROR),
@@ -351,15 +247,6 @@
FileBasedSource.fileReadMode = (String s) => s;
}
- test_getEncoding() async {
- SourceFactory factory = new SourceFactory(
- [new ResourceUriResolver(PhysicalResourceProvider.INSTANCE)]);
- String fullPath = "/does/not/exist.dart";
- JavaFile file = FileUtilities2.createFile(fullPath);
- FileBasedSource source = new FileBasedSource(file);
- expect(factory.fromEncoding(source.encoding), source);
- }
-
test_getFullName() async {
String fullPath = "/does/not/exist.dart";
JavaFile file = FileUtilities2.createFile(fullPath);
diff --git a/pkg/analyzer/test/generated/compile_time_error_code.dart b/pkg/analyzer/test/generated/compile_time_error_code.dart
index f4aad69..49b349f 100644
--- a/pkg/analyzer/test/generated/compile_time_error_code.dart
+++ b/pkg/analyzer/test/generated/compile_time_error_code.dart
@@ -32,6 +32,7 @@
]);
}
+ @failingTest
test_accessPrivateEnumField() async {
await assertErrorsInCode(r'''
enum E { ONE }
@@ -375,8 +376,6 @@
}
test_constConstructorWithFieldInitializedByNonConst() async {
- // TODO(paulberry): the error CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE is
- // redundant and ought to be suppressed.
await assertErrorsInCode(r'''
class A {
final int i = f();
@@ -386,8 +385,6 @@
return 3;
}
''', [
- error(CompileTimeErrorCode.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE, 26,
- 3),
error(
CompileTimeErrorCode
.CONST_CONSTRUCTOR_WITH_FIELD_INITIALIZED_BY_NON_CONST,
diff --git a/pkg/analyzer/test/generated/element_resolver_test.dart b/pkg/analyzer/test/generated/element_resolver_test.dart
index f74fe27..a03c601 100644
--- a/pkg/analyzer/test/generated/element_resolver_test.dart
+++ b/pkg/analyzer/test/generated/element_resolver_test.dart
@@ -26,6 +26,7 @@
import '../src/dart/resolution/driver_resolution.dart';
import '../util/element_type_matchers.dart';
+import 'elements_types_mixin.dart';
import 'test_analysis_context.dart';
import 'test_support.dart';
@@ -297,7 +298,8 @@
}
@reflectiveTest
-class ElementResolverTest extends EngineTestCase with ResourceProviderMixin {
+class ElementResolverTest extends EngineTestCase
+ with ResourceProviderMixin, ElementsTypesMixin {
/**
* The error listener to which errors will be reported.
*/
@@ -323,6 +325,8 @@
*/
ElementResolver _resolver;
+ TypeProvider get typeProvider => _typeProvider;
+
void fail_visitExportDirective_combinators() {
_fail("Not yet tested");
// Need to set up the exported library so that the identifier can be
@@ -392,22 +396,23 @@
// class B implements A {}
//
ClassElementImpl classB = ElementFactory.classElement2("B");
- classB.interfaces = <InterfaceType>[classA.type];
+ classB.interfaces = <InterfaceType>[interfaceType(classA)];
//
// class C extends Object with B {}
//
ClassElementImpl classC = ElementFactory.classElement2("C");
- classC.mixins = <InterfaceType>[classB.type];
+ classC.mixins = <InterfaceType>[interfaceType(classB)];
//
// class D extends C {}
//
- ClassElementImpl classD = ElementFactory.classElement("D", classC.type);
+ ClassElementImpl classD =
+ ElementFactory.classElement("D", interfaceType(classC));
//
// D a;
// a[i];
//
SimpleIdentifier array = AstTestFactory.identifier3("a");
- array.staticType = classD.type;
+ array.staticType = interfaceType(classD);
IndexExpression expression =
AstTestFactory.indexExpression(array, AstTestFactory.identifier3("i"));
expect(_resolveIndexExpression(expression), same(operator));
@@ -852,9 +857,9 @@
classA.accessors = <PropertyAccessorElement>[getter];
SimpleIdentifier target = AstTestFactory.identifier3("a");
VariableElementImpl variable = ElementFactory.localVariableElement(target);
- variable.type = classA.type;
+ variable.type = interfaceType(classA);
target.staticElement = variable;
- target.staticType = classA.type;
+ target.staticType = interfaceType(classA);
PrefixedIdentifier identifier = AstTestFactory.identifier(
target, AstTestFactory.identifier3(getterName));
_resolveNode(identifier);
@@ -868,14 +873,14 @@
// set accessors
String propName = "b";
PropertyAccessorElement getter =
- ElementFactory.getterElement(propName, false, _typeProvider.intType);
+ ElementFactory.getterElement(propName, true, _typeProvider.intType);
PropertyAccessorElement setter =
- ElementFactory.setterElement(propName, false, _typeProvider.intType);
+ ElementFactory.setterElement(propName, true, _typeProvider.intType);
classA.accessors = <PropertyAccessorElement>[getter, setter];
- // prepare "A.m"
+ // prepare "A.b"
SimpleIdentifier target = AstTestFactory.identifier3("A");
target.staticElement = classA;
- target.staticType = classA.type;
+ target.staticType = interfaceType(classA);
PrefixedIdentifier identifier =
AstTestFactory.identifier(target, AstTestFactory.identifier3(propName));
// resolve
@@ -889,17 +894,16 @@
ClassElementImpl classA = ElementFactory.classElement2("A");
// set methods
String propName = "m";
- MethodElement method =
- ElementFactory.methodElement("m", _typeProvider.intType);
+ var method = ElementFactory.methodElement("m", _typeProvider.intType);
+ method.isStatic = true;
classA.methods = <MethodElement>[method];
// prepare "A.m"
SimpleIdentifier target = AstTestFactory.identifier3("A");
target.staticElement = classA;
- target.staticType = classA.type;
+ target.staticType = interfaceType(classA);
PrefixedIdentifier identifier =
AstTestFactory.identifier(target, AstTestFactory.identifier3(propName));
- AstTestFactory.assignmentExpression(
- identifier, TokenType.EQ, AstTestFactory.nullLiteral());
+ AstTestFactory.expressionStatement(identifier);
// resolve
_resolveNode(identifier);
expect(identifier.staticElement, same(method));
@@ -912,14 +916,14 @@
// set accessors
String propName = "b";
PropertyAccessorElement getter =
- ElementFactory.getterElement(propName, false, _typeProvider.intType);
+ ElementFactory.getterElement(propName, true, _typeProvider.intType);
PropertyAccessorElement setter =
- ElementFactory.setterElement(propName, false, _typeProvider.intType);
+ ElementFactory.setterElement(propName, true, _typeProvider.intType);
classA.accessors = <PropertyAccessorElement>[getter, setter];
// prepare "A.b = null"
SimpleIdentifier target = AstTestFactory.identifier3("A");
target.staticElement = classA;
- target.staticType = classA.type;
+ target.staticType = interfaceType(classA);
PrefixedIdentifier identifier =
AstTestFactory.identifier(target, AstTestFactory.identifier3(propName));
AstTestFactory.assignmentExpression(
@@ -949,7 +953,7 @@
ElementFactory.getterElement(getterName, false, _typeProvider.intType);
classA.accessors = <PropertyAccessorElement>[getter];
SimpleIdentifier target = AstTestFactory.identifier3("a");
- target.staticType = classA.type;
+ target.staticType = interfaceType(classA);
PropertyAccess access = AstTestFactory.propertyAccess2(target, getterName);
_resolveNode(access);
expect(access.propertyName.staticElement, same(getter));
@@ -971,7 +975,8 @@
ElementFactory.getterElement(getterName, false, _typeProvider.intType);
classA.accessors = <PropertyAccessorElement>[getter];
SuperExpression target = AstTestFactory.superExpression();
- target.staticType = ElementFactory.classElement("B", classA.type).type;
+ target.staticType =
+ interfaceType(ElementFactory.classElement("B", interfaceType(classA)));
PropertyAccess access = AstTestFactory.propertyAccess2(target, getterName);
AstTestFactory.methodDeclaration2(
null,
@@ -993,7 +998,7 @@
ElementFactory.setterElement(setterName, false, _typeProvider.intType);
classA.accessors = <PropertyAccessorElement>[setter];
ThisExpression target = AstTestFactory.thisExpression();
- target.staticType = classA.type;
+ target.staticType = interfaceType(classA);
PropertyAccess access = AstTestFactory.propertyAccess2(target, setterName);
AstTestFactory.assignmentExpression(
access, TokenType.EQ, AstTestFactory.integer(0));
@@ -1049,7 +1054,7 @@
ElementFactory.constructorElement2(superclass, null);
superclass.constructors = <ConstructorElement>[superConstructor];
ClassElementImpl subclass =
- ElementFactory.classElement("B", superclass.type);
+ ElementFactory.classElement("B", interfaceType(superclass));
ConstructorElementImpl subConstructor =
ElementFactory.constructorElement2(subclass, null);
subclass.constructors = <ConstructorElement>[subConstructor];
@@ -1072,7 +1077,7 @@
superConstructor.parameters = <ParameterElement>[parameter];
superclass.constructors = <ConstructorElement>[superConstructor];
ClassElementImpl subclass =
- ElementFactory.classElement("B", superclass.type);
+ ElementFactory.classElement("B", interfaceType(superclass));
ConstructorElementImpl subConstructor =
ElementFactory.constructorElement2(subclass, null);
subclass.constructors = <ConstructorElement>[subConstructor];
diff --git a/pkg/analyzer/test/generated/elements_types_mixin.dart b/pkg/analyzer/test/generated/elements_types_mixin.dart
new file mode 100644
index 0000000..fe87f3d
--- /dev/null
+++ b/pkg/analyzer/test/generated/elements_types_mixin.dart
@@ -0,0 +1,206 @@
+// Copyright (c) 2019, 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.
+
+import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/dart/element/nullability_suffix.dart';
+import 'package:analyzer/dart/element/type.dart';
+import 'package:analyzer/src/dart/element/element.dart';
+import 'package:analyzer/src/dart/element/type.dart';
+import 'package:analyzer/src/generated/resolver.dart';
+import 'package:analyzer/src/generated/utilities_dart.dart';
+import 'package:meta/meta.dart';
+
+mixin ElementsTypesMixin {
+ DynamicTypeImpl get dynamicType => typeProvider.dynamicType;
+
+ TypeProvider get typeProvider;
+
+ ClassElementImpl class_({
+ @required String name,
+ bool isAbstract = false,
+ InterfaceType superType,
+ List<TypeParameterElement> typeParameters = const [],
+ List<InterfaceType> interfaces = const [],
+ List<InterfaceType> mixins = const [],
+ List<MethodElement> methods = const [],
+ }) {
+ var element = ClassElementImpl(name, 0);
+ element.typeParameters = typeParameters;
+ element.supertype = superType ?? typeProvider.objectType;
+ element.interfaces = interfaces;
+ element.mixins = mixins;
+ element.methods = methods;
+ return element;
+ }
+
+ FunctionType functionType({
+ List<TypeParameterElement> typeFormals,
+ List<DartType> required,
+ List<DartType> optional,
+ Map<String, DartType> named,
+ DartType returns,
+ NullabilitySuffix nullabilitySuffix = NullabilitySuffix.star,
+ }) {
+ if (optional != null && named != null) {
+ throw ArgumentError(
+ 'Cannot have both optional positional and named parameters.',
+ );
+ }
+
+ var parameters = <ParameterElement>[];
+ if (required != null) {
+ for (var i = 0; i < required.length; ++i) {
+ parameters.add(
+ ParameterElementImpl.synthetic(
+ 'r$i',
+ required[i],
+ ParameterKind.REQUIRED,
+ ),
+ );
+ }
+ }
+ if (optional != null) {
+ for (var i = 0; i < optional.length; ++i) {
+ parameters.add(
+ ParameterElementImpl.synthetic(
+ 'p$i',
+ optional[i],
+ ParameterKind.POSITIONAL,
+ ),
+ );
+ }
+ }
+ if (named != null) {
+ for (var namedEntry in named.entries) {
+ parameters.add(
+ ParameterElementImpl.synthetic(
+ namedEntry.key,
+ namedEntry.value,
+ ParameterKind.NAMED,
+ ),
+ );
+ }
+ }
+
+ return FunctionTypeImpl.synthetic(
+ returns ?? typeProvider.voidType,
+ typeFormals ?? const <TypeParameterElement>[],
+ parameters,
+ nullabilitySuffix: nullabilitySuffix,
+ );
+ }
+
+ FunctionType functionTypeAliasType(
+ FunctionTypeAliasElement element, {
+ List<DartType> typeArguments = const [],
+ NullabilitySuffix nullabilitySuffix = NullabilitySuffix.star,
+ }) {
+ return element.instantiate2(
+ typeArguments: typeArguments,
+ nullabilitySuffix: nullabilitySuffix,
+ );
+ }
+
+ DartType futureType(DartType T) {
+ var futureElement = typeProvider.futureElement;
+ return interfaceType(futureElement, typeArguments: [T]);
+ }
+
+ GenericFunctionTypeElementImpl genericFunctionType({
+ List<TypeParameterElement> typeParameters,
+ List<ParameterElement> parameters,
+ DartType returnType,
+ }) {
+ var result = GenericFunctionTypeElementImpl.forOffset(0);
+ result.typeParameters = typeParameters;
+ result.parameters = parameters;
+ result.returnType = returnType ?? typeProvider.voidType;
+ return result;
+ }
+
+ GenericTypeAliasElementImpl genericTypeAlias({
+ @required String name,
+ List<TypeParameterElement> typeParameters = const [],
+ @required GenericFunctionTypeElement function,
+ }) {
+ return GenericTypeAliasElementImpl(name, 0)
+ ..typeParameters = typeParameters
+ ..function = function;
+ }
+
+ InterfaceType interfaceType(
+ ClassElement element, {
+ List<DartType> typeArguments = const [],
+ NullabilitySuffix nullabilitySuffix = NullabilitySuffix.star,
+ }) {
+ return InterfaceTypeImpl.explicit(
+ element,
+ typeArguments,
+ nullabilitySuffix: nullabilitySuffix,
+ );
+ }
+
+ MethodElement method(
+ String name,
+ DartType returnType, {
+ bool isStatic = false,
+ List<TypeParameterElement> typeFormals = const [],
+ List<ParameterElement> parameters = const [],
+ }) {
+ var element = MethodElementImpl(name, 0)
+ ..isStatic = isStatic
+ ..parameters = parameters
+ ..returnType = returnType
+ ..typeParameters = typeFormals;
+ element.type = _typeOfExecutableElement(element);
+ return element;
+ }
+
+ ParameterElement namedParameter(String name, {@required DartType type}) {
+ var parameter = ParameterElementImpl(name, 0);
+ parameter.parameterKind = ParameterKind.NAMED;
+ parameter.type = type;
+ return parameter;
+ }
+
+ ParameterElement positionalParameter(String name, {@required DartType type}) {
+ var parameter = ParameterElementImpl(name, 0);
+ parameter.parameterKind = ParameterKind.POSITIONAL;
+ parameter.type = type;
+ return parameter;
+ }
+
+ ParameterElement requiredParameter(String name, {@required DartType type}) {
+ var parameter = ParameterElementImpl(name, 0);
+ parameter.parameterKind = ParameterKind.REQUIRED;
+ parameter.type = type;
+ return parameter;
+ }
+
+ TypeParameterElementImpl typeParameter(String name, {DartType bound}) {
+ var element = TypeParameterElementImpl.synthetic(name);
+ element.bound = bound;
+ return element;
+ }
+
+ TypeParameterTypeImpl typeParameterType(
+ TypeParameterElement element, {
+ NullabilitySuffix nullabilitySuffix = NullabilitySuffix.star,
+ }) {
+ return TypeParameterTypeImpl(
+ element,
+ nullabilitySuffix: nullabilitySuffix,
+ );
+ }
+
+ /// TODO(scheglov) We should do the opposite - build type in the element.
+ /// But build a similar synthetic / structured type.
+ FunctionType _typeOfExecutableElement(ExecutableElement element) {
+ return FunctionTypeImpl.synthetic(
+ element.returnType,
+ element.typeParameters,
+ element.parameters,
+ );
+ }
+}
diff --git a/pkg/analyzer/test/generated/inheritance_manager_test.dart b/pkg/analyzer/test/generated/inheritance_manager_test.dart
index 881eb2c..2b47aa3 100644
--- a/pkg/analyzer/test/generated/inheritance_manager_test.dart
+++ b/pkg/analyzer/test/generated/inheritance_manager_test.dart
@@ -3,6 +3,7 @@
// BSD-style license that can be found in the LICENSE file.
import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/dart/element/nullability_suffix.dart';
import 'package:analyzer/dart/element/type.dart';
import 'package:analyzer/src/dart/element/element.dart';
import 'package:analyzer/src/dart/element/type.dart';
@@ -68,7 +69,8 @@
PropertyAccessorElement getterG =
ElementFactory.getterElement(getterName, false, _typeProvider.intType);
classA.accessors = <PropertyAccessorElement>[getterG];
- ClassElementImpl classB = ElementFactory.classElement("B", classA.type);
+ ClassElementImpl classB =
+ ElementFactory.classElement("B", _interfaceType(classA));
Map<String, ExecutableElement> mapB =
_inheritanceManager.getMembersInheritedFromClasses(classB);
Map<String, ExecutableElement> mapA =
@@ -88,7 +90,7 @@
ElementFactory.getterElement(getterName, false, _typeProvider.intType);
classA.accessors = <PropertyAccessorElement>[getterG];
ClassElementImpl classB = ElementFactory.classElement2("B");
- classB.interfaces = <InterfaceType>[classA.type];
+ classB.interfaces = <InterfaceType>[_interfaceType(classA)];
Map<String, ExecutableElement> mapB =
_inheritanceManager.getMembersInheritedFromClasses(classB);
Map<String, ExecutableElement> mapA =
@@ -108,7 +110,7 @@
ElementFactory.getterElement(getterName, false, _typeProvider.intType);
classA.accessors = <PropertyAccessorElement>[getterG];
ClassElementImpl classB = ElementFactory.classElement2("B");
- classB.mixins = <InterfaceType>[classA.type];
+ classB.mixins = <InterfaceType>[_interfaceType(classA)];
Map<String, ExecutableElement> mapB =
_inheritanceManager.getMembersInheritedFromClasses(classB);
Map<String, ExecutableElement> mapA =
@@ -137,7 +139,7 @@
ElementFactory.methodElement(methodName, _typeProvider.intType);
classA.methods = <MethodElement>[methodM];
ClassElementImpl classB = ElementFactory.classElement2("B");
- classB.supertype = classA.type;
+ classB.supertype = _interfaceType(classA);
Map<String, ExecutableElement> mapB =
_inheritanceManager.getMembersInheritedFromClasses(classB);
Map<String, ExecutableElement> mapA =
@@ -157,7 +159,7 @@
ElementFactory.methodElement(methodName, _typeProvider.intType);
classA.methods = <MethodElement>[methodM];
ClassElementImpl classB = ElementFactory.classElement2("B");
- classB.interfaces = <InterfaceType>[classA.type];
+ classB.interfaces = <InterfaceType>[_interfaceType(classA)];
Map<String, ExecutableElement> mapB =
_inheritanceManager.getMembersInheritedFromClasses(classB);
Map<String, ExecutableElement> mapA =
@@ -177,7 +179,7 @@
ElementFactory.methodElement(methodName, _typeProvider.intType);
classA.methods = <MethodElement>[methodM];
ClassElementImpl classB = ElementFactory.classElement2("B");
- classB.mixins = <InterfaceType>[classA.type];
+ classB.mixins = <InterfaceType>[_interfaceType(classA)];
Map<String, ExecutableElement> mapB =
_inheritanceManager.getMembersInheritedFromClasses(classB);
Map<String, ExecutableElement> mapA =
@@ -202,7 +204,10 @@
ElementFactory.methodElement(methodName, _typeProvider.intType);
classA2.methods = <MethodElement>[methodA2M];
ClassElementImpl classB = ElementFactory.classElement2("B");
- classB.mixins = <InterfaceType>[classA1.type, classA2.type];
+ classB.mixins = <InterfaceType>[
+ _interfaceType(classA1),
+ _interfaceType(classA2)
+ ];
Map<String, ExecutableElement> mapB =
_inheritanceManager.getMembersInheritedFromClasses(classB);
expect(mapB[methodName], same(methodA2M));
@@ -217,7 +222,8 @@
PropertyAccessorElement getterG =
ElementFactory.getterElement(getterName, false, _typeProvider.intType);
classA.accessors = <PropertyAccessorElement>[getterG];
- ClassElementImpl classB = ElementFactory.classElement("B", classA.type);
+ ClassElementImpl classB =
+ ElementFactory.classElement("B", _interfaceType(classA));
Map<String, ExecutableElement> mapB =
_inheritanceManager.getMembersInheritedFromInterfaces(classB);
Map<String, ExecutableElement> mapA =
@@ -237,7 +243,7 @@
ElementFactory.getterElement(getterName, false, _typeProvider.intType);
classA.accessors = <PropertyAccessorElement>[getterG];
ClassElementImpl classB = ElementFactory.classElement2("B");
- classB.interfaces = <InterfaceType>[classA.type];
+ classB.interfaces = <InterfaceType>[_interfaceType(classA)];
Map<String, ExecutableElement> mapB =
_inheritanceManager.getMembersInheritedFromInterfaces(classB);
Map<String, ExecutableElement> mapA =
@@ -257,7 +263,7 @@
ElementFactory.getterElement(getterName, false, _typeProvider.intType);
classA.accessors = <PropertyAccessorElement>[getterG];
ClassElementImpl classB = ElementFactory.classElement2("B");
- classB.mixins = <InterfaceType>[classA.type];
+ classB.mixins = <InterfaceType>[_interfaceType(classA)];
Map<String, ExecutableElement> mapB =
_inheritanceManager.getMembersInheritedFromInterfaces(classB);
Map<String, ExecutableElement> mapA =
@@ -279,10 +285,11 @@
classA.fields = <FieldElement>[fieldF];
classA.accessors = <PropertyAccessorElement>[fieldF.getter, fieldF.setter];
- ClassElementImpl classB = ElementFactory.classElement('B', classA.type);
+ ClassElementImpl classB =
+ ElementFactory.classElement('B', _interfaceType(classA));
ClassElementImpl classC = ElementFactory.classElement2('C');
- classC.mixins = <InterfaceType>[classB.type];
+ classC.mixins = <InterfaceType>[_interfaceType(classB)];
Map<String, ExecutableElement> mapC =
_inheritanceManager.getMembersInheritedFromInterfaces(classC);
@@ -309,7 +316,8 @@
MethodElement methodM =
ElementFactory.methodElement(methodName, _typeProvider.intType);
classA.methods = <MethodElement>[methodM];
- ClassElementImpl classB = ElementFactory.classElement("B", classA.type);
+ ClassElementImpl classB =
+ ElementFactory.classElement("B", _interfaceType(classA));
Map<String, ExecutableElement> mapB =
_inheritanceManager.getMembersInheritedFromInterfaces(classB);
Map<String, ExecutableElement> mapA =
@@ -329,7 +337,7 @@
ElementFactory.methodElement(methodName, _typeProvider.intType);
classA.methods = <MethodElement>[methodM];
ClassElementImpl classB = ElementFactory.classElement2("B");
- classB.interfaces = <InterfaceType>[classA.type];
+ classB.interfaces = <InterfaceType>[_interfaceType(classA)];
Map<String, ExecutableElement> mapB =
_inheritanceManager.getMembersInheritedFromInterfaces(classB);
Map<String, ExecutableElement> mapA =
@@ -349,7 +357,7 @@
ElementFactory.methodElement(methodName, _typeProvider.intType);
classA.methods = <MethodElement>[methodM];
ClassElementImpl classB = ElementFactory.classElement2("B");
- classB.mixins = <InterfaceType>[classA.type];
+ classB.mixins = <InterfaceType>[_interfaceType(classA)];
Map<String, ExecutableElement> mapB =
_inheritanceManager.getMembersInheritedFromInterfaces(classB);
Map<String, ExecutableElement> mapA =
@@ -375,7 +383,10 @@
ElementFactory.methodElement(methodName2, _typeProvider.intType);
classI2.methods = <MethodElement>[methodM2];
ClassElementImpl classA = ElementFactory.classElement2("A");
- classA.interfaces = <InterfaceType>[classI1.type, classI2.type];
+ classA.interfaces = <InterfaceType>[
+ _interfaceType(classI1),
+ _interfaceType(classI2)
+ ];
Map<String, ExecutableElement> mapA =
_inheritanceManager.getMembersInheritedFromInterfaces(classA);
expect(mapA.length, _numOfMembersInObject + 2);
@@ -399,7 +410,10 @@
accessorName, false, _typeProvider.numType);
classI2.accessors = <PropertyAccessorElement>[getter2];
ClassElementImpl classA = ElementFactory.classElement2("A");
- classA.interfaces = <InterfaceType>[classI1.type, classI2.type];
+ classA.interfaces = <InterfaceType>[
+ _interfaceType(classI1),
+ _interfaceType(classI2)
+ ];
Map<String, ExecutableElement> mapA =
_inheritanceManager.getMembersInheritedFromInterfaces(classA);
expect(mapA.length, _numOfMembersInObject + 1);
@@ -435,7 +449,10 @@
methodM2.parameters = <ParameterElement>[parameter2];
classI2.methods = <MethodElement>[methodM2];
ClassElementImpl classA = ElementFactory.classElement2("A");
- classA.interfaces = <InterfaceType>[classI1.type, classI2.type];
+ classA.interfaces = <InterfaceType>[
+ _interfaceType(classI1),
+ _interfaceType(classI2)
+ ];
Map<String, ExecutableElement> mapA =
_inheritanceManager.getMembersInheritedFromInterfaces(classA);
expect(mapA.length, _numOfMembersInObject + 1);
@@ -461,7 +478,10 @@
accessorName, false, _typeProvider.numType);
classI2.accessors = <PropertyAccessorElement>[setter2];
ClassElementImpl classA = ElementFactory.classElement2("A");
- classA.interfaces = <InterfaceType>[classI1.type, classI2.type];
+ classA.interfaces = <InterfaceType>[
+ _interfaceType(classI1),
+ _interfaceType(classI2)
+ ];
Map<String, ExecutableElement> mapA =
_inheritanceManager.getMembersInheritedFromInterfaces(classA);
expect(mapA.length, _numOfMembersInObject + 1);
@@ -483,33 +503,35 @@
// class I3 { C get g; }
// class D implements I1, I2, I3 {}
ClassElementImpl classA = ElementFactory.classElement2("A");
- ClassElementImpl classB = ElementFactory.classElement("B", classA.type);
- ClassElementImpl classC = ElementFactory.classElement("C", classB.type);
+ ClassElementImpl classB =
+ ElementFactory.classElement("B", _interfaceType(classA));
+ ClassElementImpl classC =
+ ElementFactory.classElement("C", _interfaceType(classB));
ClassElementImpl classI1 = ElementFactory.classElement2("I1");
String accessorName = "g";
- PropertyAccessorElement getter1 =
- ElementFactory.getterElement(accessorName, false, classA.type);
+ PropertyAccessorElement getter1 = ElementFactory.getterElement(
+ accessorName, false, _interfaceType(classA));
classI1.accessors = <PropertyAccessorElement>[getter1];
ClassElementImpl classI2 = ElementFactory.classElement2("I2");
- PropertyAccessorElement getter2 =
- ElementFactory.getterElement(accessorName, false, classB.type);
+ PropertyAccessorElement getter2 = ElementFactory.getterElement(
+ accessorName, false, _interfaceType(classB));
classI2.accessors = <PropertyAccessorElement>[getter2];
ClassElementImpl classI3 = ElementFactory.classElement2("I3");
- PropertyAccessorElement getter3 =
- ElementFactory.getterElement(accessorName, false, classC.type);
+ PropertyAccessorElement getter3 = ElementFactory.getterElement(
+ accessorName, false, _interfaceType(classC));
classI3.accessors = <PropertyAccessorElement>[getter3];
ClassElementImpl classD = ElementFactory.classElement2("D");
classD.interfaces = <InterfaceType>[
- classI1.type,
- classI2.type,
- classI3.type
+ _interfaceType(classI1),
+ _interfaceType(classI2),
+ _interfaceType(classI3),
];
Map<String, ExecutableElement> mapD =
_inheritanceManager.getMembersInheritedFromInterfaces(classD);
expect(mapD.length, _numOfMembersInObject + 1);
PropertyAccessorElement syntheticAccessor;
- syntheticAccessor =
- ElementFactory.getterElement(accessorName, false, classC.type);
+ syntheticAccessor = ElementFactory.getterElement(
+ accessorName, false, _interfaceType(classC));
expect(mapD[accessorName].type, syntheticAccessor.type);
}
@@ -524,15 +546,17 @@
// class I3 { dynamic m(C c); }
// class D implements I1, I2, I3 {}
ClassElementImpl classA = ElementFactory.classElement2("A");
- ClassElementImpl classB = ElementFactory.classElement("B", classA.type);
- ClassElementImpl classC = ElementFactory.classElement("C", classB.type);
+ ClassElementImpl classB =
+ ElementFactory.classElement("B", _interfaceType(classA));
+ ClassElementImpl classC =
+ ElementFactory.classElement("C", _interfaceType(classB));
ClassElementImpl classI1 = ElementFactory.classElement2("I1");
String methodName = "m";
MethodElementImpl methodM1 =
ElementFactory.methodElement(methodName, _typeProvider.dynamicType);
ParameterElementImpl parameter1 =
new ParameterElementImpl.forNode(AstTestFactory.identifier3("a0"));
- parameter1.type = classA.type;
+ parameter1.type = _interfaceType(classA);
parameter1.parameterKind = ParameterKind.REQUIRED;
methodM1.parameters = <ParameterElement>[parameter1];
classI1.methods = <MethodElement>[methodM1];
@@ -541,7 +565,7 @@
ElementFactory.methodElement(methodName, _typeProvider.dynamicType);
ParameterElementImpl parameter2 =
new ParameterElementImpl.forNode(AstTestFactory.identifier3("a0"));
- parameter2.type = classB.type;
+ parameter2.type = _interfaceType(classB);
parameter2.parameterKind = ParameterKind.REQUIRED;
methodM2.parameters = <ParameterElement>[parameter2];
classI2.methods = <MethodElement>[methodM2];
@@ -550,22 +574,22 @@
ElementFactory.methodElement(methodName, _typeProvider.dynamicType);
ParameterElementImpl parameter3 =
new ParameterElementImpl.forNode(AstTestFactory.identifier3("a0"));
- parameter3.type = classC.type;
+ parameter3.type = _interfaceType(classC);
parameter3.parameterKind = ParameterKind.REQUIRED;
methodM3.parameters = <ParameterElement>[parameter3];
classI3.methods = <MethodElement>[methodM3];
ClassElementImpl classD = ElementFactory.classElement2("D");
classD.interfaces = <InterfaceType>[
- classI1.type,
- classI2.type,
- classI3.type
+ _interfaceType(classI1),
+ _interfaceType(classI2),
+ _interfaceType(classI3)
];
Map<String, ExecutableElement> mapD =
_inheritanceManager.getMembersInheritedFromInterfaces(classD);
expect(mapD.length, _numOfMembersInObject + 1);
MethodElement syntheticMethod;
syntheticMethod = ElementFactory.methodElement(
- methodName, _typeProvider.dynamicType, [classA.type]);
+ methodName, _typeProvider.dynamicType, [_interfaceType(classA)]);
expect(mapD[methodName].type, syntheticMethod.type);
}
@@ -580,33 +604,35 @@
// class I3 { set s(C); }
// class D implements I1, I2, I3 {}
ClassElementImpl classA = ElementFactory.classElement2("A");
- ClassElementImpl classB = ElementFactory.classElement("B", classA.type);
- ClassElementImpl classC = ElementFactory.classElement("C", classB.type);
+ ClassElementImpl classB =
+ ElementFactory.classElement("B", _interfaceType(classA));
+ ClassElementImpl classC =
+ ElementFactory.classElement("C", _interfaceType(classB));
ClassElementImpl classI1 = ElementFactory.classElement2("I1");
String accessorName = "s";
- PropertyAccessorElement setter1 =
- ElementFactory.setterElement(accessorName, false, classA.type);
+ PropertyAccessorElement setter1 = ElementFactory.setterElement(
+ accessorName, false, _interfaceType(classA));
classI1.accessors = <PropertyAccessorElement>[setter1];
ClassElementImpl classI2 = ElementFactory.classElement2("I2");
- PropertyAccessorElement setter2 =
- ElementFactory.setterElement(accessorName, false, classB.type);
+ PropertyAccessorElement setter2 = ElementFactory.setterElement(
+ accessorName, false, _interfaceType(classB));
classI2.accessors = <PropertyAccessorElement>[setter2];
ClassElementImpl classI3 = ElementFactory.classElement2("I3");
- PropertyAccessorElement setter3 =
- ElementFactory.setterElement(accessorName, false, classC.type);
+ PropertyAccessorElement setter3 = ElementFactory.setterElement(
+ accessorName, false, _interfaceType(classC));
classI3.accessors = <PropertyAccessorElement>[setter3];
ClassElementImpl classD = ElementFactory.classElement2("D");
classD.interfaces = <InterfaceType>[
- classI1.type,
- classI2.type,
- classI3.type
+ _interfaceType(classI1),
+ _interfaceType(classI2),
+ _interfaceType(classI3)
];
Map<String, ExecutableElement> mapD =
_inheritanceManager.getMembersInheritedFromInterfaces(classD);
expect(mapD.length, _numOfMembersInObject + 1);
PropertyAccessorElementImpl syntheticAccessor;
- syntheticAccessor =
- ElementFactory.setterElement(accessorName, false, classA.type);
+ syntheticAccessor = ElementFactory.setterElement(
+ accessorName, false, _interfaceType(classA));
syntheticAccessor.returnType = VoidTypeImpl.instance;
expect(mapD["$accessorName="].type, syntheticAccessor.type);
}
@@ -632,7 +658,10 @@
methodM2.parameters = <ParameterElement>[parameter1];
classI2.methods = <MethodElement>[methodM2];
ClassElementImpl classA = ElementFactory.classElement2("A");
- classA.interfaces = <InterfaceType>[classI1.type, classI2.type];
+ classA.interfaces = <InterfaceType>[
+ _interfaceType(classI1),
+ _interfaceType(classI2)
+ ];
Map<String, ExecutableElement> mapA =
_inheritanceManager.getMembersInheritedFromInterfaces(classA);
expect(mapA.length, _numOfMembersInObject + 1);
@@ -675,9 +704,9 @@
classI3.methods = <MethodElement>[methodM3];
ClassElementImpl classA = ElementFactory.classElement2("A");
classA.interfaces = <InterfaceType>[
- classI1.type,
- classI2.type,
- classI3.type
+ _interfaceType(classI1),
+ _interfaceType(classI2),
+ _interfaceType(classI3)
];
Map<String, ExecutableElement> mapA =
_inheritanceManager.getMembersInheritedFromInterfaces(classA);
@@ -726,10 +755,10 @@
classI4.methods = <MethodElement>[methodM4];
ClassElementImpl classA = ElementFactory.classElement2("A");
classA.interfaces = <InterfaceType>[
- classI1.type,
- classI2.type,
- classI3.type,
- classI4.type
+ _interfaceType(classI1),
+ _interfaceType(classI2),
+ _interfaceType(classI3),
+ _interfaceType(classI4),
];
Map<String, ExecutableElement> mapA =
_inheritanceManager.getMembersInheritedFromInterfaces(classA);
@@ -749,10 +778,11 @@
classA.fields = <FieldElement>[fieldF];
classA.accessors = <PropertyAccessorElement>[fieldF.getter, fieldF.setter];
- ClassElementImpl classB = ElementFactory.classElement('B', classA.type);
+ ClassElementImpl classB =
+ ElementFactory.classElement('B', _interfaceType(classA));
ClassElementImpl classC = ElementFactory.classElement2('C');
- classC.mixins = <InterfaceType>[classB.type];
+ classC.mixins = <InterfaceType>[_interfaceType(classB)];
Map<String, ExecutableElement> mapC =
_inheritanceManager.getMembersInheritedFromClasses(classC);
@@ -767,7 +797,7 @@
ElementFactory.getterElement(getterName, false, _typeProvider.intType);
classA.accessors = <PropertyAccessorElement>[getterG];
ClassElementImpl classB = ElementFactory.classElement2("B");
- classB.interfaces = <InterfaceType>[classA.type];
+ classB.interfaces = <InterfaceType>[_interfaceType(classA)];
expect(_inheritanceManager.lookupInheritance(classB, getterName),
same(getterG));
}
@@ -780,7 +810,7 @@
ElementFactory.methodElement(methodName, _typeProvider.intType);
classA.methods = <MethodElement>[methodM];
ClassElementImpl classB = ElementFactory.classElement2("B");
- classB.interfaces = <InterfaceType>[classA.type];
+ classB.interfaces = <InterfaceType>[_interfaceType(classA)];
expect(_inheritanceManager.lookupInheritance(classB, methodName),
same(methodM));
}
@@ -793,7 +823,7 @@
ElementFactory.setterElement(setterName, false, _typeProvider.intType);
classA.accessors = <PropertyAccessorElement>[setterS];
ClassElementImpl classB = ElementFactory.classElement2("B");
- classB.interfaces = <InterfaceType>[classA.type];
+ classB.interfaces = <InterfaceType>[_interfaceType(classA)];
expect(_inheritanceManager.lookupInheritance(classB, "$setterName="),
same(setterS));
}
@@ -807,14 +837,14 @@
(methodM as MethodElementImpl).isStatic = true;
classA.methods = <MethodElement>[methodM];
ClassElementImpl classB = ElementFactory.classElement2("B");
- classB.interfaces = <InterfaceType>[classA.type];
+ classB.interfaces = <InterfaceType>[_interfaceType(classA)];
expect(_inheritanceManager.lookupInheritance(classB, methodName), isNull);
}
@deprecated
void test_lookupInheritance_interfaces_infiniteLoop() {
ClassElementImpl classA = ElementFactory.classElement2("A");
- classA.interfaces = <InterfaceType>[classA.type];
+ classA.interfaces = <InterfaceType>[_interfaceType(classA)];
expect(_inheritanceManager.lookupInheritance(classA, "name"), isNull);
}
@@ -822,8 +852,8 @@
void test_lookupInheritance_interfaces_infiniteLoop2() {
ClassElementImpl classA = ElementFactory.classElement2("A");
ClassElementImpl classB = ElementFactory.classElement2("B");
- classA.interfaces = <InterfaceType>[classB.type];
- classB.interfaces = <InterfaceType>[classA.type];
+ classA.interfaces = <InterfaceType>[_interfaceType(classB)];
+ classB.interfaces = <InterfaceType>[_interfaceType(classA)];
expect(_inheritanceManager.lookupInheritance(classA, "name"), isNull);
}
@@ -839,9 +869,9 @@
MethodElement methodM2 =
ElementFactory.methodElement(methodName2, _typeProvider.intType);
classI2.methods = <MethodElement>[methodM2];
- classI2.interfaces = <InterfaceType>[classI1.type];
+ classI2.interfaces = <InterfaceType>[_interfaceType(classI1)];
ClassElementImpl classA = ElementFactory.classElement2("A");
- classA.interfaces = <InterfaceType>[classI2.type];
+ classA.interfaces = <InterfaceType>[_interfaceType(classI2)];
expect(_inheritanceManager.lookupInheritance(classA, methodName1),
same(methodM1));
expect(_inheritanceManager.lookupInheritance(classA, methodName2),
@@ -856,7 +886,7 @@
ElementFactory.getterElement(getterName, false, _typeProvider.intType);
classA.accessors = <PropertyAccessorElement>[getterG];
ClassElementImpl classB = ElementFactory.classElement2("B");
- classB.mixins = <InterfaceType>[classA.type];
+ classB.mixins = <InterfaceType>[_interfaceType(classA)];
expect(_inheritanceManager.lookupInheritance(classB, getterName),
same(getterG));
}
@@ -869,7 +899,7 @@
ElementFactory.methodElement(methodName, _typeProvider.intType);
classA.methods = <MethodElement>[methodM];
ClassElementImpl classB = ElementFactory.classElement2("B");
- classB.mixins = <InterfaceType>[classA.type];
+ classB.mixins = <InterfaceType>[_interfaceType(classA)];
expect(_inheritanceManager.lookupInheritance(classB, methodName),
same(methodM));
}
@@ -882,7 +912,7 @@
ElementFactory.setterElement(setterName, false, _typeProvider.intType);
classA.accessors = <PropertyAccessorElement>[setterS];
ClassElementImpl classB = ElementFactory.classElement2("B");
- classB.mixins = <InterfaceType>[classA.type];
+ classB.mixins = <InterfaceType>[_interfaceType(classA)];
expect(_inheritanceManager.lookupInheritance(classB, "$setterName="),
same(setterS));
}
@@ -896,7 +926,7 @@
(methodM as MethodElementImpl).isStatic = true;
classA.methods = <MethodElement>[methodM];
ClassElementImpl classB = ElementFactory.classElement2("B");
- classB.mixins = <InterfaceType>[classA.type];
+ classB.mixins = <InterfaceType>[_interfaceType(classA)];
expect(_inheritanceManager.lookupInheritance(classB, methodName), isNull);
}
@@ -913,7 +943,8 @@
PropertyAccessorElement getterG =
ElementFactory.getterElement(getterName, false, _typeProvider.intType);
classA.accessors = <PropertyAccessorElement>[getterG];
- ClassElementImpl classB = ElementFactory.classElement("B", classA.type);
+ ClassElementImpl classB =
+ ElementFactory.classElement("B", _interfaceType(classA));
expect(_inheritanceManager.lookupInheritance(classB, getterName),
same(getterG));
}
@@ -921,7 +952,7 @@
@deprecated
void test_lookupInheritance_superclass_infiniteLoop() {
ClassElementImpl classA = ElementFactory.classElement2("A");
- classA.supertype = classA.type;
+ classA.supertype = _interfaceType(classA);
expect(_inheritanceManager.lookupInheritance(classA, "name"), isNull);
}
@@ -929,8 +960,8 @@
void test_lookupInheritance_superclass_infiniteLoop2() {
ClassElementImpl classA = ElementFactory.classElement2("A");
ClassElementImpl classB = ElementFactory.classElement2("B");
- classA.supertype = classB.type;
- classB.supertype = classA.type;
+ classA.supertype = _interfaceType(classB);
+ classB.supertype = _interfaceType(classA);
expect(_inheritanceManager.lookupInheritance(classA, "name"), isNull);
}
@@ -941,7 +972,8 @@
MethodElement methodM =
ElementFactory.methodElement(methodName, _typeProvider.intType);
classA.methods = <MethodElement>[methodM];
- ClassElementImpl classB = ElementFactory.classElement("B", classA.type);
+ ClassElementImpl classB =
+ ElementFactory.classElement("B", _interfaceType(classA));
expect(_inheritanceManager.lookupInheritance(classB, methodName),
same(methodM));
}
@@ -953,7 +985,8 @@
PropertyAccessorElement setterS =
ElementFactory.setterElement(setterName, false, _typeProvider.intType);
classA.accessors = <PropertyAccessorElement>[setterS];
- ClassElementImpl classB = ElementFactory.classElement("B", classA.type);
+ ClassElementImpl classB =
+ ElementFactory.classElement("B", _interfaceType(classA));
expect(_inheritanceManager.lookupInheritance(classB, "$setterName="),
same(setterS));
}
@@ -966,7 +999,8 @@
ElementFactory.methodElement(methodName, _typeProvider.intType);
(methodM as MethodElementImpl).isStatic = true;
classA.methods = <MethodElement>[methodM];
- ClassElementImpl classB = ElementFactory.classElement("B", classA.type);
+ ClassElementImpl classB =
+ ElementFactory.classElement("B", _interfaceType(classA));
expect(_inheritanceManager.lookupInheritance(classB, methodName), isNull);
}
@@ -1056,7 +1090,8 @@
MethodElementImpl methodMinA =
ElementFactory.methodElement(methodName, _typeProvider.intType);
classA.methods = <MethodElement>[methodMinA];
- ClassElementImpl classB = ElementFactory.classElement("B", classA.type);
+ ClassElementImpl classB =
+ ElementFactory.classElement("B", _interfaceType(classA));
MethodElementImpl methodMinB =
ElementFactory.methodElement(methodName, _typeProvider.intType);
classB.methods = <MethodElement>[methodMinB];
@@ -1073,7 +1108,7 @@
ElementFactory.methodElement(methodName, _typeProvider.intType);
classA.methods = <MethodElement>[methodMinA];
ClassElementImpl classB = ElementFactory.classElement2("B");
- classB.interfaces = <InterfaceType>[classA.type];
+ classB.interfaces = <InterfaceType>[_interfaceType(classA)];
MethodElementImpl methodMinB =
ElementFactory.methodElement(methodName, _typeProvider.intType);
classB.methods = <MethodElement>[methodMinB];
@@ -1094,7 +1129,10 @@
ElementFactory.methodElement(methodName, _typeProvider.doubleType);
classB.methods = <MethodElement>[methodMinB];
ClassElementImpl classC = ElementFactory.classElement2("C");
- classC.interfaces = <InterfaceType>[classA.type, classB.type];
+ classC.interfaces = <InterfaceType>[
+ _interfaceType(classA),
+ _interfaceType(classB)
+ ];
MethodElementImpl methodMinC =
ElementFactory.methodElement(methodName, _typeProvider.numType);
classC.methods = <MethodElement>[methodMinC];
@@ -1120,4 +1158,11 @@
_definingLibrary.definingCompilationUnit = definingCompilationUnit;
return new InheritanceManager(_definingLibrary);
}
+
+ static InterfaceType _interfaceType(ClassElement element) {
+ return element.instantiate(
+ typeArguments: [],
+ nullabilitySuffix: NullabilitySuffix.star,
+ );
+ }
}
diff --git a/pkg/analyzer/test/generated/invalid_code_test.dart b/pkg/analyzer/test/generated/invalid_code_test.dart
index c77fa3e0..165a105 100644
--- a/pkg/analyzer/test/generated/invalid_code_test.dart
+++ b/pkg/analyzer/test/generated/invalid_code_test.dart
@@ -178,6 +178,12 @@
''');
}
+ test_fuzz_38091() async {
+ // https://github.com/dart-lang/sdk/issues/38091
+ // this caused an infinite loop in parser recovery
+ await _assertCanBeAnalyzed(r'c(=k(<)>');
+ }
+
test_genericFunction_asTypeArgument_ofUnresolvedClass() async {
await _assertCanBeAnalyzed(r'''
C<int Function()> c;
@@ -230,6 +236,29 @@
..contextFeatures = new FeatureSet.forTesting(
sdkVersion: '2.3.0', additionalFeatures: [Feature.extension_methods]);
+ test_extensionOverrideInAnnotationContext() async {
+ await _assertCanBeAnalyzed('''
+class R {
+ const R(int x);
+}
+
+@R(E(null).f())
+extension E on Object {
+ int f() => 0;
+}
+''');
+ }
+
+ test_extensionOverrideInConstContext() async {
+ await _assertCanBeAnalyzed('''
+extension E on Object {
+ int f() => 0;
+}
+
+const e = E(null).f();
+''');
+ }
+
test_fuzz_14() async {
// This crashes because parser produces `ConstructorDeclaration`.
// So, we try to create `ConstructorElement` for it, and it wants
diff --git a/pkg/analyzer/test/generated/parser_fasta_test.dart b/pkg/analyzer/test/generated/parser_fasta_test.dart
index 42e45f2..805d5c7 100644
--- a/pkg/analyzer/test/generated/parser_fasta_test.dart
+++ b/pkg/analyzer/test/generated/parser_fasta_test.dart
@@ -2582,6 +2582,12 @@
expect(indexExpression.toSource(), '?..[27]');
}
+ void test_cascade_withNullCheck_invalid() {
+ parseCompilationUnit('main() { a..[27]?..x; }', errors: [
+ expectedError(ParserErrorCode.NULL_AWARE_CASCADE_OUT_OF_ORDER, 16, 3),
+ ]);
+ }
+
void test_cascade_withNullCheck_methodInvocation() {
var unit = parseCompilationUnit('main() { a?..foo(); }');
FunctionDeclaration funct = unit.declarations[0];
diff --git a/pkg/analyzer/test/generated/resolver_test.dart b/pkg/analyzer/test/generated/resolver_test.dart
index 0b7c771..691b596 100644
--- a/pkg/analyzer/test/generated/resolver_test.dart
+++ b/pkg/analyzer/test/generated/resolver_test.dart
@@ -16,7 +16,6 @@
import 'package:analyzer/src/dart/element/builder.dart';
import 'package:analyzer/src/dart/element/element.dart';
import 'package:analyzer/src/dart/element/type.dart';
-import 'package:analyzer/src/dart/element/type_provider.dart';
import 'package:analyzer/src/error/codes.dart';
import 'package:analyzer/src/generated/engine.dart';
import 'package:analyzer/src/generated/parser.dart' show ParserErrorCode;
@@ -31,6 +30,7 @@
import 'package:test_reflective_loader/test_reflective_loader.dart';
import '../src/dart/resolution/driver_resolution.dart';
+import 'elements_types_mixin.dart';
import 'parser_test.dart';
import 'resolver_test_case.dart';
import 'test_analysis_context.dart';
@@ -38,13 +38,11 @@
main() {
defineReflectiveSuite(() {
- defineReflectiveTests(AnalysisDeltaTest);
defineReflectiveTests(ChangeSetTest);
defineReflectiveTests(EnclosedScopeTest);
defineReflectiveTests(ErrorResolverTest);
defineReflectiveTests(LibraryImportScopeTest);
defineReflectiveTests(LibraryScopeTest);
- defineReflectiveTests(NonNullableTypeProviderTest);
defineReflectiveTests(PrefixedNamespaceTest);
defineReflectiveTests(ScopeTest);
defineReflectiveTests(StrictModeTest);
@@ -63,46 +61,6 @@
}
@reflectiveTest
-class AnalysisDeltaTest extends EngineTestCase {
- TestSource source1 = new TestSource('/1.dart');
- TestSource source2 = new TestSource('/2.dart');
- TestSource source3 = new TestSource('/3.dart');
-
- void test_getAddedSources() {
- AnalysisDelta delta = new AnalysisDelta();
- delta.setAnalysisLevel(source1, AnalysisLevel.ALL);
- delta.setAnalysisLevel(source2, AnalysisLevel.ERRORS);
- delta.setAnalysisLevel(source3, AnalysisLevel.NONE);
- List<Source> addedSources = delta.addedSources;
- expect(addedSources, hasLength(2));
- expect(addedSources, unorderedEquals([source1, source2]));
- }
-
- void test_getAnalysisLevels() {
- AnalysisDelta delta = new AnalysisDelta();
- expect(delta.analysisLevels.length, 0);
- }
-
- void test_setAnalysisLevel() {
- AnalysisDelta delta = new AnalysisDelta();
- delta.setAnalysisLevel(source1, AnalysisLevel.ALL);
- delta.setAnalysisLevel(source2, AnalysisLevel.ERRORS);
- Map<Source, AnalysisLevel> levels = delta.analysisLevels;
- expect(levels.length, 2);
- expect(levels[source1], AnalysisLevel.ALL);
- expect(levels[source2], AnalysisLevel.ERRORS);
- }
-
- void test_toString() {
- AnalysisDelta delta = new AnalysisDelta();
- delta.setAnalysisLevel(new TestSource(), AnalysisLevel.ALL);
- String result = delta.toString();
- expect(result, isNotNull);
- expect(result.isNotEmpty, isTrue);
- }
-}
-
-@reflectiveTest
class ChangeSetTest extends EngineTestCase {
void test_changedContent() {
TestSource source = new TestSource();
@@ -530,132 +488,6 @@
}
@reflectiveTest
-class NonNullableTypeProviderTest extends EngineTestCase {
- void assertNonNullable(InterfaceType type) {
- expect((type as TypeImpl).nullabilitySuffix, NullabilitySuffix.none);
- }
-
- void test_creation() {
- //
- // Create a mock library element with the types expected to be in dart:core.
- // We cannot use either ElementFactory or TestTypeProvider (which uses
- // ElementFactory) because we side-effect the elements in ways that would
- // break other tests.
- //
- InterfaceType objectType = _classElement("Object", null).type;
- InterfaceType boolType = _classElement("bool", objectType).type;
- InterfaceType numType = _classElement("num", objectType).type;
- InterfaceType deprecatedType = _classElement('Deprecated', objectType).type;
- InterfaceType doubleType = _classElement("double", numType).type;
- InterfaceType functionType = _classElement("Function", objectType).type;
- InterfaceType futureType = _classElement("Future", objectType, ["T"]).type;
- InterfaceType futureOrType =
- _classElement("FutureOr", objectType, ["T"]).type;
- InterfaceType intType = _classElement("int", numType).type;
- InterfaceType iterableType =
- _classElement("Iterable", objectType, ["T"]).type;
- InterfaceType listType = _classElement("List", objectType, ["E"]).type;
- InterfaceType mapType = _classElement("Map", objectType, ["K", "V"]).type;
- InterfaceType nullType = _classElement('Null', objectType).type;
- InterfaceType setType = _classElement("Set", objectType, ["E"]).type;
- InterfaceType stackTraceType = _classElement("StackTrace", objectType).type;
- InterfaceType streamType = _classElement("Stream", objectType, ["T"]).type;
- InterfaceType stringType = _classElement("String", objectType).type;
- InterfaceType symbolType = _classElement("Symbol", objectType).type;
- InterfaceType typeType = _classElement("Type", objectType).type;
- CompilationUnitElementImpl coreUnit = new CompilationUnitElementImpl();
- coreUnit.types = <ClassElement>[
- boolType.element,
- deprecatedType.element,
- doubleType.element,
- functionType.element,
- intType.element,
- iterableType.element,
- listType.element,
- mapType.element,
- nullType.element,
- numType.element,
- setType.element,
- objectType.element,
- stackTraceType.element,
- stringType.element,
- symbolType.element,
- typeType.element
- ];
- coreUnit.source = new TestSource('dart:core');
- coreUnit.librarySource = coreUnit.source;
- CompilationUnitElementImpl asyncUnit = new CompilationUnitElementImpl();
- asyncUnit.types = <ClassElement>[
- futureType.element,
- futureOrType.element,
- streamType.element
- ];
- asyncUnit.source = new TestSource('dart:async');
- asyncUnit.librarySource = asyncUnit.source;
- LibraryElementImpl coreLibrary = new LibraryElementImpl.forNode(
- null, null, AstTestFactory.libraryIdentifier2(["dart.core"]), true);
- coreLibrary.definingCompilationUnit = coreUnit;
- LibraryElementImpl asyncLibrary = new LibraryElementImpl.forNode(
- null, null, AstTestFactory.libraryIdentifier2(["dart.async"]), true);
- asyncLibrary.definingCompilationUnit = asyncUnit;
- //
- // Create a type provider and ensure that it can return the expected types.
- //
- TypeProvider provider = new TypeProviderImpl(
- coreLibrary,
- asyncLibrary,
- nullabilitySuffix: NullabilitySuffix.none,
- );
- assertNonNullable(provider.boolType);
- expect(provider.bottomType, isNotNull);
- assertNonNullable(provider.deprecatedType);
- assertNonNullable(provider.doubleType);
- expect(provider.dynamicType, isNotNull);
- assertNonNullable(provider.functionType);
- assertNonNullable(provider.futureType);
- assertNonNullable(provider.futureOrType);
- assertNonNullable(provider.intType);
- assertNonNullable(provider.listType);
- assertNonNullable(provider.mapType);
- expect(provider.neverType, isNotNull);
- assertNonNullable(provider.nullType);
- assertNonNullable(provider.numType);
- assertNonNullable(provider.objectType);
- assertNonNullable(provider.stackTraceType);
- assertNonNullable(provider.streamType);
- assertNonNullable(provider.stringType);
- assertNonNullable(provider.symbolType);
- assertNonNullable(provider.typeType);
- }
-
- ClassElement _classElement(String typeName, InterfaceType superclassType,
- [List<String> parameterNames]) {
- ClassElementImpl element =
- new ClassElementImpl.forNode(AstTestFactory.identifier3(typeName));
- element.supertype = superclassType;
- if (parameterNames != null) {
- int count = parameterNames.length;
- if (count > 0) {
- List<TypeParameterElementImpl> typeParameters =
- new List<TypeParameterElementImpl>(count);
- List<TypeParameterTypeImpl> typeArguments =
- new List<TypeParameterTypeImpl>(count);
- for (int i = 0; i < count; i++) {
- TypeParameterElementImpl typeParameter =
- new TypeParameterElementImpl.forNode(
- AstTestFactory.identifier3(parameterNames[i]));
- typeParameters[i] = typeParameter;
- typeArguments[i] = new TypeParameterTypeImpl(typeParameter);
- typeParameter.type = typeArguments[i];
- }
- element.typeParameters = typeParameters;
- }
- }
- return element;
- }
-}
-
-@reflectiveTest
class PrefixedNamespaceTest extends DriverResolutionTest {
void test_lookup_missing() {
ClassElement element = ElementFactory.classElement2('A');
@@ -1332,7 +1164,7 @@
@reflectiveTest
class TypeResolverVisitorTest extends ParserTestCase
- with ResourceProviderMixin {
+ with ResourceProviderMixin, ElementsTypesMixin {
/**
* The error listener to which errors will be reported.
*/
@@ -1353,6 +1185,8 @@
*/
TypeResolverVisitor _visitor;
+ TypeProvider get typeProvider => _typeProvider;
+
fail_visitConstructorDeclaration() async {
_fail("Not yet tested");
_listener.assertNoErrors();
@@ -1370,7 +1204,7 @@
AstTestFactory.variableDeclarationList(
null, AstTestFactory.typeName(type), [node]);
//resolve(node);
- expect(node.name.staticType, same(type.type));
+ expect(node.name.staticType, interfaceType(type));
_listener.assertNoErrors();
}
@@ -1818,7 +1652,7 @@
exceptionParameter.staticElement =
new LocalVariableElementImpl.forNode(exceptionParameter);
_resolveCatchClause(
- clause, exceptionElement.type, null, [exceptionElement]);
+ clause, interfaceType(exceptionElement), null, [exceptionElement]);
_listener.assertNoErrors();
}
@@ -1834,7 +1668,7 @@
SimpleIdentifier stackTraceParameter = clause.stackTraceParameter;
stackTraceParameter.staticElement =
new LocalVariableElementImpl.forNode(stackTraceParameter);
- _resolveCatchClause(clause, exceptionElement.type,
+ _resolveCatchClause(clause, interfaceType(exceptionElement),
_typeProvider.stackTraceType, [exceptionElement]);
_listener.assertNoErrors();
}
@@ -1859,13 +1693,13 @@
null, "A", null, extendsClause, withClause, implementsClause);
declaration.name.staticElement = elementA;
_resolveNode(declaration, [elementA, elementB, elementC, elementD]);
- expect(elementA.supertype, elementB.type);
+ expect(elementA.supertype, interfaceType(elementB));
List<InterfaceType> mixins = elementA.mixins;
expect(mixins, hasLength(1));
- expect(mixins[0], elementC.type);
+ expect(mixins[0], interfaceType(elementC));
List<InterfaceType> interfaces = elementA.interfaces;
expect(interfaces, hasLength(1));
- expect(interfaces[0], elementD.type);
+ expect(interfaces[0], interfaceType(elementD));
_listener.assertNoErrors();
}
@@ -1886,7 +1720,7 @@
null, "B", null, extendsClause, null, null);
declaration.name.staticElement = elementB;
_resolveNode(declaration, [elementA, elementB]);
- expect(elementB.supertype, elementA.type);
+ expect(elementB.supertype, interfaceType(elementA));
_listener.assertNoErrors();
}
@@ -1958,10 +1792,10 @@
null));
declaration.name.staticElement = elementF;
_resolveNode(declaration, [elementR, elementP]);
- expect(declaration.returnType.type, elementR.type);
+ expect(declaration.returnType.type, interfaceType(elementR));
SimpleFormalParameter parameter =
declaration.functionExpression.parameters.parameters[0];
- expect(parameter.type.type, elementP.type);
+ expect(parameter.type.type, interfaceType(elementP));
_listener.assertNoErrors();
}
@@ -1982,10 +1816,10 @@
null));
declaration.name.staticElement = elementF;
_resolveNode(declaration, []);
- expect(declaration.returnType.type, elementE.type);
+ expect(declaration.returnType.type, typeParameterType(elementE));
SimpleFormalParameter parameter =
declaration.functionExpression.parameters.parameters[0];
- expect(parameter.type.type, elementE.type);
+ expect(parameter.type.type, typeParameterType(elementE));
_listener.assertNoErrors();
}
@@ -2022,10 +1856,10 @@
_resolveNode(fNode, [elementR, elementP]);
- expect(fNode.returnType.type, elementR.type);
- expect(gType.returnType, elementR.type);
- expect(gNode.returnType.type, elementR.type);
- expect(pNode.type.type, elementP.type);
+ expect(fNode.returnType.type, interfaceType(elementR));
+ expect(gType.returnType, interfaceType(elementR));
+ expect(gNode.returnType.type, interfaceType(elementR));
+ expect(pNode.type.type, interfaceType(elementP));
_listener.assertNoErrors();
}
@@ -2063,10 +1897,10 @@
_resolveNode(fNode, [elementR]);
- expect(fNode.returnType.type, elementR.type);
- expect(gType.returnType, elementR.type);
- expect(gNode.returnType.type, elementR.type);
- expect(eNode.type.type, elementE.type);
+ expect(fNode.returnType.type, interfaceType(elementR));
+ expect(gType.returnType, interfaceType(elementR));
+ expect(gNode.returnType.type, interfaceType(elementR));
+ expect(eNode.type.type, typeParameterType(elementE));
_listener.assertNoErrors();
}
@@ -2094,9 +1928,9 @@
]));
declaration.name.staticElement = elementM;
_resolveNode(declaration, [elementA, elementR, elementP]);
- expect(declaration.returnType.type, elementR.type);
+ expect(declaration.returnType.type, interfaceType(elementR));
SimpleFormalParameter parameter = declaration.parameters.parameters[0];
- expect(parameter.type.type, elementP.type);
+ expect(parameter.type.type, interfaceType(elementP));
_listener.assertNoErrors();
}
@@ -2121,9 +1955,9 @@
]));
declaration.name.staticElement = elementM;
_resolveNode(declaration, [elementA]);
- expect(declaration.returnType.type, elementE.type);
+ expect(declaration.returnType.type, typeParameterType(elementE));
SimpleFormalParameter parameter = declaration.parameters.parameters[0];
- expect(parameter.type.type, elementE.type);
+ expect(parameter.type.type, typeParameterType(elementE));
_listener.assertNoErrors();
}
@@ -2154,7 +1988,7 @@
TypeName typeName = AstTestFactory.typeName(classA);
typeName.type = null;
_resolveNode(typeName, [classA]);
- expect(typeName.type, classA.type);
+ expect(typeName.type, interfaceType(classA));
_listener.assertNoErrors();
}
@@ -2179,7 +2013,7 @@
expect(resultType.element, same(classA));
List<DartType> resultArguments = resultType.typeArguments;
expect(resultArguments, hasLength(1));
- expect(resultArguments[0], classB.type);
+ expect(resultArguments[0], interfaceType(classB));
_listener.assertNoErrors();
}
diff --git a/pkg/analyzer/test/generated/resolver_test_case.dart b/pkg/analyzer/test/generated/resolver_test_case.dart
index fdb3b15..aa995d1 100644
--- a/pkg/analyzer/test/generated/resolver_test_case.dart
+++ b/pkg/analyzer/test/generated/resolver_test_case.dart
@@ -20,7 +20,7 @@
import 'package:analyzer/src/dart/element/type.dart';
import 'package:analyzer/src/error/codes.dart';
import 'package:analyzer/src/file_system/file_system.dart';
-import 'package:analyzer/src/generated/engine.dart' hide AnalysisResult;
+import 'package:analyzer/src/generated/engine.dart';
import 'package:analyzer/src/generated/java_engine.dart';
import 'package:analyzer/src/generated/resolver.dart';
import 'package:analyzer/src/generated/sdk.dart';
diff --git a/pkg/analyzer/test/generated/static_type_analyzer_test.dart b/pkg/analyzer/test/generated/static_type_analyzer_test.dart
index de9c1f3..c9246a0 100644
--- a/pkg/analyzer/test/generated/static_type_analyzer_test.dart
+++ b/pkg/analyzer/test/generated/static_type_analyzer_test.dart
@@ -8,6 +8,7 @@
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/ast/token.dart';
import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/dart/element/nullability_suffix.dart';
import 'package:analyzer/dart/element/type.dart';
import 'package:analyzer/src/dart/ast/ast.dart';
import 'package:analyzer/src/dart/element/element.dart';
@@ -25,6 +26,7 @@
import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
+import 'elements_types_mixin.dart';
import 'resolver_test_case.dart';
import 'test_analysis_context.dart';
import 'test_support.dart';
@@ -172,7 +174,9 @@
typeFormals: '[S]',
identifierType: 'void Function<S>(S)');
- typeS = type.typeFormals[0].type;
+ typeS = type.typeFormals[0].instantiate(
+ nullabilitySuffix: NullabilitySuffix.star,
+ );
type = type.instantiate([DynamicTypeImpl.instance]);
expect(type.toString(), 'void Function(dynamic)');
expect(type.typeParameters.toString(), '[S]');
@@ -227,7 +231,8 @@
}
@reflectiveTest
-class StaticTypeAnalyzerTest extends EngineTestCase with ResourceProviderMixin {
+class StaticTypeAnalyzerTest extends EngineTestCase
+ with ResourceProviderMixin, ElementsTypesMixin {
/**
* The error listener to which errors will be reported.
*/
@@ -248,6 +253,8 @@
*/
TypeProvider _typeProvider;
+ TypeProvider get typeProvider => _typeProvider;
+
/**
* The type system used to analyze the test cases.
*/
@@ -279,22 +286,26 @@
// class Derived<T> extends Future<T> { ... }
ClassElementImpl derivedClass =
ElementFactory.classElement2('Derived', ['T']);
- derivedClass.supertype = _typeProvider.futureType
- .instantiate([derivedClass.typeParameters[0].type]);
+ derivedClass.supertype =
+ futureType(typeParameterType(derivedClass.typeParameters[0]));
InterfaceType intType = _typeProvider.intType;
DartType dynamicType = _typeProvider.dynamicType;
- InterfaceType derivedIntType = derivedClass.type.instantiate([intType]);
+ InterfaceType derivedIntType =
+ interfaceType(derivedClass, typeArguments: [intType]);
// flatten(Derived) = dynamic
InterfaceType derivedDynamicType =
- derivedClass.type.instantiate([dynamicType]);
+ interfaceType(derivedClass, typeArguments: [dynamicType]);
expect(_flatten(derivedDynamicType), dynamicType);
// flatten(Derived<int>) = int
expect(_flatten(derivedIntType), intType);
// flatten(Derived<Derived>) = Derived
- expect(_flatten(derivedClass.type.instantiate([derivedDynamicType])),
+ expect(
+ _flatten(
+ interfaceType(derivedClass, typeArguments: [derivedDynamicType])),
derivedDynamicType);
// flatten(Derived<Derived<int>>) = Derived<int>
- expect(_flatten(derivedClass.type.instantiate([derivedIntType])),
+ expect(
+ _flatten(interfaceType(derivedClass, typeArguments: [derivedIntType])),
derivedIntType);
}
@@ -303,13 +314,13 @@
// class B extends A
ClassElementImpl classA = ElementFactory.classElement2('A', []);
ClassElementImpl classB = ElementFactory.classElement2('B', []);
- classA.supertype = classB.type;
- classB.supertype = classA.type;
+ classA.supertype = interfaceType(classB);
+ classB.supertype = interfaceType(classA);
// flatten(A) = A and flatten(B) = B, since neither class contains Future
// in its class hierarchy. Even though there is a loop in the class
// hierarchy, flatten() should terminate.
- expect(_flatten(classA.type), classA.type);
- expect(_flatten(classB.type), classB.type);
+ expect(_flatten(interfaceType(classA)), interfaceType(classA));
+ expect(_flatten(interfaceType(classB)), interfaceType(classB));
}
void test_flatten_related_derived_types() {
@@ -318,59 +329,52 @@
// class Derived<T> extends Future<T>
ClassElementImpl derivedClass =
ElementFactory.classElement2('Derived', ['T']);
- derivedClass.supertype = _typeProvider.futureType
- .instantiate([derivedClass.typeParameters[0].type]);
- InterfaceType derivedType = derivedClass.type;
+ derivedClass.supertype =
+ futureType(typeParameterType(derivedClass.typeParameters[0]));
// class A extends Derived<int> implements Derived<num> { ... }
- ClassElementImpl classA =
- ElementFactory.classElement('A', derivedType.instantiate([intType]));
+ ClassElementImpl classA = ElementFactory.classElement(
+ 'A', interfaceType(derivedClass, typeArguments: [intType]));
classA.interfaces = <InterfaceType>[
- derivedType.instantiate([numType])
+ interfaceType(derivedClass, typeArguments: [numType]),
];
// class B extends Future<num> implements Future<int> { ... }
- ClassElementImpl classB =
- ElementFactory.classElement('B', derivedType.instantiate([numType]));
+ ClassElementImpl classB = ElementFactory.classElement(
+ 'B', interfaceType(derivedClass, typeArguments: [numType]));
classB.interfaces = <InterfaceType>[
- derivedType.instantiate([intType])
+ interfaceType(derivedClass, typeArguments: [intType])
];
// flatten(A) = flatten(B) = int, since int is more specific than num.
// The code in flatten() that inhibits infinite recursion shouldn't be
// fooled by the fact that Derived appears twice in the type hierarchy.
- expect(_flatten(classA.type), intType);
- expect(_flatten(classB.type), intType);
+ expect(_flatten(interfaceType(classA)), intType);
+ expect(_flatten(interfaceType(classB)), intType);
}
void test_flatten_related_types() {
- InterfaceType futureType = _typeProvider.futureType;
InterfaceType intType = _typeProvider.intType;
InterfaceType numType = _typeProvider.numType;
// class A extends Future<int> implements Future<num> { ... }
ClassElementImpl classA =
- ElementFactory.classElement('A', futureType.instantiate([intType]));
- classA.interfaces = <InterfaceType>[
- futureType.instantiate([numType])
- ];
+ ElementFactory.classElement('A', _typeProvider.futureType2(intType));
+ classA.interfaces = <InterfaceType>[_typeProvider.futureType2(numType)];
// class B extends Future<num> implements Future<int> { ... }
ClassElementImpl classB =
- ElementFactory.classElement('B', futureType.instantiate([numType]));
- classB.interfaces = <InterfaceType>[
- futureType.instantiate([intType])
- ];
+ ElementFactory.classElement('B', _typeProvider.futureType2(numType));
+ classB.interfaces = <InterfaceType>[_typeProvider.futureType2(intType)];
// flatten(A) = flatten(B) = int, since int is more specific than num.
- expect(_flatten(classA.type), intType);
- expect(_flatten(classB.type), intType);
+ expect(_flatten(interfaceType(classA)), intType);
+ expect(_flatten(interfaceType(classB)), intType);
}
void test_flatten_simple() {
InterfaceType intType = _typeProvider.intType;
DartType dynamicType = _typeProvider.dynamicType;
InterfaceType futureDynamicType = _typeProvider.futureDynamicType;
- InterfaceType futureIntType =
- _typeProvider.futureType.instantiate([intType]);
+ InterfaceType futureIntType = _typeProvider.futureType2(intType);
InterfaceType futureFutureDynamicType =
- _typeProvider.futureType.instantiate([futureDynamicType]);
+ _typeProvider.futureType2(futureDynamicType);
InterfaceType futureFutureIntType =
- _typeProvider.futureType.instantiate([futureIntType]);
+ _typeProvider.futureType2(futureIntType);
// flatten(int) = int
expect(_flatten(intType), intType);
// flatten(dynamic) = dynamic
@@ -386,25 +390,20 @@
}
void test_flatten_unrelated_types() {
- InterfaceType futureType = _typeProvider.futureType;
InterfaceType intType = _typeProvider.intType;
InterfaceType stringType = _typeProvider.stringType;
// class A extends Future<int> implements Future<String> { ... }
ClassElementImpl classA =
- ElementFactory.classElement('A', futureType.instantiate([intType]));
- classA.interfaces = <InterfaceType>[
- futureType.instantiate([stringType])
- ];
+ ElementFactory.classElement('A', _typeProvider.futureType2(intType));
+ classA.interfaces = <InterfaceType>[_typeProvider.futureType2(stringType)];
// class B extends Future<String> implements Future<int> { ... }
ClassElementImpl classB =
- ElementFactory.classElement('B', futureType.instantiate([stringType]));
- classB.interfaces = <InterfaceType>[
- futureType.instantiate([intType])
- ];
+ ElementFactory.classElement('B', _typeProvider.futureType2(stringType));
+ classB.interfaces = <InterfaceType>[_typeProvider.futureType2(intType)];
// flatten(A) = A and flatten(B) = B, since neither string nor int is more
// specific than the other.
- expect(_flatten(classA.type), classA.type);
- expect(_flatten(classB.type), classB.type);
+ expect(_flatten(interfaceType(classA)), interfaceType(classA));
+ expect(_flatten(interfaceType(classB)), interfaceType(classB));
}
void test_visitAdjacentStrings() {
@@ -419,11 +418,11 @@
// class A { ... this as B ... }
// class B extends A {}
ClassElement superclass = ElementFactory.classElement2("A");
- InterfaceType superclassType = superclass.type;
+ InterfaceType superclassType = interfaceType(superclass);
ClassElement subclass = ElementFactory.classElement("B", superclassType);
Expression node = AstTestFactory.asExpression(
AstTestFactory.thisExpression(), AstTestFactory.typeName(subclass));
- expect(_analyze(node, superclassType), same(subclass.type));
+ expect(_analyze(node, superclassType), interfaceType(subclass));
_listener.assertNoErrors();
}
@@ -453,10 +452,9 @@
void test_visitAwaitExpression_flattened() {
// await e, where e has type Future<Future<int>>
InterfaceType intType = _typeProvider.intType;
- InterfaceType futureIntType =
- _typeProvider.futureType.instantiate(<DartType>[intType]);
+ InterfaceType futureIntType = _typeProvider.futureType2(intType);
InterfaceType futureFutureIntType =
- _typeProvider.futureType.instantiate(<DartType>[futureIntType]);
+ _typeProvider.futureType2(futureIntType);
Expression node = AstTestFactory.awaitExpression(
_resolvedVariable(futureFutureIntType, 'e'));
expect(_analyze(node), same(futureIntType));
@@ -466,8 +464,7 @@
void test_visitAwaitExpression_simple() {
// await e, where e has type Future<int>
InterfaceType intType = _typeProvider.intType;
- InterfaceType futureIntType =
- _typeProvider.futureType.instantiate(<DartType>[intType]);
+ InterfaceType futureIntType = _typeProvider.futureType2(intType);
Expression node =
AstTestFactory.awaitExpression(_resolvedVariable(futureIntType, 'e'));
expect(_analyze(node), same(intType));
@@ -552,7 +549,7 @@
// }
// (a as A) * 2.0
ClassElementImpl classA = ElementFactory.classElement2("A");
- InterfaceType typeA = classA.type;
+ InterfaceType typeA = interfaceType(classA);
MethodElement operator =
ElementFactory.methodElement("*", typeA, [_typeProvider.doubleType]);
classA.methods = <MethodElement>[operator];
@@ -649,21 +646,15 @@
FunctionExpression node = _resolvedFunctionExpression(
AstTestFactory.formalParameterList([]), body);
DartType resultType = _analyze(node);
- _assertFunctionType(
- _typeProvider.futureType
- .instantiate(<DartType>[_typeProvider.dynamicType]),
- null,
- null,
- null,
- resultType);
+ _assertFunctionType(_typeProvider.futureType2(_typeProvider.dynamicType),
+ null, null, null, resultType);
_listener.assertNoErrors();
}
void test_visitFunctionExpression_async_expression_flatten() {
// () async => e, where e has type Future<int>
InterfaceType intType = _typeProvider.intType;
- InterfaceType futureIntType =
- _typeProvider.futureType.instantiate(<DartType>[intType]);
+ InterfaceType futureIntType = _typeProvider.futureType2(intType);
Expression expression = _resolvedVariable(futureIntType, 'e');
ExpressionFunctionBody body =
AstTestFactory.expressionFunctionBody(expression);
@@ -671,23 +662,17 @@
FunctionExpression node = _resolvedFunctionExpression(
AstTestFactory.formalParameterList([]), body);
DartType resultType = _analyze(node);
- _assertFunctionType(
- _typeProvider.futureType
- .instantiate(<DartType>[_typeProvider.dynamicType]),
- null,
- null,
- null,
- resultType);
+ _assertFunctionType(_typeProvider.futureType2(_typeProvider.dynamicType),
+ null, null, null, resultType);
_listener.assertNoErrors();
}
void test_visitFunctionExpression_async_expression_flatten_twice() {
// () async => e, where e has type Future<Future<int>>
InterfaceType intType = _typeProvider.intType;
- InterfaceType futureIntType =
- _typeProvider.futureType.instantiate(<DartType>[intType]);
+ InterfaceType futureIntType = _typeProvider.futureType2(intType);
InterfaceType futureFutureIntType =
- _typeProvider.futureType.instantiate(<DartType>[futureIntType]);
+ _typeProvider.futureType2(futureIntType);
Expression expression = _resolvedVariable(futureFutureIntType, 'e');
ExpressionFunctionBody body =
AstTestFactory.expressionFunctionBody(expression);
@@ -695,13 +680,8 @@
FunctionExpression node = _resolvedFunctionExpression(
AstTestFactory.formalParameterList([]), body);
DartType resultType = _analyze(node);
- _assertFunctionType(
- _typeProvider.futureType
- .instantiate(<DartType>[_typeProvider.dynamicType]),
- null,
- null,
- null,
- resultType);
+ _assertFunctionType(_typeProvider.futureType2(_typeProvider.dynamicType),
+ null, null, null, resultType);
_listener.assertNoErrors();
}
@@ -932,7 +912,7 @@
AstTestFactory.typeName(classElement),
[AstTestFactory.identifier3(constructorName)]);
node.staticElement = constructor;
- expect(_analyze(node), same(classElement.type));
+ expect(_analyze(node), interfaceType(classElement));
_listener.assertNoErrors();
}
@@ -945,14 +925,15 @@
elementC.constructors = <ConstructorElement>[constructor];
TypeName typeName =
AstTestFactory.typeName(elementC, [AstTestFactory.typeName(elementI)]);
- typeName.type = elementC.type.instantiate(<DartType>[elementI.type]);
+ typeName.type =
+ interfaceType(elementC, typeArguments: [interfaceType(elementI)]);
InstanceCreationExpression node =
AstTestFactory.instanceCreationExpression2(null, typeName);
node.staticElement = constructor;
- InterfaceType interfaceType = _analyze(node) as InterfaceType;
- List<DartType> typeArgs = interfaceType.typeArguments;
+ InterfaceType type = _analyze(node) as InterfaceType;
+ List<DartType> typeArgs = type.typeArguments;
expect(typeArgs.length, 1);
- expect(typeArgs[0], elementI.type);
+ expect(typeArgs[0], interfaceType(elementI));
_listener.assertNoErrors();
}
@@ -966,7 +947,7 @@
AstTestFactory.instanceCreationExpression2(
null, AstTestFactory.typeName(classElement));
node.staticElement = constructor;
- expect(_analyze(node), same(classElement.type));
+ expect(_analyze(node), interfaceType(classElement));
_listener.assertNoErrors();
}
@@ -998,9 +979,7 @@
Expression node = AstTestFactory.listLiteral();
DartType resultType = _analyze(node);
_assertType2(
- _typeProvider.listType
- .instantiate(<DartType>[_typeProvider.dynamicType]),
- resultType);
+ _typeProvider.listType2(_typeProvider.dynamicType), resultType);
_listener.assertNoErrors();
}
@@ -1008,9 +987,7 @@
// [0]
Expression node = AstTestFactory.listLiteral([_resolvedInteger(0)]);
DartType resultType = _analyze(node);
- _assertType2(
- _typeProvider.listType.instantiate(<DartType>[_typeProvider.intType]),
- resultType);
+ _assertType2(_typeProvider.listType2(_typeProvider.intType), resultType);
_listener.assertNoErrors();
}
@@ -1020,9 +997,7 @@
Expression node = AstTestFactory.listLiteral([identifier]);
DartType resultType = _analyze(node);
_assertType2(
- _typeProvider.listType
- .instantiate(<DartType>[_typeProvider.dynamicType]),
- resultType);
+ _typeProvider.listType2(_typeProvider.dynamicType), resultType);
_listener.assertNoErrors();
}
@@ -1032,9 +1007,7 @@
Expression node = AstTestFactory.listLiteral(
[_resolvedInteger(0), identifier, _resolvedInteger(1)]);
DartType resultType = _analyze(node);
- _assertType2(
- _typeProvider.listType.instantiate(<DartType>[_typeProvider.intType]),
- resultType);
+ _assertType2(_typeProvider.listType2(_typeProvider.intType), resultType);
_listener.assertNoErrors();
}
@@ -1043,8 +1016,8 @@
Expression node = AstTestFactory.setOrMapLiteral(null, null);
DartType resultType = _analyze(node);
_assertType2(
- _typeProvider.mapType.instantiate(
- <DartType>[_typeProvider.dynamicType, _typeProvider.dynamicType]),
+ _typeProvider.mapType2(
+ _typeProvider.dynamicType, _typeProvider.dynamicType),
resultType);
_listener.assertNoErrors();
}
@@ -1055,8 +1028,8 @@
null, null, [AstTestFactory.mapLiteralEntry("k", _resolvedInteger(0))]);
DartType resultType = _analyze(node);
_assertType2(
- _typeProvider.mapType.instantiate(
- <DartType>[_typeProvider.dynamicType, _typeProvider.intType]),
+ _typeProvider.mapType2(
+ _typeProvider.dynamicType, _typeProvider.intType),
resultType);
_listener.assertNoErrors();
}
@@ -1246,8 +1219,9 @@
void test_visitSuperExpression() {
// super
- InterfaceType superType = ElementFactory.classElement2("A").type;
- InterfaceType thisType = ElementFactory.classElement("B", superType).type;
+ InterfaceType superType = interfaceType(ElementFactory.classElement2("A"));
+ InterfaceType thisType =
+ interfaceType(ElementFactory.classElement("B", superType));
Expression node = AstTestFactory.superExpression();
expect(_analyze(node, thisType), same(thisType));
_listener.assertNoErrors();
@@ -1260,9 +1234,8 @@
void test_visitThisExpression() {
// this
- InterfaceType thisType =
- ElementFactory.classElement("B", ElementFactory.classElement2("A").type)
- .type;
+ InterfaceType thisType = interfaceType(ElementFactory.classElement(
+ "B", interfaceType(ElementFactory.classElement2("A"))));
Expression node = AstTestFactory.thisExpression();
expect(_analyze(node, thisType), same(thisType));
_listener.assertNoErrors();
diff --git a/pkg/analyzer/test/generated/static_warning_code_test.dart b/pkg/analyzer/test/generated/static_warning_code_test.dart
index 0cfcdb3..beea4a3 100644
--- a/pkg/analyzer/test/generated/static_warning_code_test.dart
+++ b/pkg/analyzer/test/generated/static_warning_code_test.dart
@@ -15,6 +15,9 @@
@reflectiveTest
class StaticWarningCodeTest extends DriverResolutionTest {
+ // TODO(brianwilkerson) Figure out what to do with the rest of these tests.
+ // The names do not correspond to diagnostic codes, so it isn't clear what
+ // they're testing.
test_functionWithoutCall_direct() async {
await assertNoErrorsInCode('''
class A implements Function {
@@ -83,307 +86,6 @@
]);
}
- test_staticAccessToInstanceMember_method_invocation() async {
- await assertErrorsInCode('''
-class A {
- m() {}
-}
-main() {
- A.m();
-}''', [
- error(StaticWarningCode.STATIC_ACCESS_TO_INSTANCE_MEMBER, 34, 1),
- ]);
- }
-
- test_staticAccessToInstanceMember_method_reference() async {
- await assertErrorsInCode('''
-class A {
- m() {}
-}
-main() {
- A.m;
-}''', [
- error(StaticWarningCode.STATIC_ACCESS_TO_INSTANCE_MEMBER, 34, 1),
- ]);
- }
-
- test_staticAccessToInstanceMember_propertyAccess_field() async {
- await assertErrorsInCode('''
-class A {
- var f;
-}
-main() {
- A.f;
-}''', [
- error(StaticWarningCode.STATIC_ACCESS_TO_INSTANCE_MEMBER, 34, 1),
- ]);
- }
-
- test_staticAccessToInstanceMember_propertyAccess_getter() async {
- await assertErrorsInCode('''
-class A {
- get f => 42;
-}
-main() {
- A.f;
-}''', [
- error(StaticWarningCode.STATIC_ACCESS_TO_INSTANCE_MEMBER, 40, 1),
- ]);
- }
-
- test_staticAccessToInstanceMember_propertyAccess_setter() async {
- await assertErrorsInCode('''
-class A {
- set f(x) {}
-}
-main() {
- A.f = 42;
-}''', [
- error(StaticWarningCode.STATIC_ACCESS_TO_INSTANCE_MEMBER, 39, 1),
- ]);
- }
-
- test_switchExpressionNotAssignable() async {
- await assertErrorsInCode('''
-f(int p) {
- switch (p) {
- case 'a': break;
- }
-}''', [
- error(StaticWarningCode.SWITCH_EXPRESSION_NOT_ASSIGNABLE, 21, 1),
- ]);
- }
-
- test_typeAnnotationDeferredClass_asExpression() async {
- newFile("/test/lib/lib1.dart", content: '''
-library lib1;
-class A {}''');
- await assertErrorsInCode('''
-library root;
-import 'lib1.dart' deferred as a;
-f(var v) {
- v as a.A;
-}''', [
- error(StaticWarningCode.TYPE_ANNOTATION_DEFERRED_CLASS, 66, 3),
- ]);
- }
-
- test_typeAnnotationDeferredClass_catchClause() async {
- newFile("/test/lib/lib1.dart", content: '''
-library lib1;
-class A {}''');
- await assertErrorsInCode('''
-library root;
-import 'lib1.dart' deferred as a;
-f(var v) {
- try {
- } on a.A {
- }
-}''', [
- error(StaticWarningCode.TYPE_ANNOTATION_DEFERRED_CLASS, 74, 3),
- ]);
- }
-
- test_typeAnnotationDeferredClass_fieldFormalParameter() async {
- newFile("/test/lib/lib1.dart", content: '''
-library lib1;
-class A {}''');
- await assertErrorsInCode('''
-library root;
-import 'lib1.dart' deferred as a;
-class C {
- var v;
- C(a.A this.v);
-}''', [
- error(StaticWarningCode.TYPE_ANNOTATION_DEFERRED_CLASS, 71, 3),
- ]);
- }
-
- test_typeAnnotationDeferredClass_functionDeclaration_returnType() async {
- newFile("/test/lib/lib1.dart", content: '''
-library lib1;
-class A {}''');
- await assertErrorsInCode('''
-library root;
-import 'lib1.dart' deferred as a;
-a.A f() { return null; }''', [
- error(StaticWarningCode.TYPE_ANNOTATION_DEFERRED_CLASS, 48, 3),
- ]);
- }
-
- test_typeAnnotationDeferredClass_functionTypedFormalParameter_returnType() async {
- newFile("/test/lib/lib1.dart", content: '''
-library lib1;
-class A {}''');
- await assertErrorsInCode('''
-library root;
-import 'lib1.dart' deferred as a;
-f(a.A g()) {}''', [
- error(StaticWarningCode.TYPE_ANNOTATION_DEFERRED_CLASS, 50, 3),
- ]);
- }
-
- test_typeAnnotationDeferredClass_isExpression() async {
- newFile("/test/lib/lib1.dart", content: '''
-library lib1;
-class A {}''');
- await assertErrorsInCode('''
-library root;
-import 'lib1.dart' deferred as a;
-f(var v) {
- bool b = v is a.A;
-}''', [
- error(HintCode.UNUSED_LOCAL_VARIABLE, 66, 1),
- error(StaticWarningCode.TYPE_ANNOTATION_DEFERRED_CLASS, 75, 3),
- ]);
- }
-
- test_typeAnnotationDeferredClass_methodDeclaration_returnType() async {
- newFile("/test/lib/lib1.dart", content: '''
-library lib1;
-class A {}''');
- await assertErrorsInCode('''
-library root;
-import 'lib1.dart' deferred as a;
-class C {
- a.A m() { return null; }
-}''', [
- error(StaticWarningCode.TYPE_ANNOTATION_DEFERRED_CLASS, 60, 3),
- ]);
- }
-
- test_typeAnnotationDeferredClass_simpleFormalParameter() async {
- newFile("/test/lib/lib1.dart", content: '''
-library lib1;
-class A {}''');
- await assertErrorsInCode('''
-library root;
-import 'lib1.dart' deferred as a;
-f(a.A v) {}''', [
- error(StaticWarningCode.TYPE_ANNOTATION_DEFERRED_CLASS, 50, 3),
- ]);
- }
-
- test_typeAnnotationDeferredClass_typeArgumentList() async {
- newFile("/test/lib/lib1.dart", content: '''
-library lib1;
-class A {}''');
- await assertErrorsInCode('''
-library root;
-import 'lib1.dart' deferred as a;
-class C<E> {}
-C<a.A> c;''', [
- error(StaticWarningCode.TYPE_ANNOTATION_DEFERRED_CLASS, 64, 3),
- ]);
- }
-
- test_typeAnnotationDeferredClass_typeArgumentList2() async {
- newFile("/test/lib/lib1.dart", content: '''
-library lib1;
-class A {}''');
- await assertErrorsInCode('''
-library root;
-import 'lib1.dart' deferred as a;
-class C<E, F> {}
-C<a.A, a.A> c;''', [
- error(StaticWarningCode.TYPE_ANNOTATION_DEFERRED_CLASS, 67, 3),
- error(StaticWarningCode.TYPE_ANNOTATION_DEFERRED_CLASS, 72, 3),
- ]);
- }
-
- test_typeAnnotationDeferredClass_typeParameter_bound() async {
- newFile("/test/lib/lib1.dart", content: '''
-library lib1;
-class A {}''');
- await assertErrorsInCode('''
-library root;
-import 'lib1.dart' deferred as a;
-class C<E extends a.A> {}''', [
- error(StaticWarningCode.TYPE_ANNOTATION_DEFERRED_CLASS, 66, 3),
- ]);
- }
-
- test_typeAnnotationDeferredClass_variableDeclarationList() async {
- newFile("/test/lib/lib1.dart", content: '''
-library lib1;
-class A {}''');
- await assertErrorsInCode('''
-library root;
-import 'lib1.dart' deferred as a;
-a.A v;''', [
- error(StaticWarningCode.TYPE_ANNOTATION_DEFERRED_CLASS, 48, 3),
- ]);
- }
-
- test_typeParameterReferencedByStatic_field() async {
- await assertErrorsInCode('''
-class A<K> {
- static K k;
-}''', [
- error(StaticWarningCode.TYPE_PARAMETER_REFERENCED_BY_STATIC, 22, 1),
- ]);
- }
-
- test_typeParameterReferencedByStatic_getter() async {
- await assertErrorsInCode('''
-class A<K> {
- static K get k => null;
-}''', [
- error(StaticWarningCode.TYPE_PARAMETER_REFERENCED_BY_STATIC, 22, 1),
- ]);
- }
-
- test_typeParameterReferencedByStatic_methodBodyReference() async {
- await assertErrorsInCode('''
-class A<K> {
- static m() {
- K k;
- }
-}''', [
- error(StaticWarningCode.TYPE_PARAMETER_REFERENCED_BY_STATIC, 32, 1),
- error(HintCode.UNUSED_LOCAL_VARIABLE, 34, 1),
- ]);
- }
-
- test_typeParameterReferencedByStatic_methodParameter() async {
- await assertErrorsInCode('''
-class A<K> {
- static m(K k) {}
-}''', [
- error(StaticWarningCode.TYPE_PARAMETER_REFERENCED_BY_STATIC, 24, 1),
- ]);
- }
-
- test_typeParameterReferencedByStatic_methodReturn() async {
- await assertErrorsInCode('''
-class A<K> {
- static K m() { return null; }
-}''', [
- error(StaticWarningCode.TYPE_PARAMETER_REFERENCED_BY_STATIC, 22, 1),
- ]);
- }
-
- test_typeParameterReferencedByStatic_setter() async {
- await assertErrorsInCode('''
-class A<K> {
- static set s(K k) {}
-}''', [
- error(StaticWarningCode.TYPE_PARAMETER_REFERENCED_BY_STATIC, 28, 1),
- ]);
- }
-
- test_typeParameterReferencedByStatic_simpleIdentifier() async {
- await assertErrorsInCode('''
-class A<T> {
- static foo() {
- T;
- }
-}
-''', [
- error(StaticWarningCode.TYPE_PARAMETER_REFERENCED_BY_STATIC, 34, 1),
- ]);
- }
-
test_typePromotion_functionType_arg_InterToDyn() async {
await assertNoErrorsInCode('''
typedef FuncDyn(x);
@@ -397,318 +99,6 @@
}''');
}
- test_typeTestNonType() async {
- await assertErrorsInCode('''
-var A = 0;
-f(var p) {
- if (p is A) {
- }
-}''', [
- error(StaticWarningCode.TYPE_TEST_WITH_NON_TYPE, 33, 1),
- ]);
- }
-
- test_typeTestWithUndefinedName() async {
- await assertErrorsInCode('''
-f(var p) {
- if (p is A) {
- }
-}''', [
- error(StaticWarningCode.TYPE_TEST_WITH_UNDEFINED_NAME, 22, 1),
- ]);
- }
-
- test_undefinedClass_instanceCreation() async {
- await assertErrorsInCode('''
-f() { new C(); }
-''', [
- error(CompileTimeErrorCode.UNDEFINED_CLASS, 10, 1),
- ]);
- }
-
- test_undefinedClass_variableDeclaration() async {
- await assertErrorsInCode('''
-f() { C c; }
-''', [
- error(CompileTimeErrorCode.UNDEFINED_CLASS, 6, 1),
- error(HintCode.UNUSED_LOCAL_VARIABLE, 8, 1),
- ]);
- }
-
- test_undefinedClassBoolean_variableDeclaration() async {
- await assertErrorsInCode('''
-f() { boolean v; }
-''', [
- error(StaticWarningCode.UNDEFINED_CLASS_BOOLEAN, 6, 7),
- error(HintCode.UNUSED_LOCAL_VARIABLE, 14, 1),
- ]);
- }
-
- @failingTest
- test_undefinedIdentifier_commentReference() async {
- await assertErrorsInCode('''
-/** [m] xxx [new B.c] */
-class A {
-}''', [
- error(StaticWarningCode.UNDEFINED_IDENTIFIER, 5, 1),
- error(StaticWarningCode.UNDEFINED_IDENTIFIER, 17, 1),
- ]);
- }
-
- test_undefinedIdentifier_for() async {
- await assertErrorsInCode('''
-f(var l) {
- for (e in l) {
- }
-}''', [
- error(StaticWarningCode.UNDEFINED_IDENTIFIER, 18, 1),
- ]);
- }
-
- test_undefinedIdentifier_function() async {
- await assertErrorsInCode('''
-int a() => b;
-''', [
- error(StaticWarningCode.UNDEFINED_IDENTIFIER, 11, 1),
- ]);
- }
-
- test_undefinedIdentifier_importCore_withShow() async {
- await assertErrorsInCode('''
-import 'dart:core' show List;
-main() {
- List;
- String;
-}''', [
- error(StaticWarningCode.UNDEFINED_IDENTIFIER, 49, 6),
- ]);
- }
-
- test_undefinedIdentifier_initializer() async {
- await assertErrorsInCode('''
-var a = b;
-''', [
- error(StaticWarningCode.UNDEFINED_IDENTIFIER, 8, 1),
- ]);
- }
-
- test_undefinedIdentifier_methodInvocation() async {
- await assertErrorsInCode('''
-f() { C.m(); }
-''', [
- error(StaticWarningCode.UNDEFINED_IDENTIFIER, 6, 1),
- ]);
- }
-
- test_undefinedIdentifier_private_getter() async {
- newFile("/test/lib/lib.dart", content: '''
-library lib;
-class A {
- var _foo;
-}''');
- await assertErrorsInCode('''
-import 'lib.dart';
-class B extends A {
- test() {
- var v = _foo;
- }
-}''', [
- error(HintCode.UNUSED_LOCAL_VARIABLE, 58, 1),
- error(StaticWarningCode.UNDEFINED_IDENTIFIER, 62, 4),
- ]);
- }
-
- test_undefinedIdentifier_private_setter() async {
- newFile("/test/lib/lib.dart", content: '''
-library lib;
-class A {
- var _foo;
-}''');
- await assertErrorsInCode('''
-import 'lib.dart';
-class B extends A {
- test() {
- _foo = 42;
- }
-}''', [
- error(StaticWarningCode.UNDEFINED_IDENTIFIER, 54, 4),
- ]);
- }
-
- test_undefinedIdentifierAwait_function() async {
- await assertErrorsInCode('''
-void a() { await; }
-''', [
- error(StaticWarningCode.UNDEFINED_IDENTIFIER_AWAIT, 11, 5),
- ]);
- }
-
- test_undefinedNamedParameter() async {
- await assertErrorsInCode('''
-f({a, b}) {}
-main() {
- f(c: 1);
-}''', [
- error(CompileTimeErrorCode.UNDEFINED_NAMED_PARAMETER, 26, 1),
- ]);
- }
-
- test_undefinedStaticMethodOrGetter_getter() async {
- await assertErrorsInCode('''
-class C {}
-f(var p) {
- f(C.m);
-}''', [
- error(StaticTypeWarningCode.UNDEFINED_GETTER, 28, 1),
- ]);
- }
-
- test_undefinedStaticMethodOrGetter_getter_inSuperclass() async {
- await assertErrorsInCode('''
-class S {
- static int get g => 0;
-}
-class C extends S {}
-f(var p) {
- f(C.g);
-}''', [
- error(StaticTypeWarningCode.UNDEFINED_GETTER, 75, 1),
- ]);
- }
-
- test_undefinedStaticMethodOrGetter_setter_inSuperclass() async {
- await assertErrorsInCode('''
-class S {
- static set s(int i) {}
-}
-class C extends S {}
-f(var p) {
- f(C.s = 1);
-}''', [
- error(StaticTypeWarningCode.UNDEFINED_SETTER, 75, 1),
- ]);
- }
-
- test_useOfVoidResult_assignmentExpression_function() async {
- await assertErrorsInCode('''
-void f() {}
-class A {
- n() {
- var a;
- a = f();
- }
-}''', [
- error(HintCode.UNUSED_LOCAL_VARIABLE, 38, 1),
- error(StaticWarningCode.USE_OF_VOID_RESULT, 49, 1),
- ]);
- }
-
- test_useOfVoidResult_assignmentExpression_method() async {
- await assertErrorsInCode('''
-class A {
- void m() {}
- n() {
- var a;
- a = m();
- }
-}''', [
- error(HintCode.UNUSED_LOCAL_VARIABLE, 40, 1),
- error(StaticWarningCode.USE_OF_VOID_RESULT, 51, 1),
- ]);
- }
-
- test_useOfVoidResult_await() async {
- await assertNoErrorsInCode('''
-main() async {
- void x;
- await x;
-}''');
- }
-
- test_useOfVoidResult_inForLoop_error() async {
- await assertErrorsInCode('''
-class A {
- void m() {}
- n() {
- for(Object a = m();;) {}
- }
-}''', [
- error(HintCode.UNUSED_LOCAL_VARIABLE, 47, 1),
- error(StaticWarningCode.USE_OF_VOID_RESULT, 51, 1),
- ]);
- }
-
- test_useOfVoidResult_inForLoop_ok() async {
- await assertNoErrorsInCode('''
-class A {
- void m() {}
- n() {
- for(void a = m();;) {}
- }
-}''');
- }
-
- test_useOfVoidResult_variableDeclaration_function_error() async {
- await assertErrorsInCode('''
-void f() {}
-class A {
- n() {
- Object a = f();
- }
-}''', [
- error(HintCode.UNUSED_LOCAL_VARIABLE, 41, 1),
- error(StaticWarningCode.USE_OF_VOID_RESULT, 45, 1),
- ]);
- }
-
- test_useOfVoidResult_variableDeclaration_function_ok() async {
- await assertNoErrorsInCode('''
-void f() {}
-class A {
- n() {
- void a = f();
- }
-}''');
- }
-
- test_useOfVoidResult_variableDeclaration_method2() async {
- await assertErrorsInCode('''
-class A {
- void m() {}
- n() {
- Object a = m(), b = m();
- }
-}''', [
- error(HintCode.UNUSED_LOCAL_VARIABLE, 43, 1),
- error(StaticWarningCode.USE_OF_VOID_RESULT, 47, 1),
- error(HintCode.UNUSED_LOCAL_VARIABLE, 52, 1),
- error(StaticWarningCode.USE_OF_VOID_RESULT, 56, 1),
- ]);
- }
-
- test_useOfVoidResult_variableDeclaration_method_error() async {
- await assertErrorsInCode('''
-class A {
- void m() {}
- n() {
- Object a = m();
- }
-}''', [
- error(HintCode.UNUSED_LOCAL_VARIABLE, 43, 1),
- error(StaticWarningCode.USE_OF_VOID_RESULT, 47, 1),
- ]);
- }
-
- test_useOfVoidResult_variableDeclaration_method_ok() async {
- await assertNoErrorsInCode('''
-class A {
- void m() {}
- n() {
- void a = m();
- }
-}''');
- }
-
test_voidReturnForGetter() async {
await assertNoErrorsInCode('''
class S {
diff --git a/pkg/analyzer/test/generated/strong_mode_test.dart b/pkg/analyzer/test/generated/strong_mode_test.dart
index 4970fc2..bac33e6 100644
--- a/pkg/analyzer/test/generated/strong_mode_test.dart
+++ b/pkg/analyzer/test/generated/strong_mode_test.dart
@@ -7,6 +7,7 @@
import 'package:analyzer/dart/analysis/features.dart';
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/dart/element/nullability_suffix.dart';
import 'package:analyzer/dart/element/type.dart';
import 'package:analyzer/src/dart/analysis/driver.dart';
import 'package:analyzer/src/dart/element/element.dart';
@@ -1133,7 +1134,6 @@
AsserterBuilder<DartType, DartType> _isType;
AsserterBuilder<Element, DartType> _hasElement;
- AsserterBuilder<DartType, DartType> _hasElementOf;
@override
Future<TestAnalysisResult> computeAnalysisResult(Source source) async {
@@ -1152,15 +1152,14 @@
_isListOf = _assertions.isListOf;
_isMapOf = _assertions.isMapOf;
_isFunction2Of = _assertions.isFunction2Of;
- _hasElementOf = _assertions.hasElementOf;
- _isFutureOf = _isInstantiationOf(_hasElementOf(typeProvider.futureType));
+ _isFutureOf = _isInstantiationOf(_hasElement(typeProvider.futureElement));
_isFutureOrOf =
- _isInstantiationOf(_hasElementOf(typeProvider.futureOrType));
+ _isInstantiationOf(_hasElement(typeProvider.futureOrElement));
_isFutureOfDynamic = _isFutureOf([_isDynamic]);
_isFutureOfInt = _isFutureOf([_isInt]);
_isFutureOfNull = _isFutureOf([_isNull]);
_isFutureOrOfInt = _isFutureOrOf([_isInt]);
- _isStreamOf = _isInstantiationOf(_hasElementOf(typeProvider.streamType));
+ _isStreamOf = _isInstantiationOf(_hasElement(typeProvider.streamElement));
}
return result;
}
@@ -1821,8 +1820,10 @@
ClassElement elementB = AstFinder.getClass(unit, "B").declaredElement;
ClassElement elementA = AstFinder.getClass(unit, "A").declaredElement;
expect(exp.constructorName.type.type.element, elementB);
- _isInstantiationOf(_hasElement(elementB))(
- [_isType(elementA.typeParameters[0].type)])(exp.staticType);
+ _isInstantiationOf(_hasElement(elementB))([
+ _isType(elementA.typeParameters[0]
+ .instantiate(nullabilitySuffix: NullabilitySuffix.star))
+ ])(exp.staticType);
}
test_fieldDeclaration_propagation() async {
@@ -4354,8 +4355,7 @@
expect(ft.toString(), 'List<int> Function(String)');
SimpleIdentifier x = findIdentifier('x');
- expect(x.staticType,
- typeProvider.listType.instantiate([typeProvider.intType]));
+ expect(x.staticType, typeProvider.listType2(typeProvider.intType));
}
test_genericMethod_functionExpressionInvocation_explicit() async {
diff --git a/pkg/analyzer/test/generated/test_analysis_context.dart b/pkg/analyzer/test/generated/test_analysis_context.dart
index 3c6918f..29f75ef 100644
--- a/pkg/analyzer/test/generated/test_analysis_context.dart
+++ b/pkg/analyzer/test/generated/test_analysis_context.dart
@@ -3,7 +3,7 @@
// BSD-style license that can be found in the LICENSE file.
import 'package:analyzer/dart/analysis/features.dart';
-import 'package:analyzer/src/dart/element/type.dart';
+import 'package:analyzer/dart/element/nullability_suffix.dart';
import 'package:analyzer/src/dart/element/type_provider.dart';
import 'package:analyzer/src/generated/engine.dart';
import 'package:analyzer/src/generated/resolver.dart';
@@ -15,7 +15,7 @@
final SourceFactory sourceFactory = _MockSourceFactory();
AnalysisOptions _analysisOptions;
- TypeProvider _typeProvider;
+ TypeProviderImpl _typeProvider;
TypeSystem _typeSystem;
TestAnalysisContext({FeatureSet featureSet}) {
@@ -33,6 +33,11 @@
sdkElements.coreLibrary,
sdkElements.asyncLibrary,
);
+
+ if (_analysisOptions.contextFeatures.isEnabled(Feature.non_nullable)) {
+ _typeProvider = _typeProvider.withNullability(NullabilitySuffix.none);
+ }
+
_typeSystem = Dart2TypeSystem(typeProvider);
}
diff --git a/pkg/analyzer/test/generated/type_system_test.dart b/pkg/analyzer/test/generated/type_system_test.dart
index 6e6cd92..19384d1 100644
--- a/pkg/analyzer/test/generated/type_system_test.dart
+++ b/pkg/analyzer/test/generated/type_system_test.dart
@@ -8,19 +8,18 @@
import 'package:analyzer/dart/ast/standard_ast_factory.dart' show astFactory;
import 'package:analyzer/dart/ast/token.dart' show Keyword;
import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/dart/element/nullability_suffix.dart';
import 'package:analyzer/dart/element/type.dart';
import 'package:analyzer/error/listener.dart';
import 'package:analyzer/src/dart/ast/token.dart' show KeywordToken;
import 'package:analyzer/src/dart/element/element.dart';
import 'package:analyzer/src/dart/element/type.dart';
-import 'package:analyzer/src/dart/element/type_provider.dart';
import 'package:analyzer/src/error/codes.dart';
import 'package:analyzer/src/generated/engine.dart';
import 'package:analyzer/src/generated/resolver.dart';
import 'package:analyzer/src/generated/source.dart'
show NonExistingSource, UriKind;
import 'package:analyzer/src/generated/testing/element_factory.dart';
-import 'package:analyzer/src/generated/testing/test_type_provider.dart';
import 'package:analyzer/src/generated/utilities_dart.dart';
import 'package:meta/meta.dart';
import 'package:path/path.dart' show toUri;
@@ -57,10 +56,6 @@
InterfaceType get intType => typeProvider.intType;
- InterfaceType get iterableType => typeProvider.iterableType;
-
- InterfaceType get listType => typeProvider.listType;
-
DartType get neverType => typeProvider.neverType;
DartType get nullType => typeProvider.nullType;
@@ -71,18 +66,184 @@
InterfaceType get stringType => typeProvider.stringType;
+ FeatureSet get testFeatureSet {
+ return FeatureSet.forTesting();
+ }
+
DartType get voidType => VoidTypeImpl.instance;
+ DartType futureOrType(DartType T) {
+ var futureOrElement = typeProvider.futureOrElement;
+ return _interfaceType(futureOrElement, typeArguments: [T]);
+ }
+
+ DartType futureType(DartType T) {
+ var futureElement = typeProvider.futureElement;
+ return _interfaceType(futureElement, typeArguments: [T]);
+ }
+
+ DartType iterableType(DartType T) {
+ var iterableElement = typeProvider.iterableElement;
+ return _interfaceType(iterableElement, typeArguments: [T]);
+ }
+
+ DartType listType(DartType T) {
+ var listElement = typeProvider.listElement;
+ return _interfaceType(listElement, typeArguments: [T]);
+ }
+
void setUp() {
- typeProvider = new TestTypeProvider();
- typeSystem = new Dart2TypeSystem(typeProvider);
+ var analysisContext = TestAnalysisContext(
+ featureSet: testFeatureSet,
+ );
+ typeProvider = analysisContext.typeProvider;
+ typeSystem = analysisContext.typeSystem;
+ }
+
+ ClassElementImpl _class({
+ @required String name,
+ bool isAbstract = false,
+ InterfaceType superType,
+ List<TypeParameterElement> typeParameters = const [],
+ List<InterfaceType> interfaces = const [],
+ List<InterfaceType> mixins = const [],
+ List<MethodElement> methods = const [],
+ }) {
+ var element = ClassElementImpl(name, 0);
+ element.typeParameters = typeParameters;
+ element.supertype = superType ?? objectType;
+ element.interfaces = interfaces;
+ element.mixins = mixins;
+ element.methods = methods;
+ return element;
+ }
+
+ /**
+ * Creates a function type with the given parameter and return types.
+ *
+ * The return type defaults to `void` if omitted.
+ */
+ FunctionType _functionType({
+ List<TypeParameterElement> typeFormals,
+ List<DartType> required,
+ List<DartType> optional,
+ Map<String, DartType> named,
+ DartType returns,
+ NullabilitySuffix nullabilitySuffix = NullabilitySuffix.star,
+ }) {
+ if (optional != null && named != null) {
+ throw ArgumentError(
+ 'Cannot have both optional positional and named parameters.',
+ );
+ }
+
+ var parameters = <ParameterElement>[];
+ if (required != null) {
+ for (var i = 0; i < required.length; ++i) {
+ parameters.add(
+ ParameterElementImpl.synthetic(
+ 'r$i',
+ required[i],
+ ParameterKind.REQUIRED,
+ ),
+ );
+ }
+ }
+ if (optional != null) {
+ for (var i = 0; i < optional.length; ++i) {
+ parameters.add(
+ ParameterElementImpl.synthetic(
+ 'p$i',
+ optional[i],
+ ParameterKind.POSITIONAL,
+ ),
+ );
+ }
+ }
+ if (named != null) {
+ for (var namedEntry in named.entries) {
+ parameters.add(
+ ParameterElementImpl.synthetic(
+ namedEntry.key,
+ namedEntry.value,
+ ParameterKind.NAMED,
+ ),
+ );
+ }
+ }
+
+ return FunctionTypeImpl.synthetic(
+ returns ?? voidType,
+ typeFormals ?? const <TypeParameterElement>[],
+ parameters,
+ nullabilitySuffix: nullabilitySuffix,
+ );
+ }
+
+ InterfaceType _interfaceType(
+ ClassElement element, {
+ List<DartType> typeArguments = const [],
+ NullabilitySuffix nullabilitySuffix = NullabilitySuffix.star,
+ }) {
+ return InterfaceTypeImpl.explicit(
+ element,
+ typeArguments,
+ nullabilitySuffix: nullabilitySuffix,
+ );
+ }
+
+ MethodElementImpl _method(
+ String name,
+ DartType returnType, {
+ List<TypeParameterElement> typeFormals = const [],
+ List<ParameterElement> parameters = const [],
+ }) {
+ var element = MethodElementImpl(name, 0)
+ ..parameters = parameters
+ ..returnType = returnType
+ ..typeParameters = typeFormals;
+ element.type = _typeOfExecutableElement(element);
+ return element;
+ }
+
+ ParameterElement _requiredParameter(String name, DartType type) {
+ var parameter = ParameterElementImpl(name, 0);
+ parameter.parameterKind = ParameterKind.REQUIRED;
+ parameter.type = type;
+ return parameter;
+ }
+
+ /// TODO(scheglov) We should do the opposite - build type in the element.
+ /// But build a similar synthetic / structured type.
+ FunctionType _typeOfExecutableElement(ExecutableElement element) {
+ return FunctionTypeImpl.synthetic(
+ element.returnType,
+ element.typeParameters,
+ element.parameters,
+ );
+ }
+
+ TypeParameterElementImpl _typeParameter(String name, {DartType bound}) {
+ var element = TypeParameterElementImpl.synthetic(name);
+ element.bound = bound;
+ return element;
+ }
+
+ TypeParameterTypeImpl _typeParameterType(
+ TypeParameterElement element, {
+ NullabilitySuffix nullabilitySuffix = NullabilitySuffix.star,
+ }) {
+ return TypeParameterTypeImpl(
+ element,
+ nullabilitySuffix: nullabilitySuffix,
+ );
}
}
@reflectiveTest
class AssignabilityTest extends AbstractTypeSystemTest {
void test_isAssignableTo_bottom_isBottom() {
- DartType interfaceType = ElementFactory.classElement2('A', []).type;
+ var A = _class(name: 'A');
List<DartType> interassignable = <DartType>[
dynamicType,
objectType,
@@ -90,53 +251,59 @@
doubleType,
numType,
stringType,
- interfaceType,
- bottomType
+ _interfaceType(A),
+ bottomType,
];
_checkGroups(bottomType, interassignable: interassignable);
}
void test_isAssignableTo_call_method() {
- ClassElementImpl classBottom = ElementFactory.classElement2("B");
- MethodElement methodBottom =
- ElementFactory.methodElement("call", objectType, <DartType>[intType]);
- classBottom.methods = <MethodElement>[methodBottom];
+ var B = _class(
+ name: 'B',
+ methods: [
+ _method('call', objectType, parameters: [
+ _requiredParameter('_', intType),
+ ]),
+ ],
+ );
- DartType top =
- TypeBuilder.function(required: <DartType>[intType], result: objectType);
- InterfaceType bottom = classBottom.type;
-
- _checkIsStrictAssignableTo(bottom, top);
+ _checkIsStrictAssignableTo(
+ _interfaceType(B),
+ _functionType(required: [intType], returns: objectType),
+ );
}
void test_isAssignableTo_classes() {
- ClassElement classTop = ElementFactory.classElement2("A");
- ClassElement classLeft = ElementFactory.classElement("B", classTop.type);
- ClassElement classRight = ElementFactory.classElement("C", classTop.type);
- ClassElement classBottom = ElementFactory.classElement("D", classLeft.type)
- ..interfaces = <InterfaceType>[classRight.type];
- InterfaceType top = classTop.type;
- InterfaceType left = classLeft.type;
- InterfaceType right = classRight.type;
- InterfaceType bottom = classBottom.type;
+ var classTop = _class(name: 'A');
+ var classLeft = _class(name: 'B', superType: _interfaceType(classTop));
+ var classRight = _class(name: 'C', superType: _interfaceType(classTop));
+ var classBottom = _class(
+ name: 'D',
+ superType: _interfaceType(classLeft),
+ interfaces: [_interfaceType(classRight)],
+ );
+ var top = _interfaceType(classTop);
+ var left = _interfaceType(classLeft);
+ var right = _interfaceType(classRight);
+ var bottom = _interfaceType(classBottom);
_checkLattice(top, left, right, bottom);
}
void test_isAssignableTo_double() {
- DartType interfaceType = ElementFactory.classElement2('A', []).type;
+ var A = _class(name: 'A');
List<DartType> interassignable = <DartType>[
dynamicType,
objectType,
doubleType,
numType,
- bottomType
+ bottomType,
];
List<DartType> unrelated = <DartType>[
intType,
stringType,
- interfaceType,
+ _interfaceType(A),
];
_checkGroups(doubleType,
@@ -144,7 +311,7 @@
}
void test_isAssignableTo_dynamic_isTop() {
- DartType interfaceType = ElementFactory.classElement2('A', []).type;
+ var A = _class(name: 'A');
List<DartType> interassignable = <DartType>[
dynamicType,
objectType,
@@ -152,42 +319,49 @@
doubleType,
numType,
stringType,
- interfaceType,
- bottomType
+ _interfaceType(A),
+ bottomType,
];
_checkGroups(dynamicType, interassignable: interassignable);
}
void test_isAssignableTo_generics() {
- ClassElementImpl LClass = ElementFactory.classElement2('L', ["T"]);
- InterfaceType LType = LClass.type;
- ClassElementImpl MClass = ElementFactory.classElement2('M', ["T"]);
- DartType typeParam = MClass.typeParameters[0].type;
- InterfaceType superType = LType.instantiate(<DartType>[typeParam]);
- MClass.interfaces = <InterfaceType>[superType];
- InterfaceType MType = MClass.type;
+ var LT = _typeParameter('T');
+ var L = _class(name: 'L', typeParameters: [LT]);
- InterfaceType top = LType.instantiate(<DartType>[dynamicType]);
- InterfaceType left = MType.instantiate(<DartType>[dynamicType]);
- InterfaceType right = LType.instantiate(<DartType>[intType]);
- InterfaceType bottom = MType.instantiate(<DartType>[intType]);
+ var MT = _typeParameter('T');
+ var M = _class(
+ name: 'M',
+ typeParameters: [MT],
+ interfaces: [
+ _interfaceType(
+ L,
+ typeArguments: [_typeParameterType(MT)],
+ ),
+ ],
+ );
+
+ var top = _interfaceType(L, typeArguments: [dynamicType]);
+ var left = _interfaceType(M, typeArguments: [dynamicType]);
+ var right = _interfaceType(L, typeArguments: [intType]);
+ var bottom = _interfaceType(M, typeArguments: [intType]);
_checkCrossLattice(top, left, right, bottom);
}
void test_isAssignableTo_int() {
- DartType interfaceType = ElementFactory.classElement2('A', []).type;
+ var A = _class(name: 'A');
List<DartType> interassignable = <DartType>[
dynamicType,
objectType,
intType,
numType,
- bottomType
+ bottomType,
];
List<DartType> unrelated = <DartType>[
doubleType,
stringType,
- interfaceType,
+ _interfaceType(A),
];
_checkGroups(intType,
@@ -195,36 +369,36 @@
}
void test_isAssignableTo_named_optional() {
- DartType r =
- TypeBuilder.function(required: <DartType>[intType], result: intType);
- DartType o = TypeBuilder.function(
- required: <DartType>[], optional: <DartType>[intType], result: intType);
- DartType n = TypeBuilder.function(
- required: <DartType>[],
- named: <String, DartType>{'x': intType},
- result: intType);
- DartType rr = TypeBuilder.function(
- required: <DartType>[intType, intType], result: intType);
- DartType ro = TypeBuilder.function(
- required: <DartType>[intType],
- optional: <DartType>[intType],
- result: intType);
- DartType rn = TypeBuilder.function(
- required: <DartType>[intType],
- named: <String, DartType>{'x': intType},
- result: intType);
- DartType oo = TypeBuilder.function(
- required: <DartType>[],
- optional: <DartType>[intType, intType],
- result: intType);
- DartType nn = TypeBuilder.function(
- required: <DartType>[],
- named: <String, DartType>{'x': intType, 'y': intType},
- result: intType);
- DartType nnn = TypeBuilder.function(
- required: <DartType>[],
- named: <String, DartType>{'x': intType, 'y': intType, 'z': intType},
- result: intType);
+ var r = _functionType(required: [intType], returns: intType);
+ var o = _functionType(optional: [intType], returns: intType);
+ var n = _functionType(named: {'x': intType}, returns: intType);
+
+ var rr = _functionType(
+ required: [intType, intType],
+ returns: intType,
+ );
+ var ro = _functionType(
+ required: [intType],
+ optional: [intType],
+ returns: intType,
+ );
+ var rn = _functionType(
+ required: [intType],
+ named: {'x': intType},
+ returns: intType,
+ );
+ var oo = _functionType(
+ optional: [intType, intType],
+ returns: intType,
+ );
+ var nn = _functionType(
+ named: {'x': intType, 'y': intType},
+ returns: intType,
+ );
+ var nnn = _functionType(
+ named: {'x': intType, 'y': intType, 'z': intType},
+ returns: intType,
+ );
_checkGroups(r,
interassignable: [r, o, ro, rn, oo], unrelated: [n, rr, nn, nnn]);
@@ -245,18 +419,18 @@
}
void test_isAssignableTo_num() {
- DartType interfaceType = ElementFactory.classElement2('A', []).type;
+ var A = _class(name: 'A');
List<DartType> interassignable = <DartType>[
dynamicType,
objectType,
numType,
intType,
doubleType,
- bottomType
+ bottomType,
];
List<DartType> unrelated = <DartType>[
stringType,
- interfaceType,
+ _interfaceType(A),
];
_checkGroups(numType,
@@ -264,23 +438,17 @@
}
void test_isAssignableTo_simple_function() {
- FunctionType top =
- TypeBuilder.function(required: <DartType>[intType], result: objectType);
- FunctionType left =
- TypeBuilder.function(required: <DartType>[intType], result: intType);
- FunctionType right = TypeBuilder.function(
- required: <DartType>[objectType], result: objectType);
- FunctionType bottom =
- TypeBuilder.function(required: <DartType>[objectType], result: intType);
+ var top = _functionType(required: [intType], returns: objectType);
+ var left = _functionType(required: [intType], returns: intType);
+ var right = _functionType(required: [objectType], returns: objectType);
+ var bottom = _functionType(required: [objectType], returns: intType);
_checkCrossLattice(top, left, right, bottom);
}
void test_isAssignableTo_void_functions() {
- FunctionType top =
- TypeBuilder.function(required: <DartType>[intType], result: voidType);
- FunctionType bottom =
- TypeBuilder.function(required: <DartType>[objectType], result: intType);
+ var top = _functionType(required: [intType], returns: voidType);
+ var bottom = _functionType(required: [objectType], returns: intType);
_checkEquivalent(bottom, top);
}
@@ -348,48 +516,10 @@
/**
* Base class for testing LUB and GLB in spec and strong mode.
*/
-abstract class BoundTestBase {
- TypeProvider typeProvider;
- Dart2TypeSystem typeSystem;
- FunctionType simpleFunctionType;
-
- DartType get bottomType => typeProvider.bottomType;
-
- InterfaceType get doubleType => typeProvider.doubleType;
-
- DartType get dynamicType => typeProvider.dynamicType;
-
- InterfaceType get functionType => typeProvider.functionType;
-
- InterfaceType get futureOrType => typeProvider.futureOrType;
-
- InterfaceType get intType => typeProvider.intType;
-
- InterfaceType get iterableType => typeProvider.iterableType;
-
- InterfaceType get listType => typeProvider.listType;
-
- InterfaceType get nullType => typeProvider.nullType;
-
- InterfaceType get numType => typeProvider.numType;
-
- InterfaceType get objectType => typeProvider.objectType;
-
- InterfaceType get stringType => typeProvider.stringType;
-
- DartType get voidType => VoidTypeImpl.instance;
-
- void setUp() {
- var analysisContext = TestAnalysisContext();
- typeProvider = analysisContext.typeProvider;
- var simpleFunctionElement =
- ElementFactory.genericTypeAliasElement('A', returnType: voidType);
- simpleFunctionType = simpleFunctionElement.type;
- }
-
+abstract class BoundTestBase extends AbstractTypeSystemTest {
void _checkGreatestLowerBound(
DartType type1, DartType type2, DartType expectedResult) {
- DartType glb = typeSystem.getGreatestLowerBound(type1, type2);
+ var glb = typeSystem.getGreatestLowerBound(type1, type2);
expect(glb, expectedResult);
// Check that the result is a lower bound.
expect(typeSystem.isSubtypeOf(glb, type1), true);
@@ -411,7 +541,7 @@
void _checkLeastUpperBound(
DartType type1, DartType type2, DartType expectedResult) {
- DartType lub = typeSystem.getLeastUpperBound(type1, type2);
+ var lub = typeSystem.getLeastUpperBound(type1, type2);
expect(lub, expectedResult);
// Check that the result is an upper bound.
expect(typeSystem.isSubtypeOf(type1, lub), true);
@@ -431,151 +561,68 @@
expect(lub, expectedResult);
}
}
-
- /**
- * Creates a function type with the given parameter and return types.
- *
- * The return type defaults to `void` if omitted.
- */
- FunctionType _functionType({
- List<TypeParameterElement> typeFormals,
- List<DartType> required,
- List<DartType> optional,
- Map<String, DartType> named,
- DartType returns,
- }) {
- if (optional != null && named != null) {
- throw ArgumentError(
- 'Cannot have both optional positional and named parameters.',
- );
- }
-
- var parameters = <ParameterElement>[];
- if (required != null) {
- for (var i = 0; i < required.length; ++i) {
- parameters.add(
- ParameterElementImpl.synthetic(
- 'r$i',
- required[i],
- ParameterKind.REQUIRED,
- ),
- );
- }
- }
- if (optional != null) {
- for (var i = 0; i < optional.length; ++i) {
- parameters.add(
- ParameterElementImpl.synthetic(
- 'p$i',
- optional[i],
- ParameterKind.POSITIONAL,
- ),
- );
- }
- }
- if (named != null) {
- for (var namedEntry in named.entries) {
- parameters.add(
- ParameterElementImpl.synthetic(
- namedEntry.key,
- namedEntry.value,
- ParameterKind.NAMED,
- ),
- );
- }
- }
-
- return FunctionTypeImpl.synthetic(
- returns ?? voidType,
- typeFormals ?? const <TypeParameterElement>[],
- parameters,
- );
- }
-
- TypeParameterElementImpl _typeParameterElement(String name,
- {DartType bound}) {
- var element = TypeParameterElementImpl.synthetic(name);
- element.bound = bound ?? typeProvider.objectType;
- return element;
- }
}
@reflectiveTest
-class ConstraintMatchingTest {
- TypeProvider typeProvider;
- TypeSystem typeSystem;
+class ConstraintMatchingTest extends AbstractTypeSystemTest {
TypeParameterType T;
- DartType get dynamicType => DynamicTypeImpl.instance;
-
- InterfaceType get functionType => typeProvider.functionType;
-
- InterfaceType get intType => typeProvider.intType;
-
- InterfaceType get nullType => typeProvider.nullType;
-
- InterfaceType get objectType => typeProvider.objectType;
-
- InterfaceType get stringType => typeProvider.stringType;
-
- DartType get voidType => VoidTypeImpl.instance;
-
- DartType fn(DartType paramType, DartType returnType) =>
- new FunctionElementImpl.synthetic([
- new ParameterElementImpl.synthetic(
- 'value', paramType, ParameterKind.REQUIRED)
- ], returnType)
- .type;
-
- DartType future(DartType T) => typeProvider.futureType.instantiate([T]);
-
- DartType futureOr(DartType T) => typeProvider.futureOrType.instantiate([T]);
-
- DartType iterable(DartType T) => typeProvider.iterableType.instantiate([T]);
-
- DartType list(DartType T) => typeProvider.listType.instantiate([T]);
-
void setUp() {
- var analysisContext = TestAnalysisContext();
- typeProvider = analysisContext.typeProvider;
- typeSystem = analysisContext.typeSystem;
- T = _newTypeParameter('T');
+ super.setUp();
+ T = _typeParameterType(
+ _typeParameter('T'),
+ nullabilitySuffix: NullabilitySuffix.star,
+ );
}
void test_function_coreFunction() {
- _checkOrdinarySubtypeMatch(fn(intType, stringType), functionType, [T],
- covariant: true);
+ _checkOrdinarySubtypeMatch(
+ _functionType(required: [intType], returns: stringType),
+ functionType,
+ [T],
+ covariant: true,
+ );
}
void test_function_parameter_types() {
_checkIsSubtypeMatchOf(
- fn(T, intType), fn(stringType, intType), [T], ['String <: T'],
- covariant: true);
+ _functionType(required: [T], returns: intType),
+ _functionType(required: [stringType], returns: intType),
+ [T],
+ ['String <: T'],
+ covariant: true,
+ );
}
void test_function_return_types() {
_checkIsSubtypeMatchOf(
- fn(intType, T), fn(intType, stringType), [T], ['T <: String'],
- covariant: true);
+ _functionType(required: [intType], returns: T),
+ _functionType(required: [intType], returns: stringType),
+ [T],
+ ['T <: String'],
+ covariant: true,
+ );
}
void test_futureOr_futureOr() {
_checkIsSubtypeMatchOf(
- futureOr(T), futureOr(stringType), [T], ['T <: String'],
+ futureOrType(T), futureOrType(stringType), [T], ['T <: String'],
covariant: true);
}
void test_futureOr_x_fail_future_branch() {
// FutureOr<List<T>> <: List<String> can't be satisfied because
// Future<List<T>> <: List<String> can't be satisfied
- _checkIsNotSubtypeMatchOf(futureOr(list(T)), list(stringType), [T],
+ _checkIsNotSubtypeMatchOf(
+ futureOrType(listType(T)), listType(stringType), [T],
covariant: true);
}
void test_futureOr_x_fail_nonFuture_branch() {
// FutureOr<List<T>> <: Future<List<String>> can't be satisfied because
// List<T> <: Future<List<String>> can't be satisfied
- _checkIsNotSubtypeMatchOf(futureOr(list(T)), future(list(stringType)), [T],
+ _checkIsNotSubtypeMatchOf(
+ futureOrType(listType(T)), futureType(listType(stringType)), [T],
covariant: true);
}
@@ -583,7 +630,7 @@
// FutureOr<T> <: Future<T> can be satisfied by T=Null. At this point in
// the type inference algorithm all we figure out is that T must be a
// subtype of both String and Future<String>.
- _checkIsSubtypeMatchOf(futureOr(T), future(stringType), [T],
+ _checkIsSubtypeMatchOf(futureOrType(T), futureType(stringType), [T],
['T <: String', 'T <: Future<String>'],
covariant: true);
}
@@ -593,14 +640,18 @@
_checkIsSubtypeMatchOf(nullType, T, [T], ['Null <: T'], covariant: false);
// For any other type X, Null <: X is satisfied without the need for any
// constraints.
- _checkOrdinarySubtypeMatch(nullType, list(T), [T], covariant: false);
+ _checkOrdinarySubtypeMatch(nullType, listType(T), [T], covariant: false);
_checkOrdinarySubtypeMatch(nullType, stringType, [T], covariant: false);
_checkOrdinarySubtypeMatch(nullType, voidType, [T], covariant: false);
_checkOrdinarySubtypeMatch(nullType, dynamicType, [T], covariant: false);
_checkOrdinarySubtypeMatch(nullType, objectType, [T], covariant: false);
_checkOrdinarySubtypeMatch(nullType, nullType, [T], covariant: false);
- _checkOrdinarySubtypeMatch(nullType, fn(intType, stringType), [T],
- covariant: false);
+ _checkOrdinarySubtypeMatch(
+ nullType,
+ _functionType(required: [intType], returns: stringType),
+ [T],
+ covariant: false,
+ );
}
void test_param_on_lhs_contravariant_direct() {
@@ -613,8 +664,11 @@
//
// In other words, List<S> <: List<T> is satisfied provided that
// S <: T.
- var S = _newTypeParameter('S');
- _checkIsSubtypeMatchOf(list(S), list(T), [T], ['S <: T'], covariant: false);
+ var S = _typeParameterType(
+ _typeParameter('S'),
+ );
+ _checkIsSubtypeMatchOf(listType(S), listType(T), [T], ['S <: T'],
+ covariant: false);
}
void test_param_on_lhs_contravariant_via_bound() {
@@ -625,8 +679,14 @@
//
// In other words, S <: List<T> is satisfied provided that
// bound(S) <: List<T>.
- var S = _newTypeParameter('S', list(stringType));
- _checkIsSubtypeMatchOf(S, list(T), [T], ['String <: T'], covariant: false);
+ var S = _typeParameterType(
+ _typeParameter(
+ 'S',
+ bound: listType(stringType),
+ ),
+ );
+ _checkIsSubtypeMatchOf(S, listType(T), [T], ['String <: T'],
+ covariant: false);
}
void test_param_on_lhs_covariant() {
@@ -652,7 +712,9 @@
//
// In other words, T <: S can be satisfied trivially by the constraint
// T <: S.
- var S = _newTypeParameter('S');
+ var S = _typeParameterType(
+ _typeParameter('S'),
+ );
_checkIsSubtypeMatchOf(T, S, [T], ['T <: S'], covariant: true);
}
@@ -666,17 +728,20 @@
//
// In other words, no match can be found for List<T> <: S because regardless
// of T, we can't guarantee that List<T> <: S for all S.
- var S = _newTypeParameter('S');
- _checkIsNotSubtypeMatchOf(list(T), S, [T], covariant: true);
+ var S = _typeParameterType(
+ _typeParameter('S'),
+ );
+ _checkIsNotSubtypeMatchOf(listType(T), S, [T], covariant: true);
}
void test_related_interface_types_failure() {
- _checkIsNotSubtypeMatchOf(iterable(T), list(stringType), [T],
+ _checkIsNotSubtypeMatchOf(iterableType(T), listType(stringType), [T],
covariant: true);
}
void test_related_interface_types_success() {
- _checkIsSubtypeMatchOf(list(T), iterable(stringType), [T], ['T <: String'],
+ _checkIsSubtypeMatchOf(
+ listType(T), iterableType(stringType), [T], ['T <: String'],
covariant: true);
}
@@ -686,14 +751,18 @@
covariant: true);
// For any other type X, X <: dynamic is satisfied without the need for any
// constraints.
- _checkOrdinarySubtypeMatch(list(T), dynamicType, [T], covariant: true);
+ _checkOrdinarySubtypeMatch(listType(T), dynamicType, [T], covariant: true);
_checkOrdinarySubtypeMatch(stringType, dynamicType, [T], covariant: true);
_checkOrdinarySubtypeMatch(voidType, dynamicType, [T], covariant: true);
_checkOrdinarySubtypeMatch(dynamicType, dynamicType, [T], covariant: true);
_checkOrdinarySubtypeMatch(objectType, dynamicType, [T], covariant: true);
_checkOrdinarySubtypeMatch(nullType, dynamicType, [T], covariant: true);
- _checkOrdinarySubtypeMatch(fn(intType, stringType), dynamicType, [T],
- covariant: true);
+ _checkOrdinarySubtypeMatch(
+ _functionType(required: [intType], returns: stringType),
+ dynamicType,
+ [T],
+ covariant: true,
+ );
}
void test_rhs_object() {
@@ -702,14 +771,18 @@
covariant: true);
// For any other type X, X <: Object is satisfied without the need for any
// constraints.
- _checkOrdinarySubtypeMatch(list(T), objectType, [T], covariant: true);
+ _checkOrdinarySubtypeMatch(listType(T), objectType, [T], covariant: true);
_checkOrdinarySubtypeMatch(stringType, objectType, [T], covariant: true);
_checkOrdinarySubtypeMatch(voidType, objectType, [T], covariant: true);
_checkOrdinarySubtypeMatch(dynamicType, objectType, [T], covariant: true);
_checkOrdinarySubtypeMatch(objectType, objectType, [T], covariant: true);
_checkOrdinarySubtypeMatch(nullType, objectType, [T], covariant: true);
- _checkOrdinarySubtypeMatch(fn(intType, stringType), objectType, [T],
- covariant: true);
+ _checkOrdinarySubtypeMatch(
+ _functionType(required: [intType], returns: stringType),
+ objectType,
+ [T],
+ covariant: true,
+ );
}
void test_rhs_void() {
@@ -717,25 +790,30 @@
_checkIsSubtypeMatchOf(T, voidType, [T], ['T <: void'], covariant: true);
// For any other type X, X <: void is satisfied without the need for any
// constraints.
- _checkOrdinarySubtypeMatch(list(T), voidType, [T], covariant: true);
+ _checkOrdinarySubtypeMatch(listType(T), voidType, [T], covariant: true);
_checkOrdinarySubtypeMatch(stringType, voidType, [T], covariant: true);
_checkOrdinarySubtypeMatch(voidType, voidType, [T], covariant: true);
_checkOrdinarySubtypeMatch(dynamicType, voidType, [T], covariant: true);
_checkOrdinarySubtypeMatch(objectType, voidType, [T], covariant: true);
_checkOrdinarySubtypeMatch(nullType, voidType, [T], covariant: true);
- _checkOrdinarySubtypeMatch(fn(intType, stringType), voidType, [T],
- covariant: true);
+ _checkOrdinarySubtypeMatch(
+ _functionType(required: [intType], returns: stringType),
+ voidType,
+ [T],
+ covariant: true,
+ );
}
void test_same_interface_types() {
- _checkIsSubtypeMatchOf(list(T), list(stringType), [T], ['T <: String'],
+ _checkIsSubtypeMatchOf(
+ listType(T), listType(stringType), [T], ['T <: String'],
covariant: true);
}
void test_x_futureOr_fail_both_branches() {
// List<T> <: FutureOr<String> can't be satisfied because neither
// List<T> <: Future<String> nor List<T> <: int can be satisfied
- _checkIsNotSubtypeMatchOf(list(T), futureOr(stringType), [T],
+ _checkIsNotSubtypeMatchOf(listType(T), futureOrType(stringType), [T],
covariant: true);
}
@@ -747,7 +825,7 @@
// constraint Future<String> <: T. We keep the constraint based on trying
// to match Future<String> <: Future<T>, so String <: T.
_checkIsSubtypeMatchOf(
- future(stringType), futureOr(T), [T], ['String <: T'],
+ futureType(stringType), futureOrType(T), [T], ['String <: T'],
covariant: false);
}
@@ -758,7 +836,7 @@
// T <: Object, whereas trying to match Future<T> <: Object generates no
// constraints, so we keep the constraint T <: Object.
_checkIsSubtypeMatchOf(
- future(T), futureOr(objectType), [T], ['T <: Object'],
+ futureType(T), futureOrType(objectType), [T], ['T <: Object'],
covariant: true);
}
@@ -768,7 +846,7 @@
// Trying to match Null <: FutureOr<T> generates no constraints, whereas
// trying to match Null <: T generates the constraint Null <: T,
// so we keep the constraint Null <: T.
- _checkIsSubtypeMatchOf(nullType, futureOr(T), [T], ['Null <: T'],
+ _checkIsSubtypeMatchOf(nullType, futureOrType(T), [T], ['Null <: T'],
covariant: false);
}
@@ -776,7 +854,8 @@
// Future<String> <: FutureOr<Object> is satisfied because both
// Future<String> <: Future<Object> and Future<String> <: Object.
// No constraints are recorded.
- _checkIsSubtypeMatchOf(future(stringType), futureOr(objectType), [T], [],
+ _checkIsSubtypeMatchOf(
+ futureType(stringType), futureOrType(objectType), [T], [],
covariant: true);
}
@@ -784,7 +863,7 @@
// Future<T> <: FutureOr<String> can be satisfied because
// Future<T> <: Future<String> can be satisfied
_checkIsSubtypeMatchOf(
- future(T), futureOr(stringType), [T], ['T <: String'],
+ futureType(T), futureOrType(stringType), [T], ['T <: String'],
covariant: true);
}
@@ -792,7 +871,7 @@
// List<T> <: FutureOr<List<String>> can be satisfied because
// List<T> <: List<String> can be satisfied
_checkIsSubtypeMatchOf(
- list(T), futureOr(list(stringType)), [T], ['T <: String'],
+ listType(T), futureOrType(listType(stringType)), [T], ['T <: String'],
covariant: true);
}
@@ -839,66 +918,68 @@
_checkIsNotSubtypeMatchOf(t1, t2, typeFormals);
}
}
-
- TypeParameterType _newTypeParameter(String name, [DartType bound]) {
- var element = new TypeParameterElementImpl(name, 0);
- if (bound != null) {
- element.bound = bound;
- }
- return new TypeParameterTypeImpl(element);
- }
}
@reflectiveTest
class GenericFunctionInferenceTest extends AbstractTypeSystemTest {
void test_boundedByAnotherTypeParameter() {
// <TFrom, TTo extends Iterable<TFrom>>(TFrom) -> TTo
- var tFrom = TypeBuilder.variable('TFrom');
+ var tFrom = _typeParameter('TFrom');
var tTo =
- TypeBuilder.variable('TTo', bound: iterableType.instantiate([tFrom]));
- var cast = TypeBuilder.function(
- types: [tFrom, tTo], required: [tFrom], result: tTo);
- expect(_inferCall(cast, [stringType]), [
- stringType,
- iterableType.instantiate([stringType])
- ]);
+ _typeParameter('TTo', bound: iterableType(_typeParameterType(tFrom)));
+ var cast = _functionType(
+ typeFormals: [tFrom, tTo],
+ required: [_typeParameterType(tFrom)],
+ returns: _typeParameterType(tTo),
+ );
+ expect(
+ _inferCall(cast, [stringType]), [stringType, iterableType(stringType)]);
}
void test_boundedByOuterClass() {
// Regression test for https://github.com/dart-lang/sdk/issues/25740.
// class A {}
- var a = ElementFactory.classElement('A', objectType);
+ var A = _class(name: 'A', superType: objectType);
+ var typeA = _interfaceType(A);
// class B extends A {}
- var b = ElementFactory.classElement('B', a.type);
+ var B = _class(name: 'B', superType: typeA);
+ var typeB = _interfaceType(B);
// class C<T extends A> {
- var c = ElementFactory.classElement('C', objectType, ['T']);
- (c.typeParameters[0] as TypeParameterElementImpl).bound = a.type;
+ var CT = _typeParameter('T', bound: typeA);
+ var C = _class(
+ name: 'C',
+ superType: objectType,
+ typeParameters: [CT],
+ );
// S m<S extends T>(S);
- var s = TypeBuilder.variable('S');
- (s.element as TypeParameterElementImpl).bound = c.typeParameters[0].type;
- var m = ElementFactory.methodElement('m', s, [s]);
- m.typeParameters = [s.element];
- c.methods = [m];
+ var S = _typeParameter('S', bound: _typeParameterType(CT));
+ var m = _method(
+ 'm',
+ _typeParameterType(S),
+ typeFormals: [S],
+ parameters: [_requiredParameter('_', _typeParameterType(S))],
+ );
+ C.methods = [m];
// }
// C<Object> cOfObject;
- var cOfObject = c.type.instantiate([objectType]);
+ var cOfObject = _interfaceType(C, typeArguments: [objectType]);
// C<A> cOfA;
- var cOfA = c.type.instantiate([a.type]);
+ var cOfA = _interfaceType(C, typeArguments: [typeA]);
// C<B> cOfB;
- var cOfB = c.type.instantiate([b.type]);
+ var cOfB = _interfaceType(C, typeArguments: [typeB]);
// B b;
// cOfB.m(b); // infer <B>
- expect(_inferCall2(cOfB.getMethod('m').type, [b.type]).toString(),
+ expect(_inferCall2(cOfB.getMethod('m').type, [typeB]).toString(),
'B Function(B)');
// cOfA.m(b); // infer <B>
- expect(_inferCall2(cOfA.getMethod('m').type, [b.type]).toString(),
+ expect(_inferCall2(cOfA.getMethod('m').type, [typeB]).toString(),
'B Function(B)');
// cOfObject.m(b); // infer <B>
- expect(_inferCall2(cOfObject.getMethod('m').type, [b.type]).toString(),
+ expect(_inferCall2(cOfObject.getMethod('m').type, [typeB]).toString(),
'B Function(B)');
}
@@ -906,31 +987,40 @@
// Regression test for https://github.com/dart-lang/sdk/issues/25740.
// class A {}
- var a = ElementFactory.classElement('A', objectType);
+ var A = _class(name: 'A', superType: objectType);
+ var typeA = _interfaceType(A);
// class B extends A {}
- var b = ElementFactory.classElement('B', a.type);
+ var B = _class(name: 'B', superType: typeA);
+ var typeB = _interfaceType(B);
// class C<T extends A> {
- var c = ElementFactory.classElement('C', objectType, ['T']);
- (c.typeParameters[0] as TypeParameterElementImpl).bound = a.type;
+ var CT = _typeParameter('T', bound: typeA);
+ var C = _class(
+ name: 'C',
+ superType: objectType,
+ typeParameters: [CT],
+ );
// S m<S extends Iterable<T>>(S);
- var s = TypeBuilder.variable('S');
- var iterableOfT = iterableType.instantiate([c.typeParameters[0].type]);
- (s.element as TypeParameterElementImpl).bound = iterableOfT;
- var m = ElementFactory.methodElement('m', s, [s]);
- m.typeParameters = [s.element];
- c.methods = [m];
+ var iterableOfT = iterableType(_typeParameterType(CT));
+ var S = _typeParameter('S', bound: iterableOfT);
+ var m = _method(
+ 'm',
+ _typeParameterType(S),
+ typeFormals: [S],
+ parameters: [_requiredParameter('_', _typeParameterType(S))],
+ );
+ C.methods = [m];
// }
// C<Object> cOfObject;
- var cOfObject = c.type.instantiate([objectType]);
+ var cOfObject = _interfaceType(C, typeArguments: [objectType]);
// C<A> cOfA;
- var cOfA = c.type.instantiate([a.type]);
+ var cOfA = _interfaceType(C, typeArguments: [typeA]);
// C<B> cOfB;
- var cOfB = c.type.instantiate([b.type]);
+ var cOfB = _interfaceType(C, typeArguments: [typeB]);
// List<B> b;
- var listOfB = listType.instantiate([b.type]);
+ var listOfB = listType(typeB);
// cOfB.m(b); // infer <B>
expect(_inferCall2(cOfB.getMethod('m').type, [listOfB]).toString(),
'List<B> Function(List<B>)');
@@ -943,197 +1033,316 @@
}
void test_boundedRecursively() {
- // class Cloneable<T extends Cloneable<T>>
- ClassElementImpl cloneable =
- ElementFactory.classElement('Cloneable', objectType, ['T']);
- (cloneable.typeParameters[0] as TypeParameterElementImpl).bound =
- cloneable.type;
- // class Foo extends Cloneable<Foo>
- ClassElementImpl foo = ElementFactory.classElement('Foo', null);
- foo.supertype = cloneable.type.instantiate([foo.type]);
+ // class A<T extends A<T>>
+ var T = _typeParameter('T');
+ var A = _class(
+ name: 'Cloneable',
+ superType: objectType,
+ typeParameters: [T],
+ );
+ T.bound = _interfaceType(
+ A,
+ typeArguments: [_typeParameterType(T)],
+ );
- // <S extends Cloneable<S>>
- var s = TypeBuilder.variable('S');
- (s.element as TypeParameterElementImpl).bound =
- cloneable.type.instantiate([s]);
+ // class B extends A<B> {}
+ var B = _class(name: 'B', superType: null);
+ B.supertype = _interfaceType(A, typeArguments: [_interfaceType(B)]);
+ var typeB = _interfaceType(B);
+
+ // <S extends A<S>>
+ var S = _typeParameter('S');
+ var typeS = _typeParameterType(S);
+ S.bound = _interfaceType(A, typeArguments: [typeS]);
+
// (S, S) -> S
- var clone = TypeBuilder.function(types: [s], required: [s, s], result: s);
- expect(_inferCall(clone, [foo.type, foo.type]), [foo.type]);
+ var clone = _functionType(
+ typeFormals: [S],
+ required: [typeS, typeS],
+ returns: typeS,
+ );
+ expect(_inferCall(clone, [typeB, typeB]), [typeB]);
// Something invalid...
- expect(_inferCall(clone, [stringType, numType], expectError: true),
- [objectType]);
+ expect(
+ _inferCall(clone, [stringType, numType], expectError: true),
+ [objectType],
+ );
}
void test_genericCastFunction() {
// <TFrom, TTo>(TFrom) -> TTo
- var tFrom = TypeBuilder.variable('TFrom');
- var tTo = TypeBuilder.variable('TTo');
- var cast = TypeBuilder.function(
- types: [tFrom, tTo], required: [tFrom], result: tTo);
+ var tFrom = _typeParameter('TFrom');
+ var tTo = _typeParameter('TTo');
+ var cast = _functionType(
+ typeFormals: [tFrom, tTo],
+ required: [_typeParameterType(tFrom)],
+ returns: _typeParameterType(tTo),
+ );
expect(_inferCall(cast, [intType]), [intType, dynamicType]);
}
void test_genericCastFunctionWithUpperBound() {
// <TFrom, TTo extends TFrom>(TFrom) -> TTo
- var tFrom = TypeBuilder.variable('TFrom');
- var tTo = TypeBuilder.variable('TTo', bound: tFrom);
- var cast = TypeBuilder.function(
- types: [tFrom, tTo], required: [tFrom], result: tTo);
+ var tFrom = _typeParameter('TFrom');
+ var tTo = _typeParameter('TTo', bound: _typeParameterType(tFrom));
+ var cast = _functionType(
+ typeFormals: [tFrom, tTo],
+ required: [_typeParameterType(tFrom)],
+ returns: _typeParameterType(tTo),
+ );
expect(_inferCall(cast, [intType]), [intType, intType]);
}
void test_parametersToFunctionParam() {
// <T>(f(T t)) -> T
- var t = TypeBuilder.variable('T');
- var cast = TypeBuilder.function(types: [
- t
- ], required: [
- TypeBuilder.function(required: [t], result: dynamicType)
- ], result: t);
+ var T = _typeParameter('T');
+ var cast = _functionType(
+ typeFormals: [T],
+ required: [
+ _functionType(
+ required: [_typeParameterType(T)],
+ returns: dynamicType,
+ )
+ ],
+ returns: _typeParameterType(T),
+ );
expect(
- _inferCall(cast, [
- TypeBuilder.function(required: [numType], result: dynamicType)
- ]),
- [numType]);
+ _inferCall(cast, [
+ _functionType(
+ required: [numType],
+ returns: dynamicType,
+ )
+ ]),
+ [numType],
+ );
}
void test_parametersUseLeastUpperBound() {
// <T>(T x, T y) -> T
- var t = TypeBuilder.variable('T');
- var cast = TypeBuilder.function(types: [t], required: [t, t], result: t);
+ var T = _typeParameter('T');
+ var cast = _functionType(
+ typeFormals: [T],
+ required: [
+ _typeParameterType(T),
+ _typeParameterType(T),
+ ],
+ returns: _typeParameterType(T),
+ );
expect(_inferCall(cast, [intType, doubleType]), [numType]);
}
void test_parameterTypeUsesUpperBound() {
// <T extends num>(T) -> dynamic
- var t = TypeBuilder.variable('T', bound: numType);
- var f =
- TypeBuilder.function(types: [t], required: [t], result: dynamicType);
+ var T = _typeParameter('T', bound: numType);
+ var f = _functionType(
+ typeFormals: [T],
+ required: [
+ _typeParameterType(T),
+ ],
+ returns: dynamicType,
+ );
expect(_inferCall(f, [intType]), [intType]);
}
void test_returnFunctionWithGenericParameter() {
// <T>(T -> T) -> (T -> void)
- var t = TypeBuilder.variable('T');
- var f = TypeBuilder.function(types: [
- t
- ], required: [
- TypeBuilder.function(required: [t], result: t)
- ], result: TypeBuilder.function(required: [t], result: voidType));
+ var T = _typeParameter('T');
+ var f = _functionType(
+ typeFormals: [T],
+ required: [
+ _functionType(
+ required: [
+ _typeParameterType(T),
+ ],
+ returns: _typeParameterType(T),
+ )
+ ],
+ returns: _functionType(
+ required: [
+ _typeParameterType(T),
+ ],
+ returns: voidType,
+ ),
+ );
expect(
- _inferCall(f, [
- TypeBuilder.function(required: [numType], result: intType)
- ]),
- [intType]);
+ _inferCall(f, [
+ _functionType(required: [numType], returns: intType)
+ ]),
+ [intType],
+ );
}
void test_returnFunctionWithGenericParameterAndContext() {
// <T>(T -> T) -> (T -> Null)
- var t = TypeBuilder.variable('T');
- var f = TypeBuilder.function(types: [
- t
- ], required: [
- TypeBuilder.function(required: [t], result: t)
- ], result: TypeBuilder.function(required: [t], result: nullType));
+ var T = _typeParameter('T');
+ var f = _functionType(
+ typeFormals: [T],
+ required: [
+ _functionType(
+ required: [
+ _typeParameterType(T),
+ ],
+ returns: _typeParameterType(T),
+ )
+ ],
+ returns: _functionType(
+ required: [
+ _typeParameterType(T),
+ ],
+ returns: nullType,
+ ),
+ );
expect(
- _inferCall(f, [],
- returnType:
- TypeBuilder.function(required: [numType], result: intType)),
- [numType]);
+ _inferCall(
+ f,
+ [],
+ returnType: _functionType(
+ required: [numType],
+ returns: intType,
+ ),
+ ),
+ [numType],
+ );
}
void test_returnFunctionWithGenericParameterAndReturn() {
// <T>(T -> T) -> (T -> T)
- var t = TypeBuilder.variable('T');
- var f = TypeBuilder.function(types: [
- t
- ], required: [
- TypeBuilder.function(required: [t], result: t)
- ], result: TypeBuilder.function(required: [t], result: t));
+ var T = _typeParameter('T');
+ var f = _functionType(
+ typeFormals: [T],
+ required: [
+ _functionType(
+ required: [
+ _typeParameterType(T),
+ ],
+ returns: _typeParameterType(T),
+ )
+ ],
+ returns: _functionType(
+ required: [
+ _typeParameterType(T),
+ ],
+ returns: _typeParameterType(T),
+ ),
+ );
expect(
- _inferCall(f, [
- TypeBuilder.function(required: [numType], result: intType)
- ]),
- [intType]);
+ _inferCall(f, [
+ _functionType(
+ required: [numType],
+ returns: intType,
+ )
+ ]),
+ [intType],
+ );
}
void test_returnFunctionWithGenericReturn() {
// <T>(T -> T) -> (() -> T)
- var t = TypeBuilder.variable('T');
- var f = TypeBuilder.function(types: [
- t
- ], required: [
- TypeBuilder.function(required: [t], result: t)
- ], result: TypeBuilder.function(required: [], result: t));
+ var T = _typeParameter('T');
+ var f = _functionType(
+ typeFormals: [T],
+ required: [
+ _functionType(
+ required: [
+ _typeParameterType(T),
+ ],
+ returns: _typeParameterType(T),
+ )
+ ],
+ returns: _functionType(
+ returns: _typeParameterType(T),
+ ),
+ );
expect(
- _inferCall(f, [
- TypeBuilder.function(required: [numType], result: intType)
- ]),
- [intType]);
+ _inferCall(f, [
+ _functionType(
+ required: [numType],
+ returns: intType,
+ )
+ ]),
+ [intType],
+ );
}
void test_returnTypeFromContext() {
// <T>() -> T
- var t = TypeBuilder.variable('T');
- var f = TypeBuilder.function(types: [t], required: [], result: t);
+ var T = _typeParameter('T');
+ var f = _functionType(
+ typeFormals: [T],
+ returns: _typeParameterType(T),
+ );
expect(_inferCall(f, [], returnType: stringType), [stringType]);
}
void test_returnTypeWithBoundFromContext() {
// <T extends num>() -> T
- var t = TypeBuilder.variable('T', bound: numType);
- var f = TypeBuilder.function(types: [t], required: [], result: t);
+ var T = _typeParameter('T', bound: numType);
+ var f = _functionType(
+ typeFormals: [T],
+ returns: _typeParameterType(T),
+ );
expect(_inferCall(f, [], returnType: doubleType), [doubleType]);
}
void test_returnTypeWithBoundFromInvalidContext() {
// <T extends num>() -> T
- var t = TypeBuilder.variable('T', bound: numType);
- var f = TypeBuilder.function(types: [t], required: [], result: t);
+ var T = _typeParameter('T', bound: numType);
+ var f = _functionType(
+ typeFormals: [T],
+ returns: _typeParameterType(T),
+ );
expect(_inferCall(f, [], returnType: stringType), [nullType]);
}
void test_unifyParametersToFunctionParam() {
// <T>(f(T t), g(T t)) -> T
- var t = TypeBuilder.variable('T');
- var cast = TypeBuilder.function(types: [
- t
- ], required: [
- TypeBuilder.function(required: [t], result: dynamicType),
- TypeBuilder.function(required: [t], result: dynamicType)
- ], result: t);
+ var T = _typeParameter('T');
+ var cast = _functionType(
+ typeFormals: [T],
+ required: [
+ _functionType(
+ required: [_typeParameterType(T)],
+ returns: dynamicType,
+ ),
+ _functionType(
+ required: [_typeParameterType(T)],
+ returns: dynamicType,
+ )
+ ],
+ returns: _typeParameterType(T),
+ );
expect(
- _inferCall(cast, [
- TypeBuilder.function(required: [intType], result: dynamicType),
- TypeBuilder.function(required: [doubleType], result: dynamicType)
- ]),
- [nullType]);
+ _inferCall(cast, [
+ _functionType(required: [intType], returns: dynamicType),
+ _functionType(required: [doubleType], returns: dynamicType)
+ ]),
+ [nullType],
+ );
}
void test_unusedReturnTypeIsDynamic() {
// <T>() -> T
- var t = TypeBuilder.variable('T');
- var f = TypeBuilder.function(types: [t], required: [], result: t);
+ var T = _typeParameter('T');
+ var f = _functionType(
+ typeFormals: [T],
+ returns: _typeParameterType(T),
+ );
expect(_inferCall(f, []), [dynamicType]);
}
void test_unusedReturnTypeWithUpperBound() {
// <T extends num>() -> T
- var t = TypeBuilder.variable('T', bound: numType);
- var f = TypeBuilder.function(types: [t], required: [], result: t);
+ var T = _typeParameter('T', bound: numType);
+ var f = _functionType(
+ typeFormals: [T],
+ returns: _typeParameterType(T),
+ );
expect(_inferCall(f, []), [numType]);
}
List<DartType> _inferCall(FunctionTypeImpl ft, List<DartType> arguments,
{DartType returnType, bool expectError: false}) {
- FunctionType inferred = _inferCall2(ft, arguments,
- returnType: returnType, expectError: expectError);
- return inferred?.typeArguments;
- }
-
- FunctionType _inferCall2(FunctionTypeImpl ft, List<DartType> arguments,
- {DartType returnType, bool expectError: false}) {
var listener = new RecordingErrorListener();
var reporter = new ErrorReporter(
@@ -1141,10 +1350,15 @@
new NonExistingSource(
'/test.dart', toUri('/test.dart'), UriKind.FILE_URI));
- FunctionType inferred = typeSystem.inferGenericFunctionOrType(
- ft, ft.parameters, arguments, returnType,
- errorReporter: reporter,
- errorNode: astFactory.nullLiteral(new KeywordToken(Keyword.NULL, 0)));
+ var typeArguments = typeSystem.inferGenericFunctionOrType(
+ typeParameters: ft.typeFormals,
+ parameters: ft.parameters,
+ declaredReturnType: ft.returnType,
+ argumentTypes: arguments,
+ contextReturnType: returnType,
+ errorReporter: reporter,
+ errorNode: astFactory.nullLiteral(new KeywordToken(Keyword.NULL, 0)),
+ );
if (expectError) {
expect(listener.errors.map((e) => e.errorCode).toList(),
@@ -1153,44 +1367,47 @@
} else {
expect(listener.errors, isEmpty, reason: 'did not expect any errors.');
}
- return inferred;
+ return typeArguments;
+ }
+
+ FunctionType _inferCall2(FunctionTypeImpl ft, List<DartType> arguments,
+ {DartType returnType, bool expectError: false}) {
+ var typeArguments = _inferCall(
+ ft,
+ arguments,
+ returnType: returnType,
+ expectError: expectError,
+ );
+ return ft.instantiate(typeArguments);
}
}
@reflectiveTest
class GreatestLowerBoundTest extends BoundTestBase {
- void setUp() {
- super.setUp();
- typeSystem = new Dart2TypeSystem(typeProvider);
- }
-
void test_bottom_function() {
- _checkGreatestLowerBound(bottomType, simpleFunctionType, bottomType);
+ _checkGreatestLowerBound(bottomType, _functionType(), bottomType);
}
void test_bottom_interface() {
- DartType interfaceType = ElementFactory.classElement2('A', []).type;
- _checkGreatestLowerBound(bottomType, interfaceType, bottomType);
+ var A = _class(name: 'A');
+ _checkGreatestLowerBound(bottomType, _interfaceType(A), bottomType);
}
void test_bottom_typeParam() {
- DartType typeParam = ElementFactory.typeParameterElement('T').type;
- _checkGreatestLowerBound(bottomType, typeParam, bottomType);
+ var T = _typeParameter('T');
+ _checkGreatestLowerBound(bottomType, _typeParameterType(T), bottomType);
}
void test_bounds_of_top_types_complete() {
// Test every combination of a subset of Tops programatically.
- final futureOrDynamicType = futureOrType.instantiate([dynamicType]);
- final futureOrObjectType = futureOrType.instantiate([objectType]);
- final futureOrVoidType = futureOrType.instantiate([voidType]);
- final futureOrFutureOrDynamicType =
- futureOrType.instantiate([futureOrDynamicType]);
- final futureOrFutureOrObjectType =
- futureOrType.instantiate([futureOrObjectType]);
- final futureOrFutureOrVoidType =
- futureOrType.instantiate([futureOrVoidType]);
+ var futureOrDynamicType = futureOrType(dynamicType);
+ var futureOrObjectType = futureOrType(objectType);
+ var futureOrVoidType = futureOrType(voidType);
+ final futureOrFutureOrDynamicType = futureOrType(futureOrDynamicType);
+ final futureOrFutureOrObjectType = futureOrType(futureOrObjectType);
+ final futureOrFutureOrVoidType = futureOrType(futureOrVoidType);
- final orderedTops = [
+ var orderedTops = [
// Lower index, so lower Top
voidType,
dynamicType,
@@ -1225,9 +1442,8 @@
}
void test_bounds_of_top_types_sanity() {
- final futureOrDynamicType = futureOrType.instantiate([dynamicType]);
- final futureOrFutureOrDynamicType =
- futureOrType.instantiate([futureOrDynamicType]);
+ var futureOrDynamicType = futureOrType(dynamicType);
+ final futureOrFutureOrDynamicType = futureOrType(futureOrDynamicType);
// Sanity check specific cases of top for GLB/LUB.
_checkLeastUpperBound(objectType, dynamicType, dynamicType);
@@ -1244,22 +1460,28 @@
// class A
// class B extends A
// class C extends B
- ClassElementImpl classA = ElementFactory.classElement2("A");
- ClassElementImpl classB = ElementFactory.classElement("B", classA.type);
- ClassElementImpl classC = ElementFactory.classElement("C", classB.type);
- _checkGreatestLowerBound(classA.type, classC.type, classC.type);
+ var A = _class(name: 'A');
+ var B = _class(name: 'B', superType: _interfaceType(A));
+ var C = _class(name: 'C', superType: _interfaceType(B));
+ _checkGreatestLowerBound(
+ _interfaceType(A),
+ _interfaceType(C),
+ _interfaceType(C),
+ );
}
void test_classAndSuperinterface() {
// class A
// class B implements A
// class C implements B
- ClassElementImpl classA = ElementFactory.classElement2("A");
- ClassElementImpl classB = ElementFactory.classElement2("B");
- ClassElementImpl classC = ElementFactory.classElement2("C");
- classB.interfaces = <InterfaceType>[classA.type];
- classC.interfaces = <InterfaceType>[classB.type];
- _checkGreatestLowerBound(classA.type, classC.type, classC.type);
+ var A = _class(name: 'A');
+ var B = _class(name: 'B', interfaces: [_interfaceType(A)]);
+ var C = _class(name: 'C', interfaces: [_interfaceType(B)]);
+ _checkGreatestLowerBound(
+ _interfaceType(A),
+ _interfaceType(C),
+ _interfaceType(C),
+ );
}
void test_dynamic_bottom() {
@@ -1267,18 +1489,19 @@
}
void test_dynamic_function() {
- _checkGreatestLowerBound(
- dynamicType, simpleFunctionType, simpleFunctionType);
+ _checkGreatestLowerBound(dynamicType, _functionType(), _functionType());
}
void test_dynamic_interface() {
- DartType interfaceType = ElementFactory.classElement2('A', []).type;
- _checkGreatestLowerBound(dynamicType, interfaceType, interfaceType);
+ var A = _class(name: 'A');
+ var typeA = _interfaceType(A);
+ _checkGreatestLowerBound(dynamicType, typeA, typeA);
}
void test_dynamic_typeParam() {
- DartType typeParam = ElementFactory.typeParameterElement('T').type;
- _checkGreatestLowerBound(dynamicType, typeParam, typeParam);
+ var T = _typeParameter('T');
+ var typeT = _typeParameterType(T);
+ _checkGreatestLowerBound(dynamicType, typeT, typeT);
}
void test_dynamic_void() {
@@ -1304,7 +1527,6 @@
optional: [intType],
);
var type2 = _functionType(
- required: [],
optional: [doubleType, stringType, objectType],
);
var expected = _functionType(
@@ -1404,7 +1626,6 @@
named: {'a': intType},
);
var type2 = _functionType(
- required: [],
named: {'a': intType},
);
_checkGreatestLowerBound(type1, type2, bottomType);
@@ -1455,8 +1676,9 @@
}
void test_interface_function() {
- DartType interfaceType = ElementFactory.classElement2('A', []).type;
- _checkGreatestLowerBound(interfaceType, simpleFunctionType, bottomType);
+ var A = _class(name: 'A');
+ var typeA = _interfaceType(A);
+ _checkGreatestLowerBound(typeA, _functionType(), bottomType);
}
void test_mixin() {
@@ -1464,27 +1686,38 @@
// class B
// class C
// class D extends A with B, C
- ClassElement classA = ElementFactory.classElement2("A");
- ClassElement classB = ElementFactory.classElement2("B");
- ClassElement classC = ElementFactory.classElement2("C");
- ClassElementImpl classD = ElementFactory.classElement("D", classA.type);
- classD.mixins = <InterfaceType>[classB.type, classC.type];
- _checkGreatestLowerBound(classA.type, classD.type, classD.type);
- _checkGreatestLowerBound(classB.type, classD.type, classD.type);
- _checkGreatestLowerBound(classC.type, classD.type, classD.type);
+ var A = _class(name: 'A');
+ var typeA = _interfaceType(A);
+
+ var B = _class(name: 'B');
+ var typeB = _interfaceType(B);
+
+ var C = _class(name: 'C');
+ var typeC = _interfaceType(C);
+
+ var D = _class(
+ name: 'D',
+ superType: _interfaceType(A),
+ mixins: [typeB, typeC],
+ );
+ var typeD = _interfaceType(D);
+
+ _checkGreatestLowerBound(typeA, typeD, typeD);
+ _checkGreatestLowerBound(typeB, typeD, typeD);
+ _checkGreatestLowerBound(typeC, typeD, typeD);
}
void test_self() {
- DartType typeParam = ElementFactory.typeParameterElement('T').type;
- DartType interfaceType = ElementFactory.classElement2('A', []).type;
+ var T = _typeParameter('T');
+ var A = _class(name: 'A');
List<DartType> types = [
dynamicType,
voidType,
bottomType,
- typeParam,
- interfaceType,
- simpleFunctionType
+ _typeParameterType(T),
+ _interfaceType(A),
+ _functionType(),
];
for (DartType type in types) {
@@ -1493,39 +1726,50 @@
}
void test_typeParam_function_noBound() {
- DartType typeParam = ElementFactory.typeParameterElement('T').type;
- _checkGreatestLowerBound(typeParam, simpleFunctionType, bottomType);
+ var T = _typeParameter('T');
+ _checkGreatestLowerBound(
+ _typeParameterType(T),
+ _functionType(),
+ bottomType,
+ );
}
void test_typeParam_interface_bounded() {
- DartType typeA = ElementFactory.classElement2('A', []).type;
- DartType typeB = ElementFactory.classElement('B', typeA).type;
- DartType typeC = ElementFactory.classElement('C', typeB).type;
- TypeParameterElementImpl typeParam =
- ElementFactory.typeParameterElement('T');
- typeParam.bound = typeB;
- _checkGreatestLowerBound(typeParam.type, typeC, bottomType);
+ var A = _class(name: 'A');
+ var typeA = _interfaceType(A);
+
+ var B = _class(name: 'B', superType: typeA);
+ var typeB = _interfaceType(B);
+
+ var C = _class(name: 'C', superType: typeB);
+ var typeC = _interfaceType(C);
+
+ var T = _typeParameter('T', bound: typeB);
+ _checkGreatestLowerBound(_typeParameterType(T), typeC, bottomType);
}
void test_typeParam_interface_noBound() {
// GLB(T, A) = ⊥
- DartType typeParam = ElementFactory.typeParameterElement('T').type;
- DartType interfaceType = ElementFactory.classElement2('A', []).type;
- _checkGreatestLowerBound(typeParam, interfaceType, bottomType);
+ var T = _typeParameter('T');
+ var A = _class(name: 'A');
+ _checkGreatestLowerBound(
+ _typeParameterType(T),
+ _interfaceType(A),
+ bottomType,
+ );
}
void test_typeParameters_different() {
// GLB(List<int>, List<double>) = ⊥
- InterfaceType listOfIntType = listType.instantiate(<DartType>[intType]);
- InterfaceType listOfDoubleType =
- listType.instantiate(<DartType>[doubleType]);
+ var listOfIntType = listType(intType);
+ var listOfDoubleType = listType(doubleType);
// TODO(rnystrom): Can we do something better here?
_checkGreatestLowerBound(listOfIntType, listOfDoubleType, bottomType);
}
void test_typeParameters_same() {
// GLB(List<int>, List<int>) = List<int>
- InterfaceType listOfIntType = listType.instantiate(<DartType>[intType]);
+ var listOfIntType = listType(intType);
_checkGreatestLowerBound(listOfIntType, listOfIntType, listOfIntType);
}
@@ -1533,23 +1777,25 @@
// class A
// class B
// class C
- ClassElementImpl classA = ElementFactory.classElement2("A");
- ClassElementImpl classB = ElementFactory.classElement2("B");
- _checkGreatestLowerBound(classA.type, classB.type, bottomType);
+ var A = _class(name: 'A');
+ var B = _class(name: 'B');
+ _checkGreatestLowerBound(_interfaceType(A), _interfaceType(B), bottomType);
}
void test_void() {
+ var A = _class(name: 'A');
+ var T = _typeParameter('T');
List<DartType> types = [
bottomType,
- simpleFunctionType,
- ElementFactory.classElement2('A', []).type,
- ElementFactory.typeParameterElement('T').type
+ _functionType(),
+ _interfaceType(A),
+ _typeParameterType(T),
];
for (DartType type in types) {
_checkGreatestLowerBound(
- _functionType(required: [], returns: voidType),
- _functionType(required: [], returns: type),
- _functionType(required: [], returns: type),
+ _functionType(returns: voidType),
+ _functionType(returns: type),
+ _functionType(returns: type),
);
}
}
@@ -1557,11 +1803,6 @@
@reflectiveTest
class LeastUpperBoundFunctionsTest extends BoundTestBase {
- void setUp() {
- super.setUp();
- typeSystem = new Dart2TypeSystem(typeProvider);
- }
-
void test_differentRequiredArity() {
var type1 = _functionType(required: [intType, intType]);
var type2 = _functionType(required: [intType, intType, intType]);
@@ -1692,18 +1933,27 @@
}
void test_typeFormals_differentBounds() {
- var T1 = _typeParameterElement('T1', bound: intType);
- var type1 = _functionType(typeFormals: [T1], returns: T1.type);
+ var T1 = _typeParameter('T1', bound: intType);
+ var type1 = _functionType(
+ typeFormals: [T1],
+ returns: _typeParameterType(T1),
+ );
- var T2 = _typeParameterElement('T2', bound: doubleType);
- var type2 = _functionType(typeFormals: [T2], returns: T2.type);
+ var T2 = _typeParameter('T2', bound: doubleType);
+ var type2 = _functionType(
+ typeFormals: [T2],
+ returns: _typeParameterType(T2),
+ );
_checkLeastUpperBound(type1, type2, functionType);
}
void test_typeFormals_differentNumber() {
- var T1 = _typeParameterElement('T1', bound: numType);
- var type1 = _functionType(typeFormals: [T1], returns: T1.type);
+ var T1 = _typeParameter('T1', bound: numType);
+ var type1 = _functionType(
+ typeFormals: [T1],
+ returns: _typeParameterType(T1),
+ );
var type2 = _functionType(returns: intType);
@@ -1711,14 +1961,23 @@
}
void test_typeFormals_sameBounds() {
- var T1 = _typeParameterElement('T1', bound: numType);
- var type1 = _functionType(typeFormals: [T1], returns: T1.type);
+ var T1 = _typeParameter('T1', bound: numType);
+ var type1 = _functionType(
+ typeFormals: [T1],
+ returns: _typeParameterType(T1),
+ );
- var T2 = _typeParameterElement('T2', bound: numType);
- var type2 = _functionType(typeFormals: [T2], returns: T2.type);
+ var T2 = _typeParameter('T2', bound: numType);
+ var type2 = _functionType(
+ typeFormals: [T2],
+ returns: _typeParameterType(T2),
+ );
- var TE = _typeParameterElement('T', bound: numType);
- var expected = _functionType(typeFormals: [TE], returns: TE.type);
+ var TE = _typeParameter('T', bound: numType);
+ var expected = _functionType(
+ typeFormals: [TE],
+ returns: _typeParameterType(TE),
+ );
_checkLeastUpperBound(type1, type2, expected);
}
@@ -1726,37 +1985,36 @@
@reflectiveTest
class LeastUpperBoundTest extends BoundTestBase {
- void setUp() {
- super.setUp();
- typeSystem = new Dart2TypeSystem(typeProvider);
- }
-
void test_bottom_function() {
- _checkLeastUpperBound(bottomType, simpleFunctionType, simpleFunctionType);
+ _checkLeastUpperBound(bottomType, _functionType(), _functionType());
}
void test_bottom_interface() {
- DartType interfaceType = ElementFactory.classElement2('A', []).type;
- _checkLeastUpperBound(bottomType, interfaceType, interfaceType);
+ var A = _class(name: 'A');
+ var typeA = _interfaceType(A);
+ _checkLeastUpperBound(bottomType, typeA, typeA);
}
void test_bottom_typeParam() {
- DartType typeParam = ElementFactory.typeParameterElement('T').type;
- _checkLeastUpperBound(bottomType, typeParam, typeParam);
+ var T = _typeParameter('T');
+ var typeT = _typeParameterType(T);
+ _checkLeastUpperBound(bottomType, typeT, typeT);
}
void test_directInterfaceCase() {
// class A
// class B implements A
// class C implements B
- ClassElementImpl classA = ElementFactory.classElement2("A");
- ClassElementImpl classB = ElementFactory.classElement2("B");
- ClassElementImpl classC = ElementFactory.classElement2("C");
- InterfaceType typeA = classA.type;
- InterfaceType typeB = classB.type;
- InterfaceType typeC = classC.type;
- classB.interfaces = <InterfaceType>[typeA];
- classC.interfaces = <InterfaceType>[typeB];
+
+ var A = _class(name: 'A');
+ var typeA = _interfaceType(A);
+
+ var B = _class(name: 'B', interfaces: [typeA]);
+ var typeB = _interfaceType(B);
+
+ var C = _class(name: 'C', interfaces: [typeB]);
+ var typeC = _interfaceType(C);
+
_checkLeastUpperBound(typeB, typeC, typeB);
}
@@ -1764,44 +2022,49 @@
// class A
// class B extends A
// class C extends B
- ClassElementImpl classA = ElementFactory.classElement2("A");
- ClassElementImpl classB = ElementFactory.classElement("B", classA.type);
- ClassElementImpl classC = ElementFactory.classElement("C", classB.type);
- InterfaceType typeB = classB.type;
- InterfaceType typeC = classC.type;
+
+ var A = _class(name: 'A');
+ var typeA = _interfaceType(A);
+
+ var B = _class(name: 'B', superType: typeA);
+ var typeB = _interfaceType(B);
+
+ var C = _class(name: 'C', superType: typeB);
+ var typeC = _interfaceType(C);
+
_checkLeastUpperBound(typeB, typeC, typeB);
}
void test_directSuperclass_nullability() {
- ClassElement _classElement(String name, InterfaceType supertype) {
- return ElementFactory.classElement3(name: name, supertype: supertype);
- }
+ var aElement = _class(name: 'A');
+ var aQuestion = _interfaceType(
+ aElement,
+ nullabilitySuffix: NullabilitySuffix.question,
+ );
+ var aStar = _interfaceType(
+ aElement,
+ nullabilitySuffix: NullabilitySuffix.star,
+ );
+ var aNone = _interfaceType(
+ aElement,
+ nullabilitySuffix: NullabilitySuffix.none,
+ );
- InterfaceTypeImpl _interfaceType(
- ClassElement element,
- NullabilitySuffix nullabilitySuffix,
- ) {
- return InterfaceTypeImpl.explicit(
- element,
- const [],
- nullabilitySuffix: nullabilitySuffix,
+ var bElementStar = _class(name: 'B', superType: aStar);
+ var bElementNone = _class(name: 'B', superType: aNone);
+
+ InterfaceTypeImpl _bTypeStarElement(NullabilitySuffix nullability) {
+ return _interfaceType(
+ bElementStar,
+ nullabilitySuffix: nullability,
);
}
- var aElement = ElementFactory.classElement3(name: 'A');
- var aQuestion = _interfaceType(aElement, NullabilitySuffix.question);
- var aStar = _interfaceType(aElement, NullabilitySuffix.star);
- var aNone = _interfaceType(aElement, NullabilitySuffix.none);
-
- var bElementStar = _classElement('B', aStar);
- var bElementNone = _classElement('B', aNone);
-
- InterfaceTypeImpl _bTypeStarElement(NullabilitySuffix nullability) {
- return _interfaceType(bElementStar, nullability);
- }
-
InterfaceTypeImpl _bTypeNoneElement(NullabilitySuffix nullability) {
- return _interfaceType(bElementNone, nullability);
+ return _interfaceType(
+ bElementNone,
+ nullabilitySuffix: nullability,
+ );
}
var bStarQuestion = _bTypeStarElement(NullabilitySuffix.question);
@@ -1847,17 +2110,17 @@
}
void test_dynamic_function() {
- _checkLeastUpperBound(dynamicType, simpleFunctionType, dynamicType);
+ _checkLeastUpperBound(dynamicType, _functionType(), dynamicType);
}
void test_dynamic_interface() {
- DartType interfaceType = ElementFactory.classElement2('A', []).type;
- _checkLeastUpperBound(dynamicType, interfaceType, dynamicType);
+ var A = _class(name: 'A');
+ _checkLeastUpperBound(dynamicType, _interfaceType(A), dynamicType);
}
void test_dynamic_typeParam() {
- DartType typeParam = ElementFactory.typeParameterElement('T').type;
- _checkLeastUpperBound(dynamicType, typeParam, dynamicType);
+ var T = _typeParameter('T');
+ _checkLeastUpperBound(dynamicType, _typeParameterType(T), dynamicType);
}
void test_dynamic_void() {
@@ -1866,27 +2129,25 @@
}
void test_interface_function() {
- DartType interfaceType = ElementFactory.classElement2('A', []).type;
- _checkLeastUpperBound(interfaceType, simpleFunctionType, objectType);
+ var A = _class(name: 'A');
+ _checkLeastUpperBound(_interfaceType(A), _functionType(), objectType);
}
void test_interface_sameElement_nullability() {
- var aElement = ElementFactory.classElement3(name: 'A');
+ var aElement = _class(name: 'A');
- InterfaceTypeImpl _interfaceType(
- ClassElement element,
- NullabilitySuffix nullabilitySuffix,
- ) {
- return InterfaceTypeImpl.explicit(
- element,
- const [],
- nullabilitySuffix: nullabilitySuffix,
- );
- }
-
- var aQuestion = _interfaceType(aElement, NullabilitySuffix.question);
- var aStar = _interfaceType(aElement, NullabilitySuffix.star);
- var aNone = _interfaceType(aElement, NullabilitySuffix.none);
+ var aQuestion = _interfaceType(
+ aElement,
+ nullabilitySuffix: NullabilitySuffix.question,
+ );
+ var aStar = _interfaceType(
+ aElement,
+ nullabilitySuffix: NullabilitySuffix.star,
+ );
+ var aNone = _interfaceType(
+ aElement,
+ nullabilitySuffix: NullabilitySuffix.none,
+ );
void assertLUB(DartType type1, DartType type2, DartType expected) {
expect(typeSystem.getLeastUpperBound(type1, type2), expected);
@@ -1907,10 +2168,10 @@
}
void test_mixinAndClass_constraintAndInterface() {
- var classA = ElementFactory.classElement3(name: 'A');
+ var classA = _class(name: 'A');
var instA = InstantiatedClass(classA, []);
- var classB = ElementFactory.classElement3(
+ var classB = _class(
name: 'B',
interfaces: [instA.withNullabilitySuffixNone],
);
@@ -1921,14 +2182,12 @@
);
_checkLeastUpperBound(
- InterfaceTypeImpl.explicit(
+ _interfaceType(
classB,
- [],
nullabilitySuffix: NullabilitySuffix.star,
),
- InterfaceTypeImpl.explicit(
+ _interfaceType(
mixinM,
- [],
nullabilitySuffix: NullabilitySuffix.star,
),
instA.withNullability(NullabilitySuffix.star),
@@ -1936,21 +2195,21 @@
}
void test_mixinAndClass_object() {
- var classA = ElementFactory.classElement3(name: 'A');
+ var classA = _class(name: 'A');
var mixinM = ElementFactory.mixinElement(name: 'M');
_checkLeastUpperBound(
- InterfaceTypeImpl.explicit(classA, []),
- InterfaceTypeImpl.explicit(mixinM, []),
- typeProvider.objectType,
+ _interfaceType(classA),
+ _interfaceType(mixinM),
+ objectType,
);
}
void test_mixinAndClass_sharedInterface() {
- var classA = ElementFactory.classElement3(name: 'A');
+ var classA = _class(name: 'A');
var instA = InstantiatedClass(classA, []);
- var classB = ElementFactory.classElement3(
+ var classB = _class(
name: 'B',
interfaces: [instA.withNullabilitySuffixNone],
);
@@ -1961,14 +2220,12 @@
);
_checkLeastUpperBound(
- InterfaceTypeImpl.explicit(
+ _interfaceType(
classB,
- [],
nullabilitySuffix: NullabilitySuffix.star,
),
- InterfaceTypeImpl.explicit(
+ _interfaceType(
mixinM,
- [],
nullabilitySuffix: NullabilitySuffix.star,
),
instA.withNullability(NullabilitySuffix.star),
@@ -1980,19 +2237,28 @@
// class B extends A
// class C extends A
// class D extends B with M, N, O, P
- ClassElement classA = ElementFactory.classElement2("A");
- ClassElement classB = ElementFactory.classElement("B", classA.type);
- ClassElement classC = ElementFactory.classElement("C", classA.type);
- ClassElementImpl classD = ElementFactory.classElement("D", classB.type);
- InterfaceType typeA = classA.type;
- InterfaceType typeC = classC.type;
- InterfaceType typeD = classD.type;
- classD.mixins = <InterfaceType>[
- ElementFactory.classElement2("M").type,
- ElementFactory.classElement2("N").type,
- ElementFactory.classElement2("O").type,
- ElementFactory.classElement2("P").type
- ];
+
+ var A = _class(name: 'A');
+ var typeA = _interfaceType(A);
+
+ var B = _class(name: 'B', superType: typeA);
+ var typeB = _interfaceType(B);
+
+ var C = _class(name: 'C', superType: typeA);
+ var typeC = _interfaceType(C);
+
+ var D = _class(
+ name: 'D',
+ superType: typeB,
+ mixins: [
+ _interfaceType(_class(name: 'M')),
+ _interfaceType(_class(name: 'N')),
+ _interfaceType(_class(name: 'O')),
+ _interfaceType(_class(name: 'P')),
+ ],
+ );
+ var typeD = _interfaceType(D);
+
_checkLeastUpperBound(typeD, typeC, typeA);
}
@@ -2016,17 +2282,17 @@
}
void test_nestedNestedFunctionsGlbInnermostParamTypes() {
- FunctionType type1 = _functionType(required: [
+ var type1 = _functionType(required: [
_functionType(required: [
_functionType(required: [stringType, intType, intType])
])
]);
- FunctionType type2 = _functionType(required: [
+ var type2 = _functionType(required: [
_functionType(required: [
_functionType(required: [intType, doubleType, numType])
])
]);
- FunctionType expected = _functionType(required: [
+ var expected = _functionType(required: [
_functionType(required: [
_functionType(required: [bottomType, bottomType, intType])
])
@@ -2035,13 +2301,13 @@
}
void test_object() {
- ClassElementImpl classA = ElementFactory.classElement2("A");
- ClassElementImpl classB = ElementFactory.classElement2("B");
- InterfaceType typeA = classA.type;
- InterfaceType typeB = classB.type;
- DartType typeObject = typeA.element.supertype;
+ var A = _class(name: 'A');
+ var B = _class(name: 'B');
+ var typeA = _interfaceType(A);
+ var typeB = _interfaceType(B);
+ var typeObject = typeA.element.supertype;
// assert that object does not have a super type
- expect((typeObject.element as ClassElement).supertype, isNull);
+ expect(typeObject.element.supertype, isNull);
// assert that both A and B have the same super type of Object
expect(typeB.element.supertype, typeObject);
// finally, assert that the only least upper bound of A and B is Object
@@ -2049,16 +2315,16 @@
}
void test_self() {
- DartType typeParam = ElementFactory.typeParameterElement('T').type;
- DartType interfaceType = ElementFactory.classElement2('A', []).type;
+ var T = _typeParameter('T');
+ var A = _class(name: 'A');
List<DartType> types = [
dynamicType,
voidType,
bottomType,
- typeParam,
- interfaceType,
- simpleFunctionType
+ _typeParameterType(T),
+ _interfaceType(A),
+ _functionType()
];
for (DartType type in types) {
@@ -2067,49 +2333,51 @@
}
void test_sharedSuperclass1() {
- ClassElementImpl classA = ElementFactory.classElement2("A");
- ClassElementImpl classB = ElementFactory.classElement("B", classA.type);
- ClassElementImpl classC = ElementFactory.classElement("C", classA.type);
- InterfaceType typeA = classA.type;
- InterfaceType typeB = classB.type;
- InterfaceType typeC = classC.type;
+ var A = _class(name: 'A');
+ var typeA = _interfaceType(A);
+
+ var B = _class(name: 'B', superType: typeA);
+ var typeB = _interfaceType(B);
+
+ var C = _class(name: 'C', superType: typeA);
+ var typeC = _interfaceType(C);
+
_checkLeastUpperBound(typeB, typeC, typeA);
}
void test_sharedSuperclass1_nullability() {
- ClassElementImpl _classElement(String name, InterfaceType supertype) {
- return ElementFactory.classElement3(name: name, supertype: supertype);
- }
+ var aElement = _class(name: 'A');
+ var aQuestion = _interfaceType(
+ aElement,
+ nullabilitySuffix: NullabilitySuffix.question,
+ );
+ var aStar = _interfaceType(
+ aElement,
+ nullabilitySuffix: NullabilitySuffix.star,
+ );
+ var aNone = _interfaceType(
+ aElement,
+ nullabilitySuffix: NullabilitySuffix.none,
+ );
- InterfaceTypeImpl _interfaceType(
- ClassElement element,
- NullabilitySuffix nullabilitySuffix,
- ) {
- return InterfaceTypeImpl.explicit(
- element,
- const [],
- nullabilitySuffix: nullabilitySuffix,
+ var bElementNone = _class(name: 'B', superType: aNone);
+ var bElementStar = _class(name: 'B', superType: aStar);
+
+ var cElementNone = _class(name: 'C', superType: aNone);
+ var cElementStar = _class(name: 'C', superType: aStar);
+
+ InterfaceTypeImpl bTypeElementNone(NullabilitySuffix nullability) {
+ return _interfaceType(
+ bElementNone,
+ nullabilitySuffix: nullability,
);
}
- var aElement = _classElement('A', null);
-
- var aQuestion = _interfaceType(aElement, NullabilitySuffix.question);
- var aStar = _interfaceType(aElement, NullabilitySuffix.star);
- var aNone = _interfaceType(aElement, NullabilitySuffix.none);
-
- var bElementNone = _classElement('B', aNone);
- var bElementStar = _classElement('B', aStar);
-
- var cElementNone = _classElement('C', aNone);
- var cElementStar = _classElement('C', aStar);
-
- InterfaceTypeImpl bTypeElementNone(NullabilitySuffix nullability) {
- return _interfaceType(bElementNone, nullability);
- }
-
InterfaceTypeImpl bTypeElementStar(NullabilitySuffix nullability) {
- return _interfaceType(bElementStar, nullability);
+ return _interfaceType(
+ bElementStar,
+ nullabilitySuffix: nullability,
+ );
}
var bNoneQuestion = bTypeElementNone(NullabilitySuffix.question);
@@ -2121,11 +2389,17 @@
var bStarNone = bTypeElementStar(NullabilitySuffix.none);
InterfaceTypeImpl cTypeElementNone(NullabilitySuffix nullability) {
- return _interfaceType(cElementNone, nullability);
+ return _interfaceType(
+ cElementNone,
+ nullabilitySuffix: nullability,
+ );
}
InterfaceTypeImpl cTypeElementStar(NullabilitySuffix nullability) {
- return _interfaceType(cElementStar, nullability);
+ return _interfaceType(
+ cElementStar,
+ nullabilitySuffix: nullability,
+ );
}
var cNoneQuestion = cTypeElementNone(NullabilitySuffix.question);
@@ -2185,98 +2459,117 @@
}
void test_sharedSuperclass2() {
- ClassElementImpl classA = ElementFactory.classElement2("A");
- ClassElementImpl classB = ElementFactory.classElement("B", classA.type);
- ClassElementImpl classC = ElementFactory.classElement("C", classA.type);
- ClassElementImpl classD = ElementFactory.classElement("D", classC.type);
- InterfaceType typeA = classA.type;
- InterfaceType typeB = classB.type;
- InterfaceType typeD = classD.type;
+ var A = _class(name: 'A');
+ var typeA = _interfaceType(A);
+
+ var B = _class(name: 'B', superType: typeA);
+ var typeB = _interfaceType(B);
+
+ var C = _class(name: 'C', superType: typeA);
+ var typeC = _interfaceType(C);
+
+ var D = _class(name: 'D', superType: typeC);
+ var typeD = _interfaceType(D);
+
_checkLeastUpperBound(typeB, typeD, typeA);
}
void test_sharedSuperclass3() {
- ClassElementImpl classA = ElementFactory.classElement2("A");
- ClassElementImpl classB = ElementFactory.classElement("B", classA.type);
- ClassElementImpl classC = ElementFactory.classElement("C", classB.type);
- ClassElementImpl classD = ElementFactory.classElement("D", classB.type);
- InterfaceType typeB = classB.type;
- InterfaceType typeC = classC.type;
- InterfaceType typeD = classD.type;
+ var A = _class(name: 'A');
+ var typeA = _interfaceType(A);
+
+ var B = _class(name: 'B', superType: typeA);
+ var typeB = _interfaceType(B);
+
+ var C = _class(name: 'C', superType: typeB);
+ var typeC = _interfaceType(C);
+
+ var D = _class(name: 'D', superType: typeB);
+ var typeD = _interfaceType(D);
+
_checkLeastUpperBound(typeC, typeD, typeB);
}
void test_sharedSuperclass4() {
- ClassElement classA = ElementFactory.classElement2("A");
- ClassElement classA2 = ElementFactory.classElement2("A2");
- ClassElement classA3 = ElementFactory.classElement2("A3");
- ClassElementImpl classB = ElementFactory.classElement("B", classA.type);
- ClassElementImpl classC = ElementFactory.classElement("C", classA.type);
- InterfaceType typeA = classA.type;
- InterfaceType typeA2 = classA2.type;
- InterfaceType typeA3 = classA3.type;
- InterfaceType typeB = classB.type;
- InterfaceType typeC = classC.type;
- classB.interfaces = <InterfaceType>[typeA2];
- classC.interfaces = <InterfaceType>[typeA3];
+ var A = _class(name: 'A');
+ var typeA = _interfaceType(A);
+
+ var A2 = _class(name: 'A2');
+ var typeA2 = _interfaceType(A2);
+
+ var A3 = _class(name: 'A3');
+ var typeA3 = _interfaceType(A3);
+
+ var B = _class(name: 'B', superType: typeA, interfaces: [typeA2]);
+ var typeB = _interfaceType(B);
+
+ var C = _class(name: 'C', superType: typeA, interfaces: [typeA3]);
+ var typeC = _interfaceType(C);
+
_checkLeastUpperBound(typeB, typeC, typeA);
}
void test_sharedSuperinterface1() {
- ClassElementImpl classA = ElementFactory.classElement2("A");
- ClassElementImpl classB = ElementFactory.classElement2("B");
- ClassElementImpl classC = ElementFactory.classElement2("C");
- InterfaceType typeA = classA.type;
- InterfaceType typeB = classB.type;
- InterfaceType typeC = classC.type;
- classB.interfaces = <InterfaceType>[typeA];
- classC.interfaces = <InterfaceType>[typeA];
+ var A = _class(name: 'A');
+ var typeA = _interfaceType(A);
+
+ var B = _class(name: 'B', interfaces: [typeA]);
+ var typeB = _interfaceType(B);
+
+ var C = _class(name: 'C', interfaces: [typeA]);
+ var typeC = _interfaceType(C);
+
_checkLeastUpperBound(typeB, typeC, typeA);
}
void test_sharedSuperinterface2() {
- ClassElementImpl classA = ElementFactory.classElement2("A");
- ClassElementImpl classB = ElementFactory.classElement2("B");
- ClassElementImpl classC = ElementFactory.classElement2("C");
- ClassElementImpl classD = ElementFactory.classElement2("D");
- InterfaceType typeA = classA.type;
- InterfaceType typeB = classB.type;
- InterfaceType typeC = classC.type;
- InterfaceType typeD = classD.type;
- classB.interfaces = <InterfaceType>[typeA];
- classC.interfaces = <InterfaceType>[typeA];
- classD.interfaces = <InterfaceType>[typeC];
+ var A = _class(name: 'A');
+ var typeA = _interfaceType(A);
+
+ var B = _class(name: 'B', interfaces: [typeA]);
+ var typeB = _interfaceType(B);
+
+ var C = _class(name: 'C', interfaces: [typeA]);
+ var typeC = _interfaceType(C);
+
+ var D = _class(name: 'D', interfaces: [typeC]);
+ var typeD = _interfaceType(D);
+
_checkLeastUpperBound(typeB, typeD, typeA);
}
void test_sharedSuperinterface3() {
- ClassElementImpl classA = ElementFactory.classElement2("A");
- ClassElementImpl classB = ElementFactory.classElement2("B");
- ClassElementImpl classC = ElementFactory.classElement2("C");
- ClassElementImpl classD = ElementFactory.classElement2("D");
- InterfaceType typeA = classA.type;
- InterfaceType typeB = classB.type;
- InterfaceType typeC = classC.type;
- InterfaceType typeD = classD.type;
- classB.interfaces = <InterfaceType>[typeA];
- classC.interfaces = <InterfaceType>[typeB];
- classD.interfaces = <InterfaceType>[typeB];
+ var A = _class(name: 'A');
+ var typeA = _interfaceType(A);
+
+ var B = _class(name: 'B', interfaces: [typeA]);
+ var typeB = _interfaceType(B);
+
+ var C = _class(name: 'C', interfaces: [typeB]);
+ var typeC = _interfaceType(C);
+
+ var D = _class(name: 'D', interfaces: [typeB]);
+ var typeD = _interfaceType(D);
+
_checkLeastUpperBound(typeC, typeD, typeB);
}
void test_sharedSuperinterface4() {
- ClassElement classA = ElementFactory.classElement2("A");
- ClassElement classA2 = ElementFactory.classElement2("A2");
- ClassElement classA3 = ElementFactory.classElement2("A3");
- ClassElementImpl classB = ElementFactory.classElement2("B");
- ClassElementImpl classC = ElementFactory.classElement2("C");
- InterfaceType typeA = classA.type;
- InterfaceType typeA2 = classA2.type;
- InterfaceType typeA3 = classA3.type;
- InterfaceType typeB = classB.type;
- InterfaceType typeC = classC.type;
- classB.interfaces = <InterfaceType>[typeA, typeA2];
- classC.interfaces = <InterfaceType>[typeA, typeA3];
+ var A = _class(name: 'A');
+ var typeA = _interfaceType(A);
+
+ var A2 = _class(name: 'A2');
+ var typeA2 = _interfaceType(A2);
+
+ var A3 = _class(name: 'A3');
+ var typeA3 = _interfaceType(A3);
+
+ var B = _class(name: 'B', interfaces: [typeA, typeA2]);
+ var typeB = _interfaceType(B);
+
+ var C = _class(name: 'C', interfaces: [typeA, typeA3]);
+ var typeC = _interfaceType(C);
+
_checkLeastUpperBound(typeB, typeC, typeA);
}
@@ -2285,82 +2578,90 @@
}
void test_typeParam_boundedByParam() {
- TypeParameterElementImpl typeParamElementT =
- ElementFactory.typeParameterElement('T');
- TypeParameterElementImpl typeParamElementS =
- ElementFactory.typeParameterElement('S');
- DartType typeParamT = typeParamElementT.type;
- DartType typeParamS = typeParamElementS.type;
- typeParamElementT.bound = typeParamS;
- _checkLeastUpperBound(typeParamT, typeParamS, typeParamS);
+ var S = _typeParameter('S');
+ var typeS = _typeParameterType(S);
+
+ var T = _typeParameter('T', bound: typeS);
+ var typeT = _typeParameterType(T);
+
+ _checkLeastUpperBound(typeT, typeS, typeS);
}
void test_typeParam_class_implements_Function_ignored() {
- DartType typeA = ElementFactory.classElement('A', functionType).type;
- TypeParameterElementImpl typeParamElement =
- ElementFactory.typeParameterElement('T');
- typeParamElement.bound = typeA;
- DartType typeParam = typeParamElement.type;
- _checkLeastUpperBound(typeParam, simpleFunctionType, objectType);
+ var A = _class(name: 'A', superType: functionType);
+ var T = _typeParameter('T', bound: _interfaceType(A));
+ _checkLeastUpperBound(_typeParameterType(T), _functionType(), objectType);
}
void test_typeParam_fBounded() {
- ClassElementImpl AClass = ElementFactory.classElement2('A', ["Q"]);
- InterfaceType AType = AClass.type;
+ var T = _typeParameter('Q');
+ var A = _class(name: 'A', typeParameters: [T]);
- DartType s = TypeBuilder.variable("S");
- (s.element as TypeParameterElementImpl).bound = AType.instantiate([s]);
- DartType u = TypeBuilder.variable("U");
- (u.element as TypeParameterElementImpl).bound = AType.instantiate([u]);
+ var S = _typeParameter('S');
+ var typeS = _typeParameterType(S);
+ S.bound = _interfaceType(A, typeArguments: [typeS]);
- _checkLeastUpperBound(s, u, AType.instantiate([objectType]));
+ var U = _typeParameter('U');
+ var typeU = _typeParameterType(U);
+ U.bound = _interfaceType(A, typeArguments: [typeU]);
+
+ _checkLeastUpperBound(
+ typeS,
+ _typeParameterType(U),
+ _interfaceType(A, typeArguments: [objectType]),
+ );
}
void test_typeParam_function_bounded() {
- TypeParameterElementImpl typeParamElement =
- ElementFactory.typeParameterElement('T');
- typeParamElement.bound = functionType;
- DartType typeParam = typeParamElement.type;
- _checkLeastUpperBound(typeParam, simpleFunctionType, functionType);
+ var T = _typeParameter('T', bound: functionType);
+ _checkLeastUpperBound(_typeParameterType(T), _functionType(), functionType);
}
void test_typeParam_function_noBound() {
- DartType typeParam = ElementFactory.typeParameterElement('T').type;
- _checkLeastUpperBound(typeParam, simpleFunctionType, objectType);
+ var T = _typeParameter('T');
+ _checkLeastUpperBound(_typeParameterType(T), _functionType(), objectType);
}
void test_typeParam_interface_bounded() {
- DartType typeA = ElementFactory.classElement2('A', []).type;
- DartType typeB = ElementFactory.classElement('B', typeA).type;
- DartType typeC = ElementFactory.classElement('C', typeA).type;
- TypeParameterElementImpl typeParamElement =
- ElementFactory.typeParameterElement('T');
- typeParamElement.bound = typeB;
- DartType typeParam = typeParamElement.type;
- _checkLeastUpperBound(typeParam, typeC, typeA);
+ var A = _class(name: 'A');
+ var typeA = _interfaceType(A);
+
+ var B = _class(name: 'B', superType: typeA);
+ var typeB = _interfaceType(B);
+
+ var C = _class(name: 'C', superType: typeA);
+ var typeC = _interfaceType(C);
+
+ var T = _typeParameter('T', bound: typeB);
+ var typeT = _typeParameterType(T);
+
+ _checkLeastUpperBound(typeT, typeC, typeA);
}
void test_typeParam_interface_noBound() {
- DartType typeParam = ElementFactory.typeParameterElement('T').type;
- DartType interfaceType = ElementFactory.classElement2('A', []).type;
- _checkLeastUpperBound(typeParam, interfaceType, objectType);
+ var T = _typeParameter('T');
+ var A = _class(name: 'A');
+ _checkLeastUpperBound(
+ _typeParameterType(T),
+ _interfaceType(A),
+ objectType,
+ );
}
/// Check least upper bound of the same class with different type parameters.
void test_typeParameters_different() {
// class List<int>
// class List<double>
- InterfaceType listOfIntType = listType.instantiate(<DartType>[intType]);
- InterfaceType listOfDoubleType =
- listType.instantiate(<DartType>[doubleType]);
- InterfaceType listOfNum = listType.instantiate(<DartType>[numType]);
+ var listOfIntType = listType(intType);
+ var listOfDoubleType = listType(doubleType);
+ var listOfNum = listType(numType);
_checkLeastUpperBound(listOfIntType, listOfDoubleType, listOfNum);
}
void test_typeParameters_same() {
// List<int>
// List<int>
- InterfaceType listOfIntType = listType.instantiate(<DartType>[intType]);
+ var listOfIntType = listType(intType);
_checkLeastUpperBound(listOfIntType, listOfIntType, listOfIntType);
}
@@ -2369,9 +2670,8 @@
void test_typeParametersAndClass_different() {
// class List<int>
// class Iterable<double>
- InterfaceType listOfIntType = listType.instantiate(<DartType>[intType]);
- InterfaceType iterableOfDoubleType =
- iterableType.instantiate(<DartType>[doubleType]);
+ var listOfIntType = listType(intType);
+ var iterableOfDoubleType = iterableType(doubleType);
// TODO(leafp): this should be iterableOfNumType
_checkLeastUpperBound(listOfIntType, iterableOfDoubleType, objectType);
}
@@ -2379,9 +2679,9 @@
void test_void() {
List<DartType> types = [
bottomType,
- simpleFunctionType,
- ElementFactory.classElement2('A', []).type,
- ElementFactory.typeParameterElement('T').type
+ _functionType(),
+ _interfaceType(_class(name: 'A')),
+ _typeParameterType(_typeParameter('T')),
];
for (DartType type in types) {
_checkLeastUpperBound(
@@ -2396,24 +2696,9 @@
@reflectiveTest
class NonNullableSubtypingTest extends SubtypingTestBase {
@override
- void setUp() {
- typeProvider = TestAnalysisContext(
- featureSet: FeatureSet.forTesting(
- additionalFeatures: [Feature.non_nullable],
- ),
- ).typeProvider;
-
- // TypeSystem should use the context type provider.
- typeSystem = new Dart2TypeSystem(typeProvider);
-
- LibraryElement coreLibrary = typeProvider.objectType.element.library;
- LibraryElement asyncLibrary = typeProvider.streamType.element.library;
-
- // Get a non-nullable type provider for convience during the test.
- typeProvider = TypeProviderImpl(
- coreLibrary,
- asyncLibrary,
- nullabilitySuffix: NullabilitySuffix.none,
+ FeatureSet get testFeatureSet {
+ return FeatureSet.forTesting(
+ additionalFeatures: [Feature.non_nullable],
);
}
@@ -2433,9 +2718,9 @@
(objectType as TypeImpl).withNullability(NullabilitySuffix.star);
var objectQuestion =
(objectType as TypeImpl).withNullability(NullabilitySuffix.question);
- var futureOrObject = futureOrType.instantiate([objectType]);
- var futureOrObjectStar = futureOrType.instantiate([objectStar]);
- var futureOrObjectQuestion = futureOrType.instantiate([objectQuestion]);
+ var futureOrObject = futureOrType(objectType);
+ var futureOrObjectStar = futureOrType(objectStar);
+ var futureOrObjectQuestion = futureOrType(objectQuestion);
var futureOrStarObject =
(futureOrObject as TypeImpl).withNullability(NullabilitySuffix.star);
var futureOrQuestionObject = (futureOrObject as TypeImpl)
@@ -2463,7 +2748,7 @@
futureOrQuestionObject,
futureOrQuestionObjectStar,
futureOrStarObjectQuestion,
- futureOrQuestionObjectQuestion
+ futureOrQuestionObjectQuestion,
]);
}
@@ -2571,7 +2856,7 @@
doubleType,
intType,
numType,
- objectType
+ objectType,
];
for (final formOfNull in equivalents) {
@@ -2597,7 +2882,7 @@
_question(doubleType),
_question(numType),
_question(intType),
- nullType
+ nullType,
];
_checkGroups(objectType,
equivalents: equivalents,
@@ -2616,7 +2901,7 @@
@reflectiveTest
class SubtypingTest extends SubtypingTestBase {
void test_bottom_isBottom() {
- DartType interfaceType = ElementFactory.classElement2('A', []).type;
+ var A = _class(name: 'A');
List<DartType> equivalents = <DartType>[bottomType];
List<DartType> supertypes = <DartType>[
dynamicType,
@@ -2626,36 +2911,42 @@
numType,
stringType,
functionType,
- interfaceType
+ _interfaceType(A),
];
_checkGroups(bottomType, equivalents: equivalents, supertypes: supertypes);
}
void test_call_method() {
- ClassElementImpl classBottom = ElementFactory.classElement2("Bottom");
- MethodElement methodBottom =
- ElementFactory.methodElement("call", objectType, <DartType>[intType]);
- classBottom.methods = <MethodElement>[methodBottom];
+ var A = _class(name: 'A', methods: [
+ _method('call', objectType, parameters: [
+ _requiredParameter('_', intType),
+ ]),
+ ]);
- DartType top =
- TypeBuilder.function(required: <DartType>[intType], result: objectType);
- InterfaceType bottom = classBottom.type;
-
- _checkIsNotSubtypeOf(bottom, top);
+ _checkIsNotSubtypeOf(
+ _interfaceType(A),
+ _functionType(required: [intType], returns: objectType),
+ );
}
void test_classes() {
- ClassElement classTop = ElementFactory.classElement2("A");
- ClassElement classLeft = ElementFactory.classElement("B", classTop.type);
- ClassElement classRight = ElementFactory.classElement("C", classTop.type);
- ClassElement classBottom = ElementFactory.classElement("D", classLeft.type)
- ..interfaces = <InterfaceType>[classRight.type];
- InterfaceType top = classTop.type;
- InterfaceType left = classLeft.type;
- InterfaceType right = classRight.type;
- InterfaceType bottom = classBottom.type;
+ var A = _class(name: 'A');
+ var typeA = _interfaceType(A);
- _checkLattice(top, left, right, bottom);
+ var B = _class(name: 'B', superType: typeA);
+ var typeB = _interfaceType(B);
+
+ var C = _class(name: 'C', superType: typeA);
+ var typeC = _interfaceType(C);
+
+ var D = _class(
+ name: 'D',
+ superType: _interfaceType(B),
+ interfaces: [typeC],
+ );
+ var typeD = _interfaceType(D);
+
+ _checkLattice(typeA, typeB, typeC, typeD);
}
void test_double() {
@@ -2667,7 +2958,7 @@
}
void test_dynamic_isTop() {
- DartType interfaceType = ElementFactory.classElement2('A', []).type;
+ var A = _class(name: 'A');
List<DartType> equivalents = <DartType>[dynamicType, objectType, voidType];
List<DartType> subtypes = <DartType>[
intType,
@@ -2675,8 +2966,8 @@
numType,
stringType,
functionType,
- interfaceType,
- bottomType
+ _interfaceType(A),
+ bottomType,
];
_checkGroups(dynamicType, equivalents: equivalents, subtypes: subtypes);
}
@@ -2684,10 +2975,9 @@
void test_function_subtypes_itself_top_types() {
var tops = [dynamicType, objectType, voidType];
// Add FutureOr<T> for T := dynamic, object, void
- tops.addAll(tops.map((t) => futureOrType.instantiate([t])).toList());
+ tops.addAll(tops.map((t) => futureOrType(t)).toList());
// Add FutureOr<FutureOr<T>> for T := dynamic, object, void
- tops.addAll(
- tops.skip(3).map((t) => futureOrType.instantiate([t])).toList());
+ tops.addAll(tops.skip(3).map((t) => futureOrType(t)).toList());
// Function should subtype all of those top types.
_checkGroups(functionType, supertypes: [
@@ -2697,106 +2987,187 @@
]);
// Create a non-identical but equal copy of Function, and verify subtyping
- var copyOfFunction = new InterfaceTypeImpl(functionType.element);
+ var copyOfFunction = _interfaceType(functionType.element);
_checkEquivalent(functionType, copyOfFunction);
}
void test_genericFunction_generic_monomorphic() {
- DartType s = TypeBuilder.variable("S");
- DartType t = TypeBuilder.variable("T", bound: s);
- DartType u = TypeBuilder.variable("U", bound: intType);
- DartType v = TypeBuilder.variable("V", bound: u);
+ var S = _typeParameter('S');
+ var T = _typeParameter('T', bound: _typeParameterType(S));
+ var U = _typeParameter('U', bound: intType);
+ var V = _typeParameter('V', bound: _typeParameterType(U));
- DartType a = TypeBuilder.variable("A");
- DartType b = TypeBuilder.variable("B", bound: a);
- DartType c = TypeBuilder.variable("C", bound: intType);
- DartType d = TypeBuilder.variable("D", bound: c);
+ var A = _typeParameter('A');
+ var B = _typeParameter('B', bound: _typeParameterType(A));
+ var C = _typeParameter('C', bound: intType);
+ var D = _typeParameter('D', bound: _typeParameterType(C));
_checkIsStrictSubtypeOf(
- TypeBuilder.function(types: [s, t], required: [s], result: t),
- TypeBuilder.function(
- types: [a, b], required: [bottomType], result: dynamicType));
+ _functionType(
+ typeFormals: [S, T],
+ required: [_typeParameterType(S)],
+ returns: _typeParameterType(T),
+ ),
+ _functionType(
+ typeFormals: [A, B],
+ required: [bottomType],
+ returns: dynamicType,
+ ),
+ );
_checkIsNotSubtypeOf(
- TypeBuilder.function(types: [u, v], required: [u], result: v),
- TypeBuilder.function(
- types: [c, d], required: [objectType], result: objectType));
+ _functionType(
+ typeFormals: [U, V],
+ required: [_typeParameterType(U)],
+ returns: _typeParameterType(V),
+ ),
+ _functionType(
+ typeFormals: [C, D],
+ required: [objectType],
+ returns: objectType,
+ ),
+ );
_checkIsNotSubtypeOf(
- TypeBuilder.function(types: [u, v], required: [u], result: v),
- TypeBuilder.function(
- types: [c, d], required: [intType], result: intType));
+ _functionType(
+ typeFormals: [U, V],
+ required: [_typeParameterType(U)],
+ returns: _typeParameterType(V),
+ ),
+ _functionType(
+ typeFormals: [C, D],
+ required: [intType],
+ returns: intType,
+ ),
+ );
}
void test_genericFunction_genericDoesNotSubtypeNonGeneric() {
- DartType s = TypeBuilder.variable("S");
- DartType t = TypeBuilder.variable("T", bound: s);
- DartType u = TypeBuilder.variable("U", bound: intType);
- DartType v = TypeBuilder.variable("V", bound: u);
+ var S = _typeParameter('S');
+ var T = _typeParameter('T', bound: _typeParameterType(S));
+ var U = _typeParameter('U', bound: intType);
+ var V = _typeParameter('V', bound: _typeParameterType(U));
_checkIsNotSubtypeOf(
- TypeBuilder.function(types: [s, t], required: [s], result: t),
- TypeBuilder.function(required: [dynamicType], result: dynamicType));
+ _functionType(
+ typeFormals: [S, T],
+ required: [_typeParameterType(S)],
+ returns: _typeParameterType(T),
+ ),
+ _functionType(required: [dynamicType], returns: dynamicType),
+ );
_checkIsNotSubtypeOf(
- TypeBuilder.function(types: [u, v], required: [u], result: v),
- TypeBuilder.function(required: [objectType], result: objectType));
+ _functionType(
+ typeFormals: [U, V],
+ required: [_typeParameterType(U)],
+ returns: _typeParameterType(V),
+ ),
+ _functionType(required: [objectType], returns: objectType),
+ );
_checkIsNotSubtypeOf(
- TypeBuilder.function(types: [u, v], required: [u], result: v),
- TypeBuilder.function(required: [intType], result: intType));
+ _functionType(
+ typeFormals: [U, V],
+ required: [_typeParameterType(U)],
+ returns: _typeParameterType(V),
+ ),
+ _functionType(required: [intType], returns: intType),
+ );
}
void test_genericFunction_simple() {
- DartType s = TypeBuilder.variable("S");
- DartType t = TypeBuilder.variable("T");
+ var S = _typeParameter('S');
+ var T = _typeParameter('T');
_checkEquivalent(
- TypeBuilder.function(types: [t]), TypeBuilder.function(types: [s]));
+ _functionType(typeFormals: [T]),
+ _functionType(typeFormals: [S]),
+ );
- _checkEquivalent(TypeBuilder.function(types: [t], required: [t], result: t),
- TypeBuilder.function(types: [s], required: [s], result: s));
+ _checkEquivalent(
+ _functionType(
+ typeFormals: [T],
+ required: [_typeParameterType(T)],
+ returns: _typeParameterType(T),
+ ),
+ _functionType(
+ typeFormals: [S],
+ required: [_typeParameterType(S)],
+ returns: _typeParameterType(S),
+ ),
+ );
}
void test_genericFunction_simple_bounded() {
- DartType s = TypeBuilder.variable("S");
- DartType t = TypeBuilder.variable("T", bound: s);
- DartType u = TypeBuilder.variable("U");
- DartType v = TypeBuilder.variable("V", bound: u);
-
- _checkEquivalent(TypeBuilder.function(types: [s, t]),
- TypeBuilder.function(types: [u, v]));
+ var S = _typeParameter('S');
+ var T = _typeParameter('T', bound: _typeParameterType(S));
+ var U = _typeParameter('U');
+ var V = _typeParameter('V', bound: _typeParameterType(U));
_checkEquivalent(
- TypeBuilder.function(types: [s, t], required: [s], result: t),
- TypeBuilder.function(types: [u, v], required: [u], result: v));
+ _functionType(typeFormals: [S, T]),
+ _functionType(typeFormals: [U, V]),
+ );
+
+ _checkEquivalent(
+ _functionType(
+ typeFormals: [S, T],
+ required: [_typeParameterType(S)],
+ returns: _typeParameterType(T),
+ ),
+ _functionType(
+ typeFormals: [U, V],
+ required: [_typeParameterType(U)],
+ returns: _typeParameterType(V),
+ ),
+ );
{
- DartType top =
- TypeBuilder.function(types: [s, t], required: [t], result: s);
- DartType left =
- TypeBuilder.function(types: [u, v], required: [u], result: u);
- DartType right =
- TypeBuilder.function(types: [u, v], required: [v], result: v);
- DartType bottom =
- TypeBuilder.function(types: [s, t], required: [s], result: t);
+ var top = _functionType(
+ typeFormals: [S, T],
+ required: [_typeParameterType(T)],
+ returns: _typeParameterType(S),
+ );
+ var left = _functionType(
+ typeFormals: [U, V],
+ required: [_typeParameterType(U)],
+ returns: _typeParameterType(U),
+ );
+ var right = _functionType(
+ typeFormals: [U, V],
+ required: [_typeParameterType(V)],
+ returns: _typeParameterType(V),
+ );
+ var bottom = _functionType(
+ typeFormals: [S, T],
+ required: [_typeParameterType(S)],
+ returns: _typeParameterType(T),
+ );
_checkLattice(top, left, right, bottom);
}
}
void test_generics() {
- ClassElementImpl LClass = ElementFactory.classElement2('L', ["T"]);
- InterfaceType LType = LClass.type;
- ClassElementImpl MClass = ElementFactory.classElement2('M', ["T"]);
- DartType typeParam = MClass.typeParameters[0].type;
- InterfaceType superType = LType.instantiate(<DartType>[typeParam]);
- MClass.interfaces = <InterfaceType>[superType];
- InterfaceType MType = MClass.type;
+ var LT = _typeParameter('T');
+ var L = _class(name: 'L', typeParameters: [LT]);
- InterfaceType top = LType.instantiate(<DartType>[dynamicType]);
- InterfaceType left = MType.instantiate(<DartType>[dynamicType]);
- InterfaceType right = LType.instantiate(<DartType>[intType]);
- InterfaceType bottom = MType.instantiate(<DartType>[intType]);
+ var MT = _typeParameter('T');
+ var M = _class(
+ name: 'M',
+ typeParameters: [MT],
+ interfaces: [
+ _interfaceType(
+ L,
+ typeArguments: [_typeParameterType(MT)],
+ )
+ ],
+ );
+
+ var top = _interfaceType(L, typeArguments: [dynamicType]);
+ var left = _interfaceType(M, typeArguments: [dynamicType]);
+ var right = _interfaceType(L, typeArguments: [intType]);
+ var bottom = _interfaceType(M, typeArguments: [intType]);
_checkLattice(top, left, right, bottom);
}
@@ -2810,36 +3181,36 @@
}
void test_named_optional() {
- DartType r =
- TypeBuilder.function(required: <DartType>[intType], result: intType);
- DartType o = TypeBuilder.function(
- required: <DartType>[], optional: <DartType>[intType], result: intType);
- DartType n = TypeBuilder.function(
- required: <DartType>[],
- named: <String, DartType>{'x': intType},
- result: intType);
- DartType rr = TypeBuilder.function(
- required: <DartType>[intType, intType], result: intType);
- DartType ro = TypeBuilder.function(
- required: <DartType>[intType],
- optional: <DartType>[intType],
- result: intType);
- DartType rn = TypeBuilder.function(
- required: <DartType>[intType],
- named: <String, DartType>{'x': intType},
- result: intType);
- DartType oo = TypeBuilder.function(
- required: <DartType>[],
- optional: <DartType>[intType, intType],
- result: intType);
- DartType nn = TypeBuilder.function(
- required: <DartType>[],
- named: <String, DartType>{'x': intType, 'y': intType},
- result: intType);
- DartType nnn = TypeBuilder.function(
- required: <DartType>[],
- named: <String, DartType>{'x': intType, 'y': intType, 'z': intType},
- result: intType);
+ var r = _functionType(required: [intType], returns: intType);
+ var o = _functionType(optional: [intType], returns: intType);
+ var n = _functionType(named: {'x': intType}, returns: intType);
+
+ var rr = _functionType(
+ required: [intType, intType],
+ returns: intType,
+ );
+ var ro = _functionType(
+ required: [intType],
+ optional: [intType],
+ returns: intType,
+ );
+ var rn = _functionType(
+ required: [intType],
+ named: {'x': intType},
+ returns: intType,
+ );
+ var oo = _functionType(
+ optional: [intType, intType],
+ returns: intType,
+ );
+ var nn = _functionType(
+ named: {'x': intType, 'y': intType},
+ returns: intType,
+ );
+ var nnn = _functionType(
+ named: {'x': intType, 'y': intType, 'z': intType},
+ returns: intType,
+ );
_checkGroups(r,
equivalents: [r],
@@ -2882,36 +3253,29 @@
}
void test_simple_function() {
- FunctionType top =
- TypeBuilder.function(required: <DartType>[intType], result: objectType);
- FunctionType left =
- TypeBuilder.function(required: <DartType>[intType], result: intType);
- FunctionType right = TypeBuilder.function(
- required: <DartType>[objectType], result: objectType);
- FunctionType bottom =
- TypeBuilder.function(required: <DartType>[objectType], result: intType);
+ var top = _functionType(required: [intType], returns: objectType);
+ var left = _functionType(required: [intType], returns: intType);
+ var right = _functionType(required: [objectType], returns: objectType);
+ var bottom = _functionType(required: [objectType], returns: intType);
_checkLattice(top, left, right, bottom);
}
/// Regression test for https://github.com/dart-lang/sdk/issues/25069
void test_simple_function_void() {
- FunctionType functionType =
- TypeBuilder.function(required: <DartType>[intType], result: objectType);
+ var functionType = _functionType(required: [intType], returns: objectType);
_checkIsNotSubtypeOf(voidType, functionType);
}
void test_void_functions() {
- FunctionType top =
- TypeBuilder.function(required: <DartType>[intType], result: voidType);
- FunctionType bottom =
- TypeBuilder.function(required: <DartType>[objectType], result: intType);
+ var top = _functionType(required: [intType], returns: voidType);
+ var bottom = _functionType(required: [objectType], returns: intType);
_checkIsStrictSubtypeOf(bottom, top);
}
void test_void_isTop() {
- DartType interfaceType = ElementFactory.classElement2('A', []).type;
+ var A = _class(name: 'A');
List<DartType> equivalents = <DartType>[dynamicType, objectType, voidType];
List<DartType> subtypes = <DartType>[
intType,
@@ -2919,47 +3283,14 @@
numType,
stringType,
functionType,
- interfaceType,
+ _interfaceType(A),
bottomType
];
_checkGroups(voidType, equivalents: equivalents, subtypes: subtypes);
}
}
-class SubtypingTestBase {
- TypeProvider typeProvider;
- TypeSystem typeSystem;
-
- DartType get bottomType => typeProvider.bottomType;
-
- InterfaceType get doubleType => typeProvider.doubleType;
-
- DartType get dynamicType => typeProvider.dynamicType;
-
- InterfaceType get functionType => typeProvider.functionType;
-
- InterfaceType get futureOrType => typeProvider.futureOrType;
-
- InterfaceType get intType => typeProvider.intType;
-
- InterfaceType get listType => typeProvider.listType;
-
- DartType get nullType => typeProvider.nullType;
-
- InterfaceType get numType => typeProvider.numType;
-
- InterfaceType get objectType => typeProvider.objectType;
-
- InterfaceType get stringType => typeProvider.stringType;
-
- DartType get voidType => VoidTypeImpl.instance;
-
- void setUp() {
- var analysisContext = TestAnalysisContext();
- typeProvider = analysisContext.typeProvider;
- typeSystem = analysisContext.typeSystem;
- }
-
+class SubtypingTestBase extends AbstractTypeSystemTest {
void _checkEquivalent(DartType type1, DartType type2) {
_checkIsSubtypeOf(type1, type2);
_checkIsSubtypeOf(type2, type1);
@@ -3033,50 +3364,25 @@
}
}
-class TypeBuilder {
- static FunctionTypeImpl function(
- {List<DartType> types,
- List<DartType> required,
- List<DartType> optional,
- Map<String, DartType> named,
- DartType result}) {
- result = result ?? VoidTypeImpl.instance;
- required = required ?? [];
- FunctionElementImpl f = ElementFactory.functionElement8(required, result,
- optional: optional, named: named);
- if (types != null) {
- f.typeParameters =
- new List<TypeParameterElement>.from(types.map((t) => t.element));
- }
- return f.type = new FunctionTypeImpl(f);
- }
-
- static TypeParameterType variable(String name, {DartType bound}) =>
- ElementFactory.typeParameterWithType(name, bound).type;
-}
-
@reflectiveTest
class TypeSystemTest extends AbstractTypeSystemTest {
InterfaceTypeImpl get functionClassTypeNone {
- return InterfaceTypeImpl.explicit(
+ return _interfaceType(
typeProvider.functionType.element,
- const <DartType>[],
nullabilitySuffix: NullabilitySuffix.none,
);
}
InterfaceTypeImpl get functionClassTypeQuestion {
- return InterfaceTypeImpl.explicit(
+ return _interfaceType(
typeProvider.functionType.element,
- const <DartType>[],
nullabilitySuffix: NullabilitySuffix.question,
);
}
InterfaceTypeImpl get functionClassTypeStar {
- return InterfaceTypeImpl.explicit(
+ return _interfaceType(
typeProvider.functionType.element,
- const <DartType>[],
nullabilitySuffix: NullabilitySuffix.star,
);
}
@@ -3085,28 +3391,22 @@
.withNullability(NullabilitySuffix.none);
FunctionTypeImpl get nothingToVoidFunctionTypeNone {
- return FunctionTypeImpl.synthetic(
- voidType,
- const <TypeParameterElement>[],
- const <ParameterElement>[],
+ return _functionType(
+ returns: voidType,
nullabilitySuffix: NullabilitySuffix.none,
);
}
FunctionTypeImpl get nothingToVoidFunctionTypeQuestion {
- return FunctionTypeImpl.synthetic(
- voidType,
- const <TypeParameterElement>[],
- const <ParameterElement>[],
+ return _functionType(
+ returns: voidType,
nullabilitySuffix: NullabilitySuffix.question,
);
}
FunctionTypeImpl get nothingToVoidFunctionTypeStar {
- return FunctionTypeImpl.synthetic(
- voidType,
- const <TypeParameterElement>[],
- const <ParameterElement>[],
+ return _functionType(
+ returns: voidType,
nullabilitySuffix: NullabilitySuffix.star,
);
}
@@ -3127,79 +3427,76 @@
.withNullability(NullabilitySuffix.star);
InterfaceTypeImpl get stringClassTypeNone {
- return InterfaceTypeImpl.explicit(
+ return _interfaceType(
typeProvider.stringType.element,
- const <DartType>[],
nullabilitySuffix: NullabilitySuffix.none,
);
}
InterfaceTypeImpl get stringClassTypeQuestion {
- return InterfaceTypeImpl.explicit(
+ return _interfaceType(
typeProvider.stringType.element,
- const <DartType>[],
nullabilitySuffix: NullabilitySuffix.question,
);
}
InterfaceTypeImpl get stringClassTypeStar {
- return InterfaceTypeImpl.explicit(
+ return _interfaceType(
typeProvider.stringType.element,
- const <DartType>[],
nullabilitySuffix: NullabilitySuffix.star,
);
}
InterfaceTypeImpl futureOrTypeNone({@required DartType argument}) {
- var element = typeProvider.futureOrType.element;
- return InterfaceTypeImpl.explicit(
+ var element = typeProvider.futureOrElement;
+ return _interfaceType(
element,
- <DartType>[argument],
+ typeArguments: <DartType>[argument],
nullabilitySuffix: NullabilitySuffix.none,
);
}
InterfaceTypeImpl futureOrTypeQuestion({@required DartType argument}) {
- var element = typeProvider.futureOrType.element;
- return InterfaceTypeImpl.explicit(
+ var element = typeProvider.futureOrElement;
+ return _interfaceType(
element,
- <DartType>[argument],
+ typeArguments: <DartType>[argument],
nullabilitySuffix: NullabilitySuffix.question,
);
}
InterfaceTypeImpl futureOrTypeStar({@required DartType argument}) {
- var element = typeProvider.futureOrType.element;
- return InterfaceTypeImpl.explicit(
+ var element = typeProvider.futureOrElement;
+ return _interfaceType(
element,
- <DartType>[argument],
+ typeArguments: <DartType>[argument],
nullabilitySuffix: NullabilitySuffix.star,
);
}
InterfaceTypeImpl listClassTypeNone(DartType argument) {
- var element = typeProvider.listType.element;
- return InterfaceTypeImpl.explicit(
+ var element = typeProvider.listElement;
+ return _interfaceType(
element,
- <DartType>[argument],
+ typeArguments: <DartType>[argument],
nullabilitySuffix: NullabilitySuffix.none,
);
}
InterfaceTypeImpl listClassTypeQuestion(DartType argument) {
- var element = typeProvider.listType.element;
- return InterfaceTypeImpl.explicit(
+ var element = typeProvider.listElement;
+ return _interfaceType(
element,
- <DartType>[argument],
+ typeArguments: <DartType>[argument],
nullabilitySuffix: NullabilitySuffix.question,
);
}
InterfaceTypeImpl listClassTypeStar(DartType argument) {
- var element = typeProvider.listType.element;
- return InterfaceTypeImpl.explicit(
+ var element = typeProvider.listElement;
+ return _interfaceType(
element,
- <DartType>[argument],
+ typeArguments: <DartType>[argument],
nullabilitySuffix: NullabilitySuffix.star,
);
}
@@ -3808,27 +4105,24 @@
}
DartType typeParameterTypeNone({@required DartType bound}) {
- var element = TypeParameterElementImpl.synthetic('T');
- element.bound = bound;
- return TypeParameterTypeImpl(
+ var element = _typeParameter('T', bound: bound);
+ return _typeParameterType(
element,
nullabilitySuffix: NullabilitySuffix.none,
);
}
DartType typeParameterTypeQuestion({@required DartType bound}) {
- var element = TypeParameterElementImpl.synthetic('T');
- element.bound = bound;
- return TypeParameterTypeImpl(
+ var element = _typeParameter('T', bound: bound);
+ return _typeParameterType(
element,
nullabilitySuffix: NullabilitySuffix.question,
);
}
DartType typeParameterTypeStar({@required DartType bound}) {
- var element = TypeParameterElementImpl.synthetic('T');
- element.bound = bound;
- return TypeParameterTypeImpl(
+ var element = _typeParameter('T', bound: bound);
+ return _typeParameterType(
element,
nullabilitySuffix: NullabilitySuffix.star,
);
diff --git a/pkg/analyzer/test/src/dart/analysis/driver_resolution_test.dart b/pkg/analyzer/test/src/dart/analysis/driver_resolution_test.dart
index 0d03acf..35828ff 100644
--- a/pkg/analyzer/test/src/dart/analysis/driver_resolution_test.dart
+++ b/pkg/analyzer/test/src/dart/analysis/driver_resolution_test.dart
@@ -8,6 +8,7 @@
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/ast/token.dart';
import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/dart/element/nullability_suffix.dart';
import 'package:analyzer/dart/element/type.dart';
import 'package:analyzer/src/dart/analysis/driver.dart';
import 'package:analyzer/src/dart/analysis/experiments.dart';
@@ -22,6 +23,7 @@
import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
+import '../../../generated/elements_types_mixin.dart';
import '../../../utils.dart';
import 'base.dart';
@@ -42,7 +44,8 @@
* Integration tests for resolution.
*/
@reflectiveTest
-class AnalysisDriverResolutionTest extends BaseAnalysisDriverTest {
+class AnalysisDriverResolutionTest extends BaseAnalysisDriverTest
+ with ElementsTypesMixin {
ResolvedUnitResult result;
FindNode findNode;
FindElement findElement;
@@ -55,17 +58,15 @@
DynamicTypeImpl get dynamicType => DynamicTypeImpl.instance;
- ClassElement get futureElement => typeProvider.futureType.element;
+ ClassElement get futureElement => typeProvider.futureElement;
ClassElement get intElement => typeProvider.intType.element;
InterfaceType get intType => typeProvider.intType;
- ClassElement get listElement => typeProvider.listType.element;
+ ClassElement get listElement => typeProvider.listElement;
- ClassElement get mapElement => typeProvider.mapType.element;
-
- InterfaceType get mapType => typeProvider.mapType;
+ ClassElement get mapElement => typeProvider.mapElement;
ClassElement get numElement => typeProvider.numType.element;
@@ -716,7 +717,7 @@
PrefixedIdentifier prefixed = annotation.name;
expect(prefixed.prefix.staticElement, same(aClass));
- expect(prefixed.prefix.staticType, aClass.type);
+ expect(prefixed.prefix.staticType, interfaceType(aClass));
expect(prefixed.identifier.staticElement, same(aGetter));
expect(prefixed.identifier.staticType, typeProvider.intType);
@@ -776,7 +777,7 @@
PrefixedIdentifier prefixed = annotation.name;
expect(prefixed.prefix.staticElement, same(aClass));
- expect(prefixed.prefix.staticType, aClass.type);
+ expect(prefixed.prefix.staticType, interfaceType(aClass));
expect(prefixed.identifier.staticElement, same(constructor));
expect(
@@ -814,10 +815,10 @@
expect(atD.element, constructorD);
expect(constC.staticElement, constructorC);
- expect(constC.staticType, elementC.type);
+ expect(constC.staticType, interfaceType(elementC));
expect(constC.constructorName.staticElement, constructorC);
- expect(constC.constructorName.type.type, elementC.type);
+ expect(constC.constructorName.type.type, interfaceType(elementC));
}
test_annotation_unprefixed_topLevelVariable() async {
@@ -1448,11 +1449,11 @@
expect(constructorName.staticElement, same(aUnnamed));
TypeName typeName = constructorName.type;
- expect(typeName.type, aElement.type);
+ expect(typeName.type, interfaceType(aElement));
SimpleIdentifier identifier = typeName.name;
expect(identifier.staticElement, same(aElement));
- expect(identifier.staticType, aElement.type);
+ expect(identifier.staticType, interfaceType(aElement));
expect(constructorName.name, isNull);
}
@@ -1468,11 +1469,11 @@
expect(constructorName.staticElement, same(aNamed));
TypeName typeName = constructorName.type;
- expect(typeName.type, aElement.type);
+ expect(typeName.type, interfaceType(aElement));
SimpleIdentifier identifier = typeName.name;
expect(identifier.staticElement, same(aElement));
- expect(identifier.staticType, aElement.type);
+ expect(identifier.staticType, interfaceType(aElement));
expect(constructorName.name.staticElement, aNamed);
expect(constructorName.name.staticType, isNull);
@@ -1497,8 +1498,12 @@
ClassElement aElement = aNode.declaredElement;
ClassDeclaration bNode = result.unit.declarations[1];
- TypeParameterType uType = bNode.declaredElement.typeParameters[0].type;
- InterfaceType auType = aElement.type.instantiate([uType]);
+ TypeParameterType uType =
+ typeParameterType(bNode.declaredElement.typeParameters[0]);
+ InterfaceType auType = aElement.instantiate(
+ typeArguments: [uType],
+ nullabilitySuffix: NullabilitySuffix.star,
+ );
{
ConstructorElement expectedElement = aElement.constructors[0];
@@ -1872,7 +1877,7 @@
FieldDeclaration fDeclaration = cNode.members[0];
VariableDeclaration fNode = fDeclaration.fields.variables[0];
FieldElement fElement = fNode.declaredElement;
- expect(fElement.type, typeProvider.listType.instantiate([tElement.type]));
+ expect(fElement.type, typeProvider.listType2(typeParameterType(tElement)));
}
test_field_generic() async {
@@ -2146,8 +2151,7 @@
var typeProvider = unit.declaredElement.context.typeProvider;
InterfaceType intType = typeProvider.intType;
- InterfaceType listType = typeProvider.listType;
- InterfaceType listIntType = listType.instantiate([intType]);
+ InterfaceType listIntType = typeProvider.listType2(intType);
List<Statement> mainStatements = _getMainStatements(result);
@@ -2195,14 +2199,14 @@
VariableDeclaration aNode = aDeclaration.variables.variables[0];
InstanceCreationExpression value = aNode.initializer;
expect(value.staticElement, defaultConstructor);
- expect(value.staticType, cElement.type);
+ expect(value.staticType, interfaceType(cElement));
TypeName typeName = value.constructorName.type;
expect(typeName.typeArguments, isNull);
Identifier typeIdentifier = typeName.name;
expect(typeIdentifier.staticElement, cElement);
- expect(typeIdentifier.staticType, cElement.type);
+ expect(typeIdentifier.staticType, interfaceType(cElement));
expect(value.constructorName.name, isNull);
}
@@ -2212,14 +2216,14 @@
VariableDeclaration bNode = bDeclaration.variables.variables[0];
InstanceCreationExpression value = bNode.initializer;
expect(value.staticElement, namedConstructor);
- expect(value.staticType, cElement.type);
+ expect(value.staticType, interfaceType(cElement));
TypeName typeName = value.constructorName.type;
expect(typeName.typeArguments, isNull);
SimpleIdentifier typeIdentifier = typeName.name;
expect(typeIdentifier.staticElement, cElement);
- expect(typeIdentifier.staticType, cElement.type);
+ expect(typeIdentifier.staticType, interfaceType(cElement));
SimpleIdentifier constructorName = value.constructorName.name;
expect(constructorName.staticElement, namedConstructor);
@@ -2248,14 +2252,14 @@
InstanceCreationExpression creation = vNode.initializer;
List<Expression> arguments = creation.argumentList.arguments;
expect(creation.staticElement, constructorElement);
- expect(creation.staticType, xElement.type);
+ expect(creation.staticType, interfaceType(xElement));
TypeName typeName = creation.constructorName.type;
expect(typeName.typeArguments, isNull);
Identifier typeIdentifier = typeName.name;
expect(typeIdentifier.staticElement, xElement);
- expect(typeIdentifier.staticType, xElement.type);
+ expect(typeIdentifier.staticType, interfaceType(xElement));
expect(creation.constructorName.name, isNull);
@@ -2288,14 +2292,14 @@
VariableDeclaration aNode = aDeclaration.variables.variables[0];
InstanceCreationExpression value = aNode.initializer;
expect(value.staticElement, defaultConstructor);
- expect(value.staticType, cElement.type);
+ expect(value.staticType, interfaceType(cElement));
TypeName typeName = value.constructorName.type;
expect(typeName.typeArguments, isNull);
Identifier typeIdentifier = typeName.name;
expect(typeIdentifier.staticElement, cElement);
- expect(typeIdentifier.staticType, cElement.type);
+ expect(typeIdentifier.staticType, interfaceType(cElement));
expect(value.constructorName.name, isNull);
@@ -2308,14 +2312,14 @@
VariableDeclaration bNode = bDeclaration.variables.variables[0];
InstanceCreationExpression value = bNode.initializer;
expect(value.staticElement, namedConstructor);
- expect(value.staticType, cElement.type);
+ expect(value.staticType, interfaceType(cElement));
TypeName typeName = value.constructorName.type;
expect(typeName.typeArguments, isNull);
SimpleIdentifier typeIdentifier = typeName.name;
expect(typeIdentifier.staticElement, cElement);
- expect(typeIdentifier.staticType, cElement.type);
+ expect(typeIdentifier.staticType, interfaceType(cElement));
SimpleIdentifier constructorName = value.constructorName.name;
expect(constructorName.staticElement, namedConstructor);
@@ -2351,12 +2355,17 @@
ClassElement cElement = aLibrary.getType('C');
ConstructorElement defaultConstructor = cElement.constructors[0];
ConstructorElement namedConstructor = cElement.constructors[1];
- InterfaceType cType = cElement.type;
- var cTypeDynamic = cType.instantiate([DynamicTypeImpl.instance]);
+ InterfaceType cTypeDynamic = cElement.instantiate(
+ typeArguments: [DynamicTypeImpl.instance],
+ nullabilitySuffix: NullabilitySuffix.star,
+ );
var statements = _getMainStatements(result);
{
- var cTypeInt = cType.instantiate([typeProvider.intType]);
+ var cTypeInt = cElement.instantiate(
+ typeArguments: [typeProvider.intType],
+ nullabilitySuffix: NullabilitySuffix.star,
+ );
ExpressionStatement statement = statements[0];
InstanceCreationExpression creation = statement.expression;
@@ -2381,7 +2390,10 @@
}
{
- var cTypeDouble = cType.instantiate([typeProvider.doubleType]);
+ var cTypeDouble = cElement.instantiate(
+ typeArguments: [typeProvider.doubleType],
+ nullabilitySuffix: NullabilitySuffix.star,
+ );
ExpressionStatement statement = statements[1];
InstanceCreationExpression creation = statement.expression;
@@ -2408,7 +2420,10 @@
}
{
- var cTypeBool = cType.instantiate([typeProvider.boolType]);
+ var cTypeBool = cElement.instantiate(
+ typeArguments: [typeProvider.boolType],
+ nullabilitySuffix: NullabilitySuffix.star,
+ );
ExpressionStatement statement = statements[2];
InstanceCreationExpression creation = statement.expression;
@@ -2460,7 +2475,7 @@
ClassElement cElement = unitElement.getType('C');
ConstructorElement defaultConstructor = cElement.constructors[0];
ConstructorElement namedConstructor = cElement.constructors[1];
- InterfaceType cType = cElement.type;
+ InterfaceType cType = interfaceType(cElement);
var statements = _getMainStatements(result);
{
@@ -4161,7 +4176,7 @@
TypeName fReturnTypeNode = fNode.returnType;
expect(fReturnTypeNode.name.staticElement, same(tElement));
- expect(fReturnTypeNode.type, tElement.type);
+ expect(fReturnTypeNode.type, typeParameterType(tElement));
expect(fExpression.declaredElement, same(fElement));
@@ -4176,13 +4191,13 @@
name: 'a',
offset: 28,
kind: ParameterKind.REQUIRED,
- type: tElement.type);
+ type: typeParameterType(tElement));
_assertSimpleParameter(nodes[1], parameters[1],
name: 'b',
offset: 33,
kind: ParameterKind.REQUIRED,
- type: uElement.type);
+ type: typeParameterType(uElement));
var aRef = findNode.simple('a;');
assertElement(aRef, parameters[0]);
@@ -5209,10 +5224,8 @@
{
ExpressionStatement statement = statements[0];
SetOrMapLiteral mapLiteral = statement.expression;
- expect(
- mapLiteral.staticType,
- typeProvider.mapType
- .instantiate([typeProvider.intType, typeProvider.doubleType]));
+ expect(mapLiteral.staticType,
+ typeProvider.mapType2(typeProvider.intType, typeProvider.doubleType));
}
{
@@ -5220,8 +5233,8 @@
SetOrMapLiteral mapLiteral = statement.expression;
expect(
mapLiteral.staticType,
- typeProvider.mapType
- .instantiate([typeProvider.boolType, typeProvider.stringType]));
+ typeProvider.mapType2(
+ typeProvider.boolType, typeProvider.stringType));
}
}
@@ -5722,7 +5735,7 @@
SimpleIdentifier target = invocation.target;
expect(target.staticElement, same(cElement));
- expect(target.staticType, same(cElement.type));
+ expect(target.staticType, interfaceType(cElement));
var invokeTypeStr = 'void Function(int)';
expect(invocation.staticType.toString(), 'void');
@@ -6376,7 +6389,7 @@
SimpleIdentifier prefix = prefixed.prefix;
expect(prefix.staticElement, same(vElement));
- expect(prefix.staticType, cElement.type);
+ expect(prefix.staticType, interfaceType(cElement));
SimpleIdentifier identifier = prefixed.identifier;
expect(identifier.staticElement, same(fElement.getter));
@@ -6407,7 +6420,7 @@
SimpleIdentifier prefix = prefixed.prefix;
expect(prefix.staticElement, same(cElement));
- expect(prefix.staticType, cElement.type);
+ expect(prefix.staticType, interfaceType(cElement));
SimpleIdentifier identifier = prefixed.identifier;
expect(identifier.staticElement, same(fElement.getter));
@@ -6704,7 +6717,7 @@
InstanceCreationExpression newC = access.target;
expect(newC.staticElement, cClassElement.unnamedConstructor);
- expect(newC.staticType, cClassElement.type);
+ expect(newC.staticType, interfaceType(cClassElement));
expect(access.propertyName.staticElement, same(fElement.getter));
expect(access.propertyName.staticType, typeProvider.intType);
@@ -6739,7 +6752,7 @@
InstanceCreationExpression newC = access.target;
expect(newC.staticElement, cClassElement.unnamedConstructor);
- expect(newC.staticType, cClassElement.type);
+ expect(newC.staticType, interfaceType(cClassElement));
expect(access.propertyName.staticElement, same(fElement.getter));
expect(access.propertyName.staticType, typeProvider.intType);
@@ -6905,7 +6918,7 @@
MethodInvocation invocation = statement.expression;
SuperExpression target = invocation.target;
- expect(target.staticType, bNode.declaredElement.type); // raw
+ expect(target.staticType, interfaceType(bNode.declaredElement)); // raw
expect(invocation.methodName.staticElement, same(methodElement));
}
@@ -6926,7 +6939,7 @@
expect(propertyAccess.staticType, typeProvider.intType);
SuperExpression target = propertyAccess.target;
- expect(target.staticType, bNode.declaredElement.type); // raw
+ expect(target.staticType, interfaceType(bNode.declaredElement)); // raw
expect(propertyAccess.propertyName.staticElement, same(getterElement));
expect(propertyAccess.propertyName.staticType, typeProvider.intType);
@@ -6950,7 +6963,7 @@
PropertyAccess propertyAccess = assignment.leftHandSide;
SuperExpression target = propertyAccess.target;
- expect(target.staticType, bNode.declaredElement.type); // raw
+ expect(target.staticType, interfaceType(bNode.declaredElement)); // raw
expect(propertyAccess.propertyName.staticElement, same(setterElement));
expect(propertyAccess.propertyName.staticType, typeProvider.intType);
@@ -6962,7 +6975,7 @@
BinaryExpression binary = statement.expression;
ThisExpression target = binary.leftOperand;
- expect(target.staticType, bNode.declaredElement.type); // raw
+ expect(target.staticType, interfaceType(bNode.declaredElement)); // raw
expect(binary.staticElement, same(operatorElement));
expect(binary.staticType, typeProvider.intType);
@@ -7001,6 +7014,9 @@
BlockFunctionBody testBody = testNode.body;
List<Statement> testStatements = testBody.block.statements;
+ var elementA = findElement.class_('A');
+ var thisTypeA = interfaceType(elementA);
+
// method(1);
{
ExpressionStatement statement = testStatements[0];
@@ -7017,7 +7033,7 @@
MethodInvocation invocation = statement.expression;
ThisExpression target = invocation.target;
- expect(target.staticType, aNode.declaredElement.type); // raw
+ expect(target.staticType, thisTypeA); // raw
expect(invocation.methodName.staticElement, same(methodElement));
}
@@ -7038,7 +7054,7 @@
expect(propertyAccess.staticType, typeProvider.intType);
ThisExpression target = propertyAccess.target;
- expect(target.staticType, aNode.declaredElement.type); // raw
+ expect(target.staticType, thisTypeA); // raw
expect(propertyAccess.propertyName.staticElement, same(getterElement));
expect(propertyAccess.propertyName.staticType, typeProvider.intType);
@@ -7062,7 +7078,7 @@
PropertyAccess propertyAccess = assignment.leftHandSide;
ThisExpression target = propertyAccess.target;
- expect(target.staticType, aNode.declaredElement.type); // raw
+ expect(target.staticType, thisTypeA); // raw
expect(propertyAccess.propertyName.staticElement, same(setterElement));
expect(propertyAccess.propertyName.staticType, typeProvider.intType);
@@ -7074,7 +7090,7 @@
BinaryExpression binary = statement.expression;
ThisExpression target = binary.leftOperand;
- expect(target.staticType, aNode.declaredElement.type); // raw
+ expect(target.staticType, thisTypeA); // raw
expect(binary.staticElement, same(operatorElement));
expect(binary.staticType, typeProvider.intType);
@@ -7152,8 +7168,10 @@
expect(dName.staticType, typeProvider.typeType);
{
- var aRawType = aElement.type;
- var expectedType = aRawType.instantiate([typeProvider.boolType]);
+ var expectedType = aElement.instantiate(
+ typeArguments: [typeProvider.boolType],
+ nullabilitySuffix: NullabilitySuffix.star,
+ );
TypeName superClass = dNode.extendsClause.superclass;
expect(superClass.type, expectedType);
@@ -7164,8 +7182,10 @@
}
{
- var bRawType = bElement.type;
- var expectedType = bRawType.instantiate([typeProvider.intType]);
+ var expectedType = bElement.instantiate(
+ typeArguments: [typeProvider.intType],
+ nullabilitySuffix: NullabilitySuffix.star,
+ );
TypeName mixinType = dNode.withClause.mixinTypes[0];
expect(mixinType.type, expectedType);
@@ -7176,8 +7196,10 @@
}
{
- var cRawType = cElement.type;
- var expectedType = cRawType.instantiate([typeProvider.doubleType]);
+ var expectedType = cElement.instantiate(
+ typeArguments: [typeProvider.doubleType],
+ nullabilitySuffix: NullabilitySuffix.star,
+ );
TypeName implementedType = dNode.implementsClause.interfaces[0];
expect(implementedType.type, expectedType);
@@ -7215,8 +7237,10 @@
expect(dName.staticType, typeProvider.typeType);
{
- var aRawType = aElement.type;
- var expectedType = aRawType.instantiate([typeProvider.boolType]);
+ var expectedType = aElement.instantiate(
+ typeArguments: [typeProvider.boolType],
+ nullabilitySuffix: NullabilitySuffix.star,
+ );
TypeName superClass = dNode.superclass;
expect(superClass.type, expectedType);
@@ -7227,8 +7251,10 @@
}
{
- var bRawType = bElement.type;
- var expectedType = bRawType.instantiate([typeProvider.intType]);
+ var expectedType = bElement.instantiate(
+ typeArguments: [typeProvider.intType],
+ nullabilitySuffix: NullabilitySuffix.star,
+ );
TypeName mixinType = dNode.withClause.mixinTypes[0];
expect(mixinType.type, expectedType);
@@ -7239,8 +7265,10 @@
}
{
- var cRawType = cElement.type;
- var expectedType = cRawType.instantiate([typeProvider.doubleType]);
+ var expectedType = cElement.instantiate(
+ typeArguments: [typeProvider.doubleType],
+ nullabilitySuffix: NullabilitySuffix.star,
+ );
TypeName interfaceType = dNode.implementsClause.interfaces[0];
expect(interfaceType.type, expectedType);
@@ -7272,7 +7300,7 @@
var aNode = enumNode.constants[0];
expect(aNode.declaredElement, same(aElement));
expect(aNode.name.staticElement, same(aElement));
- expect(aNode.name.staticType, same(enumElement.type));
+ expect(aNode.name.staticType, interfaceType(enumElement));
}
{
@@ -7280,7 +7308,7 @@
var bNode = enumNode.constants[1];
expect(bNode.declaredElement, same(bElement));
expect(bNode.name.staticElement, same(bElement));
- expect(bNode.name.staticType, same(enumElement.type));
+ expect(bNode.name.staticType, interfaceType(enumElement));
}
}
@@ -7557,11 +7585,11 @@
TypeName typeName = bDeclaration.fields.type;
SimpleIdentifier typeIdentifier = typeName.name;
expect(typeIdentifier.staticElement, same(tElement));
- expect(typeIdentifier.staticType, tElement.type);
+ expect(typeIdentifier.staticType, typeParameterType(tElement));
VariableDeclaration bNode = bDeclaration.fields.variables[0];
expect(bNode.declaredElement, same(bElement));
- expect(bElement.type, tElement.type);
+ expect(bElement.type, typeParameterType(tElement));
expect(bNode.name.staticElement, same(bElement));
expect(bNode.name.staticType, same(bElement.type));
}
@@ -7803,7 +7831,7 @@
name: 'b',
offset: 27,
kind: ParameterKind.REQUIRED,
- type: aliasElement.typeParameters[0].type);
+ type: typeParameterType(aliasElement.typeParameters[0]));
}
test_top_typeParameter() async {
@@ -7830,16 +7858,19 @@
expect(tNode.declaredElement, same(cElement.typeParameters[0]));
TypeName bound = tNode.bound;
- expect(bound.type, aElement.type);
+ expect(bound.type, interfaceType(aElement));
SimpleIdentifier boundIdentifier = bound.name;
expect(boundIdentifier.staticElement, same(aElement));
- expect(boundIdentifier.staticType, aElement.type);
+ expect(boundIdentifier.staticType, interfaceType(aElement));
}
{
- var listElement = typeProvider.listType.element;
- var listOfA = typeProvider.listType.instantiate([aElement.type]);
+ var listElement = typeProvider.listElement;
+ var listOfA = listElement.instantiate(
+ typeArguments: [interfaceType(aElement)],
+ nullabilitySuffix: NullabilitySuffix.star,
+ );
TypeParameter uNode = cNode.typeParameters.typeParameters[1];
expect(uNode.declaredElement, same(cElement.typeParameters[1]));
@@ -7852,11 +7883,11 @@
expect(listIdentifier.staticType, listOfA);
TypeName aTypeName = bound.typeArguments.arguments[0];
- expect(aTypeName.type, aElement.type);
+ expect(aTypeName.type, interfaceType(aElement));
SimpleIdentifier aIdentifier = aTypeName.name;
expect(aIdentifier.staticElement, same(aElement));
- expect(aIdentifier.staticType, aElement.type);
+ expect(aIdentifier.staticType, interfaceType(aElement));
}
{
@@ -8358,7 +8389,7 @@
ExpressionStatement statement = statements[0];
InstanceCreationExpression creation = statement.expression;
- expect(creation.staticType, randomElement.type);
+ expect(creation.staticType, interfaceType(randomElement));
ConstructorName constructorName = creation.constructorName;
@@ -8901,8 +8932,6 @@
}
fail('Not found $name');
}
-
-// String _p(String path) => convertPath(path);
}
/**
diff --git a/pkg/analyzer/test/src/dart/analysis/index_test.dart b/pkg/analyzer/test/src/dart/analysis/index_test.dart
index 38f6ff8..c83c483 100644
--- a/pkg/analyzer/test/src/dart/analysis/index_test.dart
+++ b/pkg/analyzer/test/src/dart/analysis/index_test.dart
@@ -67,6 +67,19 @@
return imports[index].importedLibrary.definingCompilationUnit;
}
+ test_fieldFormalParameter_noSuchField() async {
+ await _indexTestUnit('''
+class B<T> {
+ B({this.x}) {}
+
+ foo() {
+ B<int>(x: 1);
+ }
+}
+''');
+ // No exceptions.
+ }
+
test_hasAncestor_ClassDeclaration() async {
await _indexTestUnit('''
class A {}
diff --git a/pkg/analyzer/test/src/dart/ast/utilities_test.dart b/pkg/analyzer/test/src/dart/ast/utilities_test.dart
index 0a8e03d..88f8e7a 100644
--- a/pkg/analyzer/test/src/dart/ast/utilities_test.dart
+++ b/pkg/analyzer/test/src/dart/ast/utilities_test.dart
@@ -11,12 +11,15 @@
import 'package:analyzer/src/dart/ast/utilities.dart';
import 'package:analyzer/src/dart/element/element.dart';
import 'package:analyzer/src/generated/java_core.dart';
+import 'package:analyzer/src/generated/resolver.dart';
import 'package:analyzer/src/generated/testing/ast_test_factory.dart';
import 'package:analyzer/src/generated/testing/element_factory.dart';
+import 'package:analyzer/src/generated/testing/test_type_provider.dart';
import 'package:analyzer/src/generated/testing/token_factory.dart';
import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
+import '../../../generated/elements_types_mixin.dart';
import '../../../generated/parser_test.dart' show ParserTestCase;
import '../../../generated/test_support.dart';
import '../../../util/ast_type_matchers.dart';
@@ -130,7 +133,9 @@
}
@reflectiveTest
-class ResolutionCopierTest extends EngineTestCase {
+class ResolutionCopierTest with ElementsTypesMixin {
+ final TypeProvider typeProvider = TestTypeProvider();
+
void test_visitAdjacentStrings() {
AdjacentStrings createNode() => astFactory.adjacentStrings([
astFactory.simpleStringLiteral(null, 'hello'),
@@ -138,7 +143,7 @@
]);
AdjacentStrings fromNode = createNode();
- DartType staticType = ElementFactory.classElement2("B").type;
+ DartType staticType = interfaceType(ElementFactory.classElement2('B'));
fromNode.staticType = staticType;
AdjacentStrings toNode = createNode();
@@ -161,7 +166,7 @@
void test_visitAsExpression() {
AsExpression fromNode = AstTestFactory.asExpression(
AstTestFactory.identifier3("x"), AstTestFactory.typeName4("A"));
- DartType staticType = ElementFactory.classElement2("B").type;
+ DartType staticType = interfaceType(ElementFactory.classElement2('B'));
fromNode.staticType = staticType;
AsExpression toNode = AstTestFactory.asExpression(
AstTestFactory.identifier3("x"), AstTestFactory.typeName4("A"));
@@ -174,7 +179,7 @@
AstTestFactory.identifier3("a"),
TokenType.PLUS_EQ,
AstTestFactory.identifier3("b"));
- DartType staticType = ElementFactory.classElement2("C").type;
+ DartType staticType = interfaceType(ElementFactory.classElement2('C'));
MethodElement staticElement = ElementFactory.methodElement("+", staticType);
fromNode.staticElement = staticElement;
fromNode.staticType = staticType;
@@ -192,7 +197,7 @@
AstTestFactory.identifier3("a"),
TokenType.PLUS,
AstTestFactory.identifier3("b"));
- DartType staticType = ElementFactory.classElement2("C").type;
+ DartType staticType = interfaceType(ElementFactory.classElement2('C'));
MethodElement staticElement = ElementFactory.methodElement("+", staticType);
fromNode.staticElement = staticElement;
fromNode.staticType = staticType;
@@ -207,7 +212,7 @@
void test_visitBooleanLiteral() {
BooleanLiteral fromNode = AstTestFactory.booleanLiteral(true);
- DartType staticType = ElementFactory.classElement2("C").type;
+ DartType staticType = interfaceType(ElementFactory.classElement2('C'));
fromNode.staticType = staticType;
BooleanLiteral toNode = AstTestFactory.booleanLiteral(true);
ResolutionCopier.copyResolutionData(fromNode, toNode);
@@ -217,7 +222,7 @@
void test_visitCascadeExpression() {
CascadeExpression fromNode = AstTestFactory.cascadeExpression(
AstTestFactory.identifier3("a"), [AstTestFactory.identifier3("b")]);
- DartType staticType = ElementFactory.classElement2("C").type;
+ DartType staticType = interfaceType(ElementFactory.classElement2('C'));
fromNode.staticType = staticType;
CascadeExpression toNode = AstTestFactory.cascadeExpression(
AstTestFactory.identifier3("a"), [AstTestFactory.identifier3("b")]);
@@ -239,7 +244,7 @@
AstTestFactory.identifier3("c"),
AstTestFactory.identifier3("a"),
AstTestFactory.identifier3("b"));
- DartType staticType = ElementFactory.classElement2("C").type;
+ DartType staticType = interfaceType(ElementFactory.classElement2('C'));
fromNode.staticType = staticType;
ConditionalExpression toNode = AstTestFactory.conditionalExpression(
AstTestFactory.identifier3("c"),
@@ -283,7 +288,7 @@
void test_visitDoubleLiteral() {
DoubleLiteral fromNode = AstTestFactory.doubleLiteral(1.0);
- DartType staticType = ElementFactory.classElement2("C").type;
+ DartType staticType = interfaceType(ElementFactory.classElement2('C'));
fromNode.staticType = staticType;
DoubleLiteral toNode = AstTestFactory.doubleLiteral(1.0);
ResolutionCopier.copyResolutionData(fromNode, toNode);
@@ -305,7 +310,7 @@
loopVariable: AstTestFactory.declaredIdentifier3('a'),
iterable: AstTestFactory.identifier3('b'));
- DartType typeB = ElementFactory.classElement2("B").type;
+ DartType typeB = interfaceType(ElementFactory.classElement2('B'));
ForEachPartsWithDeclaration fromNode = createNode();
(fromNode.iterable as SimpleIdentifier).staticType = typeB;
@@ -321,8 +326,8 @@
identifier: AstTestFactory.identifier3('a'),
iterable: AstTestFactory.identifier3('b'));
- DartType typeA = ElementFactory.classElement2("A").type;
- DartType typeB = ElementFactory.classElement2("B").type;
+ DartType typeA = interfaceType(ElementFactory.classElement2('A'));
+ DartType typeB = interfaceType(ElementFactory.classElement2('B'));
ForEachPartsWithIdentifier fromNode = createNode();
fromNode.identifier.staticType = typeA;
@@ -341,7 +346,7 @@
iterable: AstTestFactory.identifier3('b')),
body: AstTestFactory.identifier3('c'));
- DartType typeC = ElementFactory.classElement2("C").type;
+ DartType typeC = interfaceType(ElementFactory.classElement2('C'));
ForElement fromNode = createNode();
(fromNode.body as SimpleIdentifier).staticType = typeC;
@@ -359,8 +364,8 @@
condition: AstTestFactory.identifier3('b'),
updaters: [AstTestFactory.identifier3('c')]);
- DartType typeB = ElementFactory.classElement2("B").type;
- DartType typeC = ElementFactory.classElement2("C").type;
+ DartType typeB = interfaceType(ElementFactory.classElement2('B'));
+ DartType typeC = interfaceType(ElementFactory.classElement2('C'));
ForPartsWithDeclarations fromNode = createNode();
(fromNode.condition as SimpleIdentifier).staticType = typeB;
@@ -378,9 +383,9 @@
condition: AstTestFactory.identifier3('b'),
updaters: [AstTestFactory.identifier3('c')]);
- DartType typeA = ElementFactory.classElement2("A").type;
- DartType typeB = ElementFactory.classElement2("B").type;
- DartType typeC = ElementFactory.classElement2("C").type;
+ DartType typeA = interfaceType(ElementFactory.classElement2('A'));
+ DartType typeB = interfaceType(ElementFactory.classElement2('B'));
+ DartType typeC = interfaceType(ElementFactory.classElement2('C'));
ForPartsWithExpression fromNode = createNode();
(fromNode.initialization as SimpleIdentifier).staticType = typeA;
@@ -402,9 +407,9 @@
body: AstTestFactory.expressionStatement(
AstTestFactory.identifier3('c')));
- DartType typeA = ElementFactory.classElement2("A").type;
- DartType typeB = ElementFactory.classElement2("B").type;
- DartType typeC = ElementFactory.classElement2("C").type;
+ DartType typeA = interfaceType(ElementFactory.classElement2('A'));
+ DartType typeB = interfaceType(ElementFactory.classElement2('B'));
+ DartType typeC = interfaceType(ElementFactory.classElement2('C'));
ForStatement fromNode = createNode();
ForEachPartsWithIdentifier fromForLoopParts = fromNode.forLoopParts;
@@ -430,9 +435,9 @@
AstTestFactory.formalParameterList(),
AstTestFactory.emptyFunctionBody());
MethodElement element = ElementFactory.methodElement(
- "m", ElementFactory.classElement2("C").type);
+ "m", interfaceType(ElementFactory.classElement2('C')));
fromNode.declaredElement = element;
- DartType staticType = ElementFactory.classElement2("C").type;
+ DartType staticType = interfaceType(ElementFactory.classElement2('C'));
fromNode.staticType = staticType;
FunctionExpression toNode = AstTestFactory.functionExpression2(
AstTestFactory.formalParameterList(),
@@ -447,7 +452,7 @@
AstTestFactory.functionExpressionInvocation(
AstTestFactory.identifier3("f"));
MethodElement staticElement = ElementFactory.methodElement(
- "m", ElementFactory.classElement2("C").type);
+ "m", interfaceType(ElementFactory.classElement2('C')));
fromNode.staticElement = staticElement;
FunctionExpressionInvocation toNode =
AstTestFactory.functionExpressionInvocation(
@@ -469,9 +474,9 @@
thenElement: AstTestFactory.identifier3('b'),
elseElement: AstTestFactory.identifier3('c'));
- DartType typeA = ElementFactory.classElement2("A").type;
- DartType typeB = ElementFactory.classElement2("B").type;
- DartType typeC = ElementFactory.classElement2("C").type;
+ DartType typeA = interfaceType(ElementFactory.classElement2('A'));
+ DartType typeB = interfaceType(ElementFactory.classElement2('B'));
+ DartType typeC = interfaceType(ElementFactory.classElement2('C'));
IfElement fromNode = createNode();
(fromNode.condition as SimpleIdentifier).staticType = typeA;
@@ -499,12 +504,12 @@
IndexExpression fromNode = AstTestFactory.indexExpression(
AstTestFactory.identifier3("a"), AstTestFactory.integer(0));
MethodElement staticElement = ElementFactory.methodElement(
- "m", ElementFactory.classElement2("C").type);
+ "m", interfaceType(ElementFactory.classElement2('C')));
AuxiliaryElements auxiliaryElements =
new AuxiliaryElements(staticElement, null);
fromNode.auxiliaryElements = auxiliaryElements;
fromNode.staticElement = staticElement;
- DartType staticType = ElementFactory.classElement2("C").type;
+ DartType staticType = interfaceType(ElementFactory.classElement2('C'));
fromNode.staticType = staticType;
IndexExpression toNode = AstTestFactory.indexExpression(
AstTestFactory.identifier3("a"), AstTestFactory.integer(0));
@@ -521,7 +526,7 @@
ConstructorElement staticElement = ElementFactory.constructorElement2(
ElementFactory.classElement2("C"), null);
fromNode.staticElement = staticElement;
- DartType staticType = ElementFactory.classElement2("C").type;
+ DartType staticType = interfaceType(ElementFactory.classElement2('C'));
fromNode.staticType = staticType;
InstanceCreationExpression toNode =
AstTestFactory.instanceCreationExpression2(
@@ -533,7 +538,7 @@
void test_visitIntegerLiteral() {
IntegerLiteral fromNode = AstTestFactory.integer(2);
- DartType staticType = ElementFactory.classElement2("C").type;
+ DartType staticType = interfaceType(ElementFactory.classElement2('C'));
fromNode.staticType = staticType;
IntegerLiteral toNode = AstTestFactory.integer(2);
ResolutionCopier.copyResolutionData(fromNode, toNode);
@@ -543,7 +548,7 @@
void test_visitIsExpression() {
IsExpression fromNode = AstTestFactory.isExpression(
AstTestFactory.identifier3("x"), false, AstTestFactory.typeName4("A"));
- DartType staticType = ElementFactory.classElement2("C").type;
+ DartType staticType = interfaceType(ElementFactory.classElement2('C'));
fromNode.staticType = staticType;
IsExpression toNode = AstTestFactory.isExpression(
AstTestFactory.identifier3("x"), false, AstTestFactory.typeName4("A"));
@@ -554,7 +559,7 @@
void test_visitLibraryIdentifier() {
LibraryIdentifier fromNode =
AstTestFactory.libraryIdentifier([AstTestFactory.identifier3("lib")]);
- DartType staticType = ElementFactory.classElement2("C").type;
+ DartType staticType = interfaceType(ElementFactory.classElement2('C'));
fromNode.staticType = staticType;
LibraryIdentifier toNode =
AstTestFactory.libraryIdentifier([AstTestFactory.identifier3("lib")]);
@@ -570,9 +575,9 @@
[AstTestFactory.identifier3('b')],
null);
- DartType typeA = ElementFactory.classElement2("A").type;
- DartType typeB = ElementFactory.classElement2("B").type;
- DartType typeC = ElementFactory.classElement2("C").type;
+ DartType typeA = interfaceType(ElementFactory.classElement2('A'));
+ DartType typeB = interfaceType(ElementFactory.classElement2('B'));
+ DartType typeC = interfaceType(ElementFactory.classElement2('C'));
ListLiteral fromNode = createNode();
(fromNode.typeArguments.arguments[0] as TypeName).type = typeA;
@@ -588,7 +593,7 @@
void test_visitMapLiteral() {
SetOrMapLiteral fromNode = AstTestFactory.setOrMapLiteral(null, null);
- DartType staticType = ElementFactory.classElement2("C").type;
+ DartType staticType = interfaceType(ElementFactory.classElement2('C'));
fromNode.staticType = staticType;
SetOrMapLiteral toNode = AstTestFactory.setOrMapLiteral(null, null);
ResolutionCopier.copyResolutionData(fromNode, toNode);
@@ -609,7 +614,7 @@
void test_visitNamedExpression() {
NamedExpression fromNode =
AstTestFactory.namedExpression2("n", AstTestFactory.integer(0));
- DartType staticType = ElementFactory.classElement2("C").type;
+ DartType staticType = interfaceType(ElementFactory.classElement2('C'));
fromNode.staticType = staticType;
NamedExpression toNode =
AstTestFactory.namedExpression2("n", AstTestFactory.integer(0));
@@ -619,7 +624,7 @@
void test_visitNullLiteral() {
NullLiteral fromNode = AstTestFactory.nullLiteral();
- DartType staticType = ElementFactory.classElement2("C").type;
+ DartType staticType = interfaceType(ElementFactory.classElement2('C'));
fromNode.staticType = staticType;
NullLiteral toNode = AstTestFactory.nullLiteral();
ResolutionCopier.copyResolutionData(fromNode, toNode);
@@ -629,7 +634,7 @@
void test_visitParenthesizedExpression() {
ParenthesizedExpression fromNode =
AstTestFactory.parenthesizedExpression(AstTestFactory.integer(0));
- DartType staticType = ElementFactory.classElement2("C").type;
+ DartType staticType = interfaceType(ElementFactory.classElement2('C'));
fromNode.staticType = staticType;
ParenthesizedExpression toNode =
AstTestFactory.parenthesizedExpression(AstTestFactory.integer(0));
@@ -664,9 +669,9 @@
PostfixExpression fromNode = AstTestFactory.postfixExpression(
AstTestFactory.identifier3(variableName), TokenType.PLUS_PLUS);
MethodElement staticElement = ElementFactory.methodElement(
- "+", ElementFactory.classElement2("C").type);
+ "+", interfaceType(ElementFactory.classElement2('C')));
fromNode.staticElement = staticElement;
- DartType staticType = ElementFactory.classElement2("C").type;
+ DartType staticType = interfaceType(ElementFactory.classElement2('C'));
fromNode.staticType = staticType;
PostfixExpression toNode = AstTestFactory.postfixExpression(
AstTestFactory.identifier3(variableName), TokenType.PLUS_PLUS);
@@ -677,7 +682,7 @@
void test_visitPrefixedIdentifier() {
PrefixedIdentifier fromNode = AstTestFactory.identifier5("p", "f");
- DartType staticType = ElementFactory.classElement2("C").type;
+ DartType staticType = interfaceType(ElementFactory.classElement2('C'));
fromNode.staticType = staticType;
PrefixedIdentifier toNode = AstTestFactory.identifier5("p", "f");
ResolutionCopier.copyResolutionData(fromNode, toNode);
@@ -687,9 +692,9 @@
void test_visitPrefixExpression() {
PrefixExpression fromNode = AstTestFactory.prefixExpression(
TokenType.PLUS_PLUS, AstTestFactory.identifier3("x"));
- DartType staticType = ElementFactory.classElement2("C").type;
+ DartType staticType = interfaceType(ElementFactory.classElement2('C'));
MethodElement staticElement = ElementFactory.methodElement(
- "+", ElementFactory.classElement2("C").type);
+ "+", interfaceType(ElementFactory.classElement2('C')));
fromNode.staticElement = staticElement;
fromNode.staticType = staticType;
PrefixExpression toNode = AstTestFactory.prefixExpression(
@@ -702,7 +707,7 @@
void test_visitPropertyAccess() {
PropertyAccess fromNode =
AstTestFactory.propertyAccess2(AstTestFactory.identifier3("x"), "y");
- DartType staticType = ElementFactory.classElement2("C").type;
+ DartType staticType = interfaceType(ElementFactory.classElement2('C'));
fromNode.staticType = staticType;
PropertyAccess toNode =
AstTestFactory.propertyAccess2(AstTestFactory.identifier3("x"), "y");
@@ -724,7 +729,7 @@
void test_visitRethrowExpression() {
RethrowExpression fromNode = AstTestFactory.rethrowExpression();
- DartType staticType = ElementFactory.classElement2("C").type;
+ DartType staticType = interfaceType(ElementFactory.classElement2('C'));
fromNode.staticType = staticType;
RethrowExpression toNode = AstTestFactory.rethrowExpression();
ResolutionCopier.copyResolutionData(fromNode, toNode);
@@ -737,10 +742,10 @@
[AstTestFactory.typeName4('A'), AstTestFactory.typeName4('B')]),
elements: [AstTestFactory.mapLiteralEntry3('c', 'd')]);
- DartType typeA = ElementFactory.classElement2("A").type;
- DartType typeB = ElementFactory.classElement2("B").type;
- DartType typeC = ElementFactory.classElement2("C").type;
- DartType typeD = ElementFactory.classElement2("D").type;
+ DartType typeA = interfaceType(ElementFactory.classElement2('A'));
+ DartType typeB = interfaceType(ElementFactory.classElement2('B'));
+ DartType typeC = interfaceType(ElementFactory.classElement2('C'));
+ DartType typeD = interfaceType(ElementFactory.classElement2('D'));
SetOrMapLiteral fromNode = createNode();
(fromNode.typeArguments.arguments[0] as TypeName).type = typeA;
@@ -764,8 +769,8 @@
AstTestFactory.typeArgumentList([AstTestFactory.typeName4('A')]),
elements: [AstTestFactory.identifier3('b')]);
- DartType typeA = ElementFactory.classElement2("A").type;
- DartType typeB = ElementFactory.classElement2("B").type;
+ DartType typeA = interfaceType(ElementFactory.classElement2('A'));
+ DartType typeB = interfaceType(ElementFactory.classElement2('B'));
SetOrMapLiteral fromNode = createNode();
(fromNode.typeArguments.arguments[0] as TypeName).type = typeA;
@@ -780,12 +785,12 @@
void test_visitSimpleIdentifier() {
SimpleIdentifier fromNode = AstTestFactory.identifier3("x");
MethodElement staticElement = ElementFactory.methodElement(
- "m", ElementFactory.classElement2("C").type);
+ "m", interfaceType(ElementFactory.classElement2('C')));
AuxiliaryElements auxiliaryElements =
new AuxiliaryElements(staticElement, null);
fromNode.auxiliaryElements = auxiliaryElements;
fromNode.staticElement = staticElement;
- DartType staticType = ElementFactory.classElement2("C").type;
+ DartType staticType = interfaceType(ElementFactory.classElement2('C'));
fromNode.staticType = staticType;
SimpleIdentifier toNode = AstTestFactory.identifier3("x");
ResolutionCopier.copyResolutionData(fromNode, toNode);
@@ -796,7 +801,7 @@
void test_visitSimpleStringLiteral() {
SimpleStringLiteral fromNode = AstTestFactory.string2("abc");
- DartType staticType = ElementFactory.classElement2("C").type;
+ DartType staticType = interfaceType(ElementFactory.classElement2('C'));
fromNode.staticType = staticType;
SimpleStringLiteral toNode = AstTestFactory.string2("abc");
ResolutionCopier.copyResolutionData(fromNode, toNode);
@@ -810,7 +815,7 @@
expression: astFactory.listLiteral(
null, null, null, [AstTestFactory.identifier3('a')], null));
- DartType typeA = ElementFactory.classElement2("A").type;
+ DartType typeA = interfaceType(ElementFactory.classElement2('A'));
SpreadElement fromNode = createNode();
((fromNode.expression as ListLiteral).elements[0] as SimpleIdentifier)
@@ -827,7 +832,7 @@
void test_visitStringInterpolation() {
StringInterpolation fromNode =
AstTestFactory.string([AstTestFactory.interpolationString("a", "'a'")]);
- DartType staticType = ElementFactory.classElement2("C").type;
+ DartType staticType = interfaceType(ElementFactory.classElement2('C'));
fromNode.staticType = staticType;
StringInterpolation toNode =
AstTestFactory.string([AstTestFactory.interpolationString("a", "'a'")]);
@@ -849,7 +854,7 @@
void test_visitSuperExpression() {
SuperExpression fromNode = AstTestFactory.superExpression();
- DartType staticType = ElementFactory.classElement2("C").type;
+ DartType staticType = interfaceType(ElementFactory.classElement2('C'));
fromNode.staticType = staticType;
SuperExpression toNode = AstTestFactory.superExpression();
ResolutionCopier.copyResolutionData(fromNode, toNode);
@@ -858,7 +863,7 @@
void test_visitSymbolLiteral() {
SymbolLiteral fromNode = AstTestFactory.symbolLiteral(["s"]);
- DartType staticType = ElementFactory.classElement2("C").type;
+ DartType staticType = interfaceType(ElementFactory.classElement2('C'));
fromNode.staticType = staticType;
SymbolLiteral toNode = AstTestFactory.symbolLiteral(["s"]);
ResolutionCopier.copyResolutionData(fromNode, toNode);
@@ -867,7 +872,7 @@
void test_visitThisExpression() {
ThisExpression fromNode = AstTestFactory.thisExpression();
- DartType staticType = ElementFactory.classElement2("C").type;
+ DartType staticType = interfaceType(ElementFactory.classElement2('C'));
fromNode.staticType = staticType;
ThisExpression toNode = AstTestFactory.thisExpression();
ResolutionCopier.copyResolutionData(fromNode, toNode);
@@ -876,7 +881,7 @@
void test_visitThrowExpression() {
ThrowExpression fromNode = AstTestFactory.throwExpression();
- DartType staticType = ElementFactory.classElement2("C").type;
+ DartType staticType = interfaceType(ElementFactory.classElement2('C'));
fromNode.staticType = staticType;
ThrowExpression toNode = AstTestFactory.throwExpression();
ResolutionCopier.copyResolutionData(fromNode, toNode);
@@ -885,7 +890,7 @@
void test_visitTypeName() {
TypeName fromNode = AstTestFactory.typeName4("C");
- DartType type = ElementFactory.classElement2("C").type;
+ DartType type = interfaceType(ElementFactory.classElement2('C'));
fromNode.type = type;
TypeName toNode = AstTestFactory.typeName4("C");
ResolutionCopier.copyResolutionData(fromNode, toNode);
@@ -894,10 +899,11 @@
void _copyAndVerifyInvocation(
InvocationExpression fromNode, InvocationExpression toNode) {
- DartType staticType = ElementFactory.classElement2("C").type;
+ DartType staticType = interfaceType(ElementFactory.classElement2('C'));
fromNode.staticType = staticType;
- DartType staticInvokeType = ElementFactory.classElement2("C").type;
+ DartType staticInvokeType =
+ interfaceType(ElementFactory.classElement2('C'));
fromNode.staticInvokeType = staticInvokeType;
ResolutionCopier.copyResolutionData(fromNode, toNode);
diff --git a/pkg/analyzer/test/src/dart/constant/evaluation_test.dart b/pkg/analyzer/test/src/dart/constant/evaluation_test.dart
index 6644cb8..8d0b13e 100644
--- a/pkg/analyzer/test/src/dart/constant/evaluation_test.dart
+++ b/pkg/analyzer/test/src/dart/constant/evaluation_test.dart
@@ -839,8 +839,7 @@
const c = [1, if (1 < 0) 2 else 3, 4];
''');
DartObjectImpl result = _evaluateConstant('c');
- expect(
- result.type, typeProvider.listType.instantiate([typeProvider.intType]));
+ expect(result.type, typeProvider.listType2(typeProvider.intType));
expect(result.toListValue().map((e) => e.toIntValue()), [1, 3, 4]);
}
@@ -849,8 +848,7 @@
const c = [1, if (1 < 0) 2, 3];
''');
DartObjectImpl result = _evaluateConstant('c');
- expect(
- result.type, typeProvider.listType.instantiate([typeProvider.intType]));
+ expect(result.type, typeProvider.listType2(typeProvider.intType));
expect(result.toListValue().map((e) => e.toIntValue()), [1, 3]);
}
@@ -859,8 +857,7 @@
const c = [1, if (1 > 0) 2 else 3, 4];
''');
DartObjectImpl result = _evaluateConstant('c');
- expect(
- result.type, typeProvider.listType.instantiate([typeProvider.intType]));
+ expect(result.type, typeProvider.listType2(typeProvider.intType));
expect(result.toListValue().map((e) => e.toIntValue()), [1, 2, 4]);
}
@@ -869,8 +866,7 @@
const c = [1, if (1 > 0) 2, 3];
''');
DartObjectImpl result = _evaluateConstant('c');
- expect(
- result.type, typeProvider.listType.instantiate([typeProvider.intType]));
+ expect(result.type, typeProvider.listType2(typeProvider.intType));
expect(result.toListValue().map((e) => e.toIntValue()), [1, 2, 3]);
}
@@ -881,8 +877,7 @@
DartObjectImpl result = _evaluateConstant('c');
// The expected type ought to be `List<int>`, but type inference isn't yet
// implemented.
- expect(
- result.type, typeProvider.listType.instantiate([typeProvider.intType]));
+ expect(result.type, typeProvider.listType2(typeProvider.intType));
expect(result.toListValue().map((e) => e.toIntValue()), [1, 2, 3]);
}
@@ -891,8 +886,7 @@
const c = [1, ...[2, 3], 4];
''');
DartObjectImpl result = _evaluateConstant('c');
- expect(
- result.type, typeProvider.listType.instantiate([typeProvider.intType]));
+ expect(result.type, typeProvider.listType2(typeProvider.intType));
expect(result.toListValue().map((e) => e.toIntValue()), [1, 2, 3, 4]);
}
@@ -901,10 +895,8 @@
const c = {'a' : 1, if (1 < 0) 'b' : 2 else 'c' : 3, 'd' : 4};
''');
DartObjectImpl result = _evaluateConstant('c');
- expect(
- result.type,
- typeProvider.mapType
- .instantiate([typeProvider.stringType, typeProvider.intType]));
+ expect(result.type,
+ typeProvider.mapType2(typeProvider.stringType, typeProvider.intType));
Map<DartObject, DartObject> value = result.toMapValue();
expect(value.keys.map((e) => e.toStringValue()),
unorderedEquals(['a', 'c', 'd']));
@@ -916,10 +908,8 @@
const c = {'a' : 1, if (1 < 0) 'b' : 2, 'c' : 3};
''');
DartObjectImpl result = _evaluateConstant('c');
- expect(
- result.type,
- typeProvider.mapType
- .instantiate([typeProvider.stringType, typeProvider.intType]));
+ expect(result.type,
+ typeProvider.mapType2(typeProvider.stringType, typeProvider.intType));
Map<DartObject, DartObject> value = result.toMapValue();
expect(
value.keys.map((e) => e.toStringValue()), unorderedEquals(['a', 'c']));
@@ -931,10 +921,8 @@
const c = {'a' : 1, if (1 > 0) 'b' : 2 else 'c' : 3, 'd' : 4};
''');
DartObjectImpl result = _evaluateConstant('c');
- expect(
- result.type,
- typeProvider.mapType
- .instantiate([typeProvider.stringType, typeProvider.intType]));
+ expect(result.type,
+ typeProvider.mapType2(typeProvider.stringType, typeProvider.intType));
Map<DartObject, DartObject> value = result.toMapValue();
expect(value.keys.map((e) => e.toStringValue()),
unorderedEquals(['a', 'b', 'd']));
@@ -946,10 +934,8 @@
const c = {'a' : 1, if (1 > 0) 'b' : 2, 'c' : 3};
''');
DartObjectImpl result = _evaluateConstant('c');
- expect(
- result.type,
- typeProvider.mapType
- .instantiate([typeProvider.stringType, typeProvider.intType]));
+ expect(result.type,
+ typeProvider.mapType2(typeProvider.stringType, typeProvider.intType));
Map<DartObject, DartObject> value = result.toMapValue();
expect(value.keys.map((e) => e.toStringValue()),
unorderedEquals(['a', 'b', 'c']));
@@ -963,10 +949,8 @@
const c = {'a' : 1, if (1 > 0) if (2 > 1) {'b' : 2}, 'c' : 3};
''');
DartObjectImpl result = _evaluateConstant('c');
- expect(
- result.type,
- typeProvider.mapType
- .instantiate([typeProvider.intType, typeProvider.intType]));
+ expect(result.type,
+ typeProvider.mapType2(typeProvider.intType, typeProvider.intType));
Map<DartObject, DartObject> value = result.toMapValue();
expect(value.keys.map((e) => e.toStringValue()),
unorderedEquals(['a', 'b', 'c']));
@@ -978,10 +962,8 @@
const c = {'a' : 1, ...{'b' : 2, 'c' : 3}, 'd' : 4};
''');
DartObjectImpl result = _evaluateConstant('c');
- expect(
- result.type,
- typeProvider.mapType
- .instantiate([typeProvider.stringType, typeProvider.intType]));
+ expect(result.type,
+ typeProvider.mapType2(typeProvider.stringType, typeProvider.intType));
Map<DartObject, DartObject> value = result.toMapValue();
expect(value.keys.map((e) => e.toStringValue()),
unorderedEquals(['a', 'b', 'c', 'd']));
@@ -994,8 +976,7 @@
const c = {1, if (1 < 0) 2 else 3, 4};
''');
DartObjectImpl result = _evaluateConstant('c');
- expect(
- result.type, typeProvider.setType.instantiate([typeProvider.intType]));
+ expect(result.type, typeProvider.setType2(typeProvider.intType));
expect(result.toSetValue().map((e) => e.toIntValue()), [1, 3, 4]);
}
@@ -1004,8 +985,7 @@
const c = {1, if (1 < 0) 2, 3};
''');
DartObjectImpl result = _evaluateConstant('c');
- expect(
- result.type, typeProvider.setType.instantiate([typeProvider.intType]));
+ expect(result.type, typeProvider.setType2(typeProvider.intType));
expect(result.toSetValue().map((e) => e.toIntValue()), [1, 3]);
}
@@ -1014,8 +994,7 @@
const c = {1, if (1 > 0) 2 else 3, 4};
''');
DartObjectImpl result = _evaluateConstant('c');
- expect(
- result.type, typeProvider.setType.instantiate([typeProvider.intType]));
+ expect(result.type, typeProvider.setType2(typeProvider.intType));
expect(result.toSetValue().map((e) => e.toIntValue()), [1, 2, 4]);
}
@@ -1024,8 +1003,7 @@
const c = {1, if (1 > 0) 2, 3};
''');
DartObjectImpl result = _evaluateConstant('c');
- expect(
- result.type, typeProvider.setType.instantiate([typeProvider.intType]));
+ expect(result.type, typeProvider.setType2(typeProvider.intType));
expect(result.toSetValue().map((e) => e.toIntValue()), [1, 2, 3]);
}
@@ -1034,8 +1012,7 @@
const c = {1, if (1 > 0) if (2 > 1) 2, 3};
''');
DartObjectImpl result = _evaluateConstant('c');
- expect(
- result.type, typeProvider.setType.instantiate([typeProvider.intType]));
+ expect(result.type, typeProvider.setType2(typeProvider.intType));
expect(result.toSetValue().map((e) => e.toIntValue()), [1, 2, 3]);
}
@@ -1044,8 +1021,7 @@
const c = {1, ...{2, 3}, 4};
''');
DartObjectImpl result = _evaluateConstant('c');
- expect(
- result.type, typeProvider.setType.instantiate([typeProvider.intType]));
+ expect(result.type, typeProvider.setType2(typeProvider.intType));
expect(result.toSetValue().map((e) => e.toIntValue()), [1, 2, 3, 4]);
}
}
diff --git a/pkg/analyzer/test/src/dart/constant/value_test.dart b/pkg/analyzer/test/src/dart/constant/value_test.dart
index 521182b..f337c05 100644
--- a/pkg/analyzer/test/src/dart/constant/value_test.dart
+++ b/pkg/analyzer/test/src/dart/constant/value_test.dart
@@ -2,6 +2,7 @@
// 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.
+import 'package:analyzer/dart/element/type.dart';
import 'package:analyzer/src/generated/constant.dart';
import 'package:analyzer/src/generated/resolver.dart';
import 'package:analyzer/src/generated/testing/test_type_provider.dart';
@@ -289,19 +290,35 @@
}
void test_equalEqual_list_empty() {
- _assertEqualEqual(null, _listValue(), _listValue());
+ _assertEqualEqual(
+ null,
+ _listValue(_typeProvider.intType, []),
+ _listValue(_typeProvider.intType, []),
+ );
}
void test_equalEqual_list_false() {
- _assertEqualEqual(null, _listValue(), _listValue());
+ _assertEqualEqual(
+ null,
+ _listValue(_typeProvider.intType, []),
+ _listValue(_typeProvider.intType, []),
+ );
}
void test_equalEqual_map_empty() {
- _assertEqualEqual(null, _mapValue(), _mapValue());
+ _assertEqualEqual(
+ null,
+ _mapValue(_typeProvider.intType, _typeProvider.stringType, []),
+ _mapValue(_typeProvider.intType, _typeProvider.stringType, []),
+ );
}
void test_equalEqual_map_false() {
- _assertEqualEqual(null, _mapValue(), _mapValue());
+ _assertEqualEqual(
+ null,
+ _mapValue(_typeProvider.intType, _typeProvider.stringType, []),
+ _mapValue(_typeProvider.intType, _typeProvider.stringType, []),
+ );
}
void test_equalEqual_null() {
@@ -325,26 +342,38 @@
void test_equals_list_false_differentSizes() {
expect(
- _listValue([_boolValue(true)]) ==
- _listValue([_boolValue(true), _boolValue(false)]),
+ _listValue(_typeProvider.boolType, [_boolValue(true)]) ==
+ _listValue(
+ _typeProvider.boolType, [_boolValue(true), _boolValue(false)]),
isFalse);
}
void test_equals_list_false_sameSize() {
- expect(_listValue([_boolValue(true)]) == _listValue([_boolValue(false)]),
+ expect(
+ _listValue(_typeProvider.boolType, [_boolValue(true)]) ==
+ _listValue(_typeProvider.boolType, [_boolValue(false)]),
isFalse);
}
void test_equals_list_true_empty() {
- expect(_listValue(), _listValue());
+ expect(
+ _listValue(_typeProvider.intType, []),
+ _listValue(_typeProvider.intType, []),
+ );
}
void test_equals_list_true_nonEmpty() {
- expect(_listValue([_boolValue(true)]), _listValue([_boolValue(true)]));
+ expect(
+ _listValue(_typeProvider.boolType, [_boolValue(true)]),
+ _listValue(_typeProvider.boolType, [_boolValue(true)]),
+ );
}
void test_equals_map_true_empty() {
- expect(_mapValue(), _mapValue());
+ expect(
+ _mapValue(_typeProvider.intType, _typeProvider.stringType, []),
+ _mapValue(_typeProvider.intType, _typeProvider.stringType, []),
+ );
}
void test_equals_symbol_false() {
@@ -386,27 +415,29 @@
}
void test_getValue_list_empty() {
- Object result = _listValue().toListValue();
+ Object result = _listValue(_typeProvider.intType, []).toListValue();
_assertInstanceOfObjectArray(result);
List<Object> array = result as List<Object>;
expect(array, hasLength(0));
}
void test_getValue_list_valid() {
- Object result = _listValue([_intValue(23)]).toListValue();
+ Object result =
+ _listValue(_typeProvider.intType, [_intValue(23)]).toListValue();
_assertInstanceOfObjectArray(result);
List<Object> array = result as List<Object>;
expect(array, hasLength(1));
}
void test_getValue_map_empty() {
- Map result = _mapValue().toMapValue();
+ Map result = _mapValue(_typeProvider.intType, _typeProvider.stringType, [])
+ .toMapValue();
expect(result, hasLength(0));
}
void test_getValue_map_valid() {
- Map result =
- _mapValue([_stringValue("key"), _stringValue("value")]).toMapValue();
+ Map result = _mapValue(_typeProvider.stringType, _typeProvider.stringType,
+ [_stringValue("key"), _stringValue("value")]).toMapValue();
expect(result, hasLength(1));
}
@@ -415,16 +446,14 @@
}
void test_getValue_set_empty() {
- Object result = _setValue().toSetValue();
- _assertInstanceOfObjectArray(result);
- Set<Object> set = result as Set<Object>;
+ DartObjectImpl object = _setValue(_typeProvider.intType, null);
+ Set<DartObject> set = object.toSetValue();
expect(set, hasLength(0));
}
void test_getValue_set_valid() {
- Object result = _setValue(new Set.from([_intValue(23)])).toSetValue();
- _assertInstanceOfObjectArray(result);
- Set<Object> set = result as Set<Object>;
+ DartObjectImpl object = _setValue(_typeProvider.intType, {_intValue(23)});
+ Set<DartObject> set = object.toSetValue();
expect(set, hasLength(1));
}
@@ -604,20 +633,25 @@
}
void test_hasKnownValue_list_empty() {
- expect(_listValue().hasKnownValue, isTrue);
+ expect(_listValue(_typeProvider.intType, []).hasKnownValue, isTrue);
}
void test_hasKnownValue_list_valid() {
- expect(_listValue([_intValue(23)]).hasKnownValue, isTrue);
+ expect(_listValue(_typeProvider.intType, [_intValue(23)]).hasKnownValue,
+ isTrue);
}
void test_hasKnownValue_map_empty() {
- expect(_mapValue().hasKnownValue, isTrue);
+ expect(
+ _mapValue(_typeProvider.intType, _typeProvider.stringType, [])
+ .hasKnownValue,
+ isTrue);
}
void test_hasKnownValue_map_valid() {
expect(
- _mapValue([_stringValue("key"), _stringValue("value")]).hasKnownValue,
+ _mapValue(_typeProvider.stringType, _typeProvider.stringType,
+ [_stringValue("key"), _stringValue("value")]).hasKnownValue,
isTrue);
}
@@ -670,21 +704,36 @@
}
void test_identical_list_empty() {
- _assertIdentical(_boolValue(true), _listValue(), _listValue());
+ _assertIdentical(
+ _boolValue(true),
+ _listValue(_typeProvider.intType, []),
+ _listValue(_typeProvider.intType, []),
+ );
}
void test_identical_list_false() {
- _assertIdentical(
- _boolValue(false), _listValue(), _listValue([_intValue(3)]));
+ _assertIdentical(_boolValue(false), _listValue(_typeProvider.intType, []),
+ _listValue(_typeProvider.intType, [_intValue(3)]));
}
void test_identical_map_empty() {
- _assertIdentical(_boolValue(true), _mapValue(), _mapValue());
+ _assertIdentical(
+ _boolValue(true),
+ _mapValue(_typeProvider.intType, _typeProvider.stringType, []),
+ _mapValue(_typeProvider.intType, _typeProvider.stringType, []),
+ );
}
void test_identical_map_false() {
- _assertIdentical(_boolValue(false), _mapValue(),
- _mapValue([_intValue(1), _intValue(2)]));
+ _assertIdentical(
+ _boolValue(false),
+ _mapValue(_typeProvider.intType, _typeProvider.intType, []),
+ _mapValue(
+ _typeProvider.intType,
+ _typeProvider.intType,
+ [_intValue(1), _intValue(2)],
+ ),
+ );
}
void test_identical_null() {
@@ -788,7 +837,8 @@
}
void test_isBoolNumStringOrNull_list() {
- expect(_listValue().isBoolNumStringOrNull, isFalse);
+ expect(
+ _listValue(_typeProvider.intType, []).isBoolNumStringOrNull, isFalse);
}
void test_isBoolNumStringOrNull_null() {
@@ -1923,28 +1973,35 @@
}
DartObjectImpl _listValue(
- [List<DartObjectImpl> elements = const <DartObjectImpl>[]]) {
- return new DartObjectImpl(_typeProvider.listType, new ListState(elements));
+ DartType elementType,
+ List<DartObjectImpl> elements,
+ ) {
+ return DartObjectImpl(
+ _typeProvider.listType2(elementType),
+ ListState(elements),
+ );
}
- DartObjectImpl _mapValue(
- [List<DartObjectImpl> keyElementPairs = const <DartObjectImpl>[]]) {
+ DartObjectImpl _mapValue(DartType keyType, DartType valueType,
+ List<DartObjectImpl> keyElementPairs) {
Map<DartObjectImpl, DartObjectImpl> map =
new Map<DartObjectImpl, DartObjectImpl>();
int count = keyElementPairs.length;
for (int i = 0; i < count;) {
map[keyElementPairs[i++]] = keyElementPairs[i++];
}
- return new DartObjectImpl(_typeProvider.mapType, new MapState(map));
+ return DartObjectImpl(
+ _typeProvider.mapType2(keyType, valueType),
+ MapState(map),
+ );
}
DartObjectImpl _nullValue() {
return new DartObjectImpl(_typeProvider.nullType, NullState.NULL_STATE);
}
- DartObjectImpl _setValue([Set<DartObjectImpl> elements]) {
- return new DartObjectImpl(_typeProvider.setType,
- new SetState(elements ?? new Set<DartObjectImpl>()));
+ DartObjectImpl _setValue(DartType type, Set<DartObjectImpl> elements) {
+ return DartObjectImpl(type, SetState(elements ?? Set<DartObjectImpl>()));
}
DartObjectImpl _stringValue(String value) {
diff --git a/pkg/analyzer/test/src/dart/element/element_test.dart b/pkg/analyzer/test/src/dart/element/element_test.dart
index 15d7978..a3d5a04 100644
--- a/pkg/analyzer/test/src/dart/element/element_test.dart
+++ b/pkg/analyzer/test/src/dart/element/element_test.dart
@@ -5,17 +5,21 @@
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/constant/value.dart';
import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/dart/element/nullability_suffix.dart';
import 'package:analyzer/dart/element/type.dart';
import 'package:analyzer/src/dart/element/element.dart';
import 'package:analyzer/src/dart/element/handle.dart';
import 'package:analyzer/src/dart/element/type.dart';
import 'package:analyzer/src/generated/engine.dart' show AnalysisContext;
+import 'package:analyzer/src/generated/resolver.dart';
import 'package:analyzer/src/generated/testing/ast_test_factory.dart';
import 'package:analyzer/src/generated/testing/element_factory.dart';
import 'package:analyzer/src/generated/testing/test_type_provider.dart';
import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
+import '../../../generated/elements_types_mixin.dart';
+import '../../../generated/test_analysis_context.dart';
import '../../../generated/test_support.dart';
import '../resolution/driver_resolution.dart';
@@ -37,16 +41,29 @@
});
}
+class AbstractTypeTest with ElementsTypesMixin {
+ AnalysisContext _analysisContext;
+ TypeProvider _typeProvider;
+
+ TypeProvider get typeProvider => _typeProvider;
+
+ void setUp() {
+ _analysisContext = TestAnalysisContext();
+ _typeProvider = _analysisContext.typeProvider;
+ }
+}
+
@reflectiveTest
-class ClassElementImplTest {
+class ClassElementImplTest extends AbstractTypeTest {
void test_getAllSupertypes_interface() {
- ClassElement classA = ElementFactory.classElement2("A");
- ClassElement classB = ElementFactory.classElement("B", classA.type);
+ ClassElement classA = class_(name: 'A');
+ ClassElement classB =
+ ElementFactory.classElement("B", interfaceType(classA));
ClassElementImpl elementC = ElementFactory.classElement2("C");
InterfaceType typeObject = classA.supertype;
- InterfaceType typeA = classA.type;
- InterfaceType typeB = classB.type;
- InterfaceType typeC = elementC.type;
+ InterfaceType typeA = interfaceType(classA);
+ InterfaceType typeB = interfaceType(classB);
+ InterfaceType typeC = interfaceType(elementC);
elementC.interfaces = <InterfaceType>[typeB];
List<InterfaceType> supers = elementC.allSupertypes;
List<InterfaceType> types = new List<InterfaceType>();
@@ -58,13 +75,14 @@
}
void test_getAllSupertypes_mixins() {
- ClassElement classA = ElementFactory.classElement2("A");
- ClassElement classB = ElementFactory.classElement("B", classA.type);
- ClassElementImpl classC = ElementFactory.classElement2("C");
+ ClassElement classA = class_(name: 'A');
+ ClassElement classB =
+ ElementFactory.classElement("B", interfaceType(classA));
+ var classC = ElementFactory.classElement2("C");
InterfaceType typeObject = classA.supertype;
- InterfaceType typeA = classA.type;
- InterfaceType typeB = classB.type;
- InterfaceType typeC = classC.type;
+ InterfaceType typeA = interfaceType(classA);
+ InterfaceType typeB = interfaceType(classB);
+ InterfaceType typeC = interfaceType(classC);
classC.mixins = <InterfaceType>[typeB];
List<InterfaceType> supers = classC.allSupertypes;
List<InterfaceType> types = new List<InterfaceType>();
@@ -76,15 +94,16 @@
}
void test_getAllSupertypes_recursive() {
- ClassElementImpl classA = ElementFactory.classElement2("A");
- ClassElementImpl classB = ElementFactory.classElement("B", classA.type);
- classA.supertype = classB.type;
+ var classA = class_(name: 'A');
+ ClassElementImpl classB =
+ ElementFactory.classElement("B", interfaceType(classA));
+ classA.supertype = interfaceType(classB);
List<InterfaceType> supers = classB.allSupertypes;
expect(supers, hasLength(1));
}
void test_getField() {
- ClassElementImpl classA = ElementFactory.classElement2("A");
+ var classA = class_(name: 'A');
String fieldName = "f";
FieldElementImpl field =
ElementFactory.fieldElement(fieldName, false, false, false, null);
@@ -96,7 +115,7 @@
}
void test_getMethod_declared() {
- ClassElementImpl classA = ElementFactory.classElement2("A");
+ var classA = class_(name: 'A');
String methodName = "m";
MethodElement method = ElementFactory.methodElement(methodName, null);
classA.methods = <MethodElement>[method];
@@ -104,7 +123,7 @@
}
void test_getMethod_undeclared() {
- ClassElementImpl classA = ElementFactory.classElement2("A");
+ var classA = class_(name: 'A');
String methodName = "m";
MethodElement method = ElementFactory.methodElement(methodName, null);
classA.methods = <MethodElement>[method];
@@ -112,60 +131,66 @@
}
void test_hasNonFinalField_false_const() {
- ClassElementImpl classA = ElementFactory.classElement2("A");
+ var classA = class_(name: 'A');
classA.fields = <FieldElement>[
- ElementFactory.fieldElement("f", false, false, true, classA.type)
+ ElementFactory.fieldElement(
+ "f", false, false, true, interfaceType(classA))
];
expect(classA.hasNonFinalField, isFalse);
}
void test_hasNonFinalField_false_final() {
- ClassElementImpl classA = ElementFactory.classElement2("A");
+ var classA = class_(name: 'A');
classA.fields = <FieldElement>[
- ElementFactory.fieldElement("f", false, true, false, classA.type)
+ ElementFactory.fieldElement(
+ "f", false, true, false, interfaceType(classA))
];
expect(classA.hasNonFinalField, isFalse);
}
void test_hasNonFinalField_false_recursive() {
- ClassElementImpl classA = ElementFactory.classElement2("A");
- ClassElementImpl classB = ElementFactory.classElement("B", classA.type);
- classA.supertype = classB.type;
+ var classA = class_(name: 'A');
+ ClassElementImpl classB =
+ ElementFactory.classElement("B", interfaceType(classA));
+ classA.supertype = interfaceType(classB);
expect(classA.hasNonFinalField, isFalse);
}
void test_hasNonFinalField_true_immediate() {
- ClassElementImpl classA = ElementFactory.classElement2("A");
+ var classA = class_(name: 'A');
classA.fields = <FieldElement>[
- ElementFactory.fieldElement("f", false, false, false, classA.type)
+ ElementFactory.fieldElement(
+ "f", false, false, false, interfaceType(classA))
];
expect(classA.hasNonFinalField, isTrue);
}
void test_hasNonFinalField_true_inherited() {
- ClassElementImpl classA = ElementFactory.classElement2("A");
- ClassElementImpl classB = ElementFactory.classElement("B", classA.type);
+ var classA = class_(name: 'A');
+ ClassElementImpl classB =
+ ElementFactory.classElement("B", interfaceType(classA));
classA.fields = <FieldElement>[
- ElementFactory.fieldElement("f", false, false, false, classA.type)
+ ElementFactory.fieldElement(
+ "f", false, false, false, interfaceType(classA))
];
expect(classB.hasNonFinalField, isTrue);
}
void test_hasStaticMember_false_empty() {
- ClassElementImpl classA = ElementFactory.classElement2("A");
+ var classA = class_(name: 'A');
// no members
expect(classA.hasStaticMember, isFalse);
}
void test_hasStaticMember_false_instanceMethod() {
- ClassElementImpl classA = ElementFactory.classElement2("A");
+ var classA = class_(name: 'A');
MethodElement method = ElementFactory.methodElement("foo", null);
classA.methods = <MethodElement>[method];
expect(classA.hasStaticMember, isFalse);
}
void test_hasStaticMember_instanceGetter() {
- ClassElementImpl classA = ElementFactory.classElement2("A");
+ var classA = class_(name: 'A');
PropertyAccessorElement getter =
ElementFactory.getterElement("foo", false, null);
classA.accessors = <PropertyAccessorElement>[getter];
@@ -173,7 +198,7 @@
}
void test_hasStaticMember_true_getter() {
- ClassElementImpl classA = ElementFactory.classElement2("A");
+ var classA = class_(name: 'A');
PropertyAccessorElementImpl getter =
ElementFactory.getterElement("foo", false, null);
classA.accessors = <PropertyAccessorElement>[getter];
@@ -183,7 +208,7 @@
}
void test_hasStaticMember_true_method() {
- ClassElementImpl classA = ElementFactory.classElement2("A");
+ var classA = class_(name: 'A');
MethodElementImpl method = ElementFactory.methodElement("foo", null);
classA.methods = <MethodElement>[method];
// "foo" is static
@@ -192,7 +217,7 @@
}
void test_hasStaticMember_true_setter() {
- ClassElementImpl classA = ElementFactory.classElement2("A");
+ var classA = class_(name: 'A');
PropertyAccessorElementImpl setter =
ElementFactory.setterElement("foo", false, null);
classA.accessors = <PropertyAccessorElement>[setter];
@@ -220,7 +245,7 @@
// m() {}
// }
LibraryElementImpl library = _newLibrary();
- ClassElementImpl classA = ElementFactory.classElement2("A");
+ var classA = class_(name: 'A');
String methodName = "m";
MethodElement method = ElementFactory.methodElement(methodName, null);
classA.methods = <MethodElement>[method];
@@ -234,7 +259,7 @@
// m();
// }
LibraryElementImpl library = _newLibrary();
- ClassElementImpl classA = ElementFactory.classElement2("A");
+ var classA = class_(name: 'A');
String methodName = "m";
MethodElementImpl method = ElementFactory.methodElement(methodName, null);
method.isAbstract = true;
@@ -252,12 +277,13 @@
// m();
// }
LibraryElementImpl library = _newLibrary();
- ClassElementImpl classA = ElementFactory.classElement2("A");
+ var classA = class_(name: 'A');
String methodName = "m";
MethodElement inheritedMethod =
ElementFactory.methodElement(methodName, null);
classA.methods = <MethodElement>[inheritedMethod];
- ClassElementImpl classB = ElementFactory.classElement("B", classA.type);
+ ClassElementImpl classB =
+ ElementFactory.classElement("B", interfaceType(classA));
MethodElementImpl method = ElementFactory.methodElement(methodName, null);
method.isAbstract = true;
classB.methods = <MethodElement>[method];
@@ -275,12 +301,13 @@
// m() {}
// }
LibraryElementImpl library = _newLibrary();
- ClassElementImpl classA = ElementFactory.classElement2("A");
+ var classA = class_(name: 'A');
String methodName = "m";
MethodElement inheritedMethod =
ElementFactory.methodElement(methodName, null);
classA.methods = <MethodElement>[inheritedMethod];
- ClassElementImpl classB = ElementFactory.classElement("B", classA.type);
+ ClassElementImpl classB =
+ ElementFactory.classElement("B", interfaceType(classA));
MethodElement method = ElementFactory.methodElement(methodName, null);
classB.methods = <MethodElement>[method];
(library.definingCompilationUnit as CompilationUnitElementImpl).types =
@@ -296,14 +323,15 @@
// m() {}
// }
LibraryElementImpl library = _newLibrary();
- ClassElementImpl classA = ElementFactory.classElement2("A");
+ var classA = class_(name: 'A');
classA.isAbstract = true;
String methodName = "m";
MethodElementImpl inheritedMethod =
ElementFactory.methodElement(methodName, null);
inheritedMethod.isAbstract = true;
classA.methods = <MethodElement>[inheritedMethod];
- ClassElementImpl classB = ElementFactory.classElement("B", classA.type);
+ ClassElementImpl classB =
+ ElementFactory.classElement("B", interfaceType(classA));
MethodElement method = ElementFactory.methodElement(methodName, null);
classB.methods = <MethodElement>[method];
(library.definingCompilationUnit as CompilationUnitElementImpl).types =
@@ -318,12 +346,13 @@
// class B extends A {
// }
LibraryElementImpl library = _newLibrary();
- ClassElementImpl classA = ElementFactory.classElement2("A");
+ var classA = class_(name: 'A');
String methodName = "m";
MethodElement inheritedMethod =
ElementFactory.methodElement(methodName, null);
classA.methods = <MethodElement>[inheritedMethod];
- ClassElementImpl classB = ElementFactory.classElement("B", classA.type);
+ ClassElementImpl classB =
+ ElementFactory.classElement("B", interfaceType(classA));
(library.definingCompilationUnit as CompilationUnitElementImpl).types =
<ClassElement>[classA, classB];
expect(classB.lookUpConcreteMethod(methodName, library),
@@ -334,7 +363,7 @@
// class A {
// }
LibraryElementImpl library = _newLibrary();
- ClassElementImpl classA = ElementFactory.classElement2("A");
+ var classA = class_(name: 'A');
(library.definingCompilationUnit as CompilationUnitElementImpl).types =
<ClassElement>[classA];
expect(classA.lookUpConcreteMethod("m", library), isNull);
@@ -345,7 +374,7 @@
// get g {}
// }
LibraryElementImpl library = _newLibrary();
- ClassElementImpl classA = ElementFactory.classElement2("A");
+ var classA = class_(name: 'A');
String getterName = "g";
PropertyAccessorElement getter =
ElementFactory.getterElement(getterName, false, null);
@@ -362,12 +391,13 @@
// class B extends A {
// }
LibraryElementImpl library = _newLibrary();
- ClassElementImpl classA = ElementFactory.classElement2("A");
+ var classA = class_(name: 'A');
String getterName = "g";
PropertyAccessorElement getter =
ElementFactory.getterElement(getterName, false, null);
classA.accessors = <PropertyAccessorElement>[getter];
- ClassElementImpl classB = ElementFactory.classElement("B", classA.type);
+ ClassElementImpl classB =
+ ElementFactory.classElement("B", interfaceType(classA));
(library.definingCompilationUnit as CompilationUnitElementImpl).types =
<ClassElement>[classA, classB];
expect(classB.lookUpGetter(getterName, library), same(getter));
@@ -377,7 +407,7 @@
// class A {
// }
LibraryElementImpl library = _newLibrary();
- ClassElementImpl classA = ElementFactory.classElement2("A");
+ var classA = class_(name: 'A');
(library.definingCompilationUnit as CompilationUnitElementImpl).types =
<ClassElement>[classA];
expect(classA.lookUpGetter("g", library), isNull);
@@ -389,9 +419,10 @@
// class B extends A {
// }
LibraryElementImpl library = _newLibrary();
- ClassElementImpl classA = ElementFactory.classElement2("A");
- ClassElementImpl classB = ElementFactory.classElement("B", classA.type);
- classA.supertype = classB.type;
+ var classA = class_(name: 'A');
+ ClassElementImpl classB =
+ ElementFactory.classElement("B", interfaceType(classA));
+ classA.supertype = interfaceType(classB);
(library.definingCompilationUnit as CompilationUnitElementImpl).types =
<ClassElement>[classA, classB];
expect(classA.lookUpGetter("g", library), isNull);
@@ -402,7 +433,7 @@
// get g {}
// }
LibraryElementImpl library = _newLibrary();
- ClassElementImpl classA = ElementFactory.classElement2("A");
+ var classA = class_(name: 'A');
String getterName = "g";
PropertyAccessorElement getter =
ElementFactory.getterElement(getterName, false, null);
@@ -419,12 +450,13 @@
// class B extends A {
// }
LibraryElementImpl library = _newLibrary();
- ClassElementImpl classA = ElementFactory.classElement2("A");
+ var classA = class_(name: 'A');
String getterName = "g";
PropertyAccessorElement inheritedGetter =
ElementFactory.getterElement(getterName, false, null);
classA.accessors = <PropertyAccessorElement>[inheritedGetter];
- ClassElementImpl classB = ElementFactory.classElement("B", classA.type);
+ ClassElementImpl classB =
+ ElementFactory.classElement("B", interfaceType(classA));
(library.definingCompilationUnit as CompilationUnitElementImpl).types =
<ClassElement>[classA, classB];
expect(classB.lookUpInheritedConcreteGetter(getterName, library),
@@ -435,7 +467,7 @@
// class A {
// }
LibraryElementImpl library = _newLibrary();
- ClassElementImpl classA = ElementFactory.classElement2("A");
+ var classA = class_(name: 'A');
(library.definingCompilationUnit as CompilationUnitElementImpl).types =
<ClassElement>[classA];
expect(classA.lookUpInheritedConcreteGetter("g", library), isNull);
@@ -447,9 +479,10 @@
// class B extends A {
// }
LibraryElementImpl library = _newLibrary();
- ClassElementImpl classA = ElementFactory.classElement2("A");
- ClassElementImpl classB = ElementFactory.classElement("B", classA.type);
- classA.supertype = classB.type;
+ var classA = class_(name: 'A');
+ ClassElementImpl classB =
+ ElementFactory.classElement("B", interfaceType(classA));
+ classA.supertype = interfaceType(classB);
(library.definingCompilationUnit as CompilationUnitElementImpl).types =
<ClassElement>[classA, classB];
expect(classA.lookUpInheritedConcreteGetter("g", library), isNull);
@@ -460,7 +493,7 @@
// m() {}
// }
LibraryElementImpl library = _newLibrary();
- ClassElementImpl classA = ElementFactory.classElement2("A");
+ var classA = class_(name: 'A');
String methodName = "m";
MethodElement method = ElementFactory.methodElement(methodName, null);
classA.methods = <MethodElement>[method];
@@ -477,12 +510,13 @@
// m();
// }
LibraryElementImpl library = _newLibrary();
- ClassElementImpl classA = ElementFactory.classElement2("A");
+ var classA = class_(name: 'A');
String methodName = "m";
MethodElement inheritedMethod =
ElementFactory.methodElement(methodName, null);
classA.methods = <MethodElement>[inheritedMethod];
- ClassElementImpl classB = ElementFactory.classElement("B", classA.type);
+ ClassElementImpl classB =
+ ElementFactory.classElement("B", interfaceType(classA));
MethodElementImpl method = ElementFactory.methodElement(methodName, null);
method.isAbstract = true;
classB.methods = <MethodElement>[method];
@@ -500,12 +534,13 @@
// m() {}
// }
LibraryElementImpl library = _newLibrary();
- ClassElementImpl classA = ElementFactory.classElement2("A");
+ var classA = class_(name: 'A');
String methodName = "m";
MethodElement inheritedMethod =
ElementFactory.methodElement(methodName, null);
classA.methods = <MethodElement>[inheritedMethod];
- ClassElementImpl classB = ElementFactory.classElement("B", classA.type);
+ ClassElementImpl classB =
+ ElementFactory.classElement("B", interfaceType(classA));
MethodElement method = ElementFactory.methodElement(methodName, null);
classB.methods = <MethodElement>[method];
(library.definingCompilationUnit as CompilationUnitElementImpl).types =
@@ -522,14 +557,15 @@
// m() {}
// }
LibraryElementImpl library = _newLibrary();
- ClassElementImpl classA = ElementFactory.classElement2("A");
+ var classA = class_(name: 'A');
classA.isAbstract = true;
String methodName = "m";
MethodElementImpl inheritedMethod =
ElementFactory.methodElement(methodName, null);
inheritedMethod.isAbstract = true;
classA.methods = <MethodElement>[inheritedMethod];
- ClassElementImpl classB = ElementFactory.classElement("B", classA.type);
+ ClassElementImpl classB =
+ ElementFactory.classElement("B", interfaceType(classA));
MethodElement method = ElementFactory.methodElement(methodName, null);
classB.methods = <MethodElement>[method];
(library.definingCompilationUnit as CompilationUnitElementImpl).types =
@@ -549,17 +585,19 @@
// m() {}
// }
LibraryElementImpl library = _newLibrary();
- ClassElementImpl classA = ElementFactory.classElement2("A");
+ var classA = class_(name: 'A');
String methodName = "m";
MethodElement inheritedMethod =
ElementFactory.methodElement(methodName, null);
classA.methods = <MethodElement>[inheritedMethod];
- ClassElementImpl classB = ElementFactory.classElement("B", classA.type);
+ ClassElementImpl classB =
+ ElementFactory.classElement("B", interfaceType(classA));
MethodElementImpl abstractMethod =
ElementFactory.methodElement(methodName, null);
abstractMethod.isAbstract = true;
classB.methods = <MethodElement>[abstractMethod];
- ClassElementImpl classC = ElementFactory.classElement("C", classB.type);
+ ClassElementImpl classC =
+ ElementFactory.classElement("C", interfaceType(classB));
MethodElementImpl method = ElementFactory.methodElement(methodName, null);
classC.methods = <MethodElement>[method];
(library.definingCompilationUnit as CompilationUnitElementImpl).types =
@@ -575,12 +613,13 @@
// class B extends A {
// }
LibraryElementImpl library = _newLibrary();
- ClassElementImpl classA = ElementFactory.classElement2("A");
+ var classA = class_(name: 'A');
String methodName = "m";
MethodElement inheritedMethod =
ElementFactory.methodElement(methodName, null);
classA.methods = <MethodElement>[inheritedMethod];
- ClassElementImpl classB = ElementFactory.classElement("B", classA.type);
+ ClassElementImpl classB =
+ ElementFactory.classElement("B", interfaceType(classA));
(library.definingCompilationUnit as CompilationUnitElementImpl).types =
<ClassElement>[classA, classB];
expect(classB.lookUpInheritedConcreteMethod(methodName, library),
@@ -591,7 +630,7 @@
// class A {
// }
LibraryElementImpl library = _newLibrary();
- ClassElementImpl classA = ElementFactory.classElement2("A");
+ var classA = class_(name: 'A');
(library.definingCompilationUnit as CompilationUnitElementImpl).types =
<ClassElement>[classA];
expect(classA.lookUpInheritedConcreteMethod("m", library), isNull);
@@ -602,7 +641,7 @@
// set g(x) {}
// }
LibraryElementImpl library = _newLibrary();
- ClassElementImpl classA = ElementFactory.classElement2("A");
+ var classA = class_(name: 'A');
String setterName = "s";
PropertyAccessorElement setter =
ElementFactory.setterElement(setterName, false, null);
@@ -619,12 +658,13 @@
// class B extends A {
// }
LibraryElementImpl library = _newLibrary();
- ClassElementImpl classA = ElementFactory.classElement2("A");
+ var classA = class_(name: 'A');
String setterName = "s";
PropertyAccessorElement setter =
ElementFactory.setterElement(setterName, false, null);
classA.accessors = <PropertyAccessorElement>[setter];
- ClassElementImpl classB = ElementFactory.classElement("B", classA.type);
+ ClassElementImpl classB =
+ ElementFactory.classElement("B", interfaceType(classA));
(library.definingCompilationUnit as CompilationUnitElementImpl).types =
<ClassElement>[classA, classB];
expect(classB.lookUpInheritedConcreteSetter(setterName, library),
@@ -635,7 +675,7 @@
// class A {
// }
LibraryElementImpl library = _newLibrary();
- ClassElementImpl classA = ElementFactory.classElement2("A");
+ var classA = class_(name: 'A');
(library.definingCompilationUnit as CompilationUnitElementImpl).types =
<ClassElement>[classA];
expect(classA.lookUpInheritedConcreteSetter("s", library), isNull);
@@ -647,9 +687,10 @@
// class B extends A {
// }
LibraryElementImpl library = _newLibrary();
- ClassElementImpl classA = ElementFactory.classElement2("A");
- ClassElementImpl classB = ElementFactory.classElement("B", classA.type);
- classA.supertype = classB.type;
+ var classA = class_(name: 'A');
+ ClassElementImpl classB =
+ ElementFactory.classElement("B", interfaceType(classA));
+ classA.supertype = interfaceType(classB);
(library.definingCompilationUnit as CompilationUnitElementImpl).types =
<ClassElement>[classA, classB];
expect(classA.lookUpInheritedConcreteSetter("s", library), isNull);
@@ -660,7 +701,7 @@
// m() {}
// }
LibraryElementImpl library = _newLibrary();
- ClassElementImpl classA = ElementFactory.classElement2("A");
+ var classA = class_(name: 'A');
String methodName = "m";
MethodElement method = ElementFactory.methodElement(methodName, null);
classA.methods = <MethodElement>[method];
@@ -677,12 +718,13 @@
// m() {}
// }
LibraryElementImpl library = _newLibrary();
- ClassElementImpl classA = ElementFactory.classElement2("A");
+ var classA = class_(name: 'A');
String methodName = "m";
MethodElement inheritedMethod =
ElementFactory.methodElement(methodName, null);
classA.methods = <MethodElement>[inheritedMethod];
- ClassElementImpl classB = ElementFactory.classElement("B", classA.type);
+ ClassElementImpl classB =
+ ElementFactory.classElement("B", interfaceType(classA));
MethodElement method = ElementFactory.methodElement(methodName, null);
classB.methods = <MethodElement>[method];
(library.definingCompilationUnit as CompilationUnitElementImpl).types =
@@ -698,12 +740,13 @@
// class B extends A {
// }
LibraryElementImpl library = _newLibrary();
- ClassElementImpl classA = ElementFactory.classElement2("A");
+ var classA = class_(name: 'A');
String methodName = "m";
MethodElement inheritedMethod =
ElementFactory.methodElement(methodName, null);
classA.methods = <MethodElement>[inheritedMethod];
- ClassElementImpl classB = ElementFactory.classElement("B", classA.type);
+ ClassElementImpl classB =
+ ElementFactory.classElement("B", interfaceType(classA));
(library.definingCompilationUnit as CompilationUnitElementImpl).types =
<ClassElement>[classA, classB];
expect(classB.lookUpInheritedMethod(methodName, library),
@@ -714,7 +757,7 @@
// class A {
// }
LibraryElementImpl library = _newLibrary();
- ClassElementImpl classA = ElementFactory.classElement2("A");
+ var classA = class_(name: 'A');
(library.definingCompilationUnit as CompilationUnitElementImpl).types =
<ClassElement>[classA];
expect(classA.lookUpInheritedMethod("m", library), isNull);
@@ -722,7 +765,7 @@
void test_lookUpMethod_declared() {
LibraryElementImpl library = _newLibrary();
- ClassElementImpl classA = ElementFactory.classElement2("A");
+ var classA = class_(name: 'A');
String methodName = "m";
MethodElement method = ElementFactory.methodElement(methodName, null);
classA.methods = <MethodElement>[method];
@@ -733,11 +776,12 @@
void test_lookUpMethod_inherited() {
LibraryElementImpl library = _newLibrary();
- ClassElementImpl classA = ElementFactory.classElement2("A");
+ var classA = class_(name: 'A');
String methodName = "m";
MethodElement method = ElementFactory.methodElement(methodName, null);
classA.methods = <MethodElement>[method];
- ClassElementImpl classB = ElementFactory.classElement("B", classA.type);
+ ClassElementImpl classB =
+ ElementFactory.classElement("B", interfaceType(classA));
(library.definingCompilationUnit as CompilationUnitElementImpl).types =
<ClassElement>[classA, classB];
expect(classB.lookUpMethod(methodName, library), same(method));
@@ -745,7 +789,7 @@
void test_lookUpMethod_undeclared() {
LibraryElementImpl library = _newLibrary();
- ClassElementImpl classA = ElementFactory.classElement2("A");
+ var classA = class_(name: 'A');
(library.definingCompilationUnit as CompilationUnitElementImpl).types =
<ClassElement>[classA];
expect(classA.lookUpMethod("m", library), isNull);
@@ -753,9 +797,10 @@
void test_lookUpMethod_undeclared_recursive() {
LibraryElementImpl library = _newLibrary();
- ClassElementImpl classA = ElementFactory.classElement2("A");
- ClassElementImpl classB = ElementFactory.classElement("B", classA.type);
- classA.supertype = classB.type;
+ var classA = class_(name: 'A');
+ ClassElementImpl classB =
+ ElementFactory.classElement("B", interfaceType(classA));
+ classA.supertype = interfaceType(classB);
(library.definingCompilationUnit as CompilationUnitElementImpl).types =
<ClassElement>[classA, classB];
expect(classA.lookUpMethod("m", library), isNull);
@@ -766,7 +811,7 @@
// set g(x) {}
// }
LibraryElementImpl library = _newLibrary();
- ClassElementImpl classA = ElementFactory.classElement2("A");
+ var classA = class_(name: 'A');
String setterName = "s";
PropertyAccessorElement setter =
ElementFactory.setterElement(setterName, false, null);
@@ -783,12 +828,13 @@
// class B extends A {
// }
LibraryElementImpl library = _newLibrary();
- ClassElementImpl classA = ElementFactory.classElement2("A");
+ var classA = class_(name: 'A');
String setterName = "s";
PropertyAccessorElement setter =
ElementFactory.setterElement(setterName, false, null);
classA.accessors = <PropertyAccessorElement>[setter];
- ClassElementImpl classB = ElementFactory.classElement("B", classA.type);
+ ClassElementImpl classB =
+ ElementFactory.classElement("B", interfaceType(classA));
(library.definingCompilationUnit as CompilationUnitElementImpl).types =
<ClassElement>[classA, classB];
expect(classB.lookUpSetter(setterName, library), same(setter));
@@ -798,7 +844,7 @@
// class A {
// }
LibraryElementImpl library = _newLibrary();
- ClassElementImpl classA = ElementFactory.classElement2("A");
+ var classA = class_(name: 'A');
(library.definingCompilationUnit as CompilationUnitElementImpl).types =
<ClassElement>[classA];
expect(classA.lookUpSetter("s", library), isNull);
@@ -810,9 +856,10 @@
// class B extends A {
// }
LibraryElementImpl library = _newLibrary();
- ClassElementImpl classA = ElementFactory.classElement2("A");
- ClassElementImpl classB = ElementFactory.classElement("B", classA.type);
- classA.supertype = classB.type;
+ var classA = class_(name: 'A');
+ ClassElementImpl classB =
+ ElementFactory.classElement("B", interfaceType(classA));
+ classA.supertype = interfaceType(classB);
(library.definingCompilationUnit as CompilationUnitElementImpl).types =
<ClassElement>[classA, classB];
expect(classA.lookUpSetter("s", library), isNull);
@@ -896,15 +943,23 @@
}
@reflectiveTest
-class ElementImplTest extends EngineTestCase {
+class ElementImplTest extends AbstractTypeTest {
void test_equals() {
LibraryElementImpl library =
- ElementFactory.library(createAnalysisContext(), "lib");
+ ElementFactory.library(_analysisContext, "lib");
ClassElementImpl classElement = ElementFactory.classElement2("C");
(library.definingCompilationUnit as CompilationUnitElementImpl).types =
<ClassElement>[classElement];
FieldElement field = ElementFactory.fieldElement(
- "next", false, false, false, classElement.type);
+ "next",
+ false,
+ false,
+ false,
+ classElement.instantiate(
+ typeArguments: [],
+ nullabilitySuffix: NullabilitySuffix.star,
+ ),
+ );
classElement.fields = <FieldElement>[field];
expect(field == field, isTrue);
expect(field == field.getter, isFalse);
@@ -913,18 +968,19 @@
}
void test_isAccessibleIn_private_differentLibrary() {
- AnalysisContext context = createAnalysisContext();
- LibraryElementImpl library1 = ElementFactory.library(context, "lib1");
+ LibraryElementImpl library1 =
+ ElementFactory.library(_analysisContext, "lib1");
ClassElement classElement = ElementFactory.classElement2("_C");
(library1.definingCompilationUnit as CompilationUnitElementImpl).types =
<ClassElement>[classElement];
- LibraryElementImpl library2 = ElementFactory.library(context, "lib2");
+ LibraryElementImpl library2 =
+ ElementFactory.library(_analysisContext, "lib2");
expect(classElement.isAccessibleIn(library2), isFalse);
}
void test_isAccessibleIn_private_sameLibrary() {
LibraryElementImpl library =
- ElementFactory.library(createAnalysisContext(), "lib");
+ ElementFactory.library(_analysisContext, "lib");
ClassElement classElement = ElementFactory.classElement2("_C");
(library.definingCompilationUnit as CompilationUnitElementImpl).types =
<ClassElement>[classElement];
@@ -932,18 +988,19 @@
}
void test_isAccessibleIn_public_differentLibrary() {
- AnalysisContext context = createAnalysisContext();
- LibraryElementImpl library1 = ElementFactory.library(context, "lib1");
+ LibraryElementImpl library1 =
+ ElementFactory.library(_analysisContext, "lib1");
ClassElement classElement = ElementFactory.classElement2("C");
(library1.definingCompilationUnit as CompilationUnitElementImpl).types =
<ClassElement>[classElement];
- LibraryElementImpl library2 = ElementFactory.library(context, "lib2");
+ LibraryElementImpl library2 =
+ ElementFactory.library(_analysisContext, "lib2");
expect(classElement.isAccessibleIn(library2), isTrue);
}
void test_isAccessibleIn_public_sameLibrary() {
LibraryElementImpl library =
- ElementFactory.library(createAnalysisContext(), "lib");
+ ElementFactory.library(_analysisContext, "lib");
ClassElement classElement = ElementFactory.classElement2("C");
(library.definingCompilationUnit as CompilationUnitElementImpl).types =
<ClassElement>[classElement];
@@ -981,7 +1038,7 @@
}
void test_SORT_BY_OFFSET() {
- ClassElementImpl classElementA = ElementFactory.classElement2("A");
+ ClassElementImpl classElementA = class_(name: 'A');
classElementA.nameOffset = 1;
ClassElementImpl classElementB = ElementFactory.classElement2("B");
classElementB.nameOffset = 2;
@@ -1075,7 +1132,7 @@
}
@reflectiveTest
-class FunctionTypeImplTest extends EngineTestCase {
+class FunctionTypeImplTest extends AbstractTypeTest {
void test_creation() {
expect(
new FunctionTypeImpl(
@@ -1088,13 +1145,16 @@
var t = ElementFactory.genericTypeAliasElement('t');
var u = ElementFactory.genericTypeAliasElement('u');
var v = ElementFactory.genericTypeAliasElement('v');
- s.function.returnType = t.type;
- t.function.returnType = s.type;
- u.function.returnType = v.type;
- v.function.returnType = u.type;
+ s.function.returnType = functionTypeAliasType(t);
+ t.function.returnType = functionTypeAliasType(s);
+ u.function.returnType = functionTypeAliasType(v);
+ v.function.returnType = functionTypeAliasType(u);
// We don't care whether the types compare equal or not. We just need the
// computation to terminate.
- expect(s.type == u.type, new TypeMatcher<bool>());
+ expect(
+ functionTypeAliasType(s) == functionTypeAliasType(u),
+ new TypeMatcher<bool>(),
+ );
}
void test_getElement() {
@@ -1239,16 +1299,16 @@
void test_hashCode_recursive() {
var s = ElementFactory.genericTypeAliasElement('s');
var t = ElementFactory.genericTypeAliasElement('t');
- s.function.returnType = t.type;
- t.function.returnType = s.type;
+ s.function.returnType = functionTypeAliasType(t);
+ t.function.returnType = functionTypeAliasType(s);
// We don't care what the hash code is. We just need its computation to
// terminate.
- expect(t.type.hashCode, new TypeMatcher<int>());
+ expect(functionTypeAliasType(t).hashCode, new TypeMatcher<int>());
}
void test_isAssignableTo_normalAndPositionalArgs() {
// ([a]) -> void <: (a) -> void
- ClassElement a = ElementFactory.classElement2("A");
+ ClassElement a = class_(name: 'A');
FunctionType t =
ElementFactory.functionElement6("t", null, <ClassElement>[a]).type;
FunctionType s =
@@ -1276,7 +1336,7 @@
// class C
// ! () -> void <: C
FunctionType f = ElementFactory.functionElement("f").type;
- InterfaceType t = ElementFactory.classElement2("C").type;
+ InterfaceType t = interfaceType(class_(name: 'C'));
expect(f.isSubtypeOf(t), isFalse);
}
@@ -1296,8 +1356,8 @@
// B extends A
// ({name: A}) -> void <: ({name: B}) -> void
// ({name: B}) -> void <: ({name: A}) -> void
- ClassElement a = ElementFactory.classElement2("A");
- ClassElement b = ElementFactory.classElement("B", a.type);
+ ClassElement a = class_(name: 'A');
+ ClassElement b = ElementFactory.classElement('B', interfaceType(a));
FunctionType t = ElementFactory.functionElement4(
"t", null, null, <String>["name"], <ClassElement>[a]).type;
FunctionType s = ElementFactory.functionElement4(
@@ -1308,12 +1368,8 @@
void test_isSubtypeOf_namedParameters_isNotAssignable() {
// ! ({name: A}) -> void <: ({name: B}) -> void
- FunctionType t = ElementFactory.functionElement4(
- "t",
- null,
- null,
- <String>["name"],
- <ClassElement>[ElementFactory.classElement2("A")]).type;
+ FunctionType t = ElementFactory.functionElement4("t", null, null,
+ <String>["name"], <ClassElement>[class_(name: 'A')]).type;
FunctionType s = ElementFactory.functionElement4(
"s",
null,
@@ -1329,8 +1385,8 @@
// void s({A diff}) {}
// ! t <: s
// ! s <: t
- ClassElement a = ElementFactory.classElement2("A");
- ClassElement b = ElementFactory.classElement("B", a.type);
+ ClassElement a = class_(name: 'A');
+ ClassElement b = ElementFactory.classElement('B', interfaceType(a));
FunctionType t = ElementFactory.functionElement4(
"t", null, null, <String>["name"], <ClassElement>[a]).type;
FunctionType s = ElementFactory.functionElement4(
@@ -1342,8 +1398,8 @@
void test_isSubtypeOf_namedParameters_orderOfParams() {
// B extends A
// ({A: A, B: B}) -> void <: ({B: B, A: A}) -> void
- ClassElement a = ElementFactory.classElement2("A");
- ClassElement b = ElementFactory.classElement("B", a.type);
+ ClassElement a = class_(name: 'A');
+ ClassElement b = ElementFactory.classElement('B', interfaceType(a));
FunctionType t = ElementFactory.functionElement4(
"t", null, null, <String>["A", "B"], <ClassElement>[a, b]).type;
FunctionType s = ElementFactory.functionElement4(
@@ -1354,8 +1410,8 @@
void test_isSubtypeOf_namedParameters_orderOfParams2() {
// B extends A
// ! ({B: B}) -> void <: ({B: B, A: A}) -> void
- ClassElement a = ElementFactory.classElement2("A");
- ClassElement b = ElementFactory.classElement("B", a.type);
+ ClassElement a = class_(name: 'A');
+ ClassElement b = ElementFactory.classElement('B', interfaceType(a));
FunctionType t = ElementFactory.functionElement4(
"t", null, null, <String>["B"], <ClassElement>[b]).type;
FunctionType s = ElementFactory.functionElement4(
@@ -1366,8 +1422,8 @@
void test_isSubtypeOf_namedParameters_orderOfParams3() {
// B extends A
// ({A: A, B: B}) -> void <: ({A: A}) -> void
- ClassElement a = ElementFactory.classElement2("A");
- ClassElement b = ElementFactory.classElement("B", a.type);
+ ClassElement a = class_(name: 'A');
+ ClassElement b = ElementFactory.classElement('B', interfaceType(a));
FunctionType t = ElementFactory.functionElement4(
"t", null, null, <String>["A", "B"], <ClassElement>[a, b]).type;
FunctionType s = ElementFactory.functionElement4(
@@ -1378,8 +1434,8 @@
void test_isSubtypeOf_namedParameters_sHasMoreParams() {
// B extends A
// ! ({name: A}) -> void <: ({name: B, name2: B}) -> void
- ClassElement a = ElementFactory.classElement2("A");
- ClassElement b = ElementFactory.classElement("B", a.type);
+ ClassElement a = class_(name: 'A');
+ ClassElement b = ElementFactory.classElement('B', interfaceType(a));
FunctionType t = ElementFactory.functionElement4(
"t", null, null, <String>["name"], <ClassElement>[a]).type;
FunctionType s = ElementFactory.functionElement4(
@@ -1390,8 +1446,8 @@
void test_isSubtypeOf_namedParameters_tHasMoreParams() {
// B extends A
// ({name: A, name2: A}) -> void <: ({name: B}) -> void
- ClassElement a = ElementFactory.classElement2("A");
- ClassElement b = ElementFactory.classElement("B", a.type);
+ ClassElement a = class_(name: 'A');
+ ClassElement b = ElementFactory.classElement('B', interfaceType(a));
FunctionType t = ElementFactory.functionElement4(
"t", null, null, <String>["name", "name2"], <ClassElement>[a, a]).type;
FunctionType s = ElementFactory.functionElement4(
@@ -1401,7 +1457,7 @@
void test_isSubtypeOf_normalAndPositionalArgs_1() {
// ([a]) -> void <: (a) -> void
- ClassElement a = ElementFactory.classElement2("A");
+ ClassElement a = class_(name: 'A');
FunctionType t =
ElementFactory.functionElement6("t", null, <ClassElement>[a]).type;
FunctionType s =
@@ -1412,7 +1468,7 @@
void test_isSubtypeOf_normalAndPositionalArgs_2() {
// (a, [a]) -> void <: (a) -> void
- ClassElement a = ElementFactory.classElement2("A");
+ ClassElement a = class_(name: 'A');
FunctionType t = ElementFactory.functionElement6(
"t", <ClassElement>[a], <ClassElement>[a]).type;
FunctionType s =
@@ -1423,7 +1479,7 @@
void test_isSubtypeOf_normalAndPositionalArgs_3() {
// ([a]) -> void <: () -> void
- ClassElement a = ElementFactory.classElement2("A");
+ ClassElement a = class_(name: 'A');
FunctionType t =
ElementFactory.functionElement6("t", null, <ClassElement>[a]).type;
FunctionType s = ElementFactory.functionElement("s").type;
@@ -1433,7 +1489,7 @@
void test_isSubtypeOf_normalAndPositionalArgs_4() {
// (a, b, [c, d, e]) -> void <: (a, b, c, [d]) -> void
- ClassElement a = ElementFactory.classElement2("A");
+ ClassElement a = class_(name: 'A');
ClassElement b = ElementFactory.classElement2("B");
ClassElement c = ElementFactory.classElement2("C");
ClassElement d = ElementFactory.classElement2("D");
@@ -1450,8 +1506,8 @@
// B extends A
// (a) -> void <: (b) -> void
// (b) -> void <: (a) -> void
- ClassElement a = ElementFactory.classElement2("A");
- ClassElement b = ElementFactory.classElement("B", a.type);
+ ClassElement a = class_(name: 'A');
+ ClassElement b = ElementFactory.classElement('B', interfaceType(a));
FunctionType t =
ElementFactory.functionElement5("t", <ClassElement>[a]).type;
FunctionType s =
@@ -1462,8 +1518,9 @@
void test_isSubtypeOf_normalParameters_isNotAssignable() {
// ! (a) -> void <: (b) -> void
- FunctionType t = ElementFactory.functionElement5(
- "t", <ClassElement>[ElementFactory.classElement2("A")]).type;
+ FunctionType t =
+ ElementFactory.functionElement5("t", <ClassElement>[class_(name: 'A')])
+ .type;
FunctionType s = ElementFactory.functionElement5(
"s", <ClassElement>[ElementFactory.classElement2("B")]).type;
expect(t.isSubtypeOf(s), isFalse);
@@ -1472,8 +1529,8 @@
void test_isSubtypeOf_normalParameters_sHasMoreParams() {
// B extends A
// ! (a) -> void <: (b, b) -> void
- ClassElement a = ElementFactory.classElement2("A");
- ClassElement b = ElementFactory.classElement("B", a.type);
+ ClassElement a = class_(name: 'A');
+ ClassElement b = ElementFactory.classElement('B', interfaceType(a));
FunctionType t =
ElementFactory.functionElement5("t", <ClassElement>[a]).type;
FunctionType s =
@@ -1484,8 +1541,8 @@
void test_isSubtypeOf_normalParameters_tHasMoreParams() {
// B extends A
// ! (a, a) -> void <: (a) -> void
- ClassElement a = ElementFactory.classElement2("A");
- ClassElement b = ElementFactory.classElement("B", a.type);
+ ClassElement a = class_(name: 'A');
+ ClassElement b = ElementFactory.classElement('B', interfaceType(a));
FunctionType t =
ElementFactory.functionElement5("t", <ClassElement>[a, a]).type;
FunctionType s =
@@ -1499,7 +1556,7 @@
void test_isSubtypeOf_Object() {
// () -> void <: Object
FunctionType f = ElementFactory.functionElement("f").type;
- InterfaceType t = ElementFactory.object.type;
+ InterfaceType t = typeProvider.objectType;
expect(f.isSubtypeOf(t), isTrue);
}
@@ -1507,8 +1564,8 @@
// B extends A
// ([a]) -> void <: ([b]) -> void
// ([b]) -> void <: ([a]) -> void
- ClassElement a = ElementFactory.classElement2("A");
- ClassElement b = ElementFactory.classElement("B", a.type);
+ ClassElement a = class_(name: 'A');
+ ClassElement b = ElementFactory.classElement('B', interfaceType(a));
FunctionType t =
ElementFactory.functionElement6("t", null, <ClassElement>[a]).type;
FunctionType s =
@@ -1520,7 +1577,7 @@
void test_isSubtypeOf_positionalParameters_isNotAssignable() {
// ! ([a]) -> void <: ([b]) -> void
FunctionType t = ElementFactory.functionElement6(
- "t", null, <ClassElement>[ElementFactory.classElement2("A")]).type;
+ "t", null, <ClassElement>[class_(name: 'A')]).type;
FunctionType s = ElementFactory.functionElement6(
"s", null, <ClassElement>[ElementFactory.classElement2("B")]).type;
expect(t.isSubtypeOf(s), isFalse);
@@ -1529,8 +1586,8 @@
void test_isSubtypeOf_positionalParameters_sHasMoreParams() {
// B extends A
// ! ([a]) -> void <: ([b, b]) -> void
- ClassElement a = ElementFactory.classElement2("A");
- ClassElement b = ElementFactory.classElement("B", a.type);
+ ClassElement a = class_(name: 'A');
+ ClassElement b = ElementFactory.classElement('B', interfaceType(a));
FunctionType t =
ElementFactory.functionElement6("t", null, <ClassElement>[a]).type;
FunctionType s =
@@ -1541,8 +1598,8 @@
void test_isSubtypeOf_positionalParameters_tHasMoreParams() {
// B extends A
// ([a, a]) -> void <: ([b]) -> void
- ClassElement a = ElementFactory.classElement2("A");
- ClassElement b = ElementFactory.classElement("B", a.type);
+ ClassElement a = class_(name: 'A');
+ ClassElement b = ElementFactory.classElement('B', interfaceType(a));
FunctionType t =
ElementFactory.functionElement6("t", null, <ClassElement>[a, a]).type;
FunctionType s =
@@ -1563,10 +1620,12 @@
// B extends A
// () -> A <: () -> B
// () -> B <: () -> A
- ClassElement a = ElementFactory.classElement2("A");
- ClassElement b = ElementFactory.classElement("B", a.type);
- FunctionType t = ElementFactory.functionElement2("t", a.type).type;
- FunctionType s = ElementFactory.functionElement2("s", b.type).type;
+ ClassElement a = class_(name: 'A');
+ ClassElement b = ElementFactory.classElement('B', interfaceType(a));
+ FunctionType t =
+ ElementFactory.functionElement2("t", interfaceType(a)).type;
+ FunctionType s =
+ ElementFactory.functionElement2("s", interfaceType(b)).type;
expect(t.isSubtypeOf(s), isTrue);
expect(s.isSubtypeOf(t), isTrue);
}
@@ -1574,11 +1633,11 @@
void test_isSubtypeOf_returnType_tNotAssignableToS() {
// ! () -> A <: () -> B
FunctionType t = ElementFactory.functionElement2(
- "t", ElementFactory.classElement2("A").type)
+ "t", interfaceType(ElementFactory.classElement2('A')))
.type;
- FunctionType s = ElementFactory.functionElement2(
- "s", ElementFactory.classElement2("B").type)
- .type;
+ FunctionType s =
+ ElementFactory.functionElement2("s", interfaceType(class_(name: 'B')))
+ .type;
expect(t.isSubtypeOf(s), isFalse);
}
@@ -1619,7 +1678,7 @@
void test_isSubtypeOf_wrongFunctionType_normal_named() {
// ! (a) -> void <: ({name: A}) -> void
// ! ({name: A}) -> void <: (a) -> void
- ClassElement a = ElementFactory.classElement2("A");
+ ClassElement a = class_(name: 'A');
FunctionType t =
ElementFactory.functionElement5("t", <ClassElement>[a]).type;
FunctionType s = ElementFactory.functionElement7(
@@ -1631,7 +1690,7 @@
void test_isSubtypeOf_wrongFunctionType_optional_named() {
// ! ([a]) -> void <: ({name: A}) -> void
// ! ({name: A}) -> void <: ([a]) -> void
- ClassElement a = ElementFactory.classElement2("A");
+ ClassElement a = class_(name: 'A');
FunctionType t =
ElementFactory.functionElement6("t", null, <ClassElement>[a]).type;
FunctionType s = ElementFactory.functionElement7(
@@ -1643,8 +1702,11 @@
void test_namedParameterTypes_pruned_no_type_arguments() {
var f = ElementFactory.genericTypeAliasElement('f');
var g = ElementFactory.genericTypeAliasElement('g');
- f.function.parameters = [ElementFactory.namedParameter2('x', g.type)];
- FunctionTypeImpl paramType = f.type.namedParameterTypes['x'];
+ f.function.parameters = [
+ ElementFactory.namedParameter2('x', functionTypeAliasType(g))
+ ];
+ FunctionTypeImpl paramType =
+ functionTypeAliasType(f).namedParameterTypes['x'];
expect(paramType.prunedTypedefs, hasLength(1));
expect(paramType.prunedTypedefs[0], same(f));
}
@@ -1653,15 +1715,19 @@
var f = ElementFactory.genericTypeAliasElement('f');
var g = ElementFactory.genericTypeAliasElement('g');
f.typeParameters = [ElementFactory.typeParameterElement('T')];
- f.function.parameters = [ElementFactory.namedParameter2('x', g.type)];
- FunctionTypeImpl paramType = f.type.namedParameterTypes['x'];
+ f.function.parameters = [
+ ElementFactory.namedParameter2('x', functionTypeAliasType(g))
+ ];
+ FunctionTypeImpl paramType =
+ functionTypeAliasType(f, typeArguments: [typeProvider.intType])
+ .namedParameterTypes['x'];
expect(paramType.prunedTypedefs, hasLength(1));
expect(paramType.prunedTypedefs[0], same(f));
}
void test_newPrune_no_previous_prune() {
var f = ElementFactory.genericTypeAliasElement('f');
- FunctionTypeImpl type = f.type;
+ FunctionTypeImpl type = functionTypeAliasType(f);
List<FunctionTypeAliasElement> pruneList = type.newPrune;
expect(pruneList, hasLength(1));
expect(pruneList[0], same(f));
@@ -1683,14 +1749,14 @@
// the user (and hence can't participate in circularities).
var f = ElementFactory.genericTypeAliasElement('f');
f.isSynthetic = true;
- FunctionTypeImpl type = f.type;
+ FunctionTypeImpl type = functionTypeAliasType(f);
expect(type.newPrune, isNull);
}
void test_newPrune_with_previous_prune() {
var f = ElementFactory.genericTypeAliasElement('f');
var g = ElementFactory.genericTypeAliasElement('g');
- FunctionTypeImpl type = f.type;
+ FunctionTypeImpl type = functionTypeAliasType(f);
FunctionTypeImpl prunedType = type.pruned([g]);
List<FunctionTypeAliasElement> pruneList = prunedType.newPrune;
expect(pruneList, hasLength(2));
@@ -1701,8 +1767,11 @@
void test_normalParameterTypes_pruned_no_type_arguments() {
var f = ElementFactory.genericTypeAliasElement('f');
var g = ElementFactory.genericTypeAliasElement('g');
- f.function.parameters = [ElementFactory.requiredParameter2('x', g.type)];
- FunctionTypeImpl paramType = f.type.normalParameterTypes[0];
+ f.function.parameters = [
+ ElementFactory.requiredParameter2('x', functionTypeAliasType(g))
+ ];
+ FunctionTypeImpl paramType =
+ functionTypeAliasType(f).normalParameterTypes[0];
expect(paramType.prunedTypedefs, hasLength(1));
expect(paramType.prunedTypedefs[0], same(f));
}
@@ -1711,8 +1780,12 @@
var f = ElementFactory.genericTypeAliasElement('f');
var g = ElementFactory.genericTypeAliasElement('g');
f.typeParameters = [ElementFactory.typeParameterElement('T')];
- f.function.parameters = [ElementFactory.requiredParameter2('x', g.type)];
- FunctionTypeImpl paramType = f.type.normalParameterTypes[0];
+ f.function.parameters = [
+ ElementFactory.requiredParameter2('x', functionTypeAliasType(g))
+ ];
+ FunctionTypeImpl paramType =
+ functionTypeAliasType(f, typeArguments: [typeProvider.intType])
+ .normalParameterTypes[0];
expect(paramType.prunedTypedefs, hasLength(1));
expect(paramType.prunedTypedefs[0], same(f));
}
@@ -1720,8 +1793,11 @@
void test_optionalParameterTypes_pruned_no_type_arguments() {
var f = ElementFactory.genericTypeAliasElement('f');
var g = ElementFactory.genericTypeAliasElement('g');
- f.function.parameters = [ElementFactory.positionalParameter2('x', g.type)];
- FunctionTypeImpl paramType = f.type.optionalParameterTypes[0];
+ f.function.parameters = [
+ ElementFactory.positionalParameter2('x', functionTypeAliasType(g))
+ ];
+ FunctionTypeImpl paramType =
+ functionTypeAliasType(f).optionalParameterTypes[0];
expect(paramType.prunedTypedefs, hasLength(1));
expect(paramType.prunedTypedefs[0], same(f));
}
@@ -1730,8 +1806,12 @@
var f = ElementFactory.genericTypeAliasElement('f');
var g = ElementFactory.genericTypeAliasElement('g');
f.typeParameters = [ElementFactory.typeParameterElement('T')];
- f.function.parameters = [ElementFactory.positionalParameter2('x', g.type)];
- FunctionTypeImpl paramType = f.type.optionalParameterTypes[0];
+ f.function.parameters = [
+ ElementFactory.positionalParameter2('x', functionTypeAliasType(g))
+ ];
+ FunctionTypeImpl paramType =
+ functionTypeAliasType(f, typeArguments: [typeProvider.intType])
+ .optionalParameterTypes[0];
expect(paramType.prunedTypedefs, hasLength(1));
expect(paramType.prunedTypedefs[0], same(f));
}
@@ -1747,8 +1827,8 @@
void test_returnType_pruned_no_type_arguments() {
var f = ElementFactory.genericTypeAliasElement('f');
var g = ElementFactory.genericTypeAliasElement('g');
- f.function.returnType = g.type;
- FunctionTypeImpl paramType = f.type.returnType;
+ f.function.returnType = functionTypeAliasType(g);
+ FunctionTypeImpl paramType = functionTypeAliasType(f).returnType;
expect(paramType.prunedTypedefs, hasLength(1));
expect(paramType.prunedTypedefs[0], same(f));
}
@@ -1757,15 +1837,18 @@
var f = ElementFactory.genericTypeAliasElement('f');
var g = ElementFactory.genericTypeAliasElement('g');
f.typeParameters = [ElementFactory.typeParameterElement('T')];
- f.function.returnType = g.type;
- FunctionTypeImpl paramType = f.type.returnType;
+ f.function.returnType = functionTypeAliasType(g);
+ FunctionTypeImpl paramType =
+ functionTypeAliasType(f, typeArguments: [typeProvider.intType])
+ .returnType;
expect(paramType.prunedTypedefs, hasLength(1));
expect(paramType.prunedTypedefs[0], same(f));
}
void test_substitute2_equal() {
ClassElementImpl definingClass = ElementFactory.classElement2("C", ["E"]);
- TypeParameterType parameterType = definingClass.typeParameters[0].type;
+ TypeParameterType parameterType =
+ typeParameterType(definingClass.typeParameters[0]);
MethodElementImpl functionElement =
new MethodElementImpl.forNode(AstTestFactory.identifier3("m"));
String namedParameterName = "c";
@@ -1833,16 +1916,19 @@
void test_toString_recursive() {
var t = ElementFactory.genericTypeAliasElement("t");
var s = ElementFactory.genericTypeAliasElement("s");
- t.function.returnType = s.type;
- s.function.returnType = t.type;
- expect(t.type.toString(), '... Function() Function()');
+ t.function.returnType = functionTypeAliasType(s);
+ s.function.returnType = functionTypeAliasType(t);
+ expect(functionTypeAliasType(t).toString(), '... Function() Function()');
}
void test_toString_recursive_via_interface_type() {
var f = ElementFactory.genericTypeAliasElement('f');
ClassElementImpl c = ElementFactory.classElement2('C', ['T']);
- f.function.returnType = c.type.instantiate([f.type]);
- expect(f.type.toString(), 'C<...> Function()');
+ f.function.returnType = c.instantiate(
+ typeArguments: [functionTypeAliasType(f)],
+ nullabilitySuffix: NullabilitySuffix.star,
+ );
+ expect(functionTypeAliasType(f).toString(), 'C<...> Function()');
}
void test_typeParameters_genericLocalFunction_genericMethod_genericClass() {
@@ -1863,7 +1949,7 @@
FunctionElementImpl function = ElementFactory.functionElement('f');
function.enclosingElement = method;
function.typeParameters = ElementFactory.typeParameters(['U']);
- function.returnType = function.typeParameters[0].type;
+ function.returnType = typeParameterType(function.typeParameters[0]);
function.type = new FunctionTypeImpl(function);
List<TypeParameterElement> inheritedParameters = <TypeParameterElement>[];
@@ -1902,7 +1988,7 @@
// Object m<T>() => null;
// }
//
- ClassElementImpl classElement = ElementFactory.classElement2('C');
+ ClassElementImpl classElement = class_(name: 'C');
MethodElementImpl method = new MethodElementImpl('m', 0);
method.enclosingElement = classElement;
method.returnType = ElementFactory.objectType;
@@ -1957,7 +2043,7 @@
// Object m<T>() => null;
// }
//
- ClassElementImpl classElement = ElementFactory.classElement2('C');
+ ClassElementImpl classElement = class_(name: 'C');
MethodElementImpl method = new MethodElementImpl('m', 0);
method.enclosingElement = classElement;
method.typeParameters = ElementFactory.typeParameters(['T']);
@@ -1977,68 +2063,85 @@
new MethodElementImpl.forNode(AstTestFactory.identifier3("m"));
enclosingClass.methods = <MethodElement>[methodElement];
FunctionTypeImpl type = new FunctionTypeImpl(methodElement);
- DartType expectedType = enclosingClass.typeParameters[0].type;
+ DartType expectedType = typeParameterType(enclosingClass.typeParameters[0]);
List<DartType> arguments = type.typeArguments;
expect(arguments, hasLength(1));
expect(arguments[0], expectedType);
}
Iterable<DartType> _toTypes(List<TypeParameterElement> typeParameters) {
- return typeParameters.map((TypeParameterElement element) => element.type);
+ return typeParameters
+ .map((TypeParameterElement element) => typeParameterType(element));
}
}
@reflectiveTest
-class InterfaceTypeImplTest extends EngineTestCase {
- /**
- * The type provider used to access the types.
- */
- TestTypeProvider _typeProvider;
-
- @override
- void setUp() {
- super.setUp();
- _typeProvider = new TestTypeProvider();
- }
-
+class InterfaceTypeImplTest extends AbstractTypeTest {
test_asInstanceOf_explicitGeneric() {
// class A<E> {}
// class B implements A<C> {}
// class C {}
- ClassElementImpl classA = ElementFactory.classElement2('A', ['E']);
- ClassElementImpl classB = ElementFactory.classElement2('B');
- ClassElementImpl classC = ElementFactory.classElement2('C');
- classB.interfaces = <InterfaceType>[
- classA.type.instantiate([classC.type])
- ];
+ var A = class_(name: 'A', typeParameters: [
+ typeParameter('E'),
+ ]);
+ var B = class_(name: 'B');
+ var C = class_(name: 'C');
- InterfaceTypeImpl targetType = classB.type as InterfaceTypeImpl;
- InterfaceType result = targetType.asInstanceOf(classA);
- expect(result, classA.type.instantiate([classC.type]));
+ var AofC = A.instantiate(
+ typeArguments: [
+ interfaceType(C),
+ ],
+ nullabilitySuffix: NullabilitySuffix.star,
+ );
+
+ B.interfaces = <InterfaceType>[AofC];
+
+ InterfaceTypeImpl targetType = interfaceType(B);
+ InterfaceType result = targetType.asInstanceOf(A);
+ expect(result, AofC);
}
test_asInstanceOf_passThroughGeneric() {
// class A<E> {}
// class B<E> implements A<E> {}
- ClassElementImpl classA = ElementFactory.classElement2('A', ['E']);
- ClassElementImpl classB = ElementFactory.classElement2('B', ['E']);
- ClassElementImpl classC = ElementFactory.classElement2('C');
- classB.interfaces = <InterfaceType>[
- classA.type.instantiate([classB.typeParameters[0].type])
- ];
+ // class C {}
+ var AE = typeParameter('E');
+ var A = class_(name: 'A', typeParameters: [AE]);
- InterfaceTypeImpl targetType =
- classB.type.instantiate([classC.type]) as InterfaceTypeImpl;
- InterfaceType result = targetType.asInstanceOf(classA);
- expect(result, classA.type.instantiate([classC.type]));
+ var BE = typeParameter('E');
+ var B = class_(
+ name: 'B',
+ typeParameters: [BE],
+ interfaces: [
+ A.instantiate(
+ typeArguments: [typeParameterType(BE)],
+ nullabilitySuffix: NullabilitySuffix.star,
+ ),
+ ],
+ );
+
+ var C = class_(name: 'C');
+
+ InterfaceTypeImpl targetType = B.instantiate(
+ typeArguments: [interfaceType(C)],
+ nullabilitySuffix: NullabilitySuffix.star,
+ );
+ InterfaceType result = targetType.asInstanceOf(A);
+ expect(
+ result,
+ A.instantiate(
+ typeArguments: [interfaceType(C)],
+ nullabilitySuffix: NullabilitySuffix.star,
+ ),
+ );
}
void test_creation() {
- expect(new InterfaceTypeImpl(ElementFactory.classElement2("A")), isNotNull);
+ expect(new InterfaceTypeImpl(class_(name: 'A')), isNotNull);
}
void test_getAccessors() {
- ClassElementImpl typeElement = ElementFactory.classElement2("A");
+ ClassElementImpl typeElement = class_(name: 'A');
PropertyAccessorElement getterG =
ElementFactory.getterElement("g", false, null);
PropertyAccessorElement getterH =
@@ -2049,13 +2152,13 @@
}
void test_getAccessors_empty() {
- ClassElementImpl typeElement = ElementFactory.classElement2("A");
+ ClassElementImpl typeElement = class_(name: 'A');
InterfaceTypeImpl type = new InterfaceTypeImpl(typeElement);
expect(type.accessors.length, 0);
}
void test_getConstructors() {
- ClassElementImpl typeElement = ElementFactory.classElement2("A");
+ ClassElementImpl typeElement = class_(name: 'A');
ConstructorElementImpl constructorOne =
ElementFactory.constructorElement(typeElement, 'one', false);
ConstructorElementImpl constructorTwo =
@@ -2069,14 +2172,14 @@
}
void test_getConstructors_empty() {
- ClassElementImpl typeElement = ElementFactory.classElement2("A");
+ ClassElementImpl typeElement = class_(name: 'A');
typeElement.constructors = const <ConstructorElement>[];
InterfaceTypeImpl type = new InterfaceTypeImpl(typeElement);
expect(type.constructors, isEmpty);
}
void test_getElement() {
- ClassElementImpl typeElement = ElementFactory.classElement2("A");
+ ClassElementImpl typeElement = class_(name: 'A');
InterfaceTypeImpl type = new InterfaceTypeImpl(typeElement);
expect(type.element, typeElement);
}
@@ -2085,12 +2188,12 @@
//
// class A { g {} }
//
- ClassElementImpl classA = ElementFactory.classElement2("A");
+ var classA = class_(name: 'A');
String getterName = "g";
PropertyAccessorElement getterG =
ElementFactory.getterElement(getterName, false, null);
classA.accessors = <PropertyAccessorElement>[getterG];
- InterfaceType typeA = classA.type;
+ InterfaceType typeA = interfaceType(classA);
expect(typeA.getGetter(getterName), same(getterG));
}
@@ -2098,31 +2201,36 @@
//
// class A<E> { E get g {} }
//
- ClassElementImpl classA = ElementFactory.classElement2("A", ["E"]);
- DartType typeE = classA.type.typeArguments[0];
+ var AE = typeParameter('E');
+ var A = class_(name: 'A', typeParameters: [AE]);
+
+ DartType typeAE = typeParameterType(AE);
String getterName = "g";
PropertyAccessorElementImpl getterG =
- ElementFactory.getterElement(getterName, false, typeE);
- classA.accessors = <PropertyAccessorElement>[getterG];
+ ElementFactory.getterElement(getterName, false, typeAE);
+ A.accessors = <PropertyAccessorElement>[getterG];
getterG.type = new FunctionTypeImpl(getterG);
//
// A<I>
//
- InterfaceType typeI = ElementFactory.classElement2("I").type;
- InterfaceTypeImpl typeAI = new InterfaceTypeImpl(classA);
- typeAI.typeArguments = <DartType>[typeI];
- PropertyAccessorElement getter = typeAI.getGetter(getterName);
+ InterfaceType I = interfaceType(class_(name: 'I'));
+ InterfaceTypeImpl AofI = A.instantiate(
+ typeArguments: [I],
+ nullabilitySuffix: NullabilitySuffix.star,
+ );
+
+ PropertyAccessorElement getter = AofI.getGetter(getterName);
expect(getter, isNotNull);
FunctionType getterType = getter.type;
- expect(getterType.returnType, same(typeI));
+ expect(getterType.returnType, same(I));
}
void test_getGetter_unimplemented() {
//
// class A {}
//
- ClassElementImpl classA = ElementFactory.classElement2("A");
- InterfaceType typeA = classA.type;
+ var classA = class_(name: 'A');
+ InterfaceType typeA = interfaceType(classA);
expect(typeA.getGetter("g"), isNull);
}
@@ -2130,13 +2238,13 @@
//
// class C implements A, B
//
- ClassElementImpl classA = ElementFactory.classElement2("A");
- InterfaceType typeA = classA.type;
- ClassElementImpl classB = ElementFactory.classElement2("B");
- InterfaceType typeB = classB.type;
- ClassElementImpl classC = ElementFactory.classElement2("C");
+ var classA = class_(name: 'A');
+ InterfaceType typeA = interfaceType(classA);
+ var classB = ElementFactory.classElement2("B");
+ InterfaceType typeB = interfaceType(classB);
+ var classC = ElementFactory.classElement2("C");
classC.interfaces = <InterfaceType>[typeA, typeB];
- List<InterfaceType> interfaces = classC.type.interfaces;
+ List<InterfaceType> interfaces = interfaceType(classC).interfaces;
expect(interfaces, hasLength(2));
if (identical(interfaces[0], typeA)) {
expect(interfaces[1], same(typeB));
@@ -2151,22 +2259,29 @@
// class A<E>
// class B<F> implements A<F>
//
- ClassElementImpl classA = ElementFactory.classElement2("A", ["E"]);
- ClassElementImpl classB = ElementFactory.classElement2("B", ["F"]);
- InterfaceType typeB = classB.type;
- InterfaceTypeImpl typeAF = new InterfaceTypeImpl(classA);
- typeAF.typeArguments = <DartType>[typeB.typeArguments[0]];
- classB.interfaces = <InterfaceType>[typeAF];
+ var E = typeParameter('E');
+ var A = class_(name: 'A', typeParameters: [E]);
+ var F = typeParameter('F');
+ var B = class_(
+ name: 'B',
+ typeParameters: [F],
+ interfaces: [
+ A.instantiate(
+ typeArguments: [typeParameterType(F)],
+ nullabilitySuffix: NullabilitySuffix.star,
+ )
+ ],
+ );
//
// B<I>
//
- InterfaceType typeI = ElementFactory.classElement2("I").type;
- InterfaceTypeImpl typeBI = new InterfaceTypeImpl(classB);
- typeBI.typeArguments = <DartType>[typeI];
+ InterfaceType typeI = interfaceType(class_(name: 'I'));
+ InterfaceTypeImpl typeBI = interfaceType(B, typeArguments: [typeI]);
+
List<InterfaceType> interfaces = typeBI.interfaces;
expect(interfaces, hasLength(1));
InterfaceType result = interfaces[0];
- expect(result.element, same(classA));
+ expect(result.element, same(A));
expect(result.typeArguments[0], same(typeI));
}
@@ -2174,11 +2289,11 @@
//
// class A { m() {} }
//
- ClassElementImpl classA = ElementFactory.classElement2("A");
+ var classA = class_(name: 'A');
String methodName = "m";
MethodElementImpl methodM = ElementFactory.methodElement(methodName, null);
classA.methods = <MethodElement>[methodM];
- InterfaceType typeA = classA.type;
+ InterfaceType typeA = interfaceType(classA);
expect(typeA.getMethod(methodName), same(methodM));
}
@@ -2187,8 +2302,8 @@
// class A<E> { B m() {} }
// class B {}
//
- ClassElementImpl classA = ElementFactory.classElement2("A", ["E"]);
- InterfaceType typeB = ElementFactory.classElement2("B").type;
+ var classA = ElementFactory.classElement2("A", ["E"]);
+ InterfaceType typeB = interfaceType(class_(name: 'B'));
String methodName = "m";
MethodElementImpl methodM =
ElementFactory.methodElement(methodName, typeB, []);
@@ -2197,7 +2312,7 @@
//
// A<I>
//
- InterfaceType typeI = ElementFactory.classElement2("I").type;
+ InterfaceType typeI = interfaceType(class_(name: 'I'));
InterfaceTypeImpl typeAI = new InterfaceTypeImpl(classA);
typeAI.typeArguments = <DartType>[typeI];
MethodElement method = typeAI.getMethod(methodName);
@@ -2211,24 +2326,25 @@
//
// class A<E> { E m(E p) {} }
//
- ClassElementImpl classA = ElementFactory.classElement2("A", ["E"]);
- DartType typeE = classA.type.typeArguments[0];
+ var E = typeParameter('E');
+ var A = class_(name: 'A', typeParameters: [E]);
+ DartType typeE = typeParameterType(E);
String methodName = "m";
MethodElementImpl methodM =
ElementFactory.methodElement(methodName, typeE, [typeE]);
- classA.methods = <MethodElement>[methodM];
+ A.methods = <MethodElement>[methodM];
methodM.type = new FunctionTypeImpl(methodM);
//
// A<I>
//
- InterfaceType typeI = ElementFactory.classElement2("I").type;
- InterfaceTypeImpl typeAI = new InterfaceTypeImpl(classA);
+ InterfaceType typeI = interfaceType(class_(name: 'I'));
+ InterfaceTypeImpl typeAI = new InterfaceTypeImpl(A);
typeAI.typeArguments = <DartType>[typeI];
// Methods list is cached.
MethodElement method = typeAI.methods.single;
expect(typeAI.methods.single, same(method));
// Methods list is flushed on version change.
- classA.version++;
+ A.version++;
expect(typeAI.methods.single, isNot(same(method)));
}
@@ -2236,18 +2352,19 @@
//
// class A<E> { E m(E p) {} }
//
- ClassElementImpl classA = ElementFactory.classElement2("A", ["E"]);
- DartType typeE = classA.type.typeArguments[0];
+ var E = typeParameter('E');
+ var A = class_(name: 'A', typeParameters: [E]);
+ DartType typeE = typeParameterType(E);
String methodName = "m";
MethodElementImpl methodM =
ElementFactory.methodElement(methodName, typeE, [typeE]);
- classA.methods = <MethodElement>[methodM];
+ A.methods = <MethodElement>[methodM];
methodM.type = new FunctionTypeImpl(methodM);
//
// A<I>
//
- InterfaceType typeI = ElementFactory.classElement2("I").type;
- InterfaceTypeImpl typeAI = new InterfaceTypeImpl(classA);
+ InterfaceType typeI = interfaceType(class_(name: 'I'));
+ InterfaceTypeImpl typeAI = new InterfaceTypeImpl(A);
typeAI.typeArguments = <DartType>[typeI];
MethodElement method = typeAI.getMethod(methodName);
expect(method, isNotNull);
@@ -2264,13 +2381,13 @@
//
// class A {}
//
- ClassElementImpl classA = ElementFactory.classElement2("A");
- InterfaceType typeA = classA.type;
+ var classA = class_(name: 'A');
+ InterfaceType typeA = interfaceType(classA);
expect(typeA.getMethod("m"), isNull);
}
void test_getMethods() {
- ClassElementImpl typeElement = ElementFactory.classElement2("A");
+ ClassElementImpl typeElement = class_(name: 'A');
MethodElementImpl methodOne = ElementFactory.methodElement("one", null);
MethodElementImpl methodTwo = ElementFactory.methodElement("two", null);
typeElement.methods = <MethodElement>[methodOne, methodTwo];
@@ -2279,7 +2396,7 @@
}
void test_getMethods_empty() {
- ClassElementImpl typeElement = ElementFactory.classElement2("A");
+ ClassElementImpl typeElement = class_(name: 'A');
InterfaceTypeImpl type = new InterfaceTypeImpl(typeElement);
expect(type.methods.length, 0);
}
@@ -2288,13 +2405,13 @@
//
// class C extends Object with A, B
//
- ClassElementImpl classA = ElementFactory.classElement2("A");
- InterfaceType typeA = classA.type;
- ClassElementImpl classB = ElementFactory.classElement2("B");
- InterfaceType typeB = classB.type;
- ClassElementImpl classC = ElementFactory.classElement2("C");
+ var classA = class_(name: 'A');
+ InterfaceType typeA = interfaceType(classA);
+ var classB = ElementFactory.classElement2("B");
+ InterfaceType typeB = interfaceType(classB);
+ var classC = ElementFactory.classElement2("C");
classC.mixins = <InterfaceType>[typeA, typeB];
- List<InterfaceType> interfaces = classC.type.mixins;
+ List<InterfaceType> interfaces = interfaceType(classC).mixins;
expect(interfaces, hasLength(2));
if (identical(interfaces[0], typeA)) {
expect(interfaces[1], same(typeB));
@@ -2309,22 +2426,29 @@
// class A<E>
// class B<F> extends Object with A<F>
//
- ClassElementImpl classA = ElementFactory.classElement2("A", ["E"]);
- ClassElementImpl classB = ElementFactory.classElement2("B", ["F"]);
- InterfaceType typeB = classB.type;
- InterfaceTypeImpl typeAF = new InterfaceTypeImpl(classA);
- typeAF.typeArguments = <DartType>[typeB.typeArguments[0]];
- classB.mixins = <InterfaceType>[typeAF];
+ var E = typeParameter('E');
+ var A = class_(name: 'A', typeParameters: [E]);
+
+ var F = typeParameter('F');
+ var B = class_(
+ name: 'B',
+ typeParameters: [F],
+ mixins: [
+ interfaceType(A, typeArguments: [
+ typeParameterType(F),
+ ]),
+ ],
+ );
//
// B<I>
//
- InterfaceType typeI = ElementFactory.classElement2("I").type;
- InterfaceTypeImpl typeBI = new InterfaceTypeImpl(classB);
+ InterfaceType typeI = interfaceType(class_(name: 'I'));
+ InterfaceTypeImpl typeBI = new InterfaceTypeImpl(B);
typeBI.typeArguments = <DartType>[typeI];
List<InterfaceType> interfaces = typeBI.mixins;
expect(interfaces, hasLength(1));
InterfaceType result = interfaces[0];
- expect(result.element, same(classA));
+ expect(result.element, same(A));
expect(result.typeArguments[0], same(typeI));
}
@@ -2332,12 +2456,12 @@
//
// class A { s() {} }
//
- ClassElementImpl classA = ElementFactory.classElement2("A");
+ var classA = class_(name: 'A');
String setterName = "s";
PropertyAccessorElement setterS =
ElementFactory.setterElement(setterName, false, null);
classA.accessors = <PropertyAccessorElement>[setterS];
- InterfaceType typeA = classA.type;
+ InterfaceType typeA = interfaceType(classA);
expect(typeA.getSetter(setterName), same(setterS));
}
@@ -2345,18 +2469,19 @@
//
// class A<E> { set s(E p) {} }
//
- ClassElementImpl classA = ElementFactory.classElement2("A", ["E"]);
- DartType typeE = classA.type.typeArguments[0];
+ var E = typeParameter('E');
+ var A = class_(name: 'A', typeParameters: [E]);
+ DartType typeE = typeParameterType(E);
String setterName = "s";
PropertyAccessorElementImpl setterS =
ElementFactory.setterElement(setterName, false, typeE);
- classA.accessors = <PropertyAccessorElement>[setterS];
+ A.accessors = <PropertyAccessorElement>[setterS];
setterS.type = new FunctionTypeImpl(setterS);
//
// A<I>
//
- InterfaceType typeI = ElementFactory.classElement2("I").type;
- InterfaceTypeImpl typeAI = new InterfaceTypeImpl(classA);
+ InterfaceType typeI = interfaceType(class_(name: 'I'));
+ InterfaceTypeImpl typeAI = new InterfaceTypeImpl(A);
typeAI.typeArguments = <DartType>[typeI];
PropertyAccessorElement setter = typeAI.getSetter(setterName);
expect(setter, isNotNull);
@@ -2370,8 +2495,8 @@
//
// class A {}
//
- ClassElementImpl classA = ElementFactory.classElement2("A");
- InterfaceType typeA = classA.type;
+ var classA = class_(name: 'A');
+ InterfaceType typeA = interfaceType(classA);
expect(typeA.getSetter("s"), isNull);
}
@@ -2379,10 +2504,10 @@
//
// class B extends A
//
- ClassElementImpl classA = ElementFactory.classElement2("A");
- InterfaceType typeA = classA.type;
- ClassElementImpl classB = ElementFactory.classElement("B", typeA);
- InterfaceType typeB = classB.type;
+ var classA = class_(name: 'A');
+ InterfaceType typeA = interfaceType(classA);
+ var classB = ElementFactory.classElement("B", typeA);
+ InterfaceType typeB = interfaceType(classB);
expect(typeB.superclass, same(typeA));
}
@@ -2391,31 +2516,38 @@
// class A<E>
// class B<F> extends A<F>
//
- ClassElementImpl classA = ElementFactory.classElement2("A", ["E"]);
- ClassElementImpl classB = ElementFactory.classElement2("B", ["F"]);
- InterfaceType typeB = classB.type;
- InterfaceTypeImpl typeAF = new InterfaceTypeImpl(classA);
- typeAF.typeArguments = <DartType>[typeB.typeArguments[0]];
- classB.supertype = typeAF;
+ var E = typeParameter('E');
+ var A = class_(name: 'A', typeParameters: [E]);
+
+ var F = typeParameter('F');
+ var typeF = typeParameterType(F);
+
+ var B = class_(
+ name: 'B',
+ typeParameters: [F],
+ superType: interfaceType(A, typeArguments: [typeF]),
+ );
+
+ var classB = B;
//
// B<I>
//
- InterfaceType typeI = ElementFactory.classElement2("I").type;
+ InterfaceType typeI = interfaceType(class_(name: 'I'));
InterfaceTypeImpl typeBI = new InterfaceTypeImpl(classB);
typeBI.typeArguments = <DartType>[typeI];
InterfaceType superclass = typeBI.superclass;
- expect(superclass.element, same(classA));
+ expect(superclass.element, same(A));
expect(superclass.typeArguments[0], same(typeI));
}
void test_getTypeArguments_empty() {
- InterfaceType type = ElementFactory.classElement2("A").type;
+ InterfaceType type = interfaceType(ElementFactory.classElement2('A'));
expect(type.typeArguments, hasLength(0));
}
void test_hashCode() {
- ClassElement classA = ElementFactory.classElement2("A");
- InterfaceType typeA = classA.type;
+ ClassElement classA = class_(name: 'A');
+ InterfaceType typeA = interfaceType(classA);
expect(0 == typeA.hashCode, isFalse);
}
@@ -2432,9 +2564,13 @@
ClassElement classA = ElementFactory.classElement2("A", ["E"]);
ClassElement classB = ElementFactory.classElement2("B", ["F", "G"]);
InterfaceTypeImpl typeAF = new InterfaceTypeImpl(classA);
- typeAF.typeArguments = <DartType>[classB.typeParameters[0].type];
+ typeAF.typeArguments = <DartType>[
+ typeParameterType(classB.typeParameters[0])
+ ];
InterfaceTypeImpl typeAG = new InterfaceTypeImpl(classA);
- typeAG.typeArguments = <DartType>[classB.typeParameters[1].type];
+ typeAG.typeArguments = <DartType>[
+ typeParameterType(classB.typeParameters[1])
+ ];
expect(typeAG.isAssignableTo(typeAF), isFalse);
}
@@ -2444,66 +2580,70 @@
}
void test_isDirectSupertypeOf_extends() {
- ClassElement classA = ElementFactory.classElement2("A");
- ClassElement classB = ElementFactory.classElement("B", classA.type);
- InterfaceType typeA = classA.type;
- InterfaceType typeB = classB.type;
+ ClassElement classA = class_(name: 'A');
+ ClassElement classB =
+ ElementFactory.classElement("B", interfaceType(classA));
+ InterfaceType typeA = interfaceType(classA);
+ InterfaceType typeB = interfaceType(classB);
// ignore: deprecated_member_use_from_same_package
expect(typeA.isDirectSupertypeOf(typeB), isTrue);
}
void test_isDirectSupertypeOf_false() {
- ClassElement classA = ElementFactory.classElement2("A");
+ ClassElement classA = class_(name: 'A');
ClassElement classB = ElementFactory.classElement2("B");
- ClassElement classC = ElementFactory.classElement("C", classB.type);
- InterfaceType typeA = classA.type;
- InterfaceType typeC = classC.type;
+ ClassElement classC =
+ ElementFactory.classElement("C", interfaceType(classB));
+ InterfaceType typeA = interfaceType(classA);
+ InterfaceType typeC = interfaceType(classC);
// ignore: deprecated_member_use_from_same_package
expect(typeA.isDirectSupertypeOf(typeC), isFalse);
}
void test_isDirectSupertypeOf_implements() {
- ClassElementImpl classA = ElementFactory.classElement2("A");
- ClassElementImpl classB = ElementFactory.classElement2("B");
- InterfaceType typeA = classA.type;
- InterfaceType typeB = classB.type;
+ var classA = class_(name: 'A');
+ var classB = ElementFactory.classElement2("B");
+ InterfaceType typeA = interfaceType(classA);
+ InterfaceType typeB = interfaceType(classB);
classB.interfaces = <InterfaceType>[typeA];
// ignore: deprecated_member_use_from_same_package
expect(typeA.isDirectSupertypeOf(typeB), isTrue);
}
void test_isDirectSupertypeOf_with() {
- ClassElementImpl classA = ElementFactory.classElement2("A");
- ClassElementImpl classB = ElementFactory.classElement2("B");
- InterfaceType typeA = classA.type;
- InterfaceType typeB = classB.type;
+ var classA = class_(name: 'A');
+ var classB = ElementFactory.classElement2("B");
+ InterfaceType typeA = interfaceType(classA);
+ InterfaceType typeB = interfaceType(classB);
classB.mixins = <InterfaceType>[typeA];
// ignore: deprecated_member_use_from_same_package
expect(typeA.isDirectSupertypeOf(typeB), isTrue);
}
void test_isMoreSpecificThan_bottom() {
- DartType type = ElementFactory.classElement2("A").type;
+ DartType type = interfaceType(ElementFactory.classElement2('A'));
expect(BottomTypeImpl.instance.isMoreSpecificThan(type), isTrue);
}
void test_isMoreSpecificThan_covariance() {
ClassElement classA = ElementFactory.classElement2("A", ["E"]);
ClassElement classI = ElementFactory.classElement2("I");
- ClassElement classJ = ElementFactory.classElement("J", classI.type);
+ ClassElement classJ =
+ ElementFactory.classElement("J", interfaceType(classI));
InterfaceTypeImpl typeAI = new InterfaceTypeImpl(classA);
InterfaceTypeImpl typeAJ = new InterfaceTypeImpl(classA);
- typeAI.typeArguments = <DartType>[classI.type];
- typeAJ.typeArguments = <DartType>[classJ.type];
+ typeAI.typeArguments = <DartType>[interfaceType(classI)];
+ typeAJ.typeArguments = <DartType>[interfaceType(classJ)];
expect(typeAJ.isMoreSpecificThan(typeAI), isTrue);
expect(typeAI.isMoreSpecificThan(typeAJ), isFalse);
}
void test_isMoreSpecificThan_directSupertype() {
- ClassElement classA = ElementFactory.classElement2("A");
- ClassElement classB = ElementFactory.classElement("B", classA.type);
- InterfaceType typeA = classA.type;
- InterfaceType typeB = classB.type;
+ ClassElement classA = class_(name: 'A');
+ ClassElement classB =
+ ElementFactory.classElement("B", interfaceType(classA));
+ InterfaceType typeA = interfaceType(classA);
+ InterfaceType typeB = interfaceType(classB);
// ignore: deprecated_member_use_from_same_package
expect(typeB.isMoreSpecificThan(typeA), isTrue);
// the opposite test tests a different branch in isMoreSpecificThan()
@@ -2512,26 +2652,35 @@
}
void test_isMoreSpecificThan_dynamic() {
- InterfaceType type = ElementFactory.classElement2("A").type;
+ InterfaceType type = interfaceType(ElementFactory.classElement2('A'));
// ignore: deprecated_member_use_from_same_package
expect(type.isMoreSpecificThan(DynamicTypeImpl.instance), isTrue);
}
void test_isMoreSpecificThan_generic() {
- ClassElement classA = ElementFactory.classElement2("A", ["E"]);
- ClassElement classB = ElementFactory.classElement2("B");
- DartType dynamicType = DynamicTypeImpl.instance;
- InterfaceType typeAOfDynamic =
- classA.type.instantiate(<DartType>[dynamicType]);
- InterfaceType typeAOfB = classA.type.instantiate(<DartType>[classB.type]);
+ ClassElement A = class_(
+ name: 'A',
+ typeParameters: [typeParameter('E')],
+ );
+ ClassElement B = class_(name: 'B');
+
+ var AofDynamic = interfaceType(
+ A,
+ typeArguments: [dynamicType],
+ );
+ var AofB = interfaceType(
+ A,
+ typeArguments: [interfaceType(B)],
+ );
+
// ignore: deprecated_member_use_from_same_package
- expect(typeAOfDynamic.isMoreSpecificThan(typeAOfB), isFalse);
+ expect(AofDynamic.isMoreSpecificThan(AofB), isFalse);
// ignore: deprecated_member_use_from_same_package
- expect(typeAOfB.isMoreSpecificThan(typeAOfDynamic), isTrue);
+ expect(AofB.isMoreSpecificThan(AofDynamic), isTrue);
}
void test_isMoreSpecificThan_self() {
- InterfaceType type = ElementFactory.classElement2("A").type;
+ InterfaceType type = interfaceType(ElementFactory.classElement2('A'));
// ignore: deprecated_member_use_from_same_package
expect(type.isMoreSpecificThan(type), isTrue);
}
@@ -2542,12 +2691,13 @@
// class B extends A {}
// class C implements B {}
//
- ClassElementImpl classA = ElementFactory.classElement2("A");
- ClassElementImpl classB = ElementFactory.classElement("B", classA.type);
- ClassElementImpl classC = ElementFactory.classElement2("C");
- classC.interfaces = <InterfaceType>[classB.type];
- InterfaceType typeA = classA.type;
- InterfaceType typeC = classC.type;
+ var classA = class_(name: 'A');
+ ClassElementImpl classB =
+ ElementFactory.classElement("B", interfaceType(classA));
+ var classC = ElementFactory.classElement2("C");
+ classC.interfaces = <InterfaceType>[interfaceType(classB)];
+ InterfaceType typeA = interfaceType(classA);
+ InterfaceType typeC = interfaceType(classC);
// ignore: deprecated_member_use_from_same_package
expect(typeC.isMoreSpecificThan(typeA), isTrue);
}
@@ -2558,12 +2708,13 @@
// class B extends A {}
// class C with B {}
//
- ClassElementImpl classA = ElementFactory.classElement2("A");
- ClassElementImpl classB = ElementFactory.classElement("B", classA.type);
- ClassElementImpl classC = ElementFactory.classElement2("C");
- classC.mixins = <InterfaceType>[classB.type];
- InterfaceType typeA = classA.type;
- InterfaceType typeC = classC.type;
+ var classA = class_(name: 'A');
+ ClassElementImpl classB =
+ ElementFactory.classElement("B", interfaceType(classA));
+ var classC = ElementFactory.classElement2("C");
+ classC.mixins = <InterfaceType>[interfaceType(classB)];
+ InterfaceType typeA = interfaceType(classA);
+ InterfaceType typeC = interfaceType(classC);
// ignore: deprecated_member_use_from_same_package
expect(typeC.isMoreSpecificThan(typeA), isTrue);
}
@@ -2574,12 +2725,13 @@
// class B extends A {}
// class C {}
//
- ClassElementImpl classA = ElementFactory.classElement2("A");
- ClassElementImpl classB = ElementFactory.classElement("B", classA.type);
- ClassElementImpl classC = ElementFactory.classElement2("C");
- InterfaceType typeA = classA.type;
- InterfaceType typeC = classC.type;
- classA.supertype = classB.type;
+ var classA = class_(name: 'A');
+ ClassElementImpl classB =
+ ElementFactory.classElement("B", interfaceType(classA));
+ var classC = ElementFactory.classElement2("C");
+ InterfaceType typeA = interfaceType(classA);
+ InterfaceType typeC = interfaceType(classC);
+ classA.supertype = interfaceType(classB);
// ignore: deprecated_member_use_from_same_package
expect(typeA.isMoreSpecificThan(typeC), isFalse);
}
@@ -2590,11 +2742,13 @@
// class B extends A {}
// class C extends B {}
//
- ClassElement classA = ElementFactory.classElement2("A");
- ClassElement classB = ElementFactory.classElement("B", classA.type);
- ClassElement classC = ElementFactory.classElement("C", classB.type);
- InterfaceType typeA = classA.type;
- InterfaceType typeC = classC.type;
+ ClassElement classA = class_(name: 'A');
+ ClassElement classB =
+ ElementFactory.classElement("B", interfaceType(classA));
+ ClassElement classC =
+ ElementFactory.classElement("C", interfaceType(classB));
+ InterfaceType typeA = interfaceType(classA);
+ InterfaceType typeC = interfaceType(classC);
// ignore: deprecated_member_use_from_same_package
expect(typeC.isMoreSpecificThan(typeA), isTrue);
}
@@ -2604,8 +2758,9 @@
// class A<E> {}
//
ClassElement classA = ElementFactory.classElement2("A", ["E"]);
- InterfaceType typeA = classA.type;
- TypeParameterType parameterType = classA.typeParameters[0].type;
+ InterfaceType typeA = interfaceType(classA);
+ TypeParameterType parameterType =
+ typeParameterType(classA.typeParameters[0]);
DartType objectType = _typeProvider.objectType;
// ignore: deprecated_member_use_from_same_package
expect(parameterType.isMoreSpecificThan(objectType), isTrue);
@@ -2618,31 +2773,31 @@
// class A {}
// class B<E extends A> {}
//
- ClassElement classA = ElementFactory.classElement2("A");
- InterfaceType typeA = classA.type;
- ClassElementImpl classB = ElementFactory.classElement2("B");
+ ClassElement classA = class_(name: 'A');
+ InterfaceType typeA = interfaceType(classA);
+ var classB = ElementFactory.classElement2("B");
TypeParameterElementImpl parameterEA =
new TypeParameterElementImpl.forNode(AstTestFactory.identifier3("E"));
TypeParameterType parameterAEType = new TypeParameterTypeImpl(parameterEA);
parameterEA.bound = typeA;
- parameterEA.type = parameterAEType;
classB.typeParameters = <TypeParameterElementImpl>[parameterEA];
// ignore: deprecated_member_use_from_same_package
expect(parameterAEType.isMoreSpecificThan(typeA), isTrue);
}
void test_isSubtypeOf_directSubtype() {
- ClassElement classA = ElementFactory.classElement2("A");
- ClassElement classB = ElementFactory.classElement("B", classA.type);
- InterfaceType typeA = classA.type;
- InterfaceType typeB = classB.type;
+ ClassElement classA = class_(name: 'A');
+ ClassElement classB =
+ ElementFactory.classElement("B", interfaceType(classA));
+ InterfaceType typeA = interfaceType(classA);
+ InterfaceType typeB = interfaceType(classB);
expect(typeB.isSubtypeOf(typeA), isTrue);
expect(typeA.isSubtypeOf(typeB), isFalse);
}
void test_isSubtypeOf_dynamic() {
- ClassElement classA = ElementFactory.classElement2("A");
- InterfaceType typeA = classA.type;
+ ClassElement classA = class_(name: 'A');
+ InterfaceType typeA = interfaceType(classA);
DartType dynamicType = DynamicTypeImpl.instance;
expect(dynamicType.isSubtypeOf(typeA), isTrue);
expect(typeA.isSubtypeOf(dynamicType), isTrue);
@@ -2656,35 +2811,37 @@
// }
//
InterfaceType stringType = _typeProvider.stringType;
- ClassElementImpl classA = ElementFactory.classElement2("A");
+ var classA = class_(name: 'A');
classA.methods = <MethodElement>[
ElementFactory.methodElement("call", VoidTypeImpl.instance, [stringType])
];
FunctionType functionType =
ElementFactory.functionElement5("f", <ClassElement>[stringType.element])
.type;
- expect(classA.type.isSubtypeOf(functionType), isTrue);
+ expect(interfaceType(classA).isSubtypeOf(functionType), isTrue);
}
void test_isSubtypeOf_generic() {
- ClassElement classA = ElementFactory.classElement2("A", ["E"]);
- ClassElement classB = ElementFactory.classElement2("B");
+ ClassElement A = ElementFactory.classElement2("A", ["E"]);
+ ClassElement B = ElementFactory.classElement2("B");
DartType dynamicType = DynamicTypeImpl.instance;
InterfaceType typeAOfDynamic =
- classA.type.instantiate(<DartType>[dynamicType]);
- InterfaceType typeAOfB = classA.type.instantiate(<DartType>[classB.type]);
+ interfaceType(A, typeArguments: [dynamicType]);
+ InterfaceType typeAOfB =
+ interfaceType(A, typeArguments: [interfaceType(B)]);
expect(typeAOfDynamic.isSubtypeOf(typeAOfB), isTrue);
expect(typeAOfB.isSubtypeOf(typeAOfDynamic), isTrue);
}
void test_isSubtypeOf_interface() {
- ClassElement classA = ElementFactory.classElement2("A");
- ClassElement classB = ElementFactory.classElement("B", classA.type);
- ClassElementImpl classC = ElementFactory.classElement2("C");
+ ClassElement classA = class_(name: 'A');
+ ClassElement classB =
+ ElementFactory.classElement("B", interfaceType(classA));
+ var classC = ElementFactory.classElement2("C");
InterfaceType typeObject = classA.supertype;
- InterfaceType typeA = classA.type;
- InterfaceType typeB = classB.type;
- InterfaceType typeC = classC.type;
+ InterfaceType typeA = interfaceType(classA);
+ InterfaceType typeB = interfaceType(classB);
+ InterfaceType typeC = interfaceType(classC);
classC.interfaces = <InterfaceType>[typeB];
expect(typeC.isSubtypeOf(typeB), isTrue);
expect(typeC.isSubtypeOf(typeObject), isTrue);
@@ -2698,13 +2855,14 @@
// class B extends A {}
// class C with B {}
//
- ClassElement classA = ElementFactory.classElement2("A");
- ClassElement classB = ElementFactory.classElement("B", classA.type);
- ClassElementImpl classC = ElementFactory.classElement2("C");
+ ClassElement classA = class_(name: 'A');
+ ClassElement classB =
+ ElementFactory.classElement("B", interfaceType(classA));
+ var classC = ElementFactory.classElement2("C");
InterfaceType typeObject = classA.supertype;
- InterfaceType typeA = classA.type;
- InterfaceType typeB = classB.type;
- InterfaceType typeC = classC.type;
+ InterfaceType typeA = interfaceType(classA);
+ InterfaceType typeB = interfaceType(classB);
+ InterfaceType typeC = interfaceType(classC);
classC.mixins = <InterfaceType>[typeB];
expect(typeC.isSubtypeOf(typeB), isTrue);
expect(typeC.isSubtypeOf(typeObject), isTrue);
@@ -2713,16 +2871,16 @@
}
void test_isSubtypeOf_object() {
- ClassElement classA = ElementFactory.classElement2("A");
- InterfaceType typeA = classA.type;
+ ClassElement classA = class_(name: 'A');
+ InterfaceType typeA = interfaceType(classA);
InterfaceType typeObject = classA.supertype;
expect(typeA.isSubtypeOf(typeObject), isTrue);
expect(typeObject.isSubtypeOf(typeA), isFalse);
}
void test_isSubtypeOf_self() {
- ClassElement classA = ElementFactory.classElement2("A");
- InterfaceType typeA = classA.type;
+ ClassElement classA = class_(name: 'A');
+ InterfaceType typeA = interfaceType(classA);
expect(typeA.isSubtypeOf(typeA), isTrue);
}
@@ -2732,21 +2890,24 @@
// class B extends A {}
// class C {}
//
- ClassElementImpl classA = ElementFactory.classElement2("A");
- ClassElementImpl classB = ElementFactory.classElement("B", classA.type);
- ClassElementImpl classC = ElementFactory.classElement2("C");
- InterfaceType typeA = classA.type;
- InterfaceType typeC = classC.type;
- classA.supertype = classB.type;
+ var classA = class_(name: 'A');
+ ClassElementImpl classB =
+ ElementFactory.classElement("B", interfaceType(classA));
+ var classC = ElementFactory.classElement2("C");
+ InterfaceType typeA = interfaceType(classA);
+ InterfaceType typeC = interfaceType(classC);
+ classA.supertype = interfaceType(classB);
expect(typeA.isSubtypeOf(typeC), isFalse);
}
void test_isSubtypeOf_transitive_superclass() {
- ClassElement classA = ElementFactory.classElement2("A");
- ClassElement classB = ElementFactory.classElement("B", classA.type);
- ClassElement classC = ElementFactory.classElement("C", classB.type);
- InterfaceType typeA = classA.type;
- InterfaceType typeC = classC.type;
+ ClassElement classA = class_(name: 'A');
+ ClassElement classB =
+ ElementFactory.classElement("B", interfaceType(classA));
+ ClassElement classC =
+ ElementFactory.classElement("C", interfaceType(classB));
+ InterfaceType typeA = interfaceType(classA);
+ InterfaceType typeC = interfaceType(classC);
expect(typeC.isSubtypeOf(typeA), isTrue);
expect(typeA.isSubtypeOf(typeC), isFalse);
}
@@ -2755,16 +2916,17 @@
DartType dynamicType = DynamicTypeImpl.instance;
ClassElement classA = ElementFactory.classElement2("A", ["E"]);
ClassElement classI = ElementFactory.classElement2("I");
- ClassElement classJ = ElementFactory.classElement("J", classI.type);
+ ClassElement classJ =
+ ElementFactory.classElement("J", interfaceType(classI));
ClassElement classK = ElementFactory.classElement2("K");
- InterfaceType typeA = classA.type;
- InterfaceType typeA_dynamic = typeA.instantiate(<DartType>[dynamicType]);
+ InterfaceType typeA_dynamic =
+ interfaceType(classA, typeArguments: [dynamicType]);
InterfaceTypeImpl typeAI = new InterfaceTypeImpl(classA);
InterfaceTypeImpl typeAJ = new InterfaceTypeImpl(classA);
InterfaceTypeImpl typeAK = new InterfaceTypeImpl(classA);
- typeAI.typeArguments = <DartType>[classI.type];
- typeAJ.typeArguments = <DartType>[classJ.type];
- typeAK.typeArguments = <DartType>[classK.type];
+ typeAI.typeArguments = <DartType>[interfaceType(classI)];
+ typeAJ.typeArguments = <DartType>[interfaceType(classJ)];
+ typeAK.typeArguments = <DartType>[interfaceType(classK)];
// A<J> <: A<I> since J <: I
expect(typeAJ.isSubtypeOf(typeAI), isTrue);
expect(typeAI.isSubtypeOf(typeAJ), isFalse);
@@ -2786,16 +2948,18 @@
// class A<E> {}
//
ClassElement classA = ElementFactory.classElement2("A", ["E"]);
- InterfaceType typeA = classA.type;
- TypeParameterType parameterType = classA.typeParameters[0].type;
+ InterfaceType typeA = interfaceType(classA);
+ TypeParameterType parameterType =
+ typeParameterType(classA.typeParameters[0]);
expect(typeA.isSubtypeOf(parameterType), isFalse);
}
void test_isSupertypeOf_directSupertype() {
- ClassElement classA = ElementFactory.classElement2("A");
- ClassElement classB = ElementFactory.classElement("B", classA.type);
- InterfaceType typeA = classA.type;
- InterfaceType typeB = classB.type;
+ ClassElement classA = class_(name: 'A');
+ ClassElement classB =
+ ElementFactory.classElement("B", interfaceType(classA));
+ InterfaceType typeA = interfaceType(classA);
+ InterfaceType typeB = interfaceType(classB);
// ignore: deprecated_member_use_from_same_package
expect(typeB.isSupertypeOf(typeA), isFalse);
// ignore: deprecated_member_use_from_same_package
@@ -2803,8 +2967,8 @@
}
void test_isSupertypeOf_dynamic() {
- ClassElement classA = ElementFactory.classElement2("A");
- InterfaceType typeA = classA.type;
+ ClassElement classA = class_(name: 'A');
+ InterfaceType typeA = interfaceType(classA);
DartType dynamicType = DynamicTypeImpl.instance;
// ignore: deprecated_member_use_from_same_package
expect(dynamicType.isSupertypeOf(typeA), isTrue);
@@ -2813,11 +2977,13 @@
}
void test_isSupertypeOf_indirectSupertype() {
- ClassElement classA = ElementFactory.classElement2("A");
- ClassElement classB = ElementFactory.classElement("B", classA.type);
- ClassElement classC = ElementFactory.classElement("C", classB.type);
- InterfaceType typeA = classA.type;
- InterfaceType typeC = classC.type;
+ ClassElement classA = class_(name: 'A');
+ ClassElement classB =
+ ElementFactory.classElement("B", interfaceType(classA));
+ ClassElement classC =
+ ElementFactory.classElement("C", interfaceType(classB));
+ InterfaceType typeA = interfaceType(classA);
+ InterfaceType typeC = interfaceType(classC);
// ignore: deprecated_member_use_from_same_package
expect(typeC.isSupertypeOf(typeA), isFalse);
// ignore: deprecated_member_use_from_same_package
@@ -2825,13 +2991,14 @@
}
void test_isSupertypeOf_interface() {
- ClassElement classA = ElementFactory.classElement2("A");
- ClassElement classB = ElementFactory.classElement("B", classA.type);
- ClassElementImpl classC = ElementFactory.classElement2("C");
+ ClassElement classA = class_(name: 'A');
+ ClassElement classB =
+ ElementFactory.classElement("B", interfaceType(classA));
+ var classC = ElementFactory.classElement2("C");
InterfaceType typeObject = classA.supertype;
- InterfaceType typeA = classA.type;
- InterfaceType typeB = classB.type;
- InterfaceType typeC = classC.type;
+ InterfaceType typeA = interfaceType(classA);
+ InterfaceType typeB = interfaceType(classB);
+ InterfaceType typeC = interfaceType(classC);
classC.interfaces = <InterfaceType>[typeB];
// ignore: deprecated_member_use_from_same_package
expect(typeB.isSupertypeOf(typeC), isTrue);
@@ -2849,13 +3016,14 @@
// class B extends A {}
// class C with B {}
//
- ClassElement classA = ElementFactory.classElement2("A");
- ClassElement classB = ElementFactory.classElement("B", classA.type);
- ClassElementImpl classC = ElementFactory.classElement2("C");
+ ClassElement classA = class_(name: 'A');
+ ClassElement classB =
+ ElementFactory.classElement("B", interfaceType(classA));
+ var classC = ElementFactory.classElement2("C");
InterfaceType typeObject = classA.supertype;
- InterfaceType typeA = classA.type;
- InterfaceType typeB = classB.type;
- InterfaceType typeC = classC.type;
+ InterfaceType typeA = interfaceType(classA);
+ InterfaceType typeB = interfaceType(classB);
+ InterfaceType typeC = interfaceType(classC);
classC.mixins = <InterfaceType>[typeB];
// ignore: deprecated_member_use_from_same_package
expect(typeB.isSupertypeOf(typeC), isTrue);
@@ -2868,8 +3036,8 @@
}
void test_isSupertypeOf_object() {
- ClassElement classA = ElementFactory.classElement2("A");
- InterfaceType typeA = classA.type;
+ ClassElement classA = class_(name: 'A');
+ InterfaceType typeA = interfaceType(classA);
InterfaceType typeObject = classA.supertype;
// ignore: deprecated_member_use_from_same_package
expect(typeA.isSupertypeOf(typeObject), isFalse);
@@ -2878,8 +3046,8 @@
}
void test_isSupertypeOf_self() {
- ClassElement classA = ElementFactory.classElement2("A");
- InterfaceType typeA = classA.type;
+ ClassElement classA = class_(name: 'A');
+ InterfaceType typeA = interfaceType(classA);
// ignore: deprecated_member_use_from_same_package
expect(typeA.isSupertypeOf(typeA), isTrue);
}
@@ -2888,14 +3056,14 @@
//
// class A { g {} }
//
- ClassElementImpl classA = ElementFactory.classElement2("A");
+ var classA = class_(name: 'A');
String getterName = "g";
PropertyAccessorElement getterG =
ElementFactory.getterElement(getterName, false, null);
classA.accessors = <PropertyAccessorElement>[getterG];
- InterfaceType typeA = classA.type;
+ InterfaceType typeA = interfaceType(classA);
LibraryElementImpl library =
- ElementFactory.library(createAnalysisContext(), "lib");
+ ElementFactory.library(_analysisContext, "lib");
CompilationUnitElement unit = library.definingCompilationUnit;
(unit as CompilationUnitElementImpl).types = <ClassElement>[classA];
expect(typeA.lookUpGetter(getterName, library), same(getterG));
@@ -2906,15 +3074,16 @@
// class A { g {} }
// class B extends A {}
//
- ClassElementImpl classA = ElementFactory.classElement2("A");
+ var classA = class_(name: 'A');
String getterName = "g";
PropertyAccessorElement getterG =
ElementFactory.getterElement(getterName, false, null);
classA.accessors = <PropertyAccessorElement>[getterG];
- ClassElementImpl classB = ElementFactory.classElement("B", classA.type);
- InterfaceType typeB = classB.type;
+ ClassElementImpl classB =
+ ElementFactory.classElement("B", interfaceType(classA));
+ InterfaceType typeB = interfaceType(classB);
LibraryElementImpl library =
- ElementFactory.library(createAnalysisContext(), "lib");
+ ElementFactory.library(_analysisContext, "lib");
CompilationUnitElement unit = library.definingCompilationUnit;
(unit as CompilationUnitElementImpl).types = <ClassElement>[classA, classB];
expect(typeB.lookUpGetter(getterName, library), same(getterG));
@@ -2929,7 +3098,7 @@
//
TestTypeProvider typeProvider = new TestTypeProvider();
String getterName = 'g';
- ClassElementImpl classB = ElementFactory.classElement2('B');
+ var classB = class_(name: 'B');
ClassElementImpl classM1 = ElementFactory.classElement2('M1');
PropertyAccessorElementImpl getterM1g = ElementFactory.getterElement(
getterName, false, typeProvider.dynamicType);
@@ -2938,13 +3107,17 @@
PropertyAccessorElementImpl getterM2g = ElementFactory.getterElement(
getterName, false, typeProvider.dynamicType);
classM2.accessors = <PropertyAccessorElement>[getterM2g];
- ClassElementImpl classC = ElementFactory.classElement('C', classB.type);
- classC.mixins = <InterfaceType>[classM1.type, classM2.type];
+ ClassElementImpl classC =
+ ElementFactory.classElement('C', interfaceType(classB));
+ classC.mixins = <InterfaceType>[
+ interfaceType(classM1),
+ interfaceType(classM2)
+ ];
LibraryElementImpl library =
- ElementFactory.library(createAnalysisContext(), "lib");
+ ElementFactory.library(_analysisContext, "lib");
CompilationUnitElementImpl unit = library.definingCompilationUnit;
unit.types = <ClassElement>[classB, classM1, classM2, classC];
- expect(classC.type.lookUpGetter(getterName, library), getterM2g);
+ expect(interfaceType(classC).lookUpGetter(getterName, library), getterM2g);
}
void test_lookUpGetter_recursive() {
@@ -2952,12 +3125,12 @@
// class A extends B {}
// class B extends A {}
//
- ClassElementImpl classA = ElementFactory.classElement2("A");
- InterfaceType typeA = classA.type;
- ClassElementImpl classB = ElementFactory.classElement("B", typeA);
- classA.supertype = classB.type;
+ var classA = class_(name: 'A');
+ InterfaceType typeA = interfaceType(classA);
+ var classB = ElementFactory.classElement("B", typeA);
+ classA.supertype = interfaceType(classB);
LibraryElementImpl library =
- ElementFactory.library(createAnalysisContext(), "lib");
+ ElementFactory.library(_analysisContext, "lib");
CompilationUnitElement unit = library.definingCompilationUnit;
(unit as CompilationUnitElementImpl).types = <ClassElement>[classA, classB];
expect(typeA.lookUpGetter("g", library), isNull);
@@ -2967,10 +3140,10 @@
//
// class A {}
//
- ClassElementImpl classA = ElementFactory.classElement2("A");
- InterfaceType typeA = classA.type;
+ var classA = class_(name: 'A');
+ InterfaceType typeA = interfaceType(classA);
LibraryElementImpl library =
- ElementFactory.library(createAnalysisContext(), "lib");
+ ElementFactory.library(_analysisContext, "lib");
CompilationUnitElement unit = library.definingCompilationUnit;
(unit as CompilationUnitElementImpl).types = <ClassElement>[classA];
expect(typeA.lookUpGetter("g", library), isNull);
@@ -2980,13 +3153,13 @@
//
// class A { m() {} }
//
- ClassElementImpl classA = ElementFactory.classElement2("A");
+ var classA = class_(name: 'A');
String methodName = "m";
MethodElementImpl methodM = ElementFactory.methodElement(methodName, null);
classA.methods = <MethodElement>[methodM];
- InterfaceType typeA = classA.type;
+ InterfaceType typeA = interfaceType(classA);
LibraryElementImpl library =
- ElementFactory.library(createAnalysisContext(), "lib");
+ ElementFactory.library(_analysisContext, "lib");
CompilationUnitElement unit = library.definingCompilationUnit;
(unit as CompilationUnitElementImpl).types = <ClassElement>[classA];
expect(typeA.lookUpMethod(methodName, library), same(methodM));
@@ -2997,14 +3170,15 @@
// class A { m() {} }
// class B extends A {}
//
- ClassElementImpl classA = ElementFactory.classElement2("A");
+ var classA = class_(name: 'A');
String methodName = "m";
MethodElementImpl methodM = ElementFactory.methodElement(methodName, null);
classA.methods = <MethodElement>[methodM];
- ClassElementImpl classB = ElementFactory.classElement("B", classA.type);
- InterfaceType typeB = classB.type;
+ ClassElementImpl classB =
+ ElementFactory.classElement("B", interfaceType(classA));
+ InterfaceType typeB = interfaceType(classB);
LibraryElementImpl library =
- ElementFactory.library(createAnalysisContext(), "lib");
+ ElementFactory.library(_analysisContext, "lib");
CompilationUnitElement unit = library.definingCompilationUnit;
(unit as CompilationUnitElementImpl).types = <ClassElement>[classA, classB];
expect(typeB.lookUpMethod(methodName, library), same(methodM));
@@ -3018,7 +3192,7 @@
// class C extends B with M1, M2 {}
//
String methodName = 'm';
- ClassElementImpl classB = ElementFactory.classElement2('B');
+ var classB = class_(name: 'B');
ClassElementImpl classM1 = ElementFactory.classElement2('M1');
MethodElementImpl methodM1m =
ElementFactory.methodElement(methodName, null);
@@ -3027,13 +3201,17 @@
MethodElementImpl methodM2m =
ElementFactory.methodElement(methodName, null);
classM2.methods = <MethodElement>[methodM2m];
- ClassElementImpl classC = ElementFactory.classElement('C', classB.type);
- classC.mixins = <InterfaceType>[classM1.type, classM2.type];
+ ClassElementImpl classC =
+ ElementFactory.classElement('C', interfaceType(classB));
+ classC.mixins = <InterfaceType>[
+ interfaceType(classM1),
+ interfaceType(classM2)
+ ];
LibraryElementImpl library =
- ElementFactory.library(createAnalysisContext(), "lib");
+ ElementFactory.library(_analysisContext, "lib");
CompilationUnitElementImpl unit = library.definingCompilationUnit;
unit.types = <ClassElement>[classB, classM1, classM2, classC];
- expect(classC.type.lookUpMethod(methodName, library), methodM2m);
+ expect(interfaceType(classC).lookUpMethod(methodName, library), methodM2m);
}
void test_lookUpMethod_parameterized() {
@@ -3041,27 +3219,32 @@
// class A<E> { E m(E p) {} }
// class B<F> extends A<F> {}
//
- ClassElementImpl classA = ElementFactory.classElement2("A", ["E"]);
- DartType typeE = classA.type.typeArguments[0];
+ var E = typeParameter('E');
+ var A = class_(name: 'A', typeParameters: [E]);
+ DartType typeE = typeParameterType(E);
String methodName = "m";
MethodElementImpl methodM =
ElementFactory.methodElement(methodName, typeE, [typeE]);
- classA.methods = <MethodElement>[methodM];
+ A.methods = <MethodElement>[methodM];
methodM.type = new FunctionTypeImpl(methodM);
- ClassElementImpl classB = ElementFactory.classElement2("B", ["F"]);
- InterfaceType typeB = classB.type;
- InterfaceTypeImpl typeAF = new InterfaceTypeImpl(classA);
- typeAF.typeArguments = <DartType>[typeB.typeArguments[0]];
- classB.supertype = typeAF;
+
+ var F = typeParameter('F');
+ var B = class_(
+ name: 'B',
+ typeParameters: [F],
+ superType: interfaceType(A, typeArguments: [
+ typeParameterType(F),
+ ]),
+ );
LibraryElementImpl library =
- ElementFactory.library(createAnalysisContext(), "lib");
+ ElementFactory.library(_analysisContext, "lib");
CompilationUnitElement unit = library.definingCompilationUnit;
- (unit as CompilationUnitElementImpl).types = <ClassElement>[classA];
+ (unit as CompilationUnitElementImpl).types = <ClassElement>[A];
//
// B<I>
//
- InterfaceType typeI = ElementFactory.classElement2("I").type;
- InterfaceTypeImpl typeBI = new InterfaceTypeImpl(classB);
+ InterfaceType typeI = interfaceType(class_(name: 'I'));
+ InterfaceTypeImpl typeBI = new InterfaceTypeImpl(B);
typeBI.typeArguments = <DartType>[typeI];
MethodElement method = typeBI.lookUpMethod(methodName, library);
expect(method, isNotNull);
@@ -3077,12 +3260,12 @@
// class A extends B {}
// class B extends A {}
//
- ClassElementImpl classA = ElementFactory.classElement2("A");
- InterfaceType typeA = classA.type;
- ClassElementImpl classB = ElementFactory.classElement("B", typeA);
- classA.supertype = classB.type;
+ var classA = class_(name: 'A');
+ InterfaceType typeA = interfaceType(classA);
+ var classB = ElementFactory.classElement("B", typeA);
+ classA.supertype = interfaceType(classB);
LibraryElementImpl library =
- ElementFactory.library(createAnalysisContext(), "lib");
+ ElementFactory.library(_analysisContext, "lib");
CompilationUnitElement unit = library.definingCompilationUnit;
(unit as CompilationUnitElementImpl).types = <ClassElement>[classA, classB];
expect(typeA.lookUpMethod("m", library), isNull);
@@ -3092,10 +3275,10 @@
//
// class A {}
//
- ClassElementImpl classA = ElementFactory.classElement2("A");
- InterfaceType typeA = classA.type;
+ var classA = class_(name: 'A');
+ InterfaceType typeA = interfaceType(classA);
LibraryElementImpl library =
- ElementFactory.library(createAnalysisContext(), "lib");
+ ElementFactory.library(_analysisContext, "lib");
CompilationUnitElement unit = library.definingCompilationUnit;
(unit as CompilationUnitElementImpl).types = <ClassElement>[classA];
expect(typeA.lookUpMethod("m", library), isNull);
@@ -3105,14 +3288,14 @@
//
// class A { s(x) {} }
//
- ClassElementImpl classA = ElementFactory.classElement2("A");
+ var classA = class_(name: 'A');
String setterName = "s";
PropertyAccessorElement setterS =
ElementFactory.setterElement(setterName, false, null);
classA.accessors = <PropertyAccessorElement>[setterS];
- InterfaceType typeA = classA.type;
+ InterfaceType typeA = interfaceType(classA);
LibraryElementImpl library =
- ElementFactory.library(createAnalysisContext(), "lib");
+ ElementFactory.library(_analysisContext, "lib");
CompilationUnitElement unit = library.definingCompilationUnit;
(unit as CompilationUnitElementImpl).types = <ClassElement>[classA];
expect(typeA.lookUpSetter(setterName, library), same(setterS));
@@ -3123,15 +3306,16 @@
// class A { s(x) {} }
// class B extends A {}
//
- ClassElementImpl classA = ElementFactory.classElement2("A");
+ var classA = class_(name: 'A');
String setterName = "g";
PropertyAccessorElement setterS =
ElementFactory.setterElement(setterName, false, null);
classA.accessors = <PropertyAccessorElement>[setterS];
- ClassElementImpl classB = ElementFactory.classElement("B", classA.type);
- InterfaceType typeB = classB.type;
+ ClassElementImpl classB =
+ ElementFactory.classElement("B", interfaceType(classA));
+ InterfaceType typeB = interfaceType(classB);
LibraryElementImpl library =
- ElementFactory.library(createAnalysisContext(), "lib");
+ ElementFactory.library(_analysisContext, "lib");
CompilationUnitElement unit = library.definingCompilationUnit;
(unit as CompilationUnitElementImpl).types = <ClassElement>[classA, classB];
expect(typeB.lookUpSetter(setterName, library), same(setterS));
@@ -3146,7 +3330,7 @@
//
TestTypeProvider typeProvider = new TestTypeProvider();
String setterName = 's';
- ClassElementImpl classB = ElementFactory.classElement2('B');
+ var classB = class_(name: 'B');
ClassElementImpl classM1 = ElementFactory.classElement2('M1');
PropertyAccessorElementImpl setterM1g = ElementFactory.setterElement(
setterName, false, typeProvider.dynamicType);
@@ -3155,13 +3339,17 @@
PropertyAccessorElementImpl setterM2g = ElementFactory.getterElement(
setterName, false, typeProvider.dynamicType);
classM2.accessors = <PropertyAccessorElement>[setterM2g];
- ClassElementImpl classC = ElementFactory.classElement('C', classB.type);
- classC.mixins = <InterfaceType>[classM1.type, classM2.type];
+ ClassElementImpl classC =
+ ElementFactory.classElement('C', interfaceType(classB));
+ classC.mixins = <InterfaceType>[
+ interfaceType(classM1),
+ interfaceType(classM2)
+ ];
LibraryElementImpl library =
- ElementFactory.library(createAnalysisContext(), "lib");
+ ElementFactory.library(_analysisContext, "lib");
CompilationUnitElementImpl unit = library.definingCompilationUnit;
unit.types = <ClassElement>[classB, classM1, classM2, classC];
- expect(classC.type.lookUpGetter(setterName, library), setterM2g);
+ expect(interfaceType(classC).lookUpGetter(setterName, library), setterM2g);
}
void test_lookUpSetter_recursive() {
@@ -3169,12 +3357,12 @@
// class A extends B {}
// class B extends A {}
//
- ClassElementImpl classA = ElementFactory.classElement2("A");
- InterfaceType typeA = classA.type;
- ClassElementImpl classB = ElementFactory.classElement("B", typeA);
- classA.supertype = classB.type;
+ var classA = class_(name: 'A');
+ InterfaceType typeA = interfaceType(classA);
+ var classB = ElementFactory.classElement("B", typeA);
+ classA.supertype = interfaceType(classB);
LibraryElementImpl library =
- ElementFactory.library(createAnalysisContext(), "lib");
+ ElementFactory.library(_analysisContext, "lib");
CompilationUnitElement unit = library.definingCompilationUnit;
(unit as CompilationUnitElementImpl).types = <ClassElement>[classA, classB];
expect(typeA.lookUpSetter("s", library), isNull);
@@ -3184,52 +3372,37 @@
//
// class A {}
//
- ClassElementImpl classA = ElementFactory.classElement2("A");
- InterfaceType typeA = classA.type;
+ var classA = class_(name: 'A');
+ InterfaceType typeA = interfaceType(classA);
LibraryElementImpl library =
- ElementFactory.library(createAnalysisContext(), "lib");
+ ElementFactory.library(_analysisContext, "lib");
CompilationUnitElement unit = library.definingCompilationUnit;
(unit as CompilationUnitElementImpl).types = <ClassElement>[classA];
expect(typeA.lookUpSetter("s", library), isNull);
}
void test_resolveToBound() {
- InterfaceTypeImpl type =
- ElementFactory.classElement2("A").type as InterfaceTypeImpl;
+ InterfaceTypeImpl type = interfaceType(ElementFactory.classElement2('A'));
// Returns this.
expect(type.resolveToBound(null), same(type));
}
void test_setTypeArguments() {
- InterfaceTypeImpl type =
- ElementFactory.classElement2("A").type as InterfaceTypeImpl;
+ InterfaceTypeImpl type = interfaceType(ElementFactory.classElement2('A'));
List<DartType> typeArguments = <DartType>[
- ElementFactory.classElement2("B").type,
- ElementFactory.classElement2("C").type
+ interfaceType(class_(name: 'B')),
+ interfaceType(class_(name: 'C'))
];
type.typeArguments = typeArguments;
expect(type.typeArguments, typeArguments);
}
- void test_substitute_equal() {
- ClassElement classAE = ElementFactory.classElement2("A", ["E"]);
- InterfaceType typeAE = classAE.type;
- InterfaceType argumentType = ElementFactory.classElement2("B").type;
- List<DartType> args = [argumentType];
- List<DartType> params = [classAE.typeParameters[0].type];
- InterfaceType typeAESubbed = typeAE.substitute2(args, params);
- expect(typeAESubbed.element, classAE);
- List<DartType> resultArguments = typeAESubbed.typeArguments;
- expect(resultArguments, hasLength(1));
- expect(resultArguments[0], argumentType);
- }
-
void test_substitute_exception() {
try {
- ClassElementImpl classA = ElementFactory.classElement2("A");
+ var classA = class_(name: 'A');
InterfaceTypeImpl type = new InterfaceTypeImpl(classA);
- InterfaceType argumentType = ElementFactory.classElement2("B").type;
+ InterfaceType argumentType = interfaceType(class_(name: 'B'));
type.substitute2(<DartType>[argumentType], <DartType>[]);
fail(
"Expected to encounter exception, argument and parameter type array lengths not equal.");
@@ -3241,14 +3414,14 @@
void test_substitute_notEqual() {
// The [test_substitute_equals] above has a slightly higher level
// implementation.
- ClassElementImpl classA = ElementFactory.classElement2("A");
+ var classA = class_(name: 'A');
TypeParameterElementImpl parameterElement =
new TypeParameterElementImpl.forNode(AstTestFactory.identifier3("E"));
InterfaceTypeImpl type = new InterfaceTypeImpl(classA);
TypeParameterTypeImpl parameter =
new TypeParameterTypeImpl(parameterElement);
type.typeArguments = <DartType>[parameter];
- InterfaceType argumentType = ElementFactory.classElement2("B").type;
+ InterfaceType argumentType = interfaceType(class_(name: 'B'));
TypeParameterTypeImpl parameterType = new TypeParameterTypeImpl(
new TypeParameterElementImpl.forNode(AstTestFactory.identifier3("F")));
InterfaceType result =
@@ -3420,7 +3593,7 @@
}
@reflectiveTest
-class TypeParameterTypeImplTest extends EngineTestCase {
+class TypeParameterTypeImplTest extends AbstractTypeTest {
void test_creation() {
expect(
new TypeParameterTypeImpl(new TypeParameterElementImpl.forNode(
@@ -3448,11 +3621,11 @@
new TypeParameterElementImpl.forNode(AstTestFactory.identifier3("E"));
TypeParameterTypeImpl type = new TypeParameterTypeImpl(element);
// E << Object
- expect(type.isMoreSpecificThan(ElementFactory.object.type), isTrue);
+ expect(type.isMoreSpecificThan(typeProvider.objectType), isTrue);
}
void test_isMoreSpecificThan_typeArguments_recursive() {
- ClassElementImpl classS = ElementFactory.classElement2("A");
+ ClassElementImpl classS = class_(name: 'A');
TypeParameterElementImpl typeParameterU =
new TypeParameterElementImpl.forNode(AstTestFactory.identifier3("U"));
TypeParameterTypeImpl typeParameterTypeU =
@@ -3465,7 +3638,8 @@
typeParameterU.bound = typeParameterTypeU;
// <T extends U> and <U extends T>
// T << S
- expect(typeParameterTypeT.isMoreSpecificThan(classS.type), isFalse);
+ expect(
+ typeParameterTypeT.isMoreSpecificThan(interfaceType(classS)), isFalse);
}
void test_isMoreSpecificThan_typeArguments_self() {
@@ -3480,10 +3654,19 @@
// class A {}
// class B extends A {}
//
- ClassElement classA = ElementFactory.classElement2("A");
- ClassElement classB = ElementFactory.classElement("B", classA.type);
- InterfaceType typeA = classA.type;
- InterfaceType typeB = classB.type;
+ ClassElement classA = class_(name: 'A');
+ ClassElement classB = ElementFactory.classElement(
+ "B",
+ classA.instantiate(
+ typeArguments: [],
+ nullabilitySuffix: NullabilitySuffix.star,
+ ),
+ );
+ InterfaceType typeA = classA.instantiate(
+ typeArguments: [],
+ nullabilitySuffix: NullabilitySuffix.star,
+ );
+ InterfaceType typeB = interfaceType(classB);
TypeParameterElementImpl typeParameterT =
new TypeParameterElementImpl.forNode(AstTestFactory.identifier3("T"));
typeParameterT.bound = typeB;
@@ -3495,10 +3678,10 @@
}
void test_isMoreSpecificThan_typeArguments_transitivity_typeParameters() {
- ClassElementImpl classS = ElementFactory.classElement2("A");
+ ClassElementImpl classS = class_(name: 'A');
TypeParameterElementImpl typeParameterU =
new TypeParameterElementImpl.forNode(AstTestFactory.identifier3("U"));
- typeParameterU.bound = classS.type;
+ typeParameterU.bound = interfaceType(classS);
TypeParameterTypeImpl typeParameterTypeU =
new TypeParameterTypeImpl(typeParameterU);
TypeParameterElementImpl typeParameterT =
@@ -3508,123 +3691,125 @@
new TypeParameterTypeImpl(typeParameterT);
// <T extends U> and <U extends S>
// T << S
- expect(typeParameterTypeT.isMoreSpecificThan(classS.type), isTrue);
+ expect(
+ typeParameterTypeT.isMoreSpecificThan(interfaceType(classS)), isTrue);
}
void test_isMoreSpecificThan_typeArguments_upperBound() {
- ClassElementImpl classS = ElementFactory.classElement2("A");
+ ClassElementImpl classS = class_(name: 'A');
TypeParameterElementImpl typeParameterT =
new TypeParameterElementImpl.forNode(AstTestFactory.identifier3("T"));
- typeParameterT.bound = classS.type;
+ typeParameterT.bound = interfaceType(classS);
TypeParameterTypeImpl typeParameterTypeT =
new TypeParameterTypeImpl(typeParameterT);
// <T extends S>
// T << S
- expect(typeParameterTypeT.isMoreSpecificThan(classS.type), isTrue);
+ expect(
+ typeParameterTypeT.isMoreSpecificThan(interfaceType(classS)), isTrue);
}
void test_resolveToBound_bound() {
- ClassElementImpl classS = ElementFactory.classElement2("A");
+ ClassElementImpl classS = class_(name: 'A');
TypeParameterElementImpl element =
new TypeParameterElementImpl.forNode(AstTestFactory.identifier3("E"));
- element.bound = classS.type;
+ element.bound = interfaceType(classS);
TypeParameterTypeImpl type = new TypeParameterTypeImpl(element);
- expect(type.resolveToBound(null), same(classS.type));
+ expect(type.resolveToBound(null), interfaceType(classS));
}
void test_resolveToBound_bound_nullableInner() {
- ClassElementImpl classS = ElementFactory.classElement2("A");
+ ClassElementImpl classS = class_(name: 'A');
TypeParameterElementImpl element =
new TypeParameterElementImpl.forNode(AstTestFactory.identifier3("E"));
- element.bound =
- (classS.type as TypeImpl).withNullability(NullabilitySuffix.question);
+ element.bound = (interfaceType(classS) as TypeImpl)
+ .withNullability(NullabilitySuffix.question);
TypeParameterTypeImpl type = new TypeParameterTypeImpl(element);
expect(type.resolveToBound(null), same(element.bound));
}
void test_resolveToBound_bound_nullableInnerOuter() {
- ClassElementImpl classS = ElementFactory.classElement2("A");
+ ClassElementImpl classS = class_(name: 'A');
TypeParameterElementImpl element =
new TypeParameterElementImpl.forNode(AstTestFactory.identifier3("E"));
- element.bound =
- (classS.type as TypeImpl).withNullability(NullabilitySuffix.question);
+ element.bound = (interfaceType(classS) as TypeImpl)
+ .withNullability(NullabilitySuffix.question);
TypeParameterTypeImpl type = new TypeParameterTypeImpl(element)
.withNullability(NullabilitySuffix.question);
expect(type.resolveToBound(null), same(element.bound));
}
void test_resolveToBound_bound_nullableInnerStarOuter() {
- ClassElementImpl classS = ElementFactory.classElement2("A");
+ ClassElementImpl classS = class_(name: 'A');
TypeParameterElementImpl element =
new TypeParameterElementImpl.forNode(AstTestFactory.identifier3("E"));
- element.bound =
- (classS.type as TypeImpl).withNullability(NullabilitySuffix.star);
+ element.bound = (interfaceType(classS) as TypeImpl)
+ .withNullability(NullabilitySuffix.star);
TypeParameterTypeImpl type = new TypeParameterTypeImpl(element)
.withNullability(NullabilitySuffix.question);
expect(
type.resolveToBound(null),
- equals((classS.type as TypeImpl)
+ equals((interfaceType(classS) as TypeImpl)
.withNullability(NullabilitySuffix.question)));
}
void test_resolveToBound_bound_nullableOuter() {
- ClassElementImpl classS = ElementFactory.classElement2("A");
+ ClassElementImpl classS = class_(name: 'A');
TypeParameterElementImpl element =
new TypeParameterElementImpl.forNode(AstTestFactory.identifier3("E"));
- element.bound = classS.type;
+ element.bound = interfaceType(classS);
TypeParameterTypeImpl type = new TypeParameterTypeImpl(element)
.withNullability(NullabilitySuffix.question);
expect(
type.resolveToBound(null),
- equals((classS.type as TypeImpl)
+ equals((interfaceType(classS) as TypeImpl)
.withNullability(NullabilitySuffix.question)));
}
void test_resolveToBound_bound_starInner() {
- ClassElementImpl classS = ElementFactory.classElement2("A");
+ ClassElementImpl classS = class_(name: 'A');
TypeParameterElementImpl element =
new TypeParameterElementImpl.forNode(AstTestFactory.identifier3("E"));
- element.bound =
- (classS.type as TypeImpl).withNullability(NullabilitySuffix.star);
+ element.bound = (interfaceType(classS) as TypeImpl)
+ .withNullability(NullabilitySuffix.star);
TypeParameterTypeImpl type = new TypeParameterTypeImpl(element);
expect(type.resolveToBound(null), same(element.bound));
}
void test_resolveToBound_bound_starInnerNullableOuter() {
- ClassElementImpl classS = ElementFactory.classElement2("A");
+ ClassElementImpl classS = class_(name: 'A');
TypeParameterElementImpl element =
new TypeParameterElementImpl.forNode(AstTestFactory.identifier3("E"));
- element.bound =
- (classS.type as TypeImpl).withNullability(NullabilitySuffix.question);
+ element.bound = (interfaceType(classS) as TypeImpl)
+ .withNullability(NullabilitySuffix.question);
TypeParameterTypeImpl type = new TypeParameterTypeImpl(element)
.withNullability(NullabilitySuffix.star);
expect(type.resolveToBound(null), same(element.bound));
}
void test_resolveToBound_bound_starOuter() {
- ClassElementImpl classS = ElementFactory.classElement2("A");
+ ClassElementImpl classS = class_(name: 'A');
TypeParameterElementImpl element =
new TypeParameterElementImpl.forNode(AstTestFactory.identifier3("E"));
- element.bound = classS.type;
+ element.bound = interfaceType(classS);
TypeParameterTypeImpl type = new TypeParameterTypeImpl(element)
.withNullability(NullabilitySuffix.star);
expect(
type.resolveToBound(null),
- same(
- (classS.type as TypeImpl).withNullability(NullabilitySuffix.star)));
+ (interfaceType(classS) as TypeImpl)
+ .withNullability(NullabilitySuffix.star));
}
void test_resolveToBound_nestedBound() {
- ClassElementImpl classS = ElementFactory.classElement2("A");
+ ClassElementImpl classS = class_(name: 'A');
TypeParameterElementImpl elementE =
new TypeParameterElementImpl.forNode(AstTestFactory.identifier3("E"));
- elementE.bound = classS.type;
+ elementE.bound = interfaceType(classS);
TypeParameterTypeImpl typeE = new TypeParameterTypeImpl(elementE);
TypeParameterElementImpl elementF =
new TypeParameterElementImpl.forNode(AstTestFactory.identifier3("F"));
elementF.bound = typeE;
TypeParameterTypeImpl typeF = new TypeParameterTypeImpl(elementE);
- expect(typeF.resolveToBound(null), same(classS.type));
+ expect(typeF.resolveToBound(null), interfaceType(classS));
}
void test_resolveToBound_unbound() {
@@ -3659,16 +3844,24 @@
}
@reflectiveTest
-class VoidTypeImplTest extends EngineTestCase {
+class VoidTypeImplTest extends AbstractTypeTest {
/**
* Reference {code VoidTypeImpl.getInstance()}.
*/
DartType _voidType = VoidTypeImpl.instance;
void test_isMoreSpecificThan_void_A() {
- ClassElement classA = ElementFactory.classElement2("A");
- // ignore: deprecated_member_use_from_same_package
- expect(_voidType.isMoreSpecificThan(classA.type), isFalse);
+ ClassElement classA = class_(name: 'A');
+ expect(
+ // ignore: deprecated_member_use_from_same_package
+ _voidType.isMoreSpecificThan(
+ classA.instantiate(
+ typeArguments: [],
+ nullabilitySuffix: NullabilitySuffix.star,
+ ),
+ ),
+ isFalse,
+ );
}
void test_isMoreSpecificThan_void_dynamic() {
@@ -3682,8 +3875,16 @@
}
void test_isSubtypeOf_void_A() {
- ClassElement classA = ElementFactory.classElement2("A");
- expect(_voidType.isSubtypeOf(classA.type), isFalse);
+ ClassElement classA = class_(name: 'A');
+ expect(
+ _voidType.isSubtypeOf(
+ classA.instantiate(
+ typeArguments: [],
+ nullabilitySuffix: NullabilitySuffix.star,
+ ),
+ ),
+ isFalse,
+ );
}
void test_isSubtypeOf_void_dynamic() {
diff --git a/pkg/analyzer/test/src/dart/element/function_type_test.dart b/pkg/analyzer/test/src/dart/element/function_type_test.dart
index eb473da..6b6aa60 100644
--- a/pkg/analyzer/test/src/dart/element/function_type_test.dart
+++ b/pkg/analyzer/test/src/dart/element/function_type_test.dart
@@ -3,14 +3,18 @@
// BSD-style license that can be found in the LICENSE file.
import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/dart/element/nullability_suffix.dart';
import 'package:analyzer/dart/element/type.dart';
import 'package:analyzer/src/dart/element/element.dart';
import 'package:analyzer/src/dart/element/member.dart';
import 'package:analyzer/src/dart/element/type.dart';
-import 'package:analyzer/src/generated/utilities_dart.dart';
+import 'package:analyzer/src/generated/resolver.dart';
+import 'package:analyzer/src/generated/testing/test_type_provider.dart';
import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
+import '../../../generated/elements_types_mixin.dart';
+
main() {
defineReflectiveSuite(() {
defineReflectiveTests(FunctionTypeTest);
@@ -30,19 +34,21 @@
}
@reflectiveTest
-class FunctionTypeTest {
+class FunctionTypeTest with ElementsTypesMixin {
static const bug_33294_fixed = false;
static const bug_33300_fixed = false;
static const bug_33301_fixed = false;
static const bug_33302_fixed = false;
- final objectType = new InterfaceTypeImpl(new MockClassElement('Object'));
+ final TypeProvider typeProvider = TestTypeProvider();
- final mapType = _makeMapType();
+ InterfaceType get intType => typeProvider.intType;
- final listType = _makeListType();
+ ClassElement get listElement => typeProvider.listElement;
- final intType = new InterfaceTypeImpl(new MockClassElement('int'));
+ ClassElement get mapElement => typeProvider.mapElement;
+
+ InterfaceType get objectType => typeProvider.objectType;
void basicChecks(FunctionType f,
{element,
@@ -81,19 +87,44 @@
expect(f.typeFormals, typeFormals, reason: 'typeFormals');
}
- DartType listOf(DartType elementType) => listType.instantiate([elementType]);
+ GenericTypeAliasElementImpl genericTypeAliasElement(
+ String name, {
+ List<ParameterElement> parameters: const [],
+ DartType returnType,
+ List<TypeParameterElement> typeParameters: const [],
+ List<TypeParameterElement> innerTypeParameters: const [],
+ }) {
+ var aliasElement = GenericTypeAliasElementImpl(name, 0);
+ aliasElement.typeParameters = typeParameters;
+
+ var functionElement = GenericFunctionTypeElementImpl.forOffset(0);
+ aliasElement.function = functionElement;
+ functionElement.typeParameters = innerTypeParameters;
+ functionElement.parameters = parameters;
+ functionElement.returnType = returnType;
+
+ return aliasElement;
+ }
+
+ DartType listOf(DartType elementType) => listElement.instantiate(
+ typeArguments: [elementType],
+ nullabilitySuffix: NullabilitySuffix.star,
+ );
DartType mapOf(DartType keyType, DartType valueType) =>
- mapType.instantiate([keyType, valueType]);
+ mapElement.instantiate(
+ typeArguments: [keyType, valueType],
+ nullabilitySuffix: NullabilitySuffix.star,
+ );
test_forInstantiatedTypedef_bothTypeParameters_noTypeArgs() {
// typedef F<T> = Map<T, U> Function<U>();
- var t = new MockTypeParameterElement('T');
- var u = new MockTypeParameterElement('U');
- var e = new MockGenericTypeAliasElement('F',
+ var t = typeParameter('T');
+ var u = typeParameter('U');
+ var e = genericTypeAliasElement('F',
typeParameters: [t],
innerTypeParameters: [u],
- returnType: mapOf(t.type, u.type));
+ returnType: mapOf(typeParameterType(t), typeParameterType(u)));
FunctionType f = new FunctionTypeImpl.forTypedef(e);
// Note: forTypedef returns the type `<T>() -> Map<T, U>`.
// See https://github.com/dart-lang/sdk/issues/34657.
@@ -102,14 +133,14 @@
displayName: 'F',
name: 'F',
typeFormals: [same(t)],
- returnType: mapOf(t.type, u.type));
+ returnType: mapOf(typeParameterType(t), typeParameterType(u)));
}
test_forInstantiatedTypedef_innerTypeParameter_noTypeArgs() {
// typedef F = T F<T>();
- var t = new MockTypeParameterElement('T');
- var e = new MockGenericTypeAliasElement('F',
- innerTypeParameters: [t], returnType: t.type);
+ var t = typeParameter('T');
+ var e = genericTypeAliasElement('F',
+ innerTypeParameters: [t], returnType: typeParameterType(t));
FunctionType f = new FunctionTypeImpl.forTypedef(e);
// Note: forTypedef returns the type `() -> T`.
// See https://github.com/dart-lang/sdk/issues/34657.
@@ -117,12 +148,12 @@
element: same(e),
displayName: 'F',
name: 'F',
- returnType: same(t.type));
+ returnType: typeParameterType(t));
}
test_forInstantiatedTypedef_noTypeParameters_noTypeArgs() {
// typedef F = void Function();
- var e = new MockGenericTypeAliasElement('F');
+ var e = genericTypeAliasElement('F');
FunctionType f = new FunctionTypeImpl.forTypedef(e);
// Note: forTypedef returns the type `() -> void`.
basicChecks(f, element: same(e), displayName: 'F', name: 'F');
@@ -130,9 +161,9 @@
test_forInstantiatedTypedef_outerTypeParameters_noTypeArgs() {
// typedef F<T> = T Function();
- var t = new MockTypeParameterElement('T');
- var e = new MockGenericTypeAliasElement('F',
- typeParameters: [t], returnType: t.type);
+ var t = typeParameter('T');
+ var e = genericTypeAliasElement('F',
+ typeParameters: [t], returnType: typeParameterType(t));
FunctionType f = new FunctionTypeImpl.forTypedef(e);
// Note: forTypedef returns the type `<T>() -> T`.
// See https://github.com/dart-lang/sdk/issues/34657.
@@ -141,64 +172,65 @@
displayName: 'F',
name: 'F',
typeFormals: [same(t)],
- returnType: same(t.type));
+ returnType: typeParameterType(t));
}
test_forTypedef() {
- var e = new MockGenericTypeAliasElement('F');
- basicChecks(e.type, element: same(e), displayName: 'F', name: 'F');
+ var e = genericTypeAliasElement('F');
+ basicChecks(functionTypeAliasType(e),
+ element: same(e), displayName: 'F', name: 'F');
basicChecks(e.function.type,
element: same(e.function), displayName: 'dynamic Function()');
}
test_forTypedef_innerAndOuterTypeParameter() {
// typedef F<T> = T Function<U>(U p);
- var t = new MockTypeParameterElement('T');
- var u = new MockTypeParameterElement('U');
- var p = new MockParameterElement('p', type: u.type);
- var e = new MockGenericTypeAliasElement('F',
+ var t = typeParameter('T');
+ var u = typeParameter('U');
+ var p = requiredParameter('p', type: typeParameterType(u));
+ var e = genericTypeAliasElement('F',
typeParameters: [t],
innerTypeParameters: [u],
- returnType: t.type,
+ returnType: typeParameterType(t),
parameters: [p]);
basicChecks(e.type,
element: same(e),
displayName: 'F',
name: 'F',
- returnType: same(t.type),
- normalParameterTypes: [same(u.type)],
+ returnType: typeParameterType(t),
+ normalParameterTypes: [typeParameterType(u)],
normalParameterNames: ['p'],
parameters: [same(p)],
typeFormals: [same(t)]);
basicChecks(e.function.type,
element: same(e.function),
displayName: 'T Function<U>(U)',
- returnType: same(t.type),
- typeArguments: [same(t.type)],
+ returnType: typeParameterType(t),
+ typeArguments: [typeParameterType(t)],
typeParameters: [same(t)],
typeFormals: [same(u)],
- normalParameterTypes: [same(u.type)],
+ normalParameterTypes: [typeParameterType(u)],
normalParameterNames: ['p'],
parameters: [same(p)]);
}
test_forTypedef_innerAndOuterTypeParameter_instantiate() {
// typedef F<T> = T Function<U>(U p);
- var t = new MockTypeParameterElement('T');
- var u = new MockTypeParameterElement('U');
- var p = new MockParameterElement('p', type: u.type);
- var e = new MockGenericTypeAliasElement('F',
+ var t = typeParameter('T');
+ var u = typeParameter('U');
+ var p = requiredParameter('p', type: typeParameterType(u));
+ var e = genericTypeAliasElement('F',
typeParameters: [t],
innerTypeParameters: [u],
- returnType: t.type,
+ returnType: typeParameterType(t),
parameters: [p]);
- var instantiated = e.type.instantiate([objectType]);
+ var instantiated = functionTypeAliasType(e, typeArguments: [objectType]);
basicChecks(instantiated,
element: same(e),
displayName: 'F<Object>',
name: 'F',
returnType: same(objectType),
- normalParameterTypes: [same(u.type)],
+ normalParameterTypes: [typeParameterType(u)],
normalParameterNames: ['p'],
parameters: [same(p)],
typeFormals: isNotNull,
@@ -213,25 +245,25 @@
test_forTypedef_innerTypeParameter() {
// typedef F = T Function<T>();
- var t = new MockTypeParameterElement('T');
- var e = new MockGenericTypeAliasElement('F',
- innerTypeParameters: [t], returnType: t.type);
- basicChecks(e.type,
+ var t = typeParameter('T');
+ var e = genericTypeAliasElement('F',
+ innerTypeParameters: [t], returnType: typeParameterType(t));
+ basicChecks(functionTypeAliasType(e),
element: same(e),
displayName: 'F',
name: 'F',
- returnType: same(t.type));
+ returnType: typeParameterType(t));
basicChecks(e.function.type,
element: same(e.function),
displayName: 'T Function<T>()',
- returnType: same(t.type),
+ returnType: typeParameterType(t),
typeFormals: [same(t)]);
}
test_forTypedef_normalParameter() {
- var p = new MockParameterElement('p');
- var e = new MockGenericTypeAliasElement('F', parameters: [p]);
- basicChecks(e.type,
+ var p = requiredParameter('p', type: dynamicType);
+ var e = genericTypeAliasElement('F', parameters: [p]);
+ basicChecks(functionTypeAliasType(e),
element: same(e),
displayName: 'F',
name: 'F',
@@ -249,14 +281,14 @@
test_forTypedef_recursive_via_interfaceTypes() {
// typedef F = List<G> Function();
// typedef G = List<F> Function();
- var f = new MockGenericTypeAliasElement('F');
- var g = new MockGenericTypeAliasElement('G');
- f.returnType = listOf(g.function.type);
- g.returnType = listOf(f.function.type);
- basicChecks(f.type,
+ var f = genericTypeAliasElement('F');
+ var g = genericTypeAliasElement('G');
+ f.function.returnType = listOf(g.function.type);
+ g.function.returnType = listOf(f.function.type);
+ basicChecks(functionTypeAliasType(f),
element: same(f), displayName: 'F', name: 'F', returnType: isNotNull);
- var fReturn = f.type.returnType;
- expect(fReturn.element, same(listType.element));
+ var fReturn = functionTypeAliasType(f).returnType;
+ expect(fReturn.element, same(listElement));
if (bug_33302_fixed) {
expect(fReturn.displayName, 'List<G>');
} else {
@@ -265,7 +297,7 @@
var fReturnArg = (fReturn as InterfaceType).typeArguments[0];
expect(fReturnArg.element, same(g.function));
var fReturnArgReturn = (fReturnArg as FunctionType).returnType;
- expect(fReturnArgReturn.element, same(listType.element));
+ expect(fReturnArgReturn.element, same(listElement));
expect((fReturnArgReturn as InterfaceType).typeArguments[0],
new TypeMatcher<CircularFunctionTypeImpl>());
basicChecks(f.function.type,
@@ -276,10 +308,10 @@
expect(
f.function.type.displayName, 'List<List<...> Function()> Function()');
}
- basicChecks(g.type,
+ basicChecks(functionTypeAliasType(g),
element: same(g), displayName: 'G', name: 'G', returnType: isNotNull);
- var gReturn = g.type.returnType;
- expect(gReturn.element, same(listType.element));
+ var gReturn = functionTypeAliasType(g).returnType;
+ expect(gReturn.element, same(listElement));
if (bug_33302_fixed) {
expect(gReturn.displayName, 'List<F>');
} else {
@@ -288,7 +320,7 @@
var gReturnArg = (gReturn as InterfaceType).typeArguments[0];
expect(gReturnArg.element, same(f.function));
var gReturnArgReturn = (gReturnArg as FunctionType).returnType;
- expect(gReturnArgReturn.element, same(listType.element));
+ expect(gReturnArgReturn.element, same(listElement));
expect((gReturnArgReturn as InterfaceType).typeArguments[0],
new TypeMatcher<CircularFunctionTypeImpl>());
basicChecks(g.function.type,
@@ -304,11 +336,11 @@
test_forTypedef_recursive_via_parameterTypes() {
// typedef F = void Function(G g);
// typedef G = void Function(F f);
- var f = new MockGenericTypeAliasElement('F', returnType: voidType);
- var g = new MockGenericTypeAliasElement('G', returnType: voidType);
- f.parameters = [new MockParameterElement('g', type: g.function.type)];
- g.parameters = [new MockParameterElement('f', type: f.function.type)];
- basicChecks(f.type,
+ var f = genericTypeAliasElement('F', returnType: voidType);
+ var g = genericTypeAliasElement('G', returnType: voidType);
+ f.function.parameters = [requiredParameter('g', type: g.function.type)];
+ g.function.parameters = [requiredParameter('f', type: f.function.type)];
+ basicChecks(functionTypeAliasType(f),
element: same(f),
displayName: 'F',
name: 'F',
@@ -316,7 +348,7 @@
normalParameterTypes: hasLength(1),
normalParameterNames: ['g'],
returnType: same(voidType));
- var fParamType = f.type.normalParameterTypes[0];
+ var fParamType = functionTypeAliasType(f).normalParameterTypes[0];
expect(fParamType.element, same(g.function));
expect((fParamType as FunctionType).normalParameterTypes[0],
new TypeMatcher<CircularFunctionTypeImpl>());
@@ -332,7 +364,7 @@
} else {
expect(f.function.type.displayName, 'void Function(void Function(...))');
}
- basicChecks(g.type,
+ basicChecks(functionTypeAliasType(g),
element: same(g),
displayName: 'G',
name: 'G',
@@ -340,7 +372,7 @@
normalParameterTypes: hasLength(1),
normalParameterNames: ['f'],
returnType: same(voidType));
- var gParamType = g.type.normalParameterTypes[0];
+ var gParamType = functionTypeAliasType(g).normalParameterTypes[0];
expect(gParamType.element, same(f.function));
expect((gParamType as FunctionType).normalParameterTypes[0],
new TypeMatcher<CircularFunctionTypeImpl>());
@@ -361,13 +393,13 @@
test_forTypedef_recursive_via_returnTypes() {
// typedef F = G Function();
// typedef G = F Function();
- var f = new MockGenericTypeAliasElement('F');
- var g = new MockGenericTypeAliasElement('G');
- f.returnType = g.function.type;
- g.returnType = f.function.type;
- basicChecks(f.type,
+ var f = genericTypeAliasElement('F');
+ var g = genericTypeAliasElement('G');
+ f.function.returnType = g.function.type;
+ g.function.returnType = f.function.type;
+ basicChecks(functionTypeAliasType(f),
element: same(f), displayName: 'F', name: 'F', returnType: isNotNull);
- var fReturn = f.type.returnType;
+ var fReturn = functionTypeAliasType(f).returnType;
expect(fReturn.element, same(g.function));
expect((fReturn as FunctionType).returnType,
new TypeMatcher<CircularFunctionTypeImpl>());
@@ -378,9 +410,9 @@
} else {
expect(f.function.type.displayName, '... Function() Function()');
}
- basicChecks(g.type,
+ basicChecks(functionTypeAliasType(g),
element: same(g), displayName: 'G', name: 'G', returnType: isNotNull);
- var gReturn = g.type.returnType;
+ var gReturn = functionTypeAliasType(g).returnType;
expect(gReturn.element, same(f.function));
expect((gReturn as FunctionType).returnType,
new TypeMatcher<CircularFunctionTypeImpl>());
@@ -394,8 +426,8 @@
}
test_forTypedef_returnType() {
- var e = new MockGenericTypeAliasElement('F', returnType: objectType);
- basicChecks(e.type,
+ var e = genericTypeAliasElement('F', returnType: objectType);
+ basicChecks(functionTypeAliasType(e),
element: same(e), displayName: 'F', name: 'F', returnType: objectType);
basicChecks(e.function.type,
element: same(e.function),
@@ -404,28 +436,29 @@
}
test_forTypedef_returnType_null() {
- var e = new MockGenericTypeAliasElement.withNullReturn('F');
- basicChecks(e.type, element: same(e), displayName: 'F', name: 'F');
+ var e = genericTypeAliasElement('F');
+ basicChecks(functionTypeAliasType(e),
+ element: same(e), displayName: 'F', name: 'F');
basicChecks(e.function.type,
element: same(e.function), displayName: 'dynamic Function()');
}
test_forTypedef_typeParameter() {
// typedef F<T> = T Function();
- var t = new MockTypeParameterElement('T');
- var e = new MockGenericTypeAliasElement('F',
- typeParameters: [t], returnType: t.type);
+ var t = typeParameter('T');
+ var e = genericTypeAliasElement('F',
+ typeParameters: [t], returnType: typeParameterType(t));
basicChecks(e.type,
element: same(e),
displayName: 'F',
name: 'F',
- returnType: same(t.type),
+ returnType: typeParameterType(t),
typeFormals: [same(t)]);
basicChecks(e.function.type,
element: same(e.function),
displayName: 'T Function()',
- returnType: same(t.type),
- typeArguments: [same(t.type)],
+ returnType: typeParameterType(t),
+ typeArguments: [typeParameterType(t)],
typeParameters: [same(t)]);
}
@@ -436,9 +469,10 @@
test_synthetic_instantiate() {
// T Function<T>(T x)
- var t = new MockTypeParameterElement('T');
- var x = new MockParameterElement('x', type: t.type);
- FunctionType f = new FunctionTypeImpl.synthetic(t.type, [t], [x]);
+ var t = typeParameter('T');
+ var x = requiredParameter('x', type: typeParameterType(t));
+ FunctionType f =
+ new FunctionTypeImpl.synthetic(typeParameterType(t), [t], [x]);
FunctionType instantiated = f.instantiate([objectType]);
basicChecks(instantiated,
element: isNull,
@@ -451,7 +485,7 @@
test_synthetic_instantiate_argument_length_mismatch() {
// dynamic Function<T>()
- var t = new MockTypeParameterElement('T');
+ var t = typeParameter('T');
FunctionType f = new FunctionTypeImpl.synthetic(dynamicType, [t], []);
expect(() => f.instantiate([]), throwsA(new TypeMatcher<ArgumentError>()));
}
@@ -463,9 +497,10 @@
test_synthetic_instantiate_share_parameters() {
// T Function<T>(int x)
- var t = new MockTypeParameterElement('T');
- var x = new MockParameterElement('x', type: intType);
- FunctionType f = new FunctionTypeImpl.synthetic(t.type, [t], [x]);
+ var t = typeParameter('T');
+ var x = requiredParameter('x', type: intType);
+ FunctionType f =
+ new FunctionTypeImpl.synthetic(typeParameterType(t), [t], [x]);
FunctionType instantiated = f.instantiate([objectType]);
basicChecks(instantiated,
element: isNull,
@@ -477,8 +512,7 @@
}
test_synthetic_namedParameter() {
- var p = new MockParameterElement('x',
- type: objectType, parameterKind: ParameterKind.NAMED);
+ var p = namedParameter('x', type: objectType);
FunctionType f = new FunctionTypeImpl.synthetic(dynamicType, [], [p]);
basicChecks(f,
element: isNull,
@@ -491,7 +525,7 @@
}
test_synthetic_normalParameter() {
- var p = new MockParameterElement('x', type: objectType);
+ var p = requiredParameter('x', type: objectType);
FunctionType f = new FunctionTypeImpl.synthetic(dynamicType, [], [p]);
basicChecks(f,
element: isNull,
@@ -505,8 +539,7 @@
}
test_synthetic_optionalParameter() {
- var p = new MockParameterElement('x',
- type: objectType, parameterKind: ParameterKind.POSITIONAL);
+ var p = positionalParameter('x', type: objectType);
FunctionType f = new FunctionTypeImpl.synthetic(dynamicType, [], [p]);
basicChecks(f,
element: isNull,
@@ -529,39 +562,44 @@
test_synthetic_substitute() {
// Map<T, U> Function<U extends T>(T x, U y)
- var t = new MockTypeParameterElement('T');
- var u = new MockTypeParameterElement('U', bound: t.type);
- var x = new MockParameterElement('x', type: t.type);
- var y = new MockParameterElement('y', type: u.type);
- FunctionType f =
- new FunctionTypeImpl.synthetic(mapOf(t.type, u.type), [u], [x, y]);
- FunctionType substituted = f.substitute2([objectType], [t.type]);
+ var t = typeParameter('T');
+ var u = typeParameter('U', bound: typeParameterType(t));
+ var x = requiredParameter('x', type: typeParameterType(t));
+ var y = requiredParameter('y', type: typeParameterType(u));
+ FunctionType f = new FunctionTypeImpl.synthetic(
+ mapOf(typeParameterType(t), typeParameterType(u)), [u], [x, y]);
+ FunctionType substituted =
+ f.substitute2([objectType], [typeParameterType(t)]);
var uSubstituted = substituted.typeFormals[0];
basicChecks(substituted,
element: isNull,
displayName: 'Map<Object, U> Function<U extends Object>(Object, U)',
- returnType: mapOf(objectType, uSubstituted.type),
+ returnType: mapOf(objectType, typeParameterType(uSubstituted)),
typeFormals: [uSubstituted],
normalParameterNames: ['x', 'y'],
- normalParameterTypes: [same(objectType), same(uSubstituted.type)],
+ normalParameterTypes: [
+ same(objectType),
+ typeParameterType(uSubstituted)
+ ],
parameters: hasLength(2));
}
test_synthetic_substitute_argument_length_mismatch() {
// dynamic Function()
- var t = new MockTypeParameterElement('T');
+ var t = typeParameter('T');
FunctionType f = new FunctionTypeImpl.synthetic(dynamicType, [], []);
- expect(() => f.substitute2([], [t.type]),
+ expect(() => f.substitute2([], [typeParameterType(t)]),
throwsA(new TypeMatcher<ArgumentError>()));
}
test_synthetic_substitute_share_returnType_and_parameters() {
// int Function<U extends T>(int x)
- var t = new MockTypeParameterElement('T');
- var u = new MockTypeParameterElement('U', bound: t.type);
- var x = new MockParameterElement('x', type: intType);
+ var t = typeParameter('T');
+ var u = typeParameter('U', bound: typeParameterType(t));
+ var x = requiredParameter('x', type: intType);
FunctionType f = new FunctionTypeImpl.synthetic(intType, [u], [x]);
- FunctionType substituted = f.substitute2([objectType], [t.type]);
+ FunctionType substituted =
+ f.substitute2([objectType], [typeParameterType(t)]);
basicChecks(substituted,
element: isNull,
displayName: 'int Function<U extends Object>(int)',
@@ -576,56 +614,61 @@
test_synthetic_substitute_share_returnType_and_typeFormals() {
// int Function<U>(T x, U y)
- var t = new MockTypeParameterElement('T');
- var u = new MockTypeParameterElement('U');
- var x = new MockParameterElement('x', type: t.type);
- var y = new MockParameterElement('y', type: u.type);
+ var t = typeParameter('T');
+ var u = typeParameter('U');
+ var x = requiredParameter('x', type: typeParameterType(t));
+ var y = requiredParameter('y', type: typeParameterType(u));
FunctionType f = new FunctionTypeImpl.synthetic(intType, [u], [x, y]);
- FunctionType substituted = f.substitute2([objectType], [t.type]);
+ FunctionType substituted =
+ f.substitute2([objectType], [typeParameterType(t)]);
basicChecks(substituted,
element: isNull,
displayName: 'int Function<U>(Object, U)',
returnType: same(f.returnType),
typeFormals: same(f.typeFormals),
normalParameterNames: ['x', 'y'],
- normalParameterTypes: [same(objectType), same(u.type)],
+ normalParameterTypes: [same(objectType), typeParameterType(u)],
parameters: hasLength(2));
}
test_synthetic_substitute_share_typeFormals_and_parameters() {
// T Function<U>(U x)
- var t = new MockTypeParameterElement('T');
- var u = new MockTypeParameterElement('U');
- var x = new MockParameterElement('x', type: u.type);
- FunctionType f = new FunctionTypeImpl.synthetic(t.type, [u], [x]);
- FunctionType substituted = f.substitute2([objectType], [t.type]);
+ var t = typeParameter('T');
+ var u = typeParameter('U');
+ var x = requiredParameter('x', type: typeParameterType(u));
+ FunctionType f =
+ new FunctionTypeImpl.synthetic(typeParameterType(t), [u], [x]);
+ FunctionType substituted =
+ f.substitute2([objectType], [typeParameterType(t)]);
basicChecks(substituted,
element: isNull,
displayName: 'Object Function<U>(U)',
returnType: same(objectType),
typeFormals: same(f.typeFormals),
normalParameterNames: ['x'],
- normalParameterTypes: [same(u.type)],
+ normalParameterTypes: [typeParameterType(u)],
parameters: same(f.parameters));
}
test_synthetic_substitute_unchanged() {
// dynamic Function<U>(U x)
- var t = new MockTypeParameterElement('T');
- var u = new MockTypeParameterElement('U');
- var x = new MockParameterElement('x', type: u.type);
+ var t = typeParameter('T');
+ var u = typeParameter('U');
+ var x = requiredParameter('x', type: typeParameterType(u));
FunctionType f = new FunctionTypeImpl.synthetic(dynamicType, [u], [x]);
- FunctionType substituted = f.substitute2([objectType], [t.type]);
+ FunctionType substituted =
+ f.substitute2([objectType], [typeParameterType(t)]);
expect(substituted, same(f));
}
test_synthetic_typeFormals() {
- var t = new MockTypeParameterElement('T');
- FunctionType f = new FunctionTypeImpl.synthetic(t.type, [t], []);
+ var t = typeParameter('T');
+ FunctionType f =
+ new FunctionTypeImpl.synthetic(typeParameterType(t), [t], []);
basicChecks(f,
element: isNull,
displayName: 'T Function<T>()',
- returnType: same(t.type),
+ returnType: typeParameterType(t),
typeFormals: [same(t)]);
}
@@ -636,29 +679,12 @@
}
test_unnamedConstructor_instantiate_argument_length_mismatch() {
- var t = new MockTypeParameterElement('T');
+ var t = typeParameter('T');
var e = new MockFunctionTypedElement(typeParameters: [t]);
FunctionType f = new FunctionTypeImpl(e);
expect(() => f.instantiate([]), throwsA(new TypeMatcher<ArgumentError>()));
}
- test_unnamedConstructor_instantiate_noop() {
- var t = new MockTypeParameterElement('T');
- var p = new MockParameterElement('x', type: t.type);
- var e = new MockFunctionTypedElement(typeParameters: [t], parameters: [p]);
- FunctionType f = new FunctionTypeImpl(e);
- var instantiated = f.instantiate([t.type]);
- basicChecks(instantiated,
- element: same(e),
- displayName: 'dynamic Function(T)',
- typeArguments: hasLength(1),
- typeParameters: [same(t)],
- normalParameterNames: ['x'],
- normalParameterTypes: [same(t.type)],
- parameters: [same(p)]);
- expect(instantiated.typeArguments[0], same(t.type));
- }
-
test_unnamedConstructor_instantiate_noTypeParameters() {
var e = new MockFunctionTypedElement();
FunctionType f = new FunctionTypeImpl(e);
@@ -666,8 +692,8 @@
}
test_unnamedConstructor_instantiate_parameterType_simple() {
- var t = new MockTypeParameterElement('T');
- var p = new MockParameterElement('x', type: t.type);
+ var t = typeParameter('T');
+ var p = requiredParameter('x', type: typeParameterType(t));
var e = new MockFunctionTypedElement(typeParameters: [t], parameters: [p]);
FunctionType f = new FunctionTypeImpl(e);
var instantiated = f.instantiate([objectType]);
@@ -685,9 +711,9 @@
}
test_unnamedConstructor_instantiate_returnType_simple() {
- var t = new MockTypeParameterElement('T');
- var e =
- new MockFunctionTypedElement(typeParameters: [t], returnType: t.type);
+ var t = typeParameter('T');
+ var e = new MockFunctionTypedElement(
+ typeParameters: [t], returnType: typeParameterType(t));
FunctionType f = new FunctionTypeImpl(e);
var instantiated = f.instantiate([objectType]);
basicChecks(instantiated,
@@ -700,7 +726,7 @@
}
test_unnamedConstructor_namedParameter() {
- var p = new MockParameterElement('x', parameterKind: ParameterKind.NAMED);
+ var p = namedParameter('x', type: dynamicType);
var e = new MockFunctionTypedElement(parameters: [p]);
FunctionType f = new FunctionTypeImpl(e);
basicChecks(f,
@@ -711,8 +737,7 @@
}
test_unnamedConstructor_namedParameter_object() {
- var p = new MockParameterElement('x',
- parameterKind: ParameterKind.NAMED, type: objectType);
+ var p = namedParameter('x', type: objectType);
var e = new MockFunctionTypedElement(parameters: [p]);
FunctionType f = new FunctionTypeImpl(e);
basicChecks(f,
@@ -729,20 +754,20 @@
}
test_unnamedConstructor_nonTypedef_withTypeArguments() {
- var t = new MockTypeParameterElement('T');
- var c = new MockClassElement('C', typeParameters: [t]);
- var e = new MockMethodElement(c, returnType: t.type);
+ var t = typeParameter('T');
+ var e = method('e', typeParameterType(t));
+ class_(name: 'C', typeParameters: [t], methods: [e]);
FunctionType f = new FunctionTypeImpl(e);
basicChecks(f,
element: same(e),
- typeArguments: [same(t.type)],
+ typeArguments: [typeParameterType(t)],
typeParameters: [same(t)],
displayName: 'T Function()',
- returnType: same(t.type));
+ returnType: typeParameterType(t));
}
test_unnamedConstructor_normalParameter() {
- var p = new MockParameterElement('x');
+ var p = requiredParameter('x', type: dynamicType);
var e = new MockFunctionTypedElement(parameters: [p]);
FunctionType f = new FunctionTypeImpl(e);
basicChecks(f,
@@ -754,7 +779,7 @@
}
test_unnamedConstructor_normalParameter_object() {
- var p = new MockParameterElement('x', type: objectType);
+ var p = requiredParameter('x', type: objectType);
var e = new MockFunctionTypedElement(parameters: [p]);
FunctionType f = new FunctionTypeImpl(e);
basicChecks(f,
@@ -766,8 +791,7 @@
}
test_unnamedConstructor_optionalParameter() {
- var p =
- new MockParameterElement('x', parameterKind: ParameterKind.POSITIONAL);
+ var p = positionalParameter('x', type: dynamicType);
var e = new MockFunctionTypedElement(parameters: [p]);
FunctionType f = new FunctionTypeImpl(e);
basicChecks(f,
@@ -779,8 +803,7 @@
}
test_unnamedConstructor_optionalParameter_object() {
- var p = new MockParameterElement('x',
- parameterKind: ParameterKind.POSITIONAL, type: objectType);
+ var p = positionalParameter('x', type: objectType);
var e = new MockFunctionTypedElement(parameters: [p]);
FunctionType f = new FunctionTypeImpl(e);
basicChecks(f,
@@ -810,9 +833,9 @@
}
test_unnamedConstructor_staticMethod_ignores_enclosing_type_params() {
- var t = new MockTypeParameterElement('T');
- var c = new MockClassElement('C', typeParameters: [t]);
- var e = new MockMethodElement(c, isStatic: true);
+ var t = typeParameter('T');
+ var e = method('e', dynamicType, isStatic: true);
+ class_(name: 'C', typeParameters: [t], methods: [e]);
FunctionType f = new FunctionTypeImpl(e);
basicChecks(f, element: same(e));
}
@@ -821,11 +844,11 @@
// abstract class C<T> {
// dynamic f();
// }
- var t = new MockTypeParameterElement('T');
- var c = new MockClassElement('C', typeParameters: [t]);
+ var t = typeParameter('T');
+ var c = class_(name: 'C', typeParameters: [t]);
var e = new MockFunctionTypedElement(enclosingElement: c);
FunctionType f = new FunctionTypeImpl(e);
- expect(() => f.substitute2([], [t.type]),
+ expect(() => f.substitute2([], [typeParameterType(t)]),
throwsA(new TypeMatcher<ArgumentError>()));
}
@@ -833,20 +856,20 @@
// abstract class C<T> {
// Map<S, V> f<S extends T, T extends U, V extends T>();
// }
- var s = new MockTypeParameterElement('S');
- var t = new MockTypeParameterElement('T');
- var u = new MockTypeParameterElement('U');
- var v = new MockTypeParameterElement('V');
- s.bound = t.type;
- t.bound = u.type;
- v.bound = t.type;
- var c = new MockClassElement('C', typeParameters: [u]);
+ var s = typeParameter('S');
+ var t = typeParameter('T');
+ var u = typeParameter('U');
+ var v = typeParameter('V');
+ s.bound = typeParameterType(t);
+ t.bound = typeParameterType(u);
+ v.bound = typeParameterType(t);
+ var c = class_(name: 'C', typeParameters: [u]);
var e = new MockFunctionTypedElement(
- returnType: mapOf(s.type, v.type),
+ returnType: mapOf(typeParameterType(s), typeParameterType(v)),
typeParameters: [s, t, v],
enclosingElement: c);
FunctionType f = new FunctionTypeImpl(e);
- var substituted = f.substitute2([objectType], [u.type]);
+ var substituted = f.substitute2([objectType], [typeParameterType(u)]);
basicChecks(substituted,
element: same(e),
displayName: isNotNull,
@@ -867,13 +890,15 @@
expect(s2.name, 'S');
expect(t2.name, 'T');
expect(v2.name, 'V');
- expect(s2.bound, t2.type);
+ expect(s2.bound, typeParameterType(t2));
expect(t2.bound, same(objectType));
- expect(v2.bound, t2.type);
+ expect(v2.bound, typeParameterType(t2));
if (bug_33301_fixed) {
- expect(substituted.returnType, mapOf(s2.type, v2.type));
+ expect(substituted.returnType,
+ mapOf(typeParameterType(s2), typeParameterType(v2)));
} else {
- expect(substituted.returnType, mapOf(s.type, v.type));
+ expect(substituted.returnType,
+ mapOf(typeParameterType(s), typeParameterType(v)));
}
}
@@ -881,23 +906,23 @@
// abstract class C<T> {
// void f<S extends T, T extends U, V extends T>(S x, V y);
// }
- var s = new MockTypeParameterElement('S');
- var t = new MockTypeParameterElement('T');
- var u = new MockTypeParameterElement('U');
- var v = new MockTypeParameterElement('V');
- s.bound = t.type;
- t.bound = u.type;
- v.bound = t.type;
- var c = new MockClassElement('C', typeParameters: [u]);
- var x = new MockParameterElement('x', type: s.type);
- var y = new MockParameterElement('y', type: v.type);
+ var s = typeParameter('S');
+ var t = typeParameter('T');
+ var u = typeParameter('U');
+ var v = typeParameter('V');
+ s.bound = typeParameterType(t);
+ t.bound = typeParameterType(u);
+ v.bound = typeParameterType(t);
+ var c = class_(name: 'C', typeParameters: [u]);
+ var x = requiredParameter('x', type: typeParameterType(s));
+ var y = requiredParameter('y', type: typeParameterType(v));
var e = new MockFunctionTypedElement(
returnType: voidType,
typeParameters: [s, t, v],
enclosingElement: c,
parameters: [x, y]);
FunctionType f = new FunctionTypeImpl(e);
- var substituted = f.substitute2([objectType], [u.type]);
+ var substituted = f.substitute2([objectType], [typeParameterType(u)]);
basicChecks(substituted,
element: same(e),
displayName: isNotNull,
@@ -921,13 +946,15 @@
expect(s2.name, 'S');
expect(t2.name, 'T');
expect(v2.name, 'V');
- expect(s2.bound, t2.type);
+ expect(s2.bound, typeParameterType(t2));
expect(t2.bound, same(objectType));
- expect(v2.bound, t2.type);
+ expect(v2.bound, typeParameterType(t2));
if (bug_33301_fixed) {
- expect(substituted.normalParameterTypes, [same(s2.type), same(v2.type)]);
+ expect(substituted.normalParameterTypes,
+ [same(typeParameterType(s2)), same(typeParameterType(v2))]);
} else {
- expect(substituted.normalParameterTypes, [same(s.type), same(v.type)]);
+ expect(substituted.normalParameterTypes,
+ [typeParameterType(s), typeParameterType(v)]);
}
}
@@ -935,13 +962,15 @@
// abstract class C<T> {
// U f<U extends T>();
// }
- var t = new MockTypeParameterElement('T');
- var c = new MockClassElement('C', typeParameters: [t]);
- var u = new MockTypeParameterElement('U', bound: t.type);
+ var t = typeParameter('T');
+ var c = class_(name: 'C', typeParameters: [t]);
+ var u = typeParameter('U', bound: typeParameterType(t));
var e = new MockFunctionTypedElement(
- typeParameters: [u], returnType: u.type, enclosingElement: c);
+ typeParameters: [u],
+ returnType: typeParameterType(u),
+ enclosingElement: c);
FunctionType f = new FunctionTypeImpl(e);
- var substituted = f.substitute2([objectType], [t.type]);
+ var substituted = f.substitute2([objectType], [typeParameterType(t)]);
basicChecks(substituted,
element: same(e),
displayName: 'U Function<U extends Object>()',
@@ -956,24 +985,25 @@
}
test_unnamedConstructor_substitute_noop() {
- var t = new MockTypeParameterElement('T');
- var e = new MockFunctionTypedElement(returnType: t.type);
+ var t = typeParameter('T');
+ var e = new MockFunctionTypedElement(returnType: typeParameterType(t));
FunctionType f = new FunctionTypeImpl(e);
- var substituted = f.substitute2([t.type], [t.type]);
+ var substituted =
+ f.substitute2([typeParameterType(t)], [typeParameterType(t)]);
basicChecks(substituted,
element: same(e),
displayName: 'T Function()',
- returnType: same(t.type));
+ returnType: typeParameterType(t));
// TODO(paulberry): test substitute length mismatch
}
test_unnamedConstructor_substitute_parameterType_simple() {
- var t = new MockTypeParameterElement('T');
- var c = new MockClassElement('C', typeParameters: [t]);
- var p = new MockParameterElement('x', type: t.type);
+ var t = typeParameter('T');
+ var c = class_(name: 'C', typeParameters: [t]);
+ var p = requiredParameter('x', type: typeParameterType(t));
var e = new MockFunctionTypedElement(parameters: [p], enclosingElement: c);
FunctionType f = new FunctionTypeImpl(e);
- var substituted = f.substitute2([objectType], [t.type]);
+ var substituted = f.substitute2([objectType], [typeParameterType(t)]);
basicChecks(substituted,
element: same(e),
displayName: 'dynamic Function(Object)',
@@ -987,12 +1017,12 @@
}
test_unnamedConstructor_substitute_returnType_simple() {
- var t = new MockTypeParameterElement('T');
- var c = new MockClassElement('C', typeParameters: [t]);
- var e =
- new MockFunctionTypedElement(returnType: t.type, enclosingElement: c);
+ var t = typeParameter('T');
+ var c = class_(name: 'C', typeParameters: [t]);
+ var e = new MockFunctionTypedElement(
+ returnType: typeParameterType(t), enclosingElement: c);
FunctionType f = new FunctionTypeImpl(e);
- var substituted = f.substitute2([objectType], [t.type]);
+ var substituted = f.substitute2([objectType], [typeParameterType(t)]);
basicChecks(substituted,
element: same(e),
displayName: 'Object Function()',
@@ -1002,7 +1032,7 @@
}
test_unnamedConstructor_typeParameter() {
- var t = new MockTypeParameterElement('T');
+ var t = typeParameter('T');
var e = new MockFunctionTypedElement(typeParameters: [t]);
FunctionType f = new FunctionTypeImpl(e);
basicChecks(f,
@@ -1013,72 +1043,40 @@
}
test_unnamedConstructor_typeParameter_with_bound() {
- var t = new MockTypeParameterElement('T');
- var c = new MockClassElement('C', typeParameters: [t]);
- var u = new MockTypeParameterElement('U', bound: t.type);
+ var t = typeParameter('T');
+ var c = class_(name: 'C', typeParameters: [t]);
+ var u = typeParameter('U', bound: typeParameterType(t));
var e = new MockFunctionTypedElement(
- typeParameters: [u], returnType: u.type, enclosingElement: c);
+ typeParameters: [u],
+ returnType: typeParameterType(u),
+ enclosingElement: c);
FunctionType f = new FunctionTypeImpl(e);
basicChecks(f,
element: same(e),
displayName: 'U Function<U extends T>()',
- typeArguments: [same(t.type)],
+ typeArguments: [typeParameterType(t)],
typeParameters: [same(t)],
- returnType: same(u.type),
+ returnType: typeParameterType(u),
typeFormals: hasLength(1));
expect(f.typeFormals[0].name, 'U');
- expect(f.typeFormals[0].bound, same(t.type));
+ expect(f.typeFormals[0].bound, typeParameterType(t));
}
test_unnamedConstructor_with_enclosing_type_parameters() {
// Test a weird behavior: substitutions are recorded in typeArguments and
// typeParameters.
- var t = new MockTypeParameterElement('T');
- var c = new MockClassElement('C', typeParameters: [t]);
- var e =
- new MockFunctionTypedElement(returnType: t.type, enclosingElement: c);
+ var t = typeParameter('T');
+ var c = class_(name: 'C', typeParameters: [t]);
+ var e = new MockFunctionTypedElement(
+ returnType: typeParameterType(t), enclosingElement: c);
FunctionType f = new FunctionTypeImpl(e);
basicChecks(f,
element: same(e),
displayName: 'T Function()',
- returnType: same(t.type),
- typeArguments: [same(t.type)],
+ returnType: typeParameterType(t),
+ typeArguments: [typeParameterType(t)],
typeParameters: [same(t)]);
}
-
- static InterfaceTypeImpl _makeListType() {
- var e = new MockTypeParameterElement('E');
- return new InterfaceTypeImpl.elementWithNameAndArgs(
- new MockClassElement('List', typeParameters: [e]),
- 'List',
- () => [e.type]);
- }
-
- static InterfaceTypeImpl _makeMapType() {
- var k = new MockTypeParameterElement('K');
- var v = new MockTypeParameterElement('V');
- return new InterfaceTypeImpl.elementWithNameAndArgs(
- new MockClassElement('Map', typeParameters: [k, v]),
- 'Map',
- () => [k.type, v.type]);
- }
-}
-
-class MockClassElement implements ClassElementImpl {
- @override
- final List<TypeParameterElement> typeParameters;
-
- @override
- final String displayName;
-
- MockClassElement(this.displayName, {this.typeParameters: const []});
-
- @override
- get enclosingElement => const MockCompilationUnitElement();
-
- noSuchMethod(Invocation invocation) {
- return super.noSuchMethod(invocation);
- }
}
class MockCompilationUnitElement implements CompilationUnitElement {
@@ -1092,12 +1090,6 @@
}
}
-class MockElementLocation implements ElementLocation {
- noSuchMethod(Invocation invocation) {
- return super.noSuchMethod(invocation);
- }
-}
-
class MockFunctionTypedElement implements FunctionTypedElement {
@override
final List<ParameterElement> parameters;
@@ -1129,81 +1121,6 @@
}
}
-class MockGenericFunctionTypeElementImpl
- implements GenericFunctionTypeElementImpl {
- @override
- final MockGenericTypeAliasElement enclosingElement;
-
- FunctionTypeImpl _type;
-
- MockGenericFunctionTypeElementImpl(this.enclosingElement);
-
- @override
- get parameters => enclosingElement.parameters;
-
- @override
- get returnType => enclosingElement.returnType;
-
- @override
- get type => _type ??= new FunctionTypeImpl(this);
-
- @override
- get typeParameters => enclosingElement.innerTypeParameters;
-
- noSuchMethod(Invocation invocation) {
- return super.noSuchMethod(invocation);
- }
-}
-
-class MockGenericTypeAliasElement implements GenericTypeAliasElement {
- @override
- final String name;
-
- @override
- List<ParameterElement> parameters;
-
- @override
- final List<TypeParameterElement> typeParameters;
-
- @override
- DartType returnType;
-
- FunctionType _type;
-
- MockGenericFunctionTypeElementImpl _function;
-
- final List<TypeParameterElement> innerTypeParameters;
-
- MockGenericTypeAliasElement(this.name,
- {this.parameters: const [],
- DartType returnType,
- this.typeParameters: const [],
- this.innerTypeParameters: const []})
- : returnType = returnType ?? dynamicType;
-
- MockGenericTypeAliasElement.withNullReturn(this.name,
- {this.parameters: const [],
- this.typeParameters: const [],
- this.innerTypeParameters: const []})
- : returnType = null;
-
- @override
- get enclosingElement => const MockCompilationUnitElement();
-
- @override
- get function => _function ??= new MockGenericFunctionTypeElementImpl(this);
-
- @override
- get isSynthetic => false;
-
- @override
- FunctionType get type => _type ??= new FunctionTypeImpl.forTypedef(this);
-
- noSuchMethod(Invocation invocation) {
- return super.noSuchMethod(invocation);
- }
-}
-
class MockLibraryElement implements LibraryElement {
const MockLibraryElement();
@@ -1214,77 +1131,3 @@
return super.noSuchMethod(invocation);
}
}
-
-class MockMethodElement extends MockFunctionTypedElement
- implements MethodElement {
- @override
- final bool isStatic;
-
- MockMethodElement(MockClassElement enclosingElement,
- {this.isStatic: false, DartType returnType})
- : super(enclosingElement: enclosingElement, returnType: returnType);
-
- @override
- ClassElement get enclosingElement => super.enclosingElement;
-}
-
-class MockParameterElement
- with ParameterElementMixin
- implements ParameterElementImpl {
- @override
- Element enclosingElement;
-
- @override
- final bool isCovariant;
-
- @override
- final String name;
-
- @override
- final ParameterKind parameterKind;
-
- @override
- final DartType type;
-
- MockParameterElement(this.name,
- {this.parameterKind: ParameterKind.REQUIRED,
- this.type,
- this.isCovariant = false});
-
- @override
- get displayName => name;
-
- noSuchMethod(Invocation invocation) {
- return super.noSuchMethod(invocation);
- }
-}
-
-class MockTypeParameterElement implements TypeParameterElement {
- @override
- final String name;
-
- TypeParameterTypeImpl _type;
-
- MockElementLocation _location;
-
- @override
- DartType bound;
-
- MockTypeParameterElement(this.name, {this.bound});
-
- @override
- get kind => ElementKind.TYPE_PARAMETER;
-
- @override
- get location => _location ??= new MockElementLocation();
-
- @override
- get type => _type ??= new TypeParameterTypeImpl(this);
-
- noSuchMethod(Invocation invocation) {
- return super.noSuchMethod(invocation);
- }
-
- @override
- toString() => name;
-}
diff --git a/pkg/analyzer/test/src/dart/element/inheritance_manager2_test.dart b/pkg/analyzer/test/src/dart/element/inheritance_manager2_test.dart
index 6286672..71b0757 100644
--- a/pkg/analyzer/test/src/dart/element/inheritance_manager2_test.dart
+++ b/pkg/analyzer/test/src/dart/element/inheritance_manager2_test.dart
@@ -2,6 +2,7 @@
// 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.
+import 'package:analyzer/dart/element/nullability_suffix.dart';
import 'package:analyzer/dart/element/type.dart';
import 'package:analyzer/src/dart/element/inheritance_manager2.dart';
import 'package:meta/meta.dart';
@@ -1154,7 +1155,7 @@
@required String name,
String expected,
}) {
- var interfaceType = findElement.classOrMixin(className).type;
+ var interfaceType = _classInterfaceType(className);
var memberType = manager.getInherited(
interfaceType,
@@ -1171,7 +1172,7 @@
bool concrete = false,
bool forSuper = false,
}) {
- var interfaceType = findElement.classOrMixin(className).type;
+ var interfaceType = _classInterfaceType(className);
var memberType = manager.getMember(
interfaceType,
@@ -1184,13 +1185,13 @@
}
void _assertInheritedConcreteMap(String className, String expected) {
- var type = findElement.class_(className).type;
+ var type = _classInterfaceType(className);
var map = manager.getInheritedConcreteMap(type);
_assertNameToFunctionTypeMap(map, expected);
}
void _assertInheritedMap(String className, String expected) {
- var type = findElement.class_(className).type;
+ var type = _classInterfaceType(className);
var map = manager.getInheritedMap(type);
_assertNameToFunctionTypeMap(map, expected);
}
@@ -1227,4 +1228,12 @@
}
expect(actual, expected);
}
+
+ InterfaceType _classInterfaceType(String className) {
+ var element = findElement.classOrMixin(className);
+ return element.instantiate(
+ typeArguments: const [],
+ nullabilitySuffix: NullabilitySuffix.star,
+ );
+ }
}
diff --git a/pkg/analyzer/test/src/dart/element/inheritance_manager3_test.dart b/pkg/analyzer/test/src/dart/element/inheritance_manager3_test.dart
index f07f824..3a5221c 100644
--- a/pkg/analyzer/test/src/dart/element/inheritance_manager3_test.dart
+++ b/pkg/analyzer/test/src/dart/element/inheritance_manager3_test.dart
@@ -3,6 +3,8 @@
// BSD-style license that can be found in the LICENSE file.
import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/dart/element/nullability_suffix.dart';
+import 'package:analyzer/dart/element/type.dart';
import 'package:analyzer/src/dart/element/inheritance_manager3.dart';
import 'package:meta/meta.dart';
import 'package:test/test.dart';
@@ -1165,7 +1167,7 @@
@required String name,
String expected,
}) {
- var interfaceType = findElement.classOrMixin(className).type;
+ var interfaceType = _classInterfaceType(className);
var member = manager.getInherited(
interfaceType,
@@ -1182,7 +1184,7 @@
bool concrete = false,
bool forSuper = false,
}) {
- var interfaceType = findElement.classOrMixin(className).type;
+ var interfaceType = _classInterfaceType(className);
var memberType = manager.getMember(
interfaceType,
@@ -1195,13 +1197,13 @@
}
void _assertInheritedConcreteMap(String className, String expected) {
- var type = findElement.class_(className).type;
+ var type = _classInterfaceType(className);
var map = manager.getInheritedConcreteMap(type);
_assertNameToExecutableMap(map, expected);
}
void _assertInheritedMap(String className, String expected) {
- var type = findElement.class_(className).type;
+ var type = _classInterfaceType(className);
var map = manager.getInheritedMap(type);
_assertNameToExecutableMap(map, expected);
}
@@ -1227,4 +1229,12 @@
}
expect(actual, expected);
}
+
+ InterfaceType _classInterfaceType(String className) {
+ var element = findElement.classOrMixin(className);
+ return element.instantiate(
+ typeArguments: const [],
+ nullabilitySuffix: NullabilitySuffix.star,
+ );
+ }
}
diff --git a/pkg/analyzer/test/src/dart/element/least_upper_bound_helper_test.dart b/pkg/analyzer/test/src/dart/element/least_upper_bound_helper_test.dart
index 13d9100..d9f6283 100644
--- a/pkg/analyzer/test/src/dart/element/least_upper_bound_helper_test.dart
+++ b/pkg/analyzer/test/src/dart/element/least_upper_bound_helper_test.dart
@@ -5,14 +5,13 @@
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/dart/element/type.dart';
import 'package:analyzer/src/dart/element/element.dart';
-import 'package:analyzer/src/dart/element/type.dart';
import 'package:analyzer/src/generated/testing/element_factory.dart';
import 'package:analyzer/src/generated/testing/test_type_provider.dart';
import 'package:analyzer/src/generated/type_system.dart';
import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
-import '../../../generated/test_support.dart';
+import '../../../generated/elements_types_mixin.dart';
main() {
defineReflectiveSuite(() {
@@ -21,17 +20,8 @@
}
@reflectiveTest
-class InterfaceLeastUpperBoundHelperTest extends EngineTestCase {
- /**
- * The type provider used to access the types.
- */
- TestTypeProvider _typeProvider;
-
- @override
- void setUp() {
- super.setUp();
- _typeProvider = new TestTypeProvider();
- }
+class InterfaceLeastUpperBoundHelperTest with ElementsTypesMixin {
+ final TestTypeProvider typeProvider = TestTypeProvider();
void test_computeLongestInheritancePathToObject_multipleInterfacePaths() {
//
@@ -50,10 +40,13 @@
ClassElementImpl classC = ElementFactory.classElement2("C");
ClassElementImpl classD = ElementFactory.classElement2("D");
ClassElementImpl classE = ElementFactory.classElement2("E");
- classB.interfaces = <InterfaceType>[classA.type];
- classC.interfaces = <InterfaceType>[classA.type];
- classD.interfaces = <InterfaceType>[classC.type];
- classE.interfaces = <InterfaceType>[classB.type, classD.type];
+ classB.interfaces = <InterfaceType>[interfaceType(classA)];
+ classC.interfaces = <InterfaceType>[interfaceType(classA)];
+ classD.interfaces = <InterfaceType>[interfaceType(classC)];
+ classE.interfaces = <InterfaceType>[
+ interfaceType(classB),
+ interfaceType(classD)
+ ];
// assertion: even though the longest path to Object for typeB is 2, and
// typeE implements typeB, the longest path for typeE is 4 since it also
// implements typeD
@@ -74,11 +67,15 @@
// E
//
ClassElement classA = ElementFactory.classElement2("A");
- ClassElement classB = ElementFactory.classElement("B", classA.type);
- ClassElement classC = ElementFactory.classElement("C", classA.type);
- ClassElement classD = ElementFactory.classElement("D", classC.type);
- ClassElementImpl classE = ElementFactory.classElement("E", classB.type);
- classE.interfaces = <InterfaceType>[classD.type];
+ ClassElement classB =
+ ElementFactory.classElement("B", interfaceType(classA));
+ ClassElement classC =
+ ElementFactory.classElement("C", interfaceType(classA));
+ ClassElement classD =
+ ElementFactory.classElement("D", interfaceType(classC));
+ ClassElementImpl classE =
+ ElementFactory.classElement("E", interfaceType(classB));
+ classE.interfaces = <InterfaceType>[interfaceType(classD)];
// assertion: even though the longest path to Object for typeB is 2, and
// typeE extends typeB, the longest path for typeE is 4 since it also
// implements typeD
@@ -87,13 +84,14 @@
}
void test_computeLongestInheritancePathToObject_object() {
- expect(_longestPathToObject(_typeProvider.objectType.element), 0);
+ expect(_longestPathToObject(typeProvider.objectType.element), 0);
}
void test_computeLongestInheritancePathToObject_recursion() {
ClassElementImpl classA = ElementFactory.classElement2("A");
- ClassElementImpl classB = ElementFactory.classElement("B", classA.type);
- classA.supertype = classB.type;
+ ClassElementImpl classB =
+ ElementFactory.classElement("B", interfaceType(classA));
+ classA.supertype = interfaceType(classB);
expect(_longestPathToObject(classA), 2);
}
@@ -110,8 +108,8 @@
ClassElementImpl classA = ElementFactory.classElement2("A");
ClassElementImpl classB = ElementFactory.classElement2("B");
ClassElementImpl classC = ElementFactory.classElement2("C");
- classB.interfaces = <InterfaceType>[classA.type];
- classC.interfaces = <InterfaceType>[classB.type];
+ classB.interfaces = <InterfaceType>[interfaceType(classA)];
+ classC.interfaces = <InterfaceType>[interfaceType(classB)];
expect(_longestPathToObject(classA), 1);
expect(_longestPathToObject(classB), 2);
expect(_longestPathToObject(classC), 3);
@@ -128,8 +126,10 @@
// C
//
ClassElement classA = ElementFactory.classElement2("A");
- ClassElement classB = ElementFactory.classElement("B", classA.type);
- ClassElement classC = ElementFactory.classElement("C", classB.type);
+ ClassElement classB =
+ ElementFactory.classElement("B", interfaceType(classA));
+ ClassElement classC =
+ ElementFactory.classElement("C", interfaceType(classB));
expect(_longestPathToObject(classA), 1);
expect(_longestPathToObject(classB), 2);
expect(_longestPathToObject(classC), 3);
@@ -146,35 +146,31 @@
// D
//
- var instObject = InstantiatedClass.of(_typeProvider.objectType);
+ var instObject = InstantiatedClass.of(typeProvider.objectType);
- ClassElementImpl classA = ElementFactory.classElement2('A');
+ ClassElementImpl classA = class_(name: 'A');
var instA = InstantiatedClass(classA, const []);
- var classB = ElementFactory.classElement3(
+ var BT = typeParameter('T');
+ var classB = class_(
name: 'B',
- typeParameterNames: ['T'],
+ typeParameters: [BT],
interfaces: [instA.withNullabilitySuffixNone],
);
- var typeParametersC = ElementFactory.typeParameters(['T']);
- var classC = ElementFactory.classElement3(
- name: 'B',
- typeParameters: typeParametersC,
+ var CT = typeParameter('T');
+ var classC = class_(
+ name: 'C',
+ typeParameters: [CT],
interfaces: [
InstantiatedClass(
classB,
- [typeParametersC[0].type],
+ [typeParameterType(CT)],
).withNullabilitySuffixNone,
],
);
- var classD = ElementFactory.classElement2('D');
-
- InterfaceTypeImpl typeBT = new InterfaceTypeImpl(classB);
- DartType typeT = classC.type.typeArguments[0];
- typeBT.typeArguments = <DartType>[typeT];
- classC.interfaces = <InterfaceType>[typeBT];
+ var classD = class_(name: 'D');
// A
expect(
@@ -185,7 +181,7 @@
// B<D>
expect(
_superInterfaces(
- InstantiatedClass(classB, [classD.type]),
+ InstantiatedClass(classB, [interfaceType(classD)]),
),
unorderedEquals([instObject, instA]),
);
@@ -193,12 +189,12 @@
// C<D>
expect(
_superInterfaces(
- InstantiatedClass(classC, [classD.type]),
+ InstantiatedClass(classC, [interfaceType(classD)]),
),
unorderedEquals([
instObject,
instA,
- InstantiatedClass(classB, [classD.type]),
+ InstantiatedClass(classB, [interfaceType(classD)]),
]),
);
}
@@ -214,7 +210,7 @@
// D
//
- var instObject = InstantiatedClass.of(_typeProvider.objectType);
+ var instObject = InstantiatedClass.of(typeProvider.objectType);
ClassElementImpl classA = ElementFactory.classElement2('A');
var instA = InstantiatedClass(classA, const []);
@@ -231,7 +227,7 @@
typeParameters: typeParametersC,
supertype: InstantiatedClass(
classB,
- [typeParametersC[0].type],
+ [typeParameterType(typeParametersC[0])],
).withNullabilitySuffixNone,
);
@@ -246,7 +242,7 @@
// B<D>
expect(
_superInterfaces(
- InstantiatedClass(classB, [classD.type]),
+ InstantiatedClass(classB, [interfaceType(classD)]),
),
unorderedEquals([instObject, instA]),
);
@@ -254,18 +250,18 @@
// C<D>
expect(
_superInterfaces(
- InstantiatedClass(classC, [classD.type]),
+ InstantiatedClass(classC, [interfaceType(classD)]),
),
unorderedEquals([
instObject,
instA,
- InstantiatedClass(classB, [classD.type]),
+ InstantiatedClass(classB, [interfaceType(classD)]),
]),
);
}
void test_computeSuperinterfaceSet_mixin_constraints() {
- var instObject = InstantiatedClass.of(_typeProvider.objectType);
+ var instObject = InstantiatedClass.of(typeProvider.objectType);
var classA = ElementFactory.classElement3(name: 'A');
var instA = InstantiatedClass(classA, const []);
@@ -295,7 +291,7 @@
}
void test_computeSuperinterfaceSet_mixin_constraints_object() {
- var instObject = InstantiatedClass.of(_typeProvider.objectType);
+ var instObject = InstantiatedClass.of(typeProvider.objectType);
var mixinM = ElementFactory.mixinElement(name: 'M');
var instM = InstantiatedClass(mixinM, const []);
@@ -307,7 +303,7 @@
}
void test_computeSuperinterfaceSet_mixin_interfaces() {
- var instObject = InstantiatedClass.of(_typeProvider.objectType);
+ var instObject = InstantiatedClass.of(typeProvider.objectType);
var classA = ElementFactory.classElement3(name: 'A');
var instA = InstantiatedClass(classA, const []);
@@ -337,7 +333,7 @@
}
void test_computeSuperinterfaceSet_multipleInterfacePaths() {
- var instObject = InstantiatedClass.of(_typeProvider.objectType);
+ var instObject = InstantiatedClass.of(typeProvider.objectType);
var classA = ElementFactory.classElement3(name: 'A');
var instA = InstantiatedClass(classA, const []);
@@ -383,7 +379,7 @@
}
void test_computeSuperinterfaceSet_multipleSuperclassPaths() {
- var instObject = InstantiatedClass.of(_typeProvider.objectType);
+ var instObject = InstantiatedClass.of(typeProvider.objectType);
var classA = ElementFactory.classElement3(name: 'A');
var instA = InstantiatedClass(classA, const []);
@@ -452,7 +448,7 @@
}
void test_computeSuperinterfaceSet_singleInterfacePath() {
- var instObject = InstantiatedClass.of(_typeProvider.objectType);
+ var instObject = InstantiatedClass.of(typeProvider.objectType);
var classA = ElementFactory.classElement3(name: 'A');
var instA = InstantiatedClass(classA, const []);
@@ -496,7 +492,7 @@
// |
// C
//
- var instObject = InstantiatedClass.of(_typeProvider.objectType);
+ var instObject = InstantiatedClass.of(typeProvider.objectType);
var classA = ElementFactory.classElement3(name: 'A');
var instA = InstantiatedClass(classA, const []);
diff --git a/pkg/analyzer/test/src/dart/element/type_algebra_test.dart b/pkg/analyzer/test/src/dart/element/type_algebra_test.dart
index 0069fd1..93095da 100644
--- a/pkg/analyzer/test/src/dart/element/type_algebra_test.dart
+++ b/pkg/analyzer/test/src/dart/element/type_algebra_test.dart
@@ -6,10 +6,11 @@
import 'package:analyzer/dart/element/type.dart';
import 'package:analyzer/src/dart/element/type.dart';
import 'package:analyzer/src/dart/element/type_algebra.dart';
+import 'package:analyzer/src/generated/testing/test_type_provider.dart';
import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
-import '../resolution/driver_resolution.dart';
+import '../../../generated/elements_types_mixin.dart';
main() {
defineReflectiveSuite(() {
@@ -22,14 +23,14 @@
}
@reflectiveTest
-class SubstituteEmptyTest extends DriverResolutionTest {
+class SubstituteEmptyTest extends _Base {
test_interface() async {
- addTestFile(r'''
-class A<T> {}
-''');
- await resolveTestFile();
+ // class A<T> {}
+ var T = typeParameter('T');
+ var A = class_(name: 'A', typeParameters: [T]);
- var type = findElement.class_('A').type;
+ var type = interfaceType(A, typeArguments: [intType]);
+
var result = Substitution.empty.substituteType(type);
expect(result, same(type));
}
@@ -38,21 +39,19 @@
@reflectiveTest
class SubstituteFromInterfaceTypeTest extends _Base {
test_interface() async {
- addTestFile(r'''
-class A<T> {}
-class B<U> extends A<U> {}
-''');
- await resolveTestFile();
+ // class A<T> {}
+ var T = typeParameter('T');
+ var A = class_(name: 'A', typeParameters: [T]);
- var a = findElement.class_('A');
- var b = findElement.class_('B');
- var u = b.typeParameters.single;
+ // class B<U> {}
+ var U = typeParameter('U');
+ var B = class_(name: 'B', typeParameters: [U]);
- var bType = _instantiate(b, [intType]);
- var substitution = Substitution.fromInterfaceType(bType);
+ var BofInt = interfaceType(B, typeArguments: [intType]);
+ var substitution = Substitution.fromInterfaceType(BofInt);
- // `extends A<U>`
- var type = _instantiate(a, [u.type]);
+ // A<U>
+ var type = interfaceType(A, typeArguments: [typeParameterType(U)]);
assertElementTypeString(type, 'A<U>');
var result = substitution.substituteType(type);
@@ -61,188 +60,209 @@
}
@reflectiveTest
-class SubstituteFromPairsTest extends DriverResolutionTest {
+class SubstituteFromPairsTest extends _Base {
test_interface() async {
- addTestFile(r'''
-class A<T, U> {}
-''');
- await resolveTestFile();
+ // class A<T, U> {}
+ var T = typeParameter('T');
+ var U = typeParameter('U');
+ var A = class_(name: 'A', typeParameters: [T, U]);
- var a = findElement.class_('A');
+ var type = interfaceType(
+ A,
+ typeArguments: [
+ typeParameterType(T),
+ typeParameterType(U),
+ ],
+ );
+
var result = Substitution.fromPairs(
- a.typeParameters,
+ [T, U],
[intType, doubleType],
- ).substituteType(a.type);
+ ).substituteType(type);
assertElementTypeString(result, 'A<int, double>');
}
}
@reflectiveTest
-class SubstituteFromUpperAndLowerBoundsTest extends DriverResolutionTest {
+class SubstituteFromUpperAndLowerBoundsTest extends _Base {
test_function() async {
- addTestFile(r'''
-typedef F<T> = T Function(T);
-''');
- await resolveTestFile();
-
- var type = findElement.genericTypeAlias('F').function.type;
- var t = findElement.typeParameter('T');
+ // T Function(T)
+ var T = typeParameter('T');
+ var type = functionType(
+ required: [typeParameterType(T)],
+ returns: typeParameterType(T),
+ );
var result = Substitution.fromUpperAndLowerBounds(
- {t: intType},
- {t: BottomTypeImpl.instance},
+ {T: typeProvider.intType},
+ {T: BottomTypeImpl.instance},
).substituteType(type);
- assertElementTypeString(result, 'int Function(Never)');
+ expect(result.toString(), 'int Function(Never)');
}
}
@reflectiveTest
class SubstituteTest extends _Base {
test_bottom() async {
- addTestFile(r'''
-class A<T> {}
-''');
- await resolveTestFile();
-
- var t = findElement.typeParameter('T');
- _assertIdenticalType(typeProvider.bottomType, {t: intType});
+ var T = typeParameter('T');
+ _assertIdenticalType(typeProvider.bottomType, {T: intType});
}
test_dynamic() async {
- addTestFile(r'''
-class A<T> {}
-''');
- await resolveTestFile();
-
- var t = findElement.typeParameter('T');
- _assertIdenticalType(typeProvider.dynamicType, {t: intType});
+ var T = typeParameter('T');
+ _assertIdenticalType(typeProvider.dynamicType, {T: intType});
}
- test_function_noTypeParameters() async {
- addTestFile(r'''
-typedef F = bool Function(int);
-class B<T> {}
-''');
- await resolveTestFile();
+ test_function_noSubstitutions() async {
+ var type = functionType(required: [intType], returns: boolType);
- var type = findElement.genericTypeAlias('F').function.type;
- var t = findElement.typeParameter('T');
- _assertIdenticalType(type, {t: intType});
+ var T = typeParameter('T');
+ _assertIdenticalType(type, {T: intType});
}
- test_function_typeFormals() async {
- addTestFile(r'''
-typedef F<T> = T Function<U extends T>(U);
-''');
- await resolveTestFile();
-
- var type = findElement.genericTypeAlias('F').function.type;
- var t = findElement.typeParameter('T');
- assertElementTypeString(type, 'T Function<U extends T>(U)');
- _assertSubstitution(
- type,
- {t: intType},
- 'int Function<U extends int>(U)',
+ test_function_parameters_returnType() async {
+ // typedef F<T, U> = T Function(U u, bool);
+ var T = typeParameter('T');
+ var U = typeParameter('U');
+ var type = functionType(
+ required: [
+ typeParameterType(U),
+ boolType,
+ ],
+ returns: typeParameterType(T),
);
- }
- test_function_typeParameters() async {
- addTestFile(r'''
-typedef F<T, U> = T Function(U u, bool);
-''');
- await resolveTestFile();
-
- var type = findElement.genericTypeAlias('F').function.type;
- var t = findElement.typeParameter('T');
- var u = findElement.typeParameter('U');
assertElementTypeString(type, 'T Function(U, bool)');
_assertSubstitution(
type,
- {t: intType},
+ {T: intType},
'int Function(U, bool)',
);
_assertSubstitution(
type,
- {t: intType, u: doubleType},
+ {T: intType, U: doubleType},
'int Function(double, bool)',
);
}
- test_interface_arguments() async {
- addTestFile(r'''
-class A<T> {}
-class B<U> {}
-''');
- await resolveTestFile();
+ test_function_typeFormals() async {
+ // typedef F<T> = T Function<U extends T>(U);
+ var T = typeParameter('T');
+ var U = typeParameter('U', bound: typeParameterType(T));
+ var type = functionType(
+ typeFormals: [U],
+ required: [
+ typeParameterType(U),
+ ],
+ returns: typeParameterType(T),
+ );
- var a = findElement.class_('A');
- var u = findElement.typeParameter('U');
- var uType = new TypeParameterTypeImpl(u);
-
- var type = _instantiate(a, [uType]);
- assertElementTypeString(type, 'A<U>');
- _assertSubstitution(type, {u: intType}, 'A<int>');
- }
-
- test_interface_arguments_deep() async {
- addTestFile(r'''
-class A<T> {}
-class B<U> {}
-''');
- await resolveTestFile();
-
- var a = findElement.class_('A');
- var u = findElement.typeParameter('U');
- var uType = new TypeParameterTypeImpl(u);
-
- var type = _instantiate(a, [
- _instantiate(listElement, [uType])
- ]);
- assertElementTypeString(type, 'A<List<U>>');
- _assertSubstitution(type, {u: intType}, 'A<List<int>>');
- }
-
- test_interface_noArguments() async {
- addTestFile(r'''
-class A {}
-class B<T> {}
-''');
- await resolveTestFile();
-
- var a = findElement.class_('A');
- var t = findElement.typeParameter('T');
- _assertIdenticalType(a.type, {t: intType});
- }
-
- test_interface_noArguments_inArguments() async {
- addTestFile(r'''
-class A<T> {}
-class B<U> {}
-''');
- await resolveTestFile();
-
- var a = findElement.class_('A');
- var u = findElement.typeParameter('U');
- _assertIdenticalType(
- _instantiate(a, [intType]),
- {u: doubleType},
+ assertElementTypeString(type, 'T Function<U extends T>(U)');
+ _assertSubstitution(
+ type,
+ {T: intType},
+ 'int Function<U extends int>(U)',
);
}
- test_void() async {
- addTestFile(r'''
-class A<T> {}
-''');
- await resolveTestFile();
+ test_function_typeFormals_bounds() async {
+ // class Triple<X, Y, Z> {}
+ // typedef F<V> = bool Function<T extends Triplet<T, U, V>, U>();
+ var classTriplet = class_(name: 'Triple', typeParameters: [
+ typeParameter('X'),
+ typeParameter('Y'),
+ typeParameter('Z'),
+ ]);
- var t = findElement.typeParameter('T');
- _assertIdenticalType(voidType, {t: intType});
+ var T = typeParameter('T');
+ var U = typeParameter('U');
+ var V = typeParameter('V');
+ T.bound = interfaceType(classTriplet, typeArguments: [
+ typeParameterType(T),
+ typeParameterType(U),
+ typeParameterType(V),
+ ]);
+ var type = functionType(
+ typeFormals: [T, U],
+ returns: boolType,
+ );
+
+ assertElementTypeString(
+ type,
+ 'bool Function<T extends Triple<T, U, V>,U>()',
+ );
+
+ var result = substitute(type, {V: intType}) as FunctionType;
+ assertElementTypeString(
+ result,
+ 'bool Function<T extends Triple<T, U, int>,U>()',
+ );
+ var T2 = result.typeFormals[0];
+ var U2 = result.typeFormals[1];
+ var T2boundArgs = (T2.bound as InterfaceType).typeArguments;
+ expect((T2boundArgs[0] as TypeParameterType).element, same(T2));
+ expect((T2boundArgs[1] as TypeParameterType).element, same(U2));
+ }
+
+ test_interface_arguments() async {
+ // class A<T> {}
+ var T = typeParameter('T');
+ var A = class_(name: 'A', typeParameters: [T]);
+
+ var U = typeParameter('U');
+ var type = interfaceType(A, typeArguments: [
+ typeParameterType(U),
+ ]);
+
+ assertElementTypeString(type, 'A<U>');
+ _assertSubstitution(type, {U: intType}, 'A<int>');
+ }
+
+ test_interface_arguments_deep() async {
+ var T = typeParameter('T');
+ var A = class_(name: 'A', typeParameters: [T]);
+
+ var U = typeParameter('U');
+ var type = interfaceType(A, typeArguments: [
+ interfaceType(
+ typeProvider.listElement,
+ typeArguments: [
+ typeParameterType(U),
+ ],
+ )
+ ]);
+ assertElementTypeString(type, 'A<List<U>>');
+
+ _assertSubstitution(type, {U: intType}, 'A<List<int>>');
+ }
+
+ test_interface_noArguments() async {
+ // class A {}
+ var A = class_(name: 'A');
+
+ var type = interfaceType(A);
+ var T = typeParameter('T');
+ _assertIdenticalType(type, {T: intType});
+ }
+
+ test_interface_noArguments_inArguments() async {
+ // class A<T> {}
+ var T = typeParameter('T');
+ var A = class_(name: 'A', typeParameters: [T]);
+
+ var type = interfaceType(A, typeArguments: [intType]);
+
+ var U = typeParameter('U');
+ _assertIdenticalType(type, {U: doubleType});
+ }
+
+ test_void() async {
+ var T = typeParameter('T');
+ _assertIdenticalType(typeProvider.voidType, {T: intType});
}
test_void_emptyMap() async {
- addTestFile('');
- await resolveTestFile();
- _assertIdenticalType(voidType, {});
+ _assertIdenticalType(intType, {});
}
void _assertIdenticalType(
@@ -261,11 +281,21 @@
}
}
-class _Base extends DriverResolutionTest {
- /// Intentionally low-level implementation for creating [InterfaceType]
- /// for [ClassElement] and type arguments. We just create it explicitly,
- /// without using `InterfaceType.instantiate()`.
- InterfaceType _instantiate(ClassElement element, List<DartType> arguments) {
- return new InterfaceTypeImpl(element)..typeArguments = arguments;
+class _Base with ElementsTypesMixin {
+ final typeProvider = TestTypeProvider();
+
+ InterfaceType get boolType => typeProvider.boolType;
+
+ InterfaceType get doubleType => typeProvider.doubleType;
+
+ InterfaceType get intType => typeProvider.intType;
+
+ /// Whether `DartType.toString()` with nullability should be asked.
+ bool get typeToStringWithNullability => false;
+
+ void assertElementTypeString(DartType type, String expected) {
+ TypeImpl typeImpl = type;
+ expect(typeImpl.toString(withNullability: typeToStringWithNullability),
+ expected);
}
}
diff --git a/pkg/analyzer/test/src/dart/resolution/assignment_test.dart b/pkg/analyzer/test/src/dart/resolution/assignment_test.dart
index e75f914..e556a7f 100644
--- a/pkg/analyzer/test/src/dart/resolution/assignment_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/assignment_test.dart
@@ -9,7 +9,6 @@
import 'package:test_reflective_loader/test_reflective_loader.dart';
import 'driver_resolution.dart';
-import 'resolution.dart';
main() {
defineReflectiveSuite(() {
@@ -18,10 +17,7 @@
}
@reflectiveTest
-class AssignmentDriverResolutionTest extends DriverResolutionTest
- with AssignmentResolutionMixin {}
-
-mixin AssignmentResolutionMixin implements ResolutionTest {
+class AssignmentDriverResolutionTest extends DriverResolutionTest {
test_compound_indexExpression() async {
addTestFile(r'''
main() {
diff --git a/pkg/analyzer/test/src/dart/resolution/class_alias_test.dart b/pkg/analyzer/test/src/dart/resolution/class_alias_test.dart
index d1b41ac..1cb1ed5 100644
--- a/pkg/analyzer/test/src/dart/resolution/class_alias_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/class_alias_test.dart
@@ -5,7 +5,6 @@
import 'package:test_reflective_loader/test_reflective_loader.dart';
import 'driver_resolution.dart';
-import 'resolution.dart';
main() {
defineReflectiveSuite(() {
@@ -14,10 +13,7 @@
}
@reflectiveTest
-class ClassAliasDriverResolutionTest extends DriverResolutionTest
- with ClassAliasResolutionMixin {}
-
-mixin ClassAliasResolutionMixin implements ResolutionTest {
+class ClassAliasDriverResolutionTest extends DriverResolutionTest {
test_defaultConstructor() async {
addTestFile(r'''
class A {}
diff --git a/pkg/analyzer/test/src/dart/resolution/class_test.dart b/pkg/analyzer/test/src/dart/resolution/class_test.dart
index 53ff0e9..aaa8176 100644
--- a/pkg/analyzer/test/src/dart/resolution/class_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/class_test.dart
@@ -6,8 +6,8 @@
import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
+import '../../../generated/elements_types_mixin.dart';
import 'driver_resolution.dart';
-import 'resolution.dart';
main() {
defineReflectiveSuite(() {
@@ -17,9 +17,7 @@
@reflectiveTest
class ClassDriverResolutionTest extends DriverResolutionTest
- with ClassResolutionMixin {}
-
-mixin ClassResolutionMixin implements ResolutionTest {
+ with ElementsTypesMixin {
test_abstractSuperMemberReference_getter() async {
addTestFile(r'''
abstract class A {
@@ -209,25 +207,32 @@
var c = findElement.class_('C');
var d = findElement.class_('D');
var e = findElement.class_('E');
+
+ var typeA = interfaceType(a);
+ var typeB = interfaceType(b);
+ var typeC = interfaceType(c);
+ var typeD = interfaceType(d);
+ var typeE = interfaceType(e);
+
assertElementTypes(
findElement.class_('X1').allSupertypes,
- [a.type, objectType],
+ [typeA, objectType],
);
assertElementTypes(
findElement.class_('X2').allSupertypes,
- [objectType, b.type],
+ [objectType, typeB],
);
assertElementTypes(
findElement.class_('X3').allSupertypes,
- [a.type, objectType, b.type],
+ [typeA, objectType, typeB],
);
assertElementTypes(
findElement.class_('X4').allSupertypes,
- [a.type, b.type, objectType, c.type],
+ [typeA, typeB, objectType, typeC],
);
assertElementTypes(
findElement.class_('X5').allSupertypes,
- [a.type, b.type, c.type, objectType, d.type, e.type],
+ [typeA, typeB, typeC, objectType, typeD, typeE],
);
}
@@ -250,16 +255,16 @@
assertElementTypes(
findElement.class_('X1').allSupertypes,
[
- a.type.instantiate([stringType]),
+ interfaceType(a, typeArguments: [stringType]),
objectType
],
);
assertElementTypes(
findElement.class_('X2').allSupertypes,
[
- b.type.instantiate([
+ interfaceType(b, typeArguments: [
stringType,
- typeProvider.listType.instantiate([intType])
+ interfaceType(listElement, typeArguments: [intType])
]),
objectType
],
@@ -267,8 +272,8 @@
assertElementTypes(
findElement.class_('X3').allSupertypes,
[
- c.type.instantiate([doubleType]),
- b.type.instantiate([intType, doubleType]),
+ interfaceType(c, typeArguments: [doubleType]),
+ interfaceType(b, typeArguments: [intType, doubleType]),
objectType
],
);
@@ -290,7 +295,7 @@
var c = findElement.class_('C');
assertElementTypes(
findElement.class_('X').allSupertypes,
- [a.type, b.type, c.type],
+ [interfaceType(a), interfaceType(b), interfaceType(c)],
);
}
diff --git a/pkg/analyzer/test/src/dart/resolution/comment_test.dart b/pkg/analyzer/test/src/dart/resolution/comment_test.dart
index c93fc8d..1d275e6 100644
--- a/pkg/analyzer/test/src/dart/resolution/comment_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/comment_test.dart
@@ -5,7 +5,6 @@
import 'package:test_reflective_loader/test_reflective_loader.dart';
import 'driver_resolution.dart';
-import 'resolution.dart';
main() {
defineReflectiveSuite(() {
@@ -13,7 +12,8 @@
});
}
-mixin ClassAliasResolutionMixin implements ResolutionTest {
+@reflectiveTest
+class CommentDriverResolutionTest extends DriverResolutionTest {
test_error_unqualifiedReferenceToNonLocalStaticMember() async {
await assertNoErrorsInCode(r'''
class A {
@@ -223,7 +223,3 @@
);
}
}
-
-@reflectiveTest
-class CommentDriverResolutionTest extends DriverResolutionTest
- with ClassAliasResolutionMixin {}
diff --git a/pkg/analyzer/test/src/dart/resolution/constant_test.dart b/pkg/analyzer/test/src/dart/resolution/constant_test.dart
index 6430fc1..fec0505 100644
--- a/pkg/analyzer/test/src/dart/resolution/constant_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/constant_test.dart
@@ -9,7 +9,6 @@
import 'package:test_reflective_loader/test_reflective_loader.dart';
import 'driver_resolution.dart';
-import 'resolution.dart';
main() {
defineReflectiveSuite(() {
@@ -18,9 +17,7 @@
}
@reflectiveTest
-class ConstantDriverTest extends DriverResolutionTest with ConstantMixin {}
-
-mixin ConstantMixin implements ResolutionTest {
+class ConstantDriverTest extends DriverResolutionTest {
test_constantValue_defaultParameter_noDefaultValue() async {
newFile('/test/lib/a.dart', content: r'''
class A {
diff --git a/pkg/analyzer/test/src/dart/resolution/enum_test.dart b/pkg/analyzer/test/src/dart/resolution/enum_test.dart
index 8e9b10b..f204d72 100644
--- a/pkg/analyzer/test/src/dart/resolution/enum_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/enum_test.dart
@@ -6,7 +6,6 @@
import 'package:test_reflective_loader/test_reflective_loader.dart';
import 'driver_resolution.dart';
-import 'resolution.dart';
main() {
defineReflectiveSuite(() {
@@ -15,10 +14,7 @@
}
@reflectiveTest
-class EnumDriverResolutionTest extends DriverResolutionTest
- with EnumResolutionMixin {}
-
-mixin EnumResolutionMixin implements ResolutionTest {
+class EnumDriverResolutionTest extends DriverResolutionTest {
test_inference_listLiteral() async {
addTestFile(r'''
enum E1 {a, b}
diff --git a/pkg/analyzer/test/src/dart/resolution/for_in_test.dart b/pkg/analyzer/test/src/dart/resolution/for_in_test.dart
index 4c8f5b8..5b83f62 100644
--- a/pkg/analyzer/test/src/dart/resolution/for_in_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/for_in_test.dart
@@ -6,7 +6,6 @@
import 'package:test_reflective_loader/test_reflective_loader.dart';
import 'driver_resolution.dart';
-import 'resolution.dart';
main() {
defineReflectiveSuite(() {
@@ -15,10 +14,7 @@
}
@reflectiveTest
-class ForInDriverResolutionTest extends DriverResolutionTest
- with ForInResolutionMixin {}
-
-mixin ForInResolutionMixin implements ResolutionTest {
+class ForInDriverResolutionTest extends DriverResolutionTest {
test_importPrefix_asIterable() async {
// TODO(scheglov) Remove this test (already tested as import prefix).
// TODO(scheglov) Move other for-in tests here.
diff --git a/pkg/analyzer/test/src/dart/resolution/import_prefix_test.dart b/pkg/analyzer/test/src/dart/resolution/import_prefix_test.dart
index b9e9d61..c514779 100644
--- a/pkg/analyzer/test/src/dart/resolution/import_prefix_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/import_prefix_test.dart
@@ -7,7 +7,6 @@
import 'package:test_reflective_loader/test_reflective_loader.dart';
import 'driver_resolution.dart';
-import 'resolution.dart';
main() {
defineReflectiveSuite(() {
@@ -16,10 +15,7 @@
}
@reflectiveTest
-class ImportPrefixDriverResolutionTest extends DriverResolutionTest
- with ImportPrefixResolutionMixin {}
-
-mixin ImportPrefixResolutionMixin implements ResolutionTest {
+class ImportPrefixDriverResolutionTest extends DriverResolutionTest {
test_asExpression_expressionStatement() async {
addTestFile(r'''
import 'dart:async' as p;
diff --git a/pkg/analyzer/test/src/dart/resolution/instance_creation_test.dart b/pkg/analyzer/test/src/dart/resolution/instance_creation_test.dart
index 2a5fd62..962eb5d 100644
--- a/pkg/analyzer/test/src/dart/resolution/instance_creation_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/instance_creation_test.dart
@@ -6,7 +6,6 @@
import 'package:test_reflective_loader/test_reflective_loader.dart';
import 'driver_resolution.dart';
-import 'resolution.dart';
main() {
defineReflectiveSuite(() {
@@ -15,10 +14,7 @@
}
@reflectiveTest
-class InstanceCreationDriverResolutionTest extends DriverResolutionTest
- with InstanceCreationResolutionMixin {}
-
-mixin InstanceCreationResolutionMixin implements ResolutionTest {
+class InstanceCreationDriverResolutionTest extends DriverResolutionTest {
test_error_newWithInvalidTypeParameters_implicitNew_inference_top() async {
addTestFile(r'''
final foo = Map<int>();
diff --git a/pkg/analyzer/test/src/dart/resolution/instance_member_inference_class_test.dart b/pkg/analyzer/test/src/dart/resolution/instance_member_inference_class_test.dart
index 1faee15..44c13fe 100644
--- a/pkg/analyzer/test/src/dart/resolution/instance_member_inference_class_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/instance_member_inference_class_test.dart
@@ -5,7 +5,6 @@
import 'package:test_reflective_loader/test_reflective_loader.dart';
import 'driver_resolution.dart';
-import 'resolution.dart';
main() {
defineReflectiveSuite(() {
@@ -15,9 +14,7 @@
@reflectiveTest
class InstanceMemberInferenceClassDriverResolutionTest
- extends DriverResolutionTest with InstanceMemberInferenceClassMixin {}
-
-mixin InstanceMemberInferenceClassMixin implements ResolutionTest {
+ extends DriverResolutionTest {
test_invalid_inheritanceCycle() async {
addTestFile('''
class A extends C {}
diff --git a/pkg/analyzer/test/src/dart/resolution/instance_member_inference_mixin_test.dart b/pkg/analyzer/test/src/dart/resolution/instance_member_inference_mixin_test.dart
index 7c2104f..0368dd9 100644
--- a/pkg/analyzer/test/src/dart/resolution/instance_member_inference_mixin_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/instance_member_inference_mixin_test.dart
@@ -5,7 +5,6 @@
import 'package:test_reflective_loader/test_reflective_loader.dart';
import 'driver_resolution.dart';
-import 'resolution.dart';
main() {
defineReflectiveSuite(() {
@@ -15,9 +14,7 @@
@reflectiveTest
class InstanceMemberInferenceMixinDriverResolutionTest
- extends DriverResolutionTest with InstanceMemberInferenceMixinMixin {}
-
-mixin InstanceMemberInferenceMixinMixin implements ResolutionTest {
+ extends DriverResolutionTest {
test_invalid_inheritanceCycle() async {
addTestFile('''
mixin A on C {}
diff --git a/pkg/analyzer/test/src/dart/resolution/mixin_test.dart b/pkg/analyzer/test/src/dart/resolution/mixin_test.dart
index 68895de..8ebd753 100644
--- a/pkg/analyzer/test/src/dart/resolution/mixin_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/mixin_test.dart
@@ -8,6 +8,7 @@
import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
+import '../../../generated/elements_types_mixin.dart';
import 'driver_resolution.dart';
main() {
@@ -17,7 +18,8 @@
}
@reflectiveTest
-class MixinDriverResolutionTest extends DriverResolutionTest {
+class MixinDriverResolutionTest extends DriverResolutionTest
+ with ElementsTypesMixin {
test_accessor_getter() async {
await assertNoErrorsInCode(r'''
mixin M {
@@ -92,7 +94,7 @@
var mElement = findElement.mixin('M');
var aElement = findElement.class_('A');
- assertElementTypes(aElement.mixins, [mElement.type]);
+ assertElementTypes(aElement.mixins, [interfaceType(mElement)]);
var mRef = findNode.typeName('M {} // A');
assertTypeName(mRef, mElement, 'M');
@@ -107,7 +109,7 @@
var mElement = findElement.mixin('M');
var aElement = findElement.class_('A');
- assertElementTypes(aElement.mixins, [mElement.type]);
+ assertElementTypes(aElement.mixins, [interfaceType(mElement)]);
var mRef = findNode.typeName('M;');
assertTypeName(mRef, mElement, 'M');
@@ -153,7 +155,8 @@
expect(element.isEnum, isFalse);
expect(element.isMixin, isTrue);
expect(element.isMixinApplication, isFalse);
- expect(element.type.isObject, isFalse);
+ expect(interfaceType(element).isObject, isFalse);
+ expect(element.isDartCoreObject, isFalse);
assertElementTypes(element.superclassConstraints, [objectType]);
assertElementTypes(element.interfaces, []);
@@ -174,11 +177,11 @@
var c = findElement.class_('C');
assertElementTypes(
findElement.mixin('M1').allSupertypes,
- [a.type, b.type, objectType],
+ [interfaceType(a), interfaceType(b), objectType],
);
assertElementTypes(
findElement.mixin('M2').allSupertypes,
- [a.type, objectType, b.type, c.type],
+ [interfaceType(a), objectType, interfaceType(b), interfaceType(c)],
);
}
@@ -196,15 +199,15 @@
assertElementTypes(
findElement.mixin('M1').allSupertypes,
[
- a.type.instantiate([intType, doubleType]),
+ interfaceType(a, typeArguments: [intType, doubleType]),
objectType
],
);
assertElementTypes(
findElement.mixin('M2').allSupertypes,
[
- b.type.instantiate([stringType]),
- a.type.instantiate([intType, stringType]),
+ interfaceType(b, typeArguments: [stringType]),
+ interfaceType(a, typeArguments: [intType, stringType]),
objectType
],
);
@@ -353,7 +356,7 @@
var randomElement = mathImport.importedLibrary.getType('Random');
var element = findElement.mixin('M');
- assertElementTypes(element.interfaces, [randomElement.type]);
+ assertElementTypes(element.interfaces, [interfaceType(randomElement)]);
var typeRef = findNode.typeName('Random {}');
assertTypeName(typeRef, randomElement, 'Random',
@@ -916,7 +919,9 @@
var randomElement = mathImport.importedLibrary.getType('Random');
var element = findElement.mixin('M');
- assertElementTypes(element.superclassConstraints, [randomElement.type]);
+ assertElementTypes(element.superclassConstraints, [
+ interfaceType(randomElement),
+ ]);
var typeRef = findNode.typeName('Random {}');
assertTypeName(typeRef, randomElement, 'Random',
@@ -993,7 +998,9 @@
var a = findElement.mixin('A');
var b = findElement.mixin('B');
- assertElementTypes(b.superclassConstraints, [a.type]);
+ assertElementTypes(b.superclassConstraints, [
+ interfaceType(a),
+ ]);
}
test_error_onRepeated() async {
@@ -1258,7 +1265,7 @@
''');
var element = findElement.mixin('M');
- var type = element.type;
+ var type = interfaceType(element);
// ignore: deprecated_member_use_from_same_package
expect(type.isMoreSpecificThan(intType), isFalse);
}
diff --git a/pkg/analyzer/test/src/dart/resolution/optional_const_test.dart b/pkg/analyzer/test/src/dart/resolution/optional_const_test.dart
index b4f9586..287b10c 100644
--- a/pkg/analyzer/test/src/dart/resolution/optional_const_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/optional_const_test.dart
@@ -11,7 +11,6 @@
import 'package:test_reflective_loader/test_reflective_loader.dart';
import 'driver_resolution.dart';
-import 'resolution.dart';
main() {
defineReflectiveSuite(() {
@@ -20,10 +19,7 @@
}
@reflectiveTest
-class OptionalConstDriverResolutionTest extends DriverResolutionTest
- with OptionalConstMixin {}
-
-mixin OptionalConstMixin implements ResolutionTest {
+class OptionalConstDriverResolutionTest extends DriverResolutionTest {
Map<String, LibraryElement> libraries = {};
LibraryElement get libraryA => libraries['package:test/a.dart'];
diff --git a/pkg/analyzer/test/src/dart/resolution/resolution.dart b/pkg/analyzer/test/src/dart/resolution/resolution.dart
index bae934f..332bcca 100644
--- a/pkg/analyzer/test/src/dart/resolution/resolution.dart
+++ b/pkg/analyzer/test/src/dart/resolution/resolution.dart
@@ -49,9 +49,9 @@
InterfaceType get intType => typeProvider.intType;
- ClassElement get listElement => typeProvider.listType.element;
+ ClassElement get listElement => typeProvider.listElement;
- ClassElement get mapElement => typeProvider.mapType.element;
+ ClassElement get mapElement => typeProvider.mapElement;
ClassElement get numElement => typeProvider.numType.element;
diff --git a/pkg/analyzer/test/src/dart/resolution/top_type_inference_test.dart b/pkg/analyzer/test/src/dart/resolution/top_type_inference_test.dart
index 65de6ba..5e56cac 100644
--- a/pkg/analyzer/test/src/dart/resolution/top_type_inference_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/top_type_inference_test.dart
@@ -6,7 +6,6 @@
import 'package:test_reflective_loader/test_reflective_loader.dart';
import 'driver_resolution.dart';
-import 'resolution.dart';
main() {
defineReflectiveSuite(() {
@@ -15,10 +14,7 @@
}
@reflectiveTest
-class TopTypeInferenceDriverResolutionTest extends DriverResolutionTest
- with TopTypeInstanceMixin {}
-
-mixin TopTypeInstanceMixin implements ResolutionTest {
+class TopTypeInferenceDriverResolutionTest extends DriverResolutionTest {
test_referenceInstanceVariable_withDeclaredType() async {
addTestFile(r'''
class A {
diff --git a/pkg/analyzer/test/src/dart/resolver/legacy_type_asserter_test.dart b/pkg/analyzer/test/src/dart/resolver/legacy_type_asserter_test.dart
index 2447515..b85f38b 100644
--- a/pkg/analyzer/test/src/dart/resolver/legacy_type_asserter_test.dart
+++ b/pkg/analyzer/test/src/dart/resolver/legacy_type_asserter_test.dart
@@ -4,6 +4,7 @@
import 'package:analyzer/dart/analysis/features.dart';
import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer/dart/element/nullability_suffix.dart';
import 'package:analyzer/src/dart/element/element.dart';
import 'package:analyzer/src/dart/element/type.dart';
import 'package:analyzer/src/dart/resolver/legacy_type_asserter.dart';
@@ -66,10 +67,9 @@
test_nullableUnit_expressionStaticType_nonNullTypeArgument() async {
var identifier = AstTestFactory.identifier3('foo');
var unit = _wrapExpression(identifier);
- identifier.staticType = typeProvider.listType.instantiate([
- (typeProvider.intType as TypeImpl)
- .withNullability(NullabilitySuffix.question)
- ]);
+ identifier.staticType = typeProvider.listType2(
+ (typeProvider.intType as TypeImpl)
+ .withNullability(NullabilitySuffix.question));
expect(() {
LegacyTypeAsserter.assertLegacyTypes(unit);
@@ -79,17 +79,14 @@
test_nullableUnit_expressionStaticType_nonNullTypeParameter() async {
var identifier = AstTestFactory.identifier3('foo');
var unit = _wrapExpression(identifier);
- final listType = typeProvider.listType;
- listType.typeParameters[0] = TypeParameterElementImpl('E', 0)
- ..type = (listType.typeParameters[0].type as TypeImpl)
- .withNullability(NullabilitySuffix.none) as TypeParameterTypeImpl;
- identifier.staticType = listType;
- expect(
- (listType as dynamic)
- .typeParameters[0]
- .type
- .toString(withNullability: true),
- 'E');
+ identifier.staticType = typeProvider.listElement.instantiate(
+ typeArguments: [
+ TypeParameterElementImpl('E', 0).instantiate(
+ nullabilitySuffix: NullabilitySuffix.none,
+ ),
+ ],
+ nullabilitySuffix: NullabilitySuffix.none,
+ );
expect(() {
LegacyTypeAsserter.assertLegacyTypes(unit);
}, throwsStateError);
@@ -98,18 +95,13 @@
test_nullableUnit_expressionStaticType_nonNullTypeParameterBound() async {
var identifier = AstTestFactory.identifier3('foo');
var unit = _wrapExpression(identifier);
- final listType = typeProvider.listType;
- (listType.typeParameters[0] as TypeParameterElementImpl).bound =
- (typeProvider.intType as TypeImpl)
- .withNullability(NullabilitySuffix.none);
- identifier.staticType = listType;
- expect(
- (listType as dynamic)
- .typeParameters[0]
- .type
- .bound
- .toString(withNullability: true),
- 'int');
+ var T = TypeParameterElementImpl.synthetic('T');
+ T.bound = (typeProvider.intType as TypeImpl)
+ .withNullability(NullabilitySuffix.none);
+ identifier.staticType = TypeParameterTypeImpl(
+ T,
+ nullabilitySuffix: NullabilitySuffix.star,
+ );
expect(() {
LegacyTypeAsserter.assertLegacyTypes(unit);
}, throwsStateError);
diff --git a/pkg/analyzer/test/src/diagnostics/assignment_to_final_no_setter_test.dart b/pkg/analyzer/test/src/diagnostics/assignment_to_final_no_setter_test.dart
index 238174f..20ed816 100644
--- a/pkg/analyzer/test/src/diagnostics/assignment_to_final_no_setter_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/assignment_to_final_no_setter_test.dart
@@ -12,6 +12,7 @@
main() {
defineReflectiveSuite(() {
defineReflectiveTests(AssignmentToFinalNoSetterTest);
+ defineReflectiveTests(AssignmentToFinalNoSetterWithExtensionMethodsTest);
});
}
@@ -47,7 +48,7 @@
}
@reflectiveTest
-class AssignmentToMethodWithExtensionMethodsTest
+class AssignmentToFinalNoSetterWithExtensionMethodsTest
extends AssignmentToFinalNoSetterTest {
@override
AnalysisOptionsImpl get analysisOptions => AnalysisOptionsImpl()
@@ -63,7 +64,7 @@
0.foo = 1;
}
''', [
- error(CompileTimeErrorCode.UNDEFINED_EXTENSION_SETTER, 53, 3),
+ error(StaticWarningCode.ASSIGNMENT_TO_FINAL_NO_SETTER, 53, 3),
]);
}
}
diff --git a/pkg/analyzer/test/src/diagnostics/duplicate_definition_test.dart b/pkg/analyzer/test/src/diagnostics/duplicate_definition_test.dart
index 8fa1978..93e0972 100644
--- a/pkg/analyzer/test/src/diagnostics/duplicate_definition_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/duplicate_definition_test.dart
@@ -3,6 +3,7 @@
// BSD-style license that can be found in the LICENSE file.
import 'package:analyzer/dart/analysis/features.dart';
+import 'package:analyzer/src/dart/error/syntactic_errors.dart';
import 'package:analyzer/src/error/codes.dart';
import 'package:analyzer/src/generated/engine.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
@@ -316,6 +317,15 @@
error(CompileTimeErrorCode.DUPLICATE_DEFINITION, 56, 3),
]);
}
+
+ test_topLevel_syntheticParameters() async {
+ await assertErrorsInCode(r'''
+f(,[]) {}
+''', [
+ error(ParserErrorCode.MISSING_IDENTIFIER, 2, 1),
+ error(ParserErrorCode.MISSING_IDENTIFIER, 4, 1),
+ ]);
+ }
}
@reflectiveTest
diff --git a/pkg/analyzer/test/src/diagnostics/extension_override_with_cascade_test.dart b/pkg/analyzer/test/src/diagnostics/extension_override_with_cascade_test.dart
new file mode 100644
index 0000000..b8bcd87
--- /dev/null
+++ b/pkg/analyzer/test/src/diagnostics/extension_override_with_cascade_test.dart
@@ -0,0 +1,63 @@
+// Copyright (c) 2019, 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.
+
+import 'package:analyzer/dart/analysis/features.dart';
+import 'package:analyzer/src/error/codes.dart';
+import 'package:analyzer/src/generated/engine.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import '../dart/resolution/driver_resolution.dart';
+
+main() {
+ defineReflectiveSuite(() {
+ defineReflectiveTests(ExtensionOverrideWithCascadeTest);
+ });
+}
+
+@reflectiveTest
+class ExtensionOverrideWithCascadeTest extends DriverResolutionTest {
+ @override
+ AnalysisOptionsImpl get analysisOptions => AnalysisOptionsImpl()
+ ..contextFeatures = new FeatureSet.forTesting(
+ sdkVersion: '2.3.0', additionalFeatures: [Feature.extension_methods]);
+
+ test_getter() async {
+ await assertErrorsInCode('''
+extension E on int {
+ int get g => 0;
+}
+f() {
+ E(3)..g;
+}
+''', [
+ error(CompileTimeErrorCode.EXTENSION_OVERRIDE_WITH_CASCADE, 53, 2),
+ ]);
+ }
+
+ test_method() async {
+ await assertErrorsInCode('''
+extension E on int {
+ void m() {}
+}
+f() {
+ E(3)..m();
+}
+''', [
+ error(CompileTimeErrorCode.EXTENSION_OVERRIDE_WITH_CASCADE, 49, 2),
+ ]);
+ }
+
+ test_setter() async {
+ await assertErrorsInCode('''
+extension E on int {
+ set s(int i) {}
+}
+f() {
+ E(3)..s = 4;
+}
+''', [
+ error(CompileTimeErrorCode.EXTENSION_OVERRIDE_WITH_CASCADE, 53, 2),
+ ]);
+ }
+}
diff --git a/pkg/analyzer/test/src/diagnostics/inference_failure_on_collection_literal_test.dart b/pkg/analyzer/test/src/diagnostics/inference_failure_on_collection_literal_test.dart
new file mode 100644
index 0000000..c73ced5
--- /dev/null
+++ b/pkg/analyzer/test/src/diagnostics/inference_failure_on_collection_literal_test.dart
@@ -0,0 +1,176 @@
+// Copyright (c) 2019, 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.
+
+import 'package:analyzer/src/error/codes.dart';
+import 'package:analyzer/src/generated/engine.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import '../dart/resolution/driver_resolution.dart';
+
+main() {
+ defineReflectiveSuite(() {
+ defineReflectiveTests(InferenceFailureOnCollectionLiteralTest);
+ });
+}
+
+@reflectiveTest
+class InferenceFailureOnCollectionLiteralTest extends DriverResolutionTest {
+ @override
+ AnalysisOptionsImpl get analysisOptions =>
+ AnalysisOptionsImpl()..strictInference = true;
+
+ test_collectionsWithAnyElements() async {
+ await assertNoErrorsInCode(r'''
+void main() {
+ var a = [7];
+ var b = [7 as dynamic];
+ var c = {7};
+ var d = {7 as dynamic};
+ var e = {7: 42};
+ var f = {7 as dynamic: 42};
+ var g = {7: 42 as dynamic};
+}
+''');
+ }
+
+ test_conditionalList() async {
+ await assertErrorsInCode(r'''
+void main() {
+ var x = "a" == "b" ? [1, 2, 3] : [];
+}
+''', [
+ error(HintCode.UNUSED_LOCAL_VARIABLE, 20, 1),
+ error(HintCode.INFERENCE_FAILURE_ON_COLLECTION_LITERAL, 49, 2),
+ ]);
+ }
+
+ test_defaultParameter_list() async {
+ await assertErrorsInCode(r'''
+void f([list = const []]) => print(list);
+''', [
+ error(HintCode.INFERENCE_FAILURE_ON_UNTYPED_PARAMETER, 8, 4),
+ error(HintCode.INFERENCE_FAILURE_ON_COLLECTION_LITERAL, 15, 8),
+ ]);
+ }
+
+ test_defaultParameter_map() async {
+ await assertErrorsInCode(r'''
+void f([map = const {}]) => print(map);
+''', [
+ error(HintCode.INFERENCE_FAILURE_ON_UNTYPED_PARAMETER, 8, 3),
+ error(HintCode.INFERENCE_FAILURE_ON_COLLECTION_LITERAL, 14, 8),
+ ]);
+ }
+
+ test_downwardsInference() async {
+ await assertNoErrorsInCode(r'''
+void main() {
+ List<dynamic> a = [];
+ Set<dynamic> b = {};
+ Map<dynamic, dynamic> c = {};
+
+ int setLength(Set<Object> set) => set.length;
+ setLength({});
+
+ List<int> f() => [];
+ Set<int> g() => {};
+ Map<int, int> h() => {};
+}
+''');
+ }
+
+ test_explicitTypeArguments() async {
+ await assertNoErrorsInCode(r'''
+void main() {
+ var a = <dynamic>[];
+ var b = <dynamic>{};
+ var c = <dynamic, dynamic>{};
+}
+''');
+ }
+
+ test_functionReturnsList_dynamicReturnType() async {
+ await assertErrorsInCode(r'''
+dynamic f() => [];
+''', [
+ error(HintCode.INFERENCE_FAILURE_ON_COLLECTION_LITERAL, 15, 2),
+ ]);
+ }
+
+ test_functionReturnsList_ObjectReturnType() async {
+ await assertNoErrorsInCode(r'''
+Object f() => [];
+''');
+ }
+
+ test_functionReturnsList_voidReturnType() async {
+ await assertNoErrorsInCode(r'''
+void f() => [];
+''');
+ }
+
+ test_inferredFromNullAware() async {
+ await assertNoErrorsInCode(r'''
+void main() {
+ var x = [1, 2, 3] ?? [];
+}
+''');
+ }
+
+ test_localConstVariable_list() async {
+ await assertErrorsInCode(r'''
+void main() {
+ const x = [];
+}
+''', [
+ error(HintCode.UNUSED_LOCAL_VARIABLE, 22, 1),
+ error(HintCode.INFERENCE_FAILURE_ON_COLLECTION_LITERAL, 26, 2),
+ ]);
+ }
+
+ test_localConstVariable_map() async {
+ await assertErrorsInCode(r'''
+void main() {
+ const x = {};
+}
+''', [
+ error(HintCode.UNUSED_LOCAL_VARIABLE, 22, 1),
+ error(HintCode.INFERENCE_FAILURE_ON_COLLECTION_LITERAL, 26, 2),
+ ]);
+ }
+
+ test_localVariable_list() async {
+ await assertErrorsInCode(r'''
+void main() {
+ var x = [];
+}
+''', [
+ error(HintCode.UNUSED_LOCAL_VARIABLE, 20, 1),
+ error(HintCode.INFERENCE_FAILURE_ON_COLLECTION_LITERAL, 24, 2),
+ ]);
+ }
+
+ test_localVariable_map() async {
+ await assertErrorsInCode(r'''
+void main() {
+ var x = {};
+}
+''', [
+ error(HintCode.UNUSED_LOCAL_VARIABLE, 20, 1),
+ error(HintCode.INFERENCE_FAILURE_ON_COLLECTION_LITERAL, 24, 2),
+ ]);
+ }
+
+ test_onlyInnerMostEmptyCollections() async {
+ await assertErrorsInCode(r'''
+void main() {
+ var x = {[]: {}};
+}
+''', [
+ error(HintCode.UNUSED_LOCAL_VARIABLE, 20, 1),
+ error(HintCode.INFERENCE_FAILURE_ON_COLLECTION_LITERAL, 25, 2),
+ error(HintCode.INFERENCE_FAILURE_ON_COLLECTION_LITERAL, 29, 2),
+ ]);
+ }
+}
diff --git a/pkg/analyzer/test/src/diagnostics/inference_failure_on_function_return_type_test.dart b/pkg/analyzer/test/src/diagnostics/inference_failure_on_function_return_type_test.dart
new file mode 100644
index 0000000..0bcdf0a
--- /dev/null
+++ b/pkg/analyzer/test/src/diagnostics/inference_failure_on_function_return_type_test.dart
@@ -0,0 +1,172 @@
+// Copyright (c) 2019, 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.
+
+import 'package:analyzer/dart/analysis/features.dart';
+import 'package:analyzer/src/error/codes.dart';
+import 'package:analyzer/src/generated/engine.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import '../dart/resolution/driver_resolution.dart';
+
+main() {
+ defineReflectiveSuite(() {
+ defineReflectiveTests(InferenceFailureOnFunctionReturnTypeTest);
+ defineReflectiveTests(InferenceFailureOnFunctionReturnType_InExtensionTest);
+ });
+}
+
+@reflectiveTest
+class InferenceFailureOnFunctionReturnType_InExtensionTest
+ extends DriverResolutionTest {
+ @override
+ AnalysisOptionsImpl get analysisOptions => AnalysisOptionsImpl()
+ ..contextFeatures = new FeatureSet.forTesting(
+ sdkVersion: '2.3.0', additionalFeatures: [Feature.extension_methods])
+ ..strictInference = true;
+
+ test_extensionMethod() async {
+ assertErrorsInCode(r'''
+extension E on List {
+ e() {
+ return 7;
+ }
+}
+''', [error(HintCode.INFERENCE_FAILURE_ON_FUNCTION_RETURN_TYPE, 24, 23)]);
+ }
+}
+
+/// Tests of HintCode.INFERENCE_FAILURE_ON_FUNCTION_RETURN_TYPE with the
+/// "strict-inference" static analysis option.
+@reflectiveTest
+class InferenceFailureOnFunctionReturnTypeTest extends DriverResolutionTest {
+ @override
+ AnalysisOptionsImpl get analysisOptions =>
+ AnalysisOptionsImpl()..strictInference = true;
+
+ test_classInstanceGetter() async {
+ await assertErrorsInCode(r'''
+class C {
+ get f => 7;
+}
+''', [error(HintCode.INFERENCE_FAILURE_ON_FUNCTION_RETURN_TYPE, 12, 11)]);
+ }
+
+ test_classInstanceMethod() async {
+ await assertErrorsInCode(r'''
+class C {
+ f() => 7;
+}
+''', [error(HintCode.INFERENCE_FAILURE_ON_FUNCTION_RETURN_TYPE, 12, 9)]);
+ }
+
+ test_classInstanceMethod_withReturnType() async {
+ await assertNoErrorsInCode(r'''
+class C {
+ Object f() => 7;
+}
+''');
+ }
+
+ test_classInstanceOperator() async {
+ await assertErrorsInCode(r'''
+class C {
+ operator +(int x) => print(x);
+}
+''', [error(HintCode.INFERENCE_FAILURE_ON_FUNCTION_RETURN_TYPE, 12, 30)]);
+ }
+
+ test_classInstanceSetter() async {
+ await assertErrorsInCode(r'''
+class C {
+ set f(int x) => print(x);
+}
+''', [error(HintCode.INFERENCE_FAILURE_ON_FUNCTION_RETURN_TYPE, 12, 25)]);
+ }
+
+ test_classStaticMethod() async {
+ await assertErrorsInCode(r'''
+class C {
+ static f() => 7;
+}
+''', [error(HintCode.INFERENCE_FAILURE_ON_FUNCTION_RETURN_TYPE, 12, 16)]);
+ }
+
+ test_classStaticMethod_withType() async {
+ await assertNoErrorsInCode(r'''
+class C {
+ static int f() => 7;
+}
+''');
+ }
+
+ test_functionTypedParameter() async {
+ await assertErrorsInCode(r'''
+void f(callback()) {
+ callback();
+}
+''', [error(HintCode.INFERENCE_FAILURE_ON_FUNCTION_RETURN_TYPE, 7, 10)]);
+ }
+
+ test_functionTypedParameter_nested() async {
+ await assertErrorsInCode(r'''
+void f(void callback(callback2())) {
+ callback(() => print('hey'));
+}
+''', [error(HintCode.INFERENCE_FAILURE_ON_FUNCTION_RETURN_TYPE, 21, 11)]);
+ }
+
+ test_functionTypedParameter_withReturnType() async {
+ await assertNoErrorsInCode(r'''
+void f(int callback()) {
+ callback();
+}
+''');
+ }
+
+ test_localFunction() async {
+ await assertNoErrorsInCode(r'''
+class C {
+ void f() {
+ g() => 7;
+ }
+}
+''');
+ }
+
+ test_mixinInstanceMethod() async {
+ await assertErrorsInCode(r'''
+mixin C {
+ f() => 7;
+}
+''', [error(HintCode.INFERENCE_FAILURE_ON_FUNCTION_RETURN_TYPE, 12, 9)]);
+ }
+
+ test_topLevelArrowFunction() async {
+ await assertErrorsInCode(r'''
+f() => 7;
+''', [error(HintCode.INFERENCE_FAILURE_ON_FUNCTION_RETURN_TYPE, 0, 9)]);
+ }
+
+ test_topLevelFunction() async {
+ await assertErrorsInCode(r'''
+f() {
+ return 7;
+}
+''', [error(HintCode.INFERENCE_FAILURE_ON_FUNCTION_RETURN_TYPE, 0, 19)]);
+ }
+
+ test_topLevelFunction_async() async {
+ await assertErrorsInCode(r'''
+f() {
+ return 7;
+}
+''', [error(HintCode.INFERENCE_FAILURE_ON_FUNCTION_RETURN_TYPE, 0, 19)]);
+ }
+
+ test_topLevelFunction_withReturnType() async {
+ await assertNoErrorsInCode(r'''
+dynamic f() => 7;
+''');
+ }
+}
diff --git a/pkg/analyzer/test/src/diagnostics/inference_failure_on_uninitialized_variable_test.dart b/pkg/analyzer/test/src/diagnostics/inference_failure_on_uninitialized_variable_test.dart
index 74d1bf6..736554b 100644
--- a/pkg/analyzer/test/src/diagnostics/inference_failure_on_uninitialized_variable_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/inference_failure_on_uninitialized_variable_test.dart
@@ -29,7 +29,7 @@
test_localVariable() async {
String code = r'''
-f() {
+void f() {
var a;
}
''';
@@ -40,7 +40,7 @@
test_localVariable_withInitializer() async {
String code = r'''
-f() {
+void f() {
var a = 7;
}
''';
@@ -50,7 +50,7 @@
test_localVariable_withType() async {
String code = r'''
-f() {
+void f() {
int a;
dynamic b;
Object c;
diff --git a/pkg/analyzer/test/src/diagnostics/inference_failure_on_untyped_parameter_test.dart b/pkg/analyzer/test/src/diagnostics/inference_failure_on_untyped_parameter_test.dart
index 2199133..e1cf255 100644
--- a/pkg/analyzer/test/src/diagnostics/inference_failure_on_untyped_parameter_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/inference_failure_on_untyped_parameter_test.dart
@@ -212,7 +212,7 @@
test_parameter_inFunctionLiteral() async {
String code = r'''
-fn() {
+void fn() {
var f = (var a) {};
}
''';
@@ -223,7 +223,7 @@
test_parameter_inFunctionLiteral_withType() async {
String code = r'''
-fn() {
+void fn() {
var f = (int a) {};
}
''';
diff --git a/pkg/analyzer/test/src/diagnostics/invalid_override_test.dart b/pkg/analyzer/test/src/diagnostics/invalid_override_test.dart
index ab75f79..8ca6262 100644
--- a/pkg/analyzer/test/src/diagnostics/invalid_override_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/invalid_override_test.dart
@@ -24,7 +24,7 @@
String get g { return 'a'; }
}
''', [
- error(CompileTimeErrorCode.INVALID_OVERRIDE, 60, 28),
+ error(CompileTimeErrorCode.INVALID_OVERRIDE, 71, 1),
]);
}
@@ -37,8 +37,8 @@
int f;
}
''', [
- error(CompileTimeErrorCode.INVALID_OVERRIDE, 46, 5),
- error(CompileTimeErrorCode.INVALID_OVERRIDE, 46, 5),
+ error(CompileTimeErrorCode.INVALID_OVERRIDE, 50, 1),
+ error(CompileTimeErrorCode.INVALID_OVERRIDE, 50, 1),
]);
}
@@ -56,8 +56,8 @@
String get getter => null;
}
''', [
- error(CompileTimeErrorCode.INVALID_OVERRIDE, 152, 26),
- error(CompileTimeErrorCode.INVALID_OVERRIDE, 152, 26),
+ error(CompileTimeErrorCode.INVALID_OVERRIDE, 163, 6),
+ error(CompileTimeErrorCode.INVALID_OVERRIDE, 163, 6),
]);
}
@@ -73,8 +73,22 @@
double get g => null;
}
''', [
- error(CompileTimeErrorCode.INVALID_OVERRIDE, 127, 21),
- error(CompileTimeErrorCode.INVALID_OVERRIDE, 127, 21),
+ error(CompileTimeErrorCode.INVALID_OVERRIDE, 138, 1),
+ error(CompileTimeErrorCode.INVALID_OVERRIDE, 138, 1),
+ ]);
+ }
+
+ test_method_abstractOverridesConcrete() async {
+ await assertErrorsInCode('''
+class A {
+ int add(int a, int b) => a + b;
+}
+class B extends A {
+ int add();
+}
+''', [
+ error(CompileTimeErrorCode.INVALID_OVERRIDE, 52, 1),
+ error(CompileTimeErrorCode.INVALID_OVERRIDE, 72, 3),
]);
}
@@ -87,7 +101,7 @@
m({a}) {}
}
''', [
- error(CompileTimeErrorCode.INVALID_OVERRIDE, 49, 9),
+ error(CompileTimeErrorCode.INVALID_OVERRIDE, 49, 1),
]);
}
@@ -100,7 +114,7 @@
m({a, c}) {}
}
''', [
- error(CompileTimeErrorCode.INVALID_OVERRIDE, 49, 12),
+ error(CompileTimeErrorCode.INVALID_OVERRIDE, 49, 1),
]);
}
@@ -113,7 +127,7 @@
m({String a}) {}
}
''', [
- error(CompileTimeErrorCode.INVALID_OVERRIDE, 53, 16),
+ error(CompileTimeErrorCode.INVALID_OVERRIDE, 53, 1),
]);
}
@@ -126,7 +140,7 @@
m(String a) {}
}
''', [
- error(CompileTimeErrorCode.INVALID_OVERRIDE, 51, 14),
+ error(CompileTimeErrorCode.INVALID_OVERRIDE, 51, 1),
]);
}
@@ -139,7 +153,7 @@
m(String a) {}
}
''', [
- error(CompileTimeErrorCode.INVALID_OVERRIDE, 48, 14),
+ error(CompileTimeErrorCode.INVALID_OVERRIDE, 48, 1),
]);
}
@@ -155,8 +169,8 @@
m(double d) {}
}
''', [
- error(CompileTimeErrorCode.INVALID_OVERRIDE, 132, 14),
- error(CompileTimeErrorCode.INVALID_OVERRIDE, 132, 14),
+ error(CompileTimeErrorCode.INVALID_OVERRIDE, 132, 1),
+ error(CompileTimeErrorCode.INVALID_OVERRIDE, 132, 1),
]);
}
@@ -173,8 +187,8 @@
m(String n) {}
}
''', [
- error(CompileTimeErrorCode.INVALID_OVERRIDE, 124, 14),
- error(CompileTimeErrorCode.INVALID_OVERRIDE, 124, 14),
+ error(CompileTimeErrorCode.INVALID_OVERRIDE, 124, 1),
+ error(CompileTimeErrorCode.INVALID_OVERRIDE, 124, 1),
]);
}
@@ -191,8 +205,8 @@
m(double d) {}
}
''', [
- error(CompileTimeErrorCode.INVALID_OVERRIDE, 125, 14),
- error(CompileTimeErrorCode.INVALID_OVERRIDE, 125, 14),
+ error(CompileTimeErrorCode.INVALID_OVERRIDE, 125, 1),
+ error(CompileTimeErrorCode.INVALID_OVERRIDE, 125, 1),
]);
}
@@ -205,7 +219,7 @@
m([String a]) {}
}
''', [
- error(CompileTimeErrorCode.INVALID_OVERRIDE, 53, 16),
+ error(CompileTimeErrorCode.INVALID_OVERRIDE, 53, 1),
]);
}
@@ -222,8 +236,8 @@
m([String n]) {}
}
''', [
- error(CompileTimeErrorCode.INVALID_OVERRIDE, 128, 16),
- error(CompileTimeErrorCode.INVALID_OVERRIDE, 128, 16),
+ error(CompileTimeErrorCode.INVALID_OVERRIDE, 128, 1),
+ error(CompileTimeErrorCode.INVALID_OVERRIDE, 128, 1),
]);
}
@@ -236,7 +250,7 @@
m([a]) {}
}
''', [
- error(CompileTimeErrorCode.INVALID_OVERRIDE, 49, 9),
+ error(CompileTimeErrorCode.INVALID_OVERRIDE, 49, 1),
]);
}
@@ -249,7 +263,7 @@
m(a, b, [c]) {}
}
''', [
- error(CompileTimeErrorCode.INVALID_OVERRIDE, 55, 15),
+ error(CompileTimeErrorCode.INVALID_OVERRIDE, 55, 1),
]);
}
@@ -262,7 +276,7 @@
m(a, [c, d]) {}
}
''', [
- error(CompileTimeErrorCode.INVALID_OVERRIDE, 55, 15),
+ error(CompileTimeErrorCode.INVALID_OVERRIDE, 55, 1),
]);
}
@@ -275,7 +289,7 @@
m(a, b) {}
}
''', [
- error(CompileTimeErrorCode.INVALID_OVERRIDE, 44, 10),
+ error(CompileTimeErrorCode.INVALID_OVERRIDE, 44, 1),
]);
}
@@ -288,7 +302,7 @@
String m() { return 'a'; }
}
''', [
- error(CompileTimeErrorCode.INVALID_OVERRIDE, 61, 26),
+ error(CompileTimeErrorCode.INVALID_OVERRIDE, 68, 1),
]);
}
@@ -303,7 +317,7 @@
String m() { return 'a'; }
}
''', [
- error(CompileTimeErrorCode.INVALID_OVERRIDE, 91, 26),
+ error(CompileTimeErrorCode.INVALID_OVERRIDE, 98, 1),
]);
}
@@ -316,7 +330,7 @@
String m() { return 'a'; }
}
''', [
- error(CompileTimeErrorCode.INVALID_OVERRIDE, 70, 26),
+ error(CompileTimeErrorCode.INVALID_OVERRIDE, 77, 1),
]);
}
@@ -329,7 +343,7 @@
String m() { return 'a'; }
}
''', [
- error(CompileTimeErrorCode.INVALID_OVERRIDE, 58, 26),
+ error(CompileTimeErrorCode.INVALID_OVERRIDE, 65, 1),
]);
}
@@ -344,7 +358,7 @@
String m() { return 'a'; }
}
''', [
- error(CompileTimeErrorCode.INVALID_OVERRIDE, 80, 26),
+ error(CompileTimeErrorCode.INVALID_OVERRIDE, 87, 1),
]);
}
@@ -361,8 +375,8 @@
String m() => '';
}
''', [
- error(CompileTimeErrorCode.INVALID_OVERRIDE, 122, 17),
- error(CompileTimeErrorCode.INVALID_OVERRIDE, 122, 17),
+ error(CompileTimeErrorCode.INVALID_OVERRIDE, 129, 1),
+ error(CompileTimeErrorCode.INVALID_OVERRIDE, 129, 1),
]);
}
@@ -375,7 +389,7 @@
void m() {}
}
''', [
- error(CompileTimeErrorCode.INVALID_OVERRIDE, 58, 11),
+ error(CompileTimeErrorCode.INVALID_OVERRIDE, 63, 1),
]);
}
@@ -388,7 +402,7 @@
void set s(String v) {}
}
''', [
- error(CompileTimeErrorCode.INVALID_OVERRIDE, 57, 23),
+ error(CompileTimeErrorCode.INVALID_OVERRIDE, 66, 1),
]);
}
@@ -405,8 +419,8 @@
set setter14(String _) => null;
}
''', [
- error(CompileTimeErrorCode.INVALID_OVERRIDE, 169, 31),
- error(CompileTimeErrorCode.INVALID_OVERRIDE, 169, 31),
+ error(CompileTimeErrorCode.INVALID_OVERRIDE, 173, 8),
+ error(CompileTimeErrorCode.INVALID_OVERRIDE, 173, 8),
]);
}
@@ -424,8 +438,8 @@
set setter14(String _) => null;
}
''', [
- error(CompileTimeErrorCode.INVALID_OVERRIDE, 162, 31),
- error(CompileTimeErrorCode.INVALID_OVERRIDE, 162, 31),
+ error(CompileTimeErrorCode.INVALID_OVERRIDE, 166, 8),
+ error(CompileTimeErrorCode.INVALID_OVERRIDE, 166, 8),
]);
}
@@ -441,8 +455,8 @@
set s(double d) {}
}
''', [
- error(CompileTimeErrorCode.INVALID_OVERRIDE, 121, 18),
- error(CompileTimeErrorCode.INVALID_OVERRIDE, 121, 18),
+ error(CompileTimeErrorCode.INVALID_OVERRIDE, 125, 1),
+ error(CompileTimeErrorCode.INVALID_OVERRIDE, 125, 1),
]);
}
}
diff --git a/pkg/analyzer/test/src/diagnostics/override_on_non_overriding_field_test.dart b/pkg/analyzer/test/src/diagnostics/override_on_non_overriding_field_test.dart
index 2a978fe..cb18626 100644
--- a/pkg/analyzer/test/src/diagnostics/override_on_non_overriding_field_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/override_on_non_overriding_field_test.dart
@@ -30,7 +30,7 @@
@override
int c;
}''', [
- error(CompileTimeErrorCode.INVALID_OVERRIDE, 126, 5),
+ error(CompileTimeErrorCode.INVALID_OVERRIDE, 130, 1),
]);
}
@@ -49,7 +49,7 @@
@override
int c;
}''', [
- error(CompileTimeErrorCode.INVALID_OVERRIDE, 123, 5),
+ error(CompileTimeErrorCode.INVALID_OVERRIDE, 127, 1),
]);
}
diff --git a/pkg/analyzer/test/src/diagnostics/static_access_to_instance_member_test.dart b/pkg/analyzer/test/src/diagnostics/static_access_to_instance_member_test.dart
index 6fc3e81..b9b0063 100644
--- a/pkg/analyzer/test/src/diagnostics/static_access_to_instance_member_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/static_access_to_instance_member_test.dart
@@ -11,13 +11,73 @@
main() {
defineReflectiveSuite(() {
-// defineReflectiveTests(StaticAccessToInstanceMemberTest);
+ defineReflectiveTests(StaticAccessToInstanceMemberTest);
defineReflectiveTests(StaticAccessToInstanceMemberWithExtensionMethodsTest);
});
}
@reflectiveTest
-class StaticAccessToInstanceMemberTest extends DriverResolutionTest {}
+class StaticAccessToInstanceMemberTest extends DriverResolutionTest {
+ test_method_invocation() async {
+ await assertErrorsInCode('''
+class A {
+ m() {}
+}
+main() {
+ A.m();
+}''', [
+ error(StaticWarningCode.STATIC_ACCESS_TO_INSTANCE_MEMBER, 34, 1),
+ ]);
+ }
+
+ test_method_reference() async {
+ await assertErrorsInCode('''
+class A {
+ m() {}
+}
+main() {
+ A.m;
+}''', [
+ error(StaticWarningCode.STATIC_ACCESS_TO_INSTANCE_MEMBER, 34, 1),
+ ]);
+ }
+
+ test_propertyAccess_field() async {
+ await assertErrorsInCode('''
+class A {
+ var f;
+}
+main() {
+ A.f;
+}''', [
+ error(StaticWarningCode.STATIC_ACCESS_TO_INSTANCE_MEMBER, 34, 1),
+ ]);
+ }
+
+ test_propertyAccess_getter() async {
+ await assertErrorsInCode('''
+class A {
+ get f => 42;
+}
+main() {
+ A.f;
+}''', [
+ error(StaticWarningCode.STATIC_ACCESS_TO_INSTANCE_MEMBER, 40, 1),
+ ]);
+ }
+
+ test_propertyAccess_setter() async {
+ await assertErrorsInCode('''
+class A {
+ set f(x) {}
+}
+main() {
+ A.f = 42;
+}''', [
+ error(StaticWarningCode.STATIC_ACCESS_TO_INSTANCE_MEMBER, 39, 1),
+ ]);
+ }
+}
@reflectiveTest
class StaticAccessToInstanceMemberWithExtensionMethodsTest
diff --git a/pkg/analyzer/test/src/diagnostics/strict_raw_type_test.dart b/pkg/analyzer/test/src/diagnostics/strict_raw_type_test.dart
new file mode 100644
index 0000000..3a50c22
--- /dev/null
+++ b/pkg/analyzer/test/src/diagnostics/strict_raw_type_test.dart
@@ -0,0 +1,318 @@
+// Copyright (c) 2019, 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.
+
+import 'package:analyzer/dart/analysis/features.dart';
+import 'package:analyzer/src/error/codes.dart';
+import 'package:analyzer/src/generated/engine.dart';
+import 'package:analyzer/src/test_utilities/package_mixin.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import '../dart/resolution/driver_resolution.dart';
+
+main() {
+ defineReflectiveSuite(() {
+ defineReflectiveTests(StrictRawTypeTest);
+ defineReflectiveTests(StrictRawType_WithExtensionsTest);
+ });
+}
+
+@reflectiveTest
+class StrictRawType_WithExtensionsTest extends DriverResolutionTest
+ with PackageMixin {
+ @override
+ AnalysisOptionsImpl get analysisOptions => AnalysisOptionsImpl()
+ ..contextFeatures = new FeatureSet.forTesting(
+ sdkVersion: '2.3.0', additionalFeatures: [Feature.extension_methods])
+ ..strictRawTypes = true;
+
+ test_typeOnExtendedType_anonymous_missing() async {
+ assertErrorsInCode(r'''
+extension on List {}
+''', [error(HintCode.STRICT_RAW_TYPE, 13, 4)]);
+ }
+
+ test_typeOnExtendedType_missing() async {
+ assertErrorsInCode(r'''
+extension E on List {}
+''', [error(HintCode.STRICT_RAW_TYPE, 15, 4)]);
+ }
+
+ test_typeOnExtendedType_optionalTypeArgs() async {
+ addMetaPackage();
+ assertNoErrorsInCode(r'''
+import 'package:meta/meta.dart';
+@optionalTypeArgs
+class C<T> {}
+extension E on C {}
+extension on C {}
+''');
+ }
+
+ test_typeOnExtendedType_present() async {
+ assertNoErrorsInCode(r'''
+extension E<T> on List<T> {}
+extension F on List<int> {}
+''');
+ }
+}
+
+@reflectiveTest
+class StrictRawTypeTest extends DriverResolutionTest with PackageMixin {
+ @override
+ AnalysisOptionsImpl get analysisOptions =>
+ AnalysisOptionsImpl()..strictRawTypes = true;
+
+ test_asExpression() async {
+ await assertNoErrorsInCode(r'''
+void f(dynamic x) {
+ print(x as List);
+ print(x as List<dynamic>);
+ print(x as List<List>);
+}
+''');
+ }
+
+ test_functionParts_optionalTypeArg() async {
+ addMetaPackage();
+ await assertNoErrorsInCode(r'''
+import 'package:meta/meta.dart';
+@optionalTypeArgs
+class C<T> {}
+C f(int a) => null;
+void g(C a) => print(a);
+''');
+ }
+
+ test_genericTypeArgument_missingTypeArg() async {
+ await assertErrorsInCode(r'''
+void f() {
+ var a = <List>[];
+}
+''', [
+ error(HintCode.UNUSED_LOCAL_VARIABLE, 17, 1),
+ error(HintCode.STRICT_RAW_TYPE, 22, 4),
+ ]);
+ }
+
+ test_genericTypeArgument_withTypeArg() async {
+ await assertNoErrorsInCode(r'''
+void f() {
+ var a = <List<int>>[];
+}
+''');
+ }
+
+ test_isExpression() async {
+ await assertNoErrorsInCode(r'''
+void f(dynamic x) {
+ print(x is List);
+ print(x is List<dynamic>);
+ print(x is List<List>);
+}
+''');
+ }
+
+ test_localVariable_missingTypeArg() async {
+ await assertErrorsInCode(r'''
+void f() {
+ List a = [1, 2, 3];
+}
+''', [
+ error(HintCode.STRICT_RAW_TYPE, 13, 4),
+ error(HintCode.UNUSED_LOCAL_VARIABLE, 18, 1),
+ ]);
+ }
+
+ test_localVariable_withTypeArg() async {
+ await assertNoErrorsInCode(r'''
+void f() {
+ List<Object> a = [1, 2, 3];
+ print(a);
+}
+''');
+ }
+
+ test_mixinApplication_missing() async {
+ await assertErrorsInCode(r'''
+class C<T> {}
+class D = Object with C;
+''', [error(HintCode.STRICT_RAW_TYPE, 36, 1)]);
+ }
+
+ test_mixinApplication_withTypeArg() async {
+ await assertNoErrorsInCode(r'''
+class C<T> {}
+class D = Object with C<int>;
+''');
+ }
+
+ test_parameter_missingTypeArg() async {
+ await assertErrorsInCode(r'''
+void f(List a) {}
+''', [error(HintCode.STRICT_RAW_TYPE, 7, 4)]);
+ }
+
+ test_returnType_missingTypeArg() async {
+ await assertErrorsInCode(r'''
+List f(int a) => [1, 2, 3];
+''', [error(HintCode.STRICT_RAW_TYPE, 0, 4)]);
+ }
+
+ test_superclassWith_missingTypeArg() async {
+ await assertErrorsInCode(r'''
+class C<T> {}
+class D extends Object with C {}
+''', [error(HintCode.STRICT_RAW_TYPE, 42, 1)]);
+ }
+
+ test_superclassWith_withTypeArg() async {
+ await assertNoErrorsInCode(r'''
+class C<T> {}
+class D extends Object with C<int> {}
+''');
+ }
+
+ test_topLevelField_missingTypeArg() async {
+ await assertErrorsInCode(r'''
+List a;
+''', [error(HintCode.STRICT_RAW_TYPE, 0, 4)]);
+ }
+
+ test_topLevelField_optionalTypeArg() async {
+ addMetaPackage();
+ await assertNoErrorsInCode(r'''
+import 'package:meta/meta.dart';
+@optionalTypeArgs
+class C<T> {}
+C a;
+C get g => null;
+void set s(C a) {}
+''');
+ }
+
+ test_topLevelField_withTypeArg() async {
+ await assertNoErrorsInCode(r'''
+List<int> a;
+List<num> get g => [];
+void set s(List<double> a) {}
+''');
+ }
+
+ test_topLevelGetter_missingTypeArg() async {
+ await assertErrorsInCode(r'''
+List get g => [];
+''', [error(HintCode.STRICT_RAW_TYPE, 0, 4)]);
+ }
+
+ test_topLevelSetter_missingTypeArg() async {
+ await assertErrorsInCode(r'''
+void set s(List a) {}
+''', [error(HintCode.STRICT_RAW_TYPE, 11, 4)]);
+ }
+
+ test_typedef_classic_missingTypeArg() async {
+ await assertErrorsInCode(r'''
+typedef T F1<T>(T _);
+F1 func;
+''', [error(HintCode.STRICT_RAW_TYPE, 22, 2)]);
+ }
+
+ test_typedef_modern_missingTypeArg() async {
+ await assertErrorsInCode(r'''
+typedef F1<T> = T Function(T);
+F1 func;
+''', [error(HintCode.STRICT_RAW_TYPE, 31, 2)]);
+ }
+
+ test_typedef_modern_optionalTypeArgs() async {
+ addMetaPackage();
+ await assertNoErrorsInCode(r'''
+import 'package:meta/meta.dart';
+@optionalTypeArgs
+typedef T F1<T>(T _);
+@optionalTypeArgs
+typedef F2<T> = T Function(T);
+F1 f1;
+F2 f2;
+''');
+ }
+
+ test_typedef_modern_withTypeArg() async {
+ await assertNoErrorsInCode(r'''
+typedef T F1<T>(T _);
+typedef F2<T> = T Function(T);
+typedef F3 = T Function<T>(T);
+F1<int> f1;
+F2<int> f2;
+F3 f3;
+''');
+ }
+
+ test_TypeOnClassDeclaration_optionalTypeArgs() async {
+ addMetaPackage();
+ await assertNoErrorsInCode(r'''
+import 'package:meta/meta.dart';
+@optionalTypeArgs
+class C<T> {}
+class D extends C {}
+class E extends Object with C {}
+class F = Object with C;
+class G implements C {}
+''');
+ }
+
+ test_TypeOnConstructor() async {
+ await assertNoErrorsInCode(r'''
+class C {
+ C();
+ C.named();
+}
+
+var c = C();
+var d = C.named();
+''');
+ }
+
+ test_TypeOnInterface_missing() async {
+ await assertErrorsInCode(r'''
+class C<T> {}
+class D implements C {}
+''', [error(HintCode.STRICT_RAW_TYPE, 33, 1)]);
+ }
+
+ test_TypeOnInterface_withTypeArg() async {
+ await assertNoErrorsInCode(r'''
+class C<T> {}
+class D implements C<int> {}
+''');
+ }
+
+ test_TypeOnSuperclass_missing() async {
+ await assertErrorsInCode(r'''
+class C<T> {}
+class D extends C {}
+''', [error(HintCode.STRICT_RAW_TYPE, 30, 1)]);
+ }
+
+ test_TypeOnSuperclass_withTypeArg() async {
+ await assertNoErrorsInCode(r'''
+class C<T> {}
+class D extends C<int> {}
+''');
+ }
+
+ test_typeParameterBound_missingTypeArg() async {
+ await assertErrorsInCode(r'''
+class C<T> {}
+class D<T extends C> {}
+''', [error(HintCode.STRICT_RAW_TYPE, 32, 1)]);
+ }
+
+ test_typeParameterBound_withTypeArg() async {
+ await assertNoErrorsInCode(r'''
+class C<T> {}
+class D<S, T extends C<S>> {}
+''');
+ }
+}
diff --git a/pkg/analyzer/test/src/diagnostics/switch_expression_not_assignable_test.dart b/pkg/analyzer/test/src/diagnostics/switch_expression_not_assignable_test.dart
new file mode 100644
index 0000000..e8d5051
--- /dev/null
+++ b/pkg/analyzer/test/src/diagnostics/switch_expression_not_assignable_test.dart
@@ -0,0 +1,28 @@
+// Copyright (c) 2019, 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.
+
+import 'package:analyzer/src/error/codes.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import '../dart/resolution/driver_resolution.dart';
+
+main() {
+ defineReflectiveSuite(() {
+ defineReflectiveTests(SwitchExpressionNotAssignableTest);
+ });
+}
+
+@reflectiveTest
+class SwitchExpressionNotAssignableTest extends DriverResolutionTest {
+ test_simple() async {
+ await assertErrorsInCode('''
+f(int p) {
+ switch (p) {
+ case 'a': break;
+ }
+}''', [
+ error(StaticWarningCode.SWITCH_EXPRESSION_NOT_ASSIGNABLE, 21, 1),
+ ]);
+ }
+}
diff --git a/pkg/analyzer/test/src/diagnostics/test_all.dart b/pkg/analyzer/test/src/diagnostics/test_all.dart
index b953550..5dbd49a 100644
--- a/pkg/analyzer/test/src/diagnostics/test_all.dart
+++ b/pkg/analyzer/test/src/diagnostics/test_all.dart
@@ -79,6 +79,8 @@
as extension_override_access_to_static_member;
import 'extension_override_argument_not_assignable_test.dart'
as extension_override_argument_not_assignable;
+import 'extension_override_with_cascade_test.dart'
+ as extension_override_with_cascade;
import 'extension_override_without_access_test.dart'
as extension_override_without_access;
import 'extra_positional_arguments_test.dart' as extra_positional_arguments;
@@ -103,6 +105,10 @@
import 'import_duplicated_library_named_test.dart'
as import_duplicated_library_named;
import 'import_of_non_library_test.dart' as import_of_non_library;
+import 'inference_failure_on_collection_literal_test.dart'
+ as inference_failure_on_collection_literal;
+import 'inference_failure_on_function_return_type_test.dart'
+ as inference_failure_on_function_return_type;
import 'inference_failure_on_uninitialized_variable_test.dart'
as inference_failure_on_uninitialized_variable;
import 'inference_failure_on_untyped_parameter_test.dart'
@@ -263,23 +269,37 @@
as spread_expression_from_deferred_library;
import 'static_access_to_instance_member_test.dart'
as static_access_to_instance_member;
+import 'strict_raw_type_test.dart' as strict_raw_type;
import 'subtype_of_sealed_class_test.dart' as subtype_of_sealed_class;
import 'super_in_extension_test.dart' as super_in_extension;
+import 'switch_expression_not_assignable_test.dart'
+ as switch_expression_not_assignable;
import 'top_level_instance_getter_test.dart' as top_level_instance_getter;
import 'top_level_instance_method_test.dart' as top_level_instance_method;
+import 'type_annotation_deferred_class_test.dart'
+ as type_annotation_deferred_class;
import 'type_argument_not_matching_bounds_test.dart'
as type_argument_not_matching_bounds;
import 'type_check_is_not_null_test.dart' as type_check_is_not_null;
import 'type_check_is_null_test.dart' as type_check_is_null;
+import 'type_parameter_referenced_by_static_test.dart'
+ as type_parameter_referenced_by_static;
+import 'type_test_with_non_type_test.dart' as type_test_with_non_type;
+import 'type_test_with_undefined_name_test.dart'
+ as type_test_with_undefined_name;
import 'unchecked_use_of_nullable_value_test.dart'
as unchecked_use_of_nullable_value;
+import 'undefined_class_boolean_test.dart' as undefined_class_boolean;
+import 'undefined_class_test.dart' as undefined_class;
import 'undefined_extension_getter_test.dart' as undefined_extension_getter;
import 'undefined_extension_method_test.dart' as undefined_extension_method;
import 'undefined_extension_setter_test.dart' as undefined_extension_setter;
import 'undefined_getter_test.dart' as undefined_getter;
import 'undefined_hidden_name_test.dart' as undefined_hidden_name;
+import 'undefined_identifier_await_test.dart' as undefined_identifier_await;
import 'undefined_identifier_test.dart' as undefined_identifier;
import 'undefined_method_test.dart' as undefined_method;
+import 'undefined_named_parameter_test.dart' as undefined_named_parameter;
import 'undefined_operator_test.dart' as undefined_operator;
import 'undefined_prefixed_name_test.dart' as undefined_prefixed_name;
import 'undefined_setter_test.dart' as undefined_setter;
@@ -293,6 +313,8 @@
as unnecessary_null_aware_spread;
import 'unnecessary_type_check_false_test.dart' as unnecessary_type_check_false;
import 'unnecessary_type_check_true_test.dart' as unnecessary_type_check_true;
+import 'unqualified_reference_to_static_member_of_extended_type_test.dart'
+ as unqualified_reference_to_static_member_of_extended_type;
import 'unused_catch_clause_test.dart' as unused_catch_clause;
import 'unused_catch_stack_test.dart' as unused_catch_stack;
import 'unused_element_test.dart' as unused_element;
@@ -362,6 +384,7 @@
extension_declares_member_of_object.main();
extension_override_access_to_static_member.main();
extension_override_argument_not_assignable.main();
+ extension_override_with_cascade.main();
extension_override_without_access.main();
extra_positional_arguments.main();
field_initialized_in_initializer_and_declaration.main();
@@ -376,6 +399,8 @@
import_deferred_library_with_load_function.main();
import_duplicated_library_named.main();
import_of_non_library.main();
+ inference_failure_on_collection_literal.main();
+ inference_failure_on_function_return_type.main();
inference_failure_on_uninitialized_variable.main();
inference_failure_on_untyped_parameter.main();
instance_access_to_static_member.main();
@@ -484,21 +509,31 @@
set_element_type_not_assignable.main();
spread_expression_from_deferred_library.main();
static_access_to_instance_member.main();
+ strict_raw_type.main();
subtype_of_sealed_class.main();
super_in_extension.main();
+ switch_expression_not_assignable.main();
top_level_instance_getter.main();
top_level_instance_method.main();
+ type_annotation_deferred_class.main();
type_argument_not_matching_bounds.main();
type_check_is_not_null.main();
type_check_is_null.main();
+ type_parameter_referenced_by_static.main();
+ type_test_with_non_type.main();
+ type_test_with_undefined_name.main();
unchecked_use_of_nullable_value.main();
+ undefined_class_boolean.main();
+ undefined_class.main();
undefined_extension_getter.main();
undefined_extension_method.main();
undefined_extension_setter.main();
undefined_getter.main();
undefined_hidden_name.main();
+ undefined_identifier_await.main();
undefined_identifier.main();
undefined_method.main();
+ undefined_named_parameter.main();
undefined_operator.main();
undefined_prefixed_name.main();
undefined_setter.main();
@@ -510,6 +545,7 @@
unnecessary_null_aware_spread.main();
unnecessary_type_check_false.main();
unnecessary_type_check_true.main();
+ unqualified_reference_to_static_member_of_extended_type.main();
unused_catch_clause.main();
unused_catch_stack.main();
unused_element.main();
diff --git a/pkg/analyzer/test/src/diagnostics/type_annotation_deferred_class_test.dart b/pkg/analyzer/test/src/diagnostics/type_annotation_deferred_class_test.dart
new file mode 100644
index 0000000..516f8c5
--- /dev/null
+++ b/pkg/analyzer/test/src/diagnostics/type_annotation_deferred_class_test.dart
@@ -0,0 +1,178 @@
+// Copyright (c) 2019, 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.
+
+import 'package:analyzer/src/error/codes.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import '../dart/resolution/driver_resolution.dart';
+
+main() {
+ defineReflectiveSuite(() {
+ defineReflectiveTests(TypeAnnotationDeferredClassTest);
+ });
+}
+
+@reflectiveTest
+class TypeAnnotationDeferredClassTest extends DriverResolutionTest {
+ test_asExpression() async {
+ newFile("/test/lib/lib1.dart", content: '''
+library lib1;
+class A {}''');
+ await assertErrorsInCode('''
+library root;
+import 'lib1.dart' deferred as a;
+f(var v) {
+ v as a.A;
+}''', [
+ error(StaticWarningCode.TYPE_ANNOTATION_DEFERRED_CLASS, 66, 3),
+ ]);
+ }
+
+ test_catchClause() async {
+ newFile("/test/lib/lib1.dart", content: '''
+library lib1;
+class A {}''');
+ await assertErrorsInCode('''
+library root;
+import 'lib1.dart' deferred as a;
+f(var v) {
+ try {
+ } on a.A {
+ }
+}''', [
+ error(StaticWarningCode.TYPE_ANNOTATION_DEFERRED_CLASS, 74, 3),
+ ]);
+ }
+
+ test_fieldFormalParameter() async {
+ newFile("/test/lib/lib1.dart", content: '''
+library lib1;
+class A {}''');
+ await assertErrorsInCode('''
+library root;
+import 'lib1.dart' deferred as a;
+class C {
+ var v;
+ C(a.A this.v);
+}''', [
+ error(StaticWarningCode.TYPE_ANNOTATION_DEFERRED_CLASS, 71, 3),
+ ]);
+ }
+
+ test_functionDeclaration_returnType() async {
+ newFile("/test/lib/lib1.dart", content: '''
+library lib1;
+class A {}''');
+ await assertErrorsInCode('''
+library root;
+import 'lib1.dart' deferred as a;
+a.A f() { return null; }''', [
+ error(StaticWarningCode.TYPE_ANNOTATION_DEFERRED_CLASS, 48, 3),
+ ]);
+ }
+
+ test_functionTypedFormalParameter_returnType() async {
+ newFile("/test/lib/lib1.dart", content: '''
+library lib1;
+class A {}''');
+ await assertErrorsInCode('''
+library root;
+import 'lib1.dart' deferred as a;
+f(a.A g()) {}''', [
+ error(StaticWarningCode.TYPE_ANNOTATION_DEFERRED_CLASS, 50, 3),
+ ]);
+ }
+
+ test_isExpression() async {
+ newFile("/test/lib/lib1.dart", content: '''
+library lib1;
+class A {}''');
+ await assertErrorsInCode('''
+library root;
+import 'lib1.dart' deferred as a;
+f(var v) {
+ bool b = v is a.A;
+}''', [
+ error(HintCode.UNUSED_LOCAL_VARIABLE, 66, 1),
+ error(StaticWarningCode.TYPE_ANNOTATION_DEFERRED_CLASS, 75, 3),
+ ]);
+ }
+
+ test_methodDeclaration_returnType() async {
+ newFile("/test/lib/lib1.dart", content: '''
+library lib1;
+class A {}''');
+ await assertErrorsInCode('''
+library root;
+import 'lib1.dart' deferred as a;
+class C {
+ a.A m() { return null; }
+}''', [
+ error(StaticWarningCode.TYPE_ANNOTATION_DEFERRED_CLASS, 60, 3),
+ ]);
+ }
+
+ test_simpleFormalParameter() async {
+ newFile("/test/lib/lib1.dart", content: '''
+library lib1;
+class A {}''');
+ await assertErrorsInCode('''
+library root;
+import 'lib1.dart' deferred as a;
+f(a.A v) {}''', [
+ error(StaticWarningCode.TYPE_ANNOTATION_DEFERRED_CLASS, 50, 3),
+ ]);
+ }
+
+ test_typeArgumentList() async {
+ newFile("/test/lib/lib1.dart", content: '''
+library lib1;
+class A {}''');
+ await assertErrorsInCode('''
+library root;
+import 'lib1.dart' deferred as a;
+class C<E> {}
+C<a.A> c;''', [
+ error(StaticWarningCode.TYPE_ANNOTATION_DEFERRED_CLASS, 64, 3),
+ ]);
+ }
+
+ test_typeArgumentList2() async {
+ newFile("/test/lib/lib1.dart", content: '''
+library lib1;
+class A {}''');
+ await assertErrorsInCode('''
+library root;
+import 'lib1.dart' deferred as a;
+class C<E, F> {}
+C<a.A, a.A> c;''', [
+ error(StaticWarningCode.TYPE_ANNOTATION_DEFERRED_CLASS, 67, 3),
+ error(StaticWarningCode.TYPE_ANNOTATION_DEFERRED_CLASS, 72, 3),
+ ]);
+ }
+
+ test_typeParameter_bound() async {
+ newFile("/test/lib/lib1.dart", content: '''
+library lib1;
+class A {}''');
+ await assertErrorsInCode('''
+library root;
+import 'lib1.dart' deferred as a;
+class C<E extends a.A> {}''', [
+ error(StaticWarningCode.TYPE_ANNOTATION_DEFERRED_CLASS, 66, 3),
+ ]);
+ }
+
+ test_variableDeclarationList() async {
+ newFile("/test/lib/lib1.dart", content: '''
+library lib1;
+class A {}''');
+ await assertErrorsInCode('''
+library root;
+import 'lib1.dart' deferred as a;
+a.A v;''', [
+ error(StaticWarningCode.TYPE_ANNOTATION_DEFERRED_CLASS, 48, 3),
+ ]);
+ }
+}
diff --git a/pkg/analyzer/test/src/diagnostics/type_parameter_referenced_by_static_test.dart b/pkg/analyzer/test/src/diagnostics/type_parameter_referenced_by_static_test.dart
new file mode 100644
index 0000000..2b54d51
--- /dev/null
+++ b/pkg/analyzer/test/src/diagnostics/type_parameter_referenced_by_static_test.dart
@@ -0,0 +1,87 @@
+// Copyright (c) 2019, 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.
+
+import 'package:analyzer/src/dart/error/hint_codes.dart';
+import 'package:analyzer/src/error/codes.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import '../dart/resolution/driver_resolution.dart';
+
+main() {
+ defineReflectiveSuite(() {
+ defineReflectiveTests(TypeParameterReferencedByStaticTest);
+ });
+}
+
+@reflectiveTest
+class TypeParameterReferencedByStaticTest extends DriverResolutionTest {
+ test_field() async {
+ await assertErrorsInCode('''
+class A<K> {
+ static K k;
+}''', [
+ error(StaticWarningCode.TYPE_PARAMETER_REFERENCED_BY_STATIC, 22, 1),
+ ]);
+ }
+
+ test_getter() async {
+ await assertErrorsInCode('''
+class A<K> {
+ static K get k => null;
+}''', [
+ error(StaticWarningCode.TYPE_PARAMETER_REFERENCED_BY_STATIC, 22, 1),
+ ]);
+ }
+
+ test_methodBodyReference() async {
+ await assertErrorsInCode('''
+class A<K> {
+ static m() {
+ K k;
+ }
+}''', [
+ error(StaticWarningCode.TYPE_PARAMETER_REFERENCED_BY_STATIC, 32, 1),
+ error(HintCode.UNUSED_LOCAL_VARIABLE, 34, 1),
+ ]);
+ }
+
+ test_methodParameter() async {
+ await assertErrorsInCode('''
+class A<K> {
+ static m(K k) {}
+}''', [
+ error(StaticWarningCode.TYPE_PARAMETER_REFERENCED_BY_STATIC, 24, 1),
+ ]);
+ }
+
+ test_methodReturn() async {
+ await assertErrorsInCode('''
+class A<K> {
+ static K m() { return null; }
+}''', [
+ error(StaticWarningCode.TYPE_PARAMETER_REFERENCED_BY_STATIC, 22, 1),
+ ]);
+ }
+
+ test_setter() async {
+ await assertErrorsInCode('''
+class A<K> {
+ static set s(K k) {}
+}''', [
+ error(StaticWarningCode.TYPE_PARAMETER_REFERENCED_BY_STATIC, 28, 1),
+ ]);
+ }
+
+ test_simpleIdentifier() async {
+ await assertErrorsInCode('''
+class A<T> {
+ static foo() {
+ T;
+ }
+}
+''', [
+ error(StaticWarningCode.TYPE_PARAMETER_REFERENCED_BY_STATIC, 34, 1),
+ ]);
+ }
+}
diff --git a/pkg/analyzer/test/src/diagnostics/type_test_with_non_type_test.dart b/pkg/analyzer/test/src/diagnostics/type_test_with_non_type_test.dart
new file mode 100644
index 0000000..39f086c9
--- /dev/null
+++ b/pkg/analyzer/test/src/diagnostics/type_test_with_non_type_test.dart
@@ -0,0 +1,28 @@
+// Copyright (c) 2019, 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.
+
+import 'package:analyzer/src/error/codes.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import '../dart/resolution/driver_resolution.dart';
+
+main() {
+ defineReflectiveSuite(() {
+ defineReflectiveTests(TypeTestWithNonTypeTest);
+ });
+}
+
+@reflectiveTest
+class TypeTestWithNonTypeTest extends DriverResolutionTest {
+ test_parameter() async {
+ await assertErrorsInCode('''
+var A = 0;
+f(var p) {
+ if (p is A) {
+ }
+}''', [
+ error(StaticWarningCode.TYPE_TEST_WITH_NON_TYPE, 33, 1),
+ ]);
+ }
+}
diff --git a/pkg/analyzer/test/src/diagnostics/type_test_with_undefined_name_test.dart b/pkg/analyzer/test/src/diagnostics/type_test_with_undefined_name_test.dart
new file mode 100644
index 0000000..b530cf4
--- /dev/null
+++ b/pkg/analyzer/test/src/diagnostics/type_test_with_undefined_name_test.dart
@@ -0,0 +1,27 @@
+// Copyright (c) 2019, 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.
+
+import 'package:analyzer/src/error/codes.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import '../dart/resolution/driver_resolution.dart';
+
+main() {
+ defineReflectiveSuite(() {
+ defineReflectiveTests(TypeTestWithUndefinedNameTest);
+ });
+}
+
+@reflectiveTest
+class TypeTestWithUndefinedNameTest extends DriverResolutionTest {
+ test_undefined() async {
+ await assertErrorsInCode('''
+f(var p) {
+ if (p is A) {
+ }
+}''', [
+ error(StaticWarningCode.TYPE_TEST_WITH_UNDEFINED_NAME, 22, 1),
+ ]);
+ }
+}
diff --git a/pkg/analyzer/test/src/diagnostics/undefined_class_boolean_test.dart b/pkg/analyzer/test/src/diagnostics/undefined_class_boolean_test.dart
new file mode 100644
index 0000000..8ee9e4b
--- /dev/null
+++ b/pkg/analyzer/test/src/diagnostics/undefined_class_boolean_test.dart
@@ -0,0 +1,27 @@
+// Copyright (c) 2019, 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.
+
+import 'package:analyzer/src/dart/error/hint_codes.dart';
+import 'package:analyzer/src/error/codes.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import '../dart/resolution/driver_resolution.dart';
+
+main() {
+ defineReflectiveSuite(() {
+ defineReflectiveTests(UndefinedClassBooleanTest);
+ });
+}
+
+@reflectiveTest
+class UndefinedClassBooleanTest extends DriverResolutionTest {
+ test_variableDeclaration() async {
+ await assertErrorsInCode('''
+f() { boolean v; }
+''', [
+ error(StaticWarningCode.UNDEFINED_CLASS_BOOLEAN, 6, 7),
+ error(HintCode.UNUSED_LOCAL_VARIABLE, 14, 1),
+ ]);
+ }
+}
diff --git a/pkg/analyzer/test/src/diagnostics/undefined_class_test.dart b/pkg/analyzer/test/src/diagnostics/undefined_class_test.dart
new file mode 100644
index 0000000..3c8a91c
--- /dev/null
+++ b/pkg/analyzer/test/src/diagnostics/undefined_class_test.dart
@@ -0,0 +1,35 @@
+// Copyright (c) 2019, 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.
+
+import 'package:analyzer/src/dart/error/hint_codes.dart';
+import 'package:analyzer/src/error/codes.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import '../dart/resolution/driver_resolution.dart';
+
+main() {
+ defineReflectiveSuite(() {
+ defineReflectiveTests(UndefinedClassTest);
+ });
+}
+
+@reflectiveTest
+class UndefinedClassTest extends DriverResolutionTest {
+ test_instanceCreation() async {
+ await assertErrorsInCode('''
+f() { new C(); }
+''', [
+ error(CompileTimeErrorCode.UNDEFINED_CLASS, 10, 1),
+ ]);
+ }
+
+ test_variableDeclaration() async {
+ await assertErrorsInCode('''
+f() { C c; }
+''', [
+ error(CompileTimeErrorCode.UNDEFINED_CLASS, 6, 1),
+ error(HintCode.UNUSED_LOCAL_VARIABLE, 8, 1),
+ ]);
+ }
+}
diff --git a/pkg/analyzer/test/src/diagnostics/undefined_extension_getter_test.dart b/pkg/analyzer/test/src/diagnostics/undefined_extension_getter_test.dart
index 1917d08..1eb33a7 100644
--- a/pkg/analyzer/test/src/diagnostics/undefined_extension_getter_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/undefined_extension_getter_test.dart
@@ -46,14 +46,27 @@
test_override_undefined_hasSetter() async {
await assertErrorsInCode('''
-extension E on String {
- void set s(int x) {}
+extension E on int {
+ set foo(int _) {}
}
f() {
- E('a').s += 1;
+ E(0).foo;
}
''', [
- error(CompileTimeErrorCode.UNDEFINED_EXTENSION_GETTER, 64, 1),
+ error(CompileTimeErrorCode.UNDEFINED_EXTENSION_GETTER, 56, 3),
+ ]);
+ }
+
+ test_override_undefined_hasSetter_plusEq() async {
+ await assertErrorsInCode('''
+extension E on int {
+ set foo(int _) {}
+}
+f() {
+ E(0).foo += 1;
+}
+''', [
+ error(CompileTimeErrorCode.UNDEFINED_EXTENSION_GETTER, 56, 3),
]);
}
diff --git a/pkg/analyzer/test/src/diagnostics/undefined_extension_setter_test.dart b/pkg/analyzer/test/src/diagnostics/undefined_extension_setter_test.dart
index f6c2f65..4dffd2a 100644
--- a/pkg/analyzer/test/src/diagnostics/undefined_extension_setter_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/undefined_extension_setter_test.dart
@@ -44,7 +44,7 @@
]);
}
- test_override_undefined_hasGetter() async {
+ test_override_undefined_hasGetter_eq() async {
await assertErrorsInCode('''
extension E on int {
int get foo => 0;
@@ -57,6 +57,19 @@
]);
}
+ test_override_undefined_hasGetter_plusEq() async {
+ await assertErrorsInCode('''
+extension E on int {
+ int get foo => 0;
+}
+f() {
+ E(0).foo += 1;
+}
+''', [
+ error(CompileTimeErrorCode.UNDEFINED_EXTENSION_SETTER, 56, 3),
+ ]);
+ }
+
test_static_undefined() async {
await assertErrorsInCode('''
extension E on int {}
diff --git a/pkg/analyzer/test/src/diagnostics/undefined_getter_test.dart b/pkg/analyzer/test/src/diagnostics/undefined_getter_test.dart
index 5f3050e..92f90de 100644
--- a/pkg/analyzer/test/src/diagnostics/undefined_getter_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/undefined_getter_test.dart
@@ -18,6 +18,34 @@
@reflectiveTest
class UndefinedGetterTest extends DriverResolutionTest {
+ test_compoundAssignment_hasSetter_instance() async {
+ await assertErrorsInCode('''
+class C {
+ set foo(int _) {}
+}
+
+f(C c) {
+ c.foo += 1;
+}
+''', [
+ error(StaticTypeWarningCode.UNDEFINED_GETTER, 46, 3),
+ ]);
+ }
+
+ test_compoundAssignment_hasSetter_static() async {
+ await assertErrorsInCode('''
+class C {
+ static set foo(int _) {}
+}
+
+f() {
+ C.foo += 1;
+}
+''', [
+ error(StaticTypeWarningCode.UNDEFINED_GETTER, 50, 3),
+ ]);
+ }
+
test_ifElement_inList_notPromoted() async {
await assertErrorsInCode('''
f(int x) {
@@ -116,6 +144,29 @@
error(StaticTypeWarningCode.UNDEFINED_GETTER, 66, 6),
]);
}
+
+ test_static_definedInSuperclass() async {
+ await assertErrorsInCode('''
+class S {
+ static int get g => 0;
+}
+class C extends S {}
+f(var p) {
+ f(C.g);
+}''', [
+ error(StaticTypeWarningCode.UNDEFINED_GETTER, 75, 1),
+ ]);
+ }
+
+ test_static_undefined() async {
+ await assertErrorsInCode('''
+class C {}
+f(var p) {
+ f(C.m);
+}''', [
+ error(StaticTypeWarningCode.UNDEFINED_GETTER, 28, 1),
+ ]);
+ }
}
@reflectiveTest
diff --git a/pkg/analyzer/test/src/diagnostics/undefined_identifier_await_test.dart b/pkg/analyzer/test/src/diagnostics/undefined_identifier_await_test.dart
new file mode 100644
index 0000000..89019f9
--- /dev/null
+++ b/pkg/analyzer/test/src/diagnostics/undefined_identifier_await_test.dart
@@ -0,0 +1,25 @@
+// Copyright (c) 2019, 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.
+
+import 'package:analyzer/src/error/codes.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import '../dart/resolution/driver_resolution.dart';
+
+main() {
+ defineReflectiveSuite(() {
+ defineReflectiveTests(UndefinedIdentifierAwaitTest);
+ });
+}
+
+@reflectiveTest
+class UndefinedIdentifierAwaitTest extends DriverResolutionTest {
+ test_function() async {
+ await assertErrorsInCode('''
+void a() { await; }
+''', [
+ error(StaticWarningCode.UNDEFINED_IDENTIFIER_AWAIT, 11, 5),
+ ]);
+ }
+}
diff --git a/pkg/analyzer/test/src/diagnostics/undefined_identifier_test.dart b/pkg/analyzer/test/src/diagnostics/undefined_identifier_test.dart
index 895322a..64d01e9 100644
--- a/pkg/analyzer/test/src/diagnostics/undefined_identifier_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/undefined_identifier_test.dart
@@ -15,6 +15,27 @@
@reflectiveTest
class UndefinedIdentifierTest extends DriverResolutionTest {
+ @failingTest
+ test_commentReference() async {
+ await assertErrorsInCode('''
+/** [m] xxx [new B.c] */
+class A {
+}''', [
+ error(StaticWarningCode.UNDEFINED_IDENTIFIER, 5, 1),
+ error(StaticWarningCode.UNDEFINED_IDENTIFIER, 17, 1),
+ ]);
+ }
+
+ test_for() async {
+ await assertErrorsInCode('''
+f(var l) {
+ for (e in l) {
+ }
+}''', [
+ error(StaticWarningCode.UNDEFINED_IDENTIFIER, 18, 1),
+ ]);
+ }
+
test_forElement_inList_insideElement() async {
await assertNoErrorsInCode('''
f(Object x) {
@@ -55,4 +76,74 @@
error(StaticWarningCode.UNDEFINED_IDENTIFIER, 31, 1),
]);
}
+
+ test_function() async {
+ await assertErrorsInCode('''
+int a() => b;
+''', [
+ error(StaticWarningCode.UNDEFINED_IDENTIFIER, 11, 1),
+ ]);
+ }
+
+ test_importCore_withShow() async {
+ await assertErrorsInCode('''
+import 'dart:core' show List;
+main() {
+ List;
+ String;
+}''', [
+ error(StaticWarningCode.UNDEFINED_IDENTIFIER, 49, 6),
+ ]);
+ }
+
+ test_initializer() async {
+ await assertErrorsInCode('''
+var a = b;
+''', [
+ error(StaticWarningCode.UNDEFINED_IDENTIFIER, 8, 1),
+ ]);
+ }
+
+ test_methodInvocation() async {
+ await assertErrorsInCode('''
+f() { C.m(); }
+''', [
+ error(StaticWarningCode.UNDEFINED_IDENTIFIER, 6, 1),
+ ]);
+ }
+
+ test_private_getter() async {
+ newFile("/test/lib/lib.dart", content: '''
+library lib;
+class A {
+ var _foo;
+}''');
+ await assertErrorsInCode('''
+import 'lib.dart';
+class B extends A {
+ test() {
+ var v = _foo;
+ }
+}''', [
+ error(HintCode.UNUSED_LOCAL_VARIABLE, 58, 1),
+ error(StaticWarningCode.UNDEFINED_IDENTIFIER, 62, 4),
+ ]);
+ }
+
+ test_private_setter() async {
+ newFile("/test/lib/lib.dart", content: '''
+library lib;
+class A {
+ var _foo;
+}''');
+ await assertErrorsInCode('''
+import 'lib.dart';
+class B extends A {
+ test() {
+ _foo = 42;
+ }
+}''', [
+ error(StaticWarningCode.UNDEFINED_IDENTIFIER, 54, 4),
+ ]);
+ }
}
diff --git a/pkg/analyzer/test/src/diagnostics/undefined_named_parameter_test.dart b/pkg/analyzer/test/src/diagnostics/undefined_named_parameter_test.dart
new file mode 100644
index 0000000..4381a76
--- /dev/null
+++ b/pkg/analyzer/test/src/diagnostics/undefined_named_parameter_test.dart
@@ -0,0 +1,27 @@
+// Copyright (c) 2019, 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.
+
+import 'package:analyzer/src/error/codes.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import '../dart/resolution/driver_resolution.dart';
+
+main() {
+ defineReflectiveSuite(() {
+ defineReflectiveTests(UndefinedNamedParameterTest);
+ });
+}
+
+@reflectiveTest
+class UndefinedNamedParameterTest extends DriverResolutionTest {
+ test_undefined() async {
+ await assertErrorsInCode('''
+f({a, b}) {}
+main() {
+ f(c: 1);
+}''', [
+ error(CompileTimeErrorCode.UNDEFINED_NAMED_PARAMETER, 26, 1),
+ ]);
+ }
+}
diff --git a/pkg/analyzer/test/src/diagnostics/undefined_setter_test.dart b/pkg/analyzer/test/src/diagnostics/undefined_setter_test.dart
index 9340c2e..f1d7322 100644
--- a/pkg/analyzer/test/src/diagnostics/undefined_setter_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/undefined_setter_test.dart
@@ -47,6 +47,19 @@
error(StaticTypeWarningCode.UNDEFINED_SETTER, 43, 1),
]);
}
+
+ test_static_definedInSuperclass() async {
+ await assertErrorsInCode('''
+class S {
+ static set s(int i) {}
+}
+class C extends S {}
+f(var p) {
+ f(C.s = 1);
+}''', [
+ error(StaticTypeWarningCode.UNDEFINED_SETTER, 75, 1),
+ ]);
+ }
}
@reflectiveTest
diff --git a/pkg/analyzer/test/src/diagnostics/unqualified_reference_to_static_member_of_extended_type_test.dart b/pkg/analyzer/test/src/diagnostics/unqualified_reference_to_static_member_of_extended_type_test.dart
new file mode 100644
index 0000000..d8cd1da
--- /dev/null
+++ b/pkg/analyzer/test/src/diagnostics/unqualified_reference_to_static_member_of_extended_type_test.dart
@@ -0,0 +1,82 @@
+// Copyright (c) 2019, 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.
+
+import 'package:analyzer/dart/analysis/features.dart';
+import 'package:analyzer/src/error/codes.dart';
+import 'package:analyzer/src/generated/engine.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import '../dart/resolution/driver_resolution.dart';
+
+main() {
+ defineReflectiveSuite(() {
+ defineReflectiveTests(UnqualifiedReferenceToStaticMemberOfExtendedTypeTest);
+ });
+}
+
+@reflectiveTest
+class UnqualifiedReferenceToStaticMemberOfExtendedTypeTest
+ extends DriverResolutionTest {
+ @override
+ AnalysisOptionsImpl get analysisOptions => AnalysisOptionsImpl()
+ ..contextFeatures = new FeatureSet.forTesting(
+ sdkVersion: '2.3.0', additionalFeatures: [Feature.extension_methods]);
+
+ test_getter() async {
+ await assertErrorsInCode('''
+class MyClass {
+ static int get zero => 0;
+}
+extension MyExtension on MyClass {
+ void m() {
+ zero;
+ }
+}
+''', [
+ error(
+ CompileTimeErrorCode
+ .UNQUALIFIED_REFERENCE_TO_STATIC_MEMBER_OF_EXTENDED_TYPE,
+ 98,
+ 4),
+ ]);
+ }
+
+ test_method() async {
+ await assertErrorsInCode('''
+class MyClass {
+ static void sm() {}
+}
+extension MyExtension on MyClass {
+ void m() {
+ sm();
+ }
+}
+''', [
+ error(
+ CompileTimeErrorCode
+ .UNQUALIFIED_REFERENCE_TO_STATIC_MEMBER_OF_EXTENDED_TYPE,
+ 92,
+ 2),
+ ]);
+ }
+
+ test_setter() async {
+ await assertErrorsInCode('''
+class MyClass {
+ static set foo(int i) {}
+}
+extension MyExtension on MyClass {
+ void m() {
+ foo = 3;
+ }
+}
+''', [
+ error(
+ CompileTimeErrorCode
+ .UNQUALIFIED_REFERENCE_TO_STATIC_MEMBER_OF_EXTENDED_TYPE,
+ 97,
+ 3),
+ ]);
+ }
+}
diff --git a/pkg/analyzer/test/src/diagnostics/use_of_void_result_test.dart b/pkg/analyzer/test/src/diagnostics/use_of_void_result_test.dart
index 322c773..52917c9 100644
--- a/pkg/analyzer/test/src/diagnostics/use_of_void_result_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/use_of_void_result_test.dart
@@ -43,6 +43,34 @@
]);
}
+ test_assignmentExpression_function() async {
+ await assertErrorsInCode('''
+void f() {}
+class A {
+ n() {
+ var a;
+ a = f();
+ }
+}''', [
+ error(HintCode.UNUSED_LOCAL_VARIABLE, 38, 1),
+ error(StaticWarningCode.USE_OF_VOID_RESULT, 49, 1),
+ ]);
+ }
+
+ test_assignmentExpression_method() async {
+ await assertErrorsInCode('''
+class A {
+ void m() {}
+ n() {
+ var a;
+ a = m();
+ }
+}''', [
+ error(HintCode.UNUSED_LOCAL_VARIABLE, 40, 1),
+ error(StaticWarningCode.USE_OF_VOID_RESULT, 51, 1),
+ ]);
+ }
+
test_assignmentToVoidParameterOk() async {
// Note: the spec may decide to disallow this, but at this point that seems
// highly unlikely.
@@ -66,6 +94,14 @@
''');
}
+ test_await() async {
+ await assertNoErrorsInCode('''
+main() async {
+ void x;
+ await x;
+}''');
+ }
+
test_implicitReturnValue() async {
await assertNoErrorsInCode(r'''
f() {}
@@ -77,6 +113,29 @@
''');
}
+ test_inForLoop_error() async {
+ await assertErrorsInCode('''
+class A {
+ void m() {}
+ n() {
+ for(Object a = m();;) {}
+ }
+}''', [
+ error(HintCode.UNUSED_LOCAL_VARIABLE, 47, 1),
+ error(StaticWarningCode.USE_OF_VOID_RESULT, 51, 1),
+ ]);
+ }
+
+ test_inForLoop_ok() async {
+ await assertNoErrorsInCode('''
+class A {
+ void m() {}
+ n() {
+ for(void a = m();;) {}
+ }
+}''');
+ }
+
test_interpolateVoidValueError() async {
await assertErrorsInCode(r'''
void main() {
@@ -504,6 +563,67 @@
''');
}
+ test_variableDeclaration_function_error() async {
+ await assertErrorsInCode('''
+void f() {}
+class A {
+ n() {
+ Object a = f();
+ }
+}''', [
+ error(HintCode.UNUSED_LOCAL_VARIABLE, 41, 1),
+ error(StaticWarningCode.USE_OF_VOID_RESULT, 45, 1),
+ ]);
+ }
+
+ test_variableDeclaration_function_ok() async {
+ await assertNoErrorsInCode('''
+void f() {}
+class A {
+ n() {
+ void a = f();
+ }
+}''');
+ }
+
+ test_variableDeclaration_method2() async {
+ await assertErrorsInCode('''
+class A {
+ void m() {}
+ n() {
+ Object a = m(), b = m();
+ }
+}''', [
+ error(HintCode.UNUSED_LOCAL_VARIABLE, 43, 1),
+ error(StaticWarningCode.USE_OF_VOID_RESULT, 47, 1),
+ error(HintCode.UNUSED_LOCAL_VARIABLE, 52, 1),
+ error(StaticWarningCode.USE_OF_VOID_RESULT, 56, 1),
+ ]);
+ }
+
+ test_variableDeclaration_method_error() async {
+ await assertErrorsInCode('''
+class A {
+ void m() {}
+ n() {
+ Object a = m();
+ }
+}''', [
+ error(HintCode.UNUSED_LOCAL_VARIABLE, 43, 1),
+ error(StaticWarningCode.USE_OF_VOID_RESULT, 47, 1),
+ ]);
+ }
+
+ test_variableDeclaration_method_ok() async {
+ await assertNoErrorsInCode('''
+class A {
+ void m() {}
+ n() {
+ void a = m();
+ }
+}''');
+ }
+
test_yieldStarVoid_asyncStar() async {
await assertErrorsInCode('''
main(void x) async* {
diff --git a/pkg/analyzer/test/src/source/source_resource_test.dart b/pkg/analyzer/test/src/source/source_resource_test.dart
index 863117b..81dbccc 100644
--- a/pkg/analyzer/test/src/source/source_resource_test.dart
+++ b/pkg/analyzer/test/src/source/source_resource_test.dart
@@ -4,7 +4,6 @@
import 'package:analyzer/file_system/file_system.dart';
import 'package:analyzer/file_system/physical_file_system.dart';
-import 'package:analyzer/src/file_system/file_system.dart';
import 'package:analyzer/src/generated/java_engine_io.dart';
import 'package:analyzer/src/generated/sdk.dart';
import 'package:analyzer/src/generated/source.dart';
@@ -86,14 +85,6 @@
FileSource.fileReadMode = (String s) => s;
}
- void test_getEncoding() {
- SourceFactory factory =
- new SourceFactory([new ResourceUriResolver(resourceProvider)]);
- File file = getFile("/does/not/exist.dart");
- FileSource source = new FileSource(file);
- expect(factory.fromEncoding(source.encoding), source);
- }
-
void test_getFullName() {
File file = getFile("/does/not/exist.dart");
FileSource source = new FileSource(file);
diff --git a/pkg/analyzer/test/src/summary/element_text.dart b/pkg/analyzer/test/src/summary/element_text.dart
index d810032..d0ffbb9 100644
--- a/pkg/analyzer/test/src/summary/element_text.dart
+++ b/pkg/analyzer/test/src/summary/element_text.dart
@@ -7,6 +7,7 @@
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/ast/token.dart';
import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/dart/element/nullability_suffix.dart';
import 'package:analyzer/dart/element/type.dart';
import 'package:analyzer/src/dart/element/element.dart';
import 'package:analyzer/src/dart/element/type.dart';
diff --git a/pkg/analyzer/test/src/summary/resynthesize_common.dart b/pkg/analyzer/test/src/summary/resynthesize_common.dart
index e68375d..d3e4e8a 100644
--- a/pkg/analyzer/test/src/summary/resynthesize_common.dart
+++ b/pkg/analyzer/test/src/summary/resynthesize_common.dart
@@ -8,6 +8,7 @@
import 'package:analyzer/dart/analysis/features.dart';
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/dart/element/nullability_suffix.dart';
import 'package:analyzer/dart/element/type.dart';
import 'package:analyzer/file_system/file_system.dart';
import 'package:analyzer/src/context/context.dart';
diff --git a/pkg/analyzer/test/src/summary/top_level_inference_test.dart b/pkg/analyzer/test/src/summary/top_level_inference_test.dart
index 72e6c9f..f738485 100644
--- a/pkg/analyzer/test/src/summary/top_level_inference_test.dart
+++ b/pkg/analyzer/test/src/summary/top_level_inference_test.dart
@@ -333,7 +333,7 @@
String aaa;
}
class C implements A, B {
- /*error:INVALID_OVERRIDE,error:INVALID_OVERRIDE*/var aaa;
+ var /*error:INVALID_OVERRIDE,error:INVALID_OVERRIDE*/aaa;
}
''';
await checkFile(content);
diff --git a/pkg/analyzer/test/src/summary2/ast_text_printer_test.dart b/pkg/analyzer/test/src/summary2/ast_text_printer_test.dart
index 906407f..a20b7da 100644
--- a/pkg/analyzer/test/src/summary2/ast_text_printer_test.dart
+++ b/pkg/analyzer/test/src/summary2/ast_text_printer_test.dart
@@ -2,6 +2,8 @@
// 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.
+import 'package:analyzer/dart/analysis/features.dart';
+import 'package:analyzer/src/generated/engine.dart';
import 'package:analyzer/src/summary2/ast_text_printer.dart';
import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
@@ -11,6 +13,7 @@
main() {
defineReflectiveSuite(() {
defineReflectiveTests(AstTextPrinterTest);
+ defineReflectiveTests(AstTextPrinterWithExtensionMethodsTest);
});
}
@@ -109,3 +112,21 @@
''');
}
}
+
+@reflectiveTest
+class AstTextPrinterWithExtensionMethodsTest extends ParseBase {
+ @override
+ AnalysisOptionsImpl get analysisOptions => AnalysisOptionsImpl()
+ ..contextFeatures = new FeatureSet.forTesting(
+ sdkVersion: '2.3.0', additionalFeatures: [Feature.extension_methods]);
+
+ test_extensionOverride() async {
+ await assertParseCodeAndPrintAst(this, '''
+extension E on Object {
+ int f() => 0;
+}
+
+const e = E(null).f();
+''');
+ }
+}
diff --git a/pkg/analyzer/test/src/task/strong/checker_test.dart b/pkg/analyzer/test/src/task/strong/checker_test.dart
index 7360730..6948841 100644
--- a/pkg/analyzer/test/src/task/strong/checker_test.dart
+++ b/pkg/analyzer/test/src/task/strong/checker_test.dart
@@ -538,16 +538,16 @@
class G extends E implements D {}
class D_error extends C {
- /*error:INVALID_OVERRIDE*/int f(int x) => x;
+ int /*error:INVALID_OVERRIDE*/f(int x) => x;
}
class E_error extends D {
- /*error:INVALID_OVERRIDE*/int f(covariant double x) => 0;
+ int /*error:INVALID_OVERRIDE*/f(covariant double x) => 0;
}
class F_error extends E {
- /*error:INVALID_OVERRIDE*/int f(covariant double x) => 0;
+ int /*error:INVALID_OVERRIDE*/f(covariant double x) => 0;
}
class G_error extends E implements D {
- /*error:INVALID_OVERRIDE*/int f(covariant double x) => 0;
+ int /*error:INVALID_OVERRIDE*/f(covariant double x) => 0;
}
''');
}
@@ -615,16 +615,16 @@
class G extends E implements D {}
class D_error extends C {
- /*error:INVALID_OVERRIDE*/int f(String x) => 0;
+ int /*error:INVALID_OVERRIDE*/f(String x) => 0;
}
class E_error extends D {
- /*error:INVALID_OVERRIDE*/int f(double x) => 0;
+ int /*error:INVALID_OVERRIDE*/f(double x) => 0;
}
class F_error extends E {
- /*error:INVALID_OVERRIDE*/int f(double x) => 0;
+ int /*error:INVALID_OVERRIDE*/f(double x) => 0;
}
class G_error extends E implements D {
- /*error:INVALID_OVERRIDE*/int f(double x) => 0;
+ int /*error:INVALID_OVERRIDE*/f(double x) => 0;
}
''');
}
@@ -717,17 +717,17 @@
}
class Child extends Base {
- /*error:INVALID_OVERRIDE*/A f1; // invalid for getter
- /*error:INVALID_OVERRIDE*/C f2; // invalid for setter
+ A /*error:INVALID_OVERRIDE*/f1; // invalid for getter
+ C /*error:INVALID_OVERRIDE*/f2; // invalid for setter
var f3;
- /*error:INVALID_OVERRIDE*/dynamic f4;
+ dynamic /*error:INVALID_OVERRIDE*/f4;
}
class Child2 implements Base {
- /*error:INVALID_OVERRIDE*/A f1; // invalid for getter
- /*error:INVALID_OVERRIDE*/C f2; // invalid for setter
+ A /*error:INVALID_OVERRIDE*/f1; // invalid for getter
+ C /*error:INVALID_OVERRIDE*/f2; // invalid for setter
var f3;
- /*error:INVALID_OVERRIDE*/dynamic f4;
+ dynamic /*error:INVALID_OVERRIDE*/f4;
}
''');
}
@@ -746,17 +746,17 @@
}
class Child extends Base {
- /*error:INVALID_OVERRIDE*/A get f1 => null;
+ A get /*error:INVALID_OVERRIDE*/f1 => null;
C get f2 => null;
get f3 => null;
- /*error:INVALID_OVERRIDE*/dynamic get f4 => null;
+ dynamic get /*error:INVALID_OVERRIDE*/f4 => null;
}
class /*error:NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_FOUR*/Child2 implements Base {
- /*error:INVALID_OVERRIDE*/A get f1 => null;
+ A get /*error:INVALID_OVERRIDE*/f1 => null;
C get f2 => null;
get f3 => null;
- /*error:INVALID_OVERRIDE*/dynamic get f4 => null;
+ dynamic get /*error:INVALID_OVERRIDE*/f4 => null;
}
''');
}
@@ -770,12 +770,12 @@
}
class G extends F {
- /*error:INVALID_OVERRIDE*/final ToVoid<int> f = null;
+ final ToVoid<int> /*error:INVALID_OVERRIDE*/f = null;
final ToVoid<dynamic> g = null;
}
class H implements F {
- /*error:INVALID_OVERRIDE*/final ToVoid<int> f = null;
+ final ToVoid<int> /*error:INVALID_OVERRIDE*/f = null;
final ToVoid<dynamic> g = null;
}
''');
@@ -833,7 +833,7 @@
B get f5 => null;
void set f1(A value) {}
- /*error:INVALID_OVERRIDE*/void set f2(C value) {}
+ void set /*error:INVALID_OVERRIDE*/f2(C value) {}
void set f3(value) {}
void set f4(dynamic value) {}
set f5(B value) {}
@@ -847,7 +847,7 @@
B get f5 => null;
void set f1(A value) {}
- /*error:INVALID_OVERRIDE*/void set f2(C value) {}
+ void set /*error:INVALID_OVERRIDE*/f2(C value) {}
void set f3(value) {}
void set f4(dynamic value) {}
set f5(B value) {}
@@ -1953,7 +1953,7 @@
}
class Derived<S extends A> extends Base<B> {
- /*error:INVALID_OVERRIDE*/S foo() => null;
+ S /*error:INVALID_OVERRIDE*/foo() => null;
}
class Derived2<S extends B> extends Base<B> {
@@ -2061,10 +2061,10 @@
}
class Child extends Base {
- /*error:INVALID_OVERRIDE*/A get f1 => null;
+ A get /*error:INVALID_OVERRIDE*/f1 => null;
C get f2 => null;
get f3 => null;
- /*error:INVALID_OVERRIDE*/dynamic get f4 => null;
+ dynamic get /*error:INVALID_OVERRIDE*/f4 => null;
}
''');
}
@@ -2079,12 +2079,12 @@
}
class G extends F {
- /*error:INVALID_OVERRIDE*/ToVoid<int> get f => null;
+ ToVoid<int> get /*error:INVALID_OVERRIDE*/f => null;
ToVoid<dynamic> get g => null;
}
class H implements F {
- /*error:INVALID_OVERRIDE*/ToVoid<int> get f => null;
+ ToVoid<int> get /*error:INVALID_OVERRIDE*/f => null;
ToVoid<dynamic> get g => null;
}
''');
@@ -2495,7 +2495,7 @@
set x(Object y) {}
}
class D implements B, C {
- /*error:INVALID_OVERRIDE*/int x;
+ int /*error:INVALID_OVERRIDE*/x;
}
''');
}
@@ -2509,13 +2509,13 @@
abstract class M implements I {}
class C extends Object with M {
- /*error:INVALID_OVERRIDE*/String x;
+ String /*error:INVALID_OVERRIDE*/x;
}
abstract class M2 = Object with M;
class C2 extends Object with M2 {
- /*error:INVALID_OVERRIDE*/String x;
+ String /*error:INVALID_OVERRIDE*/x;
}
''');
}
@@ -2545,13 +2545,13 @@
abstract class M<E> implements I<E> {}
class C extends Object with M<int> {
- /*error:INVALID_OVERRIDE*/String x;
+ String /*error:INVALID_OVERRIDE*/x;
}
abstract class D extends Object with M<num> {}
/*error:CONFLICTING_GENERIC_INTERFACES*/
/*error:CONFLICTING_GENERIC_INTERFACES*/class E extends D with M<int> {
- /*error:INVALID_OVERRIDE*/int x;
+ int /*error:INVALID_OVERRIDE*/x;
}
/*error:CONFLICTING_GENERIC_INTERFACES*/
/*error:CONFLICTING_GENERIC_INTERFACES*/class F extends D with M<int> {
@@ -2588,37 +2588,37 @@
}
class T1 extends Base {
- /*error:INVALID_OVERRIDE*/B get /*error:MISMATCHED_GETTER_AND_SETTER_TYPES*/f => null;
+ B get /*error:INVALID_OVERRIDE, error:MISMATCHED_GETTER_AND_SETTER_TYPES*/f => null;
}
class T2 extends Base {
- /*error:INVALID_OVERRIDE*/set /*error:MISMATCHED_GETTER_AND_SETTER_TYPES*/f(
+ set /*error:INVALID_OVERRIDE, error:MISMATCHED_GETTER_AND_SETTER_TYPES*/f(
B b) => null;
}
class T3 extends Base {
- /*error:INVALID_OVERRIDE*/final B
- /*error:FINAL_NOT_INITIALIZED, error:MISMATCHED_GETTER_AND_SETTER_TYPES*/f;
+ final B
+ /*error:FINAL_NOT_INITIALIZED, error:INVALID_OVERRIDE, error:MISMATCHED_GETTER_AND_SETTER_TYPES*/f;
}
class T4 extends Base {
// two: one for the getter one for the setter.
- /*error:INVALID_OVERRIDE, error:INVALID_OVERRIDE*/B f;
+ B /*error:INVALID_OVERRIDE, error:INVALID_OVERRIDE*/f;
}
class /*error:NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_ONE*/T5 implements Base {
- /*error:INVALID_OVERRIDE*/B get /*error:MISMATCHED_GETTER_AND_SETTER_TYPES*/f => null;
+ /**/B get /*error:INVALID_OVERRIDE, error:MISMATCHED_GETTER_AND_SETTER_TYPES*/f => null;
}
class /*error:NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_ONE*/T6 implements Base {
- /*error:INVALID_OVERRIDE*/set /*error:MISMATCHED_GETTER_AND_SETTER_TYPES*/f(B b) => null;
+ set /*error:INVALID_OVERRIDE, error:MISMATCHED_GETTER_AND_SETTER_TYPES*/f(B b) => null;
}
class /*error:NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_ONE*/T7 implements Base {
- /*error:INVALID_OVERRIDE*/final B /*error:MISMATCHED_GETTER_AND_SETTER_TYPES*/f = null;
+ final B /*error:INVALID_OVERRIDE, error:MISMATCHED_GETTER_AND_SETTER_TYPES*/f = null;
}
class T8 implements Base {
// two: one for the getter one for the setter.
- /*error:INVALID_OVERRIDE, error:INVALID_OVERRIDE*/B f;
+ B /*error:INVALID_OVERRIDE, error:INVALID_OVERRIDE*/f;
}
''');
}
@@ -3339,12 +3339,12 @@
}
class Child extends Base {
- /*error:INVALID_OVERRIDE*/A m1(A value) => null;
- /*error:INVALID_OVERRIDE*/C m2(C value) => null;
- /*error:INVALID_OVERRIDE*/A m3(C value) => null;
+ A /*error:INVALID_OVERRIDE*/m1(A value) => null;
+ C /*error:INVALID_OVERRIDE*/m2(C value) => null;
+ A /*error:INVALID_OVERRIDE*/m3(C value) => null;
C m4(A value) => null;
m5(value) => null;
- /*error:INVALID_OVERRIDE*/dynamic m6(dynamic value) => null;
+ dynamic /*error:INVALID_OVERRIDE*/m6(dynamic value) => null;
}
''');
}
@@ -3363,12 +3363,12 @@
}
class G extends F {
- /*error:INVALID_OVERRIDE*/void f(int x) {}
+ void /*error:INVALID_OVERRIDE*/f(int x) {}
void g(dynamic x) {}
}
class H implements F {
- /*error:INVALID_OVERRIDE*/void f(int x) {}
+ void /*error:INVALID_OVERRIDE*/f(int x) {}
void g(dynamic x) {}
}
''');
@@ -3749,7 +3749,7 @@
return checkFile(r'''
abstract class A { void test(A arg) { } }
abstract class B extends A {
- /*error:INVALID_OVERRIDE*/void test(B arg) { }
+ void /*error:INVALID_OVERRIDE*/test(B arg) { }
}
abstract class X implements A { }
@@ -3779,7 +3779,7 @@
var _f3;
var _f4;
- /*error:INVALID_OVERRIDE*/String _m1() => null;
+ String /*error:INVALID_OVERRIDE*/_m1() => null;
}
''', name: '/helper.dart');
await checkFile('''
@@ -4063,15 +4063,15 @@
class G extends F {
void set f(ToVoid<int> x) {}
- /*error:INVALID_OVERRIDE*/void set g(ToVoid<dynamic> x) {}
- /*error:INVALID_OVERRIDE*/void set h(int x) {}
+ void set /*error:INVALID_OVERRIDE*/g(ToVoid<dynamic> x) {}
+ void set /*error:INVALID_OVERRIDE*/h(int x) {}
void set i(dynamic x) {}
}
class H implements F {
void set f(ToVoid<int> x) {}
- /*error:INVALID_OVERRIDE*/void set g(ToVoid<dynamic> x) {}
- /*error:INVALID_OVERRIDE*/void set h(int x) {}
+ void set /*error:INVALID_OVERRIDE*/g(ToVoid<dynamic> x) {}
+ void set /*error:INVALID_OVERRIDE*/h(int x) {}
void set i(dynamic x) {}
}
''');
@@ -4111,7 +4111,7 @@
class Child extends Base {
void set f1(A value) {}
- /*error:INVALID_OVERRIDE*/void set f2(C value) {}
+ void set /*error:INVALID_OVERRIDE*/f2(C value) {}
void set f3(value) {}
void set f4(dynamic value) {}
set f5(B value) {}
@@ -4265,68 +4265,6 @@
await check();
}
- test_strictInference_collectionLiterals() async {
- addFile(r'''
-main() {
- var emptyList = /*info:INFERENCE_FAILURE_ON_COLLECTION_LITERAL*/[];
- var emptyMap = /*info:INFERENCE_FAILURE_ON_COLLECTION_LITERAL*/{};
- final finalEmptyList = /*info:INFERENCE_FAILURE_ON_COLLECTION_LITERAL*/[];
- final finalEmptyMap = /*info:INFERENCE_FAILURE_ON_COLLECTION_LITERAL*/{};
- const constEmptyList = /*info:INFERENCE_FAILURE_ON_COLLECTION_LITERAL*/[];
- const constEmptyMap = /*info:INFERENCE_FAILURE_ON_COLLECTION_LITERAL*/{};
-
- void listFunction(
- [list = /*info:INFERENCE_FAILURE_ON_COLLECTION_LITERAL*/const []]) => print(list);
- void mapFunction(
- [map = /*info:INFERENCE_FAILURE_ON_COLLECTION_LITERAL*/const {}]) => print(map);
-
- var conditionalEmptyList =
- "a" == "b" ? [1, 2, 3] : /*info:INFERENCE_FAILURE_ON_COLLECTION_LITERAL*/[];
-
- dynamic returnsList1() => /*info:INFERENCE_FAILURE_ON_COLLECTION_LITERAL*/[];
- Object returnsList2() => [];
- void returnsList3() => [];
-
- var onlyInnermostEmptyCollections = {
- /*info:INFERENCE_FAILURE_ON_COLLECTION_LITERAL*/[]:
- /*info:INFERENCE_FAILURE_ON_COLLECTION_LITERAL*/{}
- };
-
- // Inference has enough info in all of the cases below.
- var upwardsInfersDynamicList = [42 as dynamic];
- var upwardsInfersDynamicList2 = [42 as dynamic, 43 as dynamic];
- var upwardsInfersDynamicList3 = [42 , 43.0];
- var upwardsInfersDynamicSet = {42 as dynamic};
-
- // Upwards inference provides correct types.
- dynamic d;
- var upwardsInfersDynamicMap1 = {d: 2};
- var upwardsInfersDynamicMap2 = {4: d};
- var upwardsInfersDynamicMap3 = {d: d};
- var listWithElements = [1, 2, 3];
-
- // The type of the right side of `??` is inferred from the left.
- var nullAwareEmptyList = [1, 2, 3] ?? [];
-
- // Type arguments provide types.
- var typeArgList = <dynamic>[];
- var typeArgSet = <dynamic>{};
- var typeArgMap = <dynamic, dynamic>{};
-
- // Downwards inference provides correct types.
- Set<dynamic> downwardsInfersDynamicSet = {};
- Map<dynamic, dynamic> downwardsInfersDynamicDynamicMap = {};
- List<int> downwardsInfersIntList = [];
- Set<int> downwardsInfersIntSet = {};
-
- // The type of `set` is `Set<dynamic>`.
- int setLength(Set set) => set.length;
- setLength({});
-}
- ''');
- await check(strictInference: true);
- }
-
test_strictInference_instanceCreation() async {
addFile(r'''
class C<T> {
@@ -4343,238 +4281,14 @@
var explicitDynamicIsOK = C<dynamic>(42);
var rawConstructorCall = /*info:INFERENCE_FAILURE_ON_INSTANCE_CREATION*/C();
- var upwardsInfersDynamic = /*info:INFERENCE_FAILURE_ON_INSTANCE_CREATION*/C(42 as dynamic);
- var namedConstructor = /*info:INFERENCE_FAILURE_ON_INSTANCE_CREATION*/C.of(42 as dynamic);
var factoryConstructor = /*info:INFERENCE_FAILURE_ON_INSTANCE_CREATION*/C.from(42);
-}
- ''');
- await check(strictInference: true);
- }
-
- test_strictInference_instanceCreation_optionalTypeArgs() async {
- addMetaPackage();
- addFile(r'''
-import 'package:meta/meta.dart';
-@optionalTypeArgs
-class C<T> {
- C([T t]);
- C.of(T t);
- factory C.from(Object e) => C();
-}
-
-main() {
- var rawConstructorCall = C();
var upwardsInfersDynamic = C(42 as dynamic);
var namedConstructor = C.of(42 as dynamic);
- var factoryConstructor = C.from(42);
}
''');
await check(strictInference: true);
}
- test_strictRawTypes_classes() async {
- addFile(r'''
-class C<T> {
- C([T t]);
-}
-
-class M<T> {}
-
-class ExtendRawType extends /*info:STRICT_RAW_TYPE*/C {}
-class MixinRawType extends Object with /*info:STRICT_RAW_TYPE*/M {}
-class ImplementRawType implements /*info:STRICT_RAW_TYPE*/C {}
-class MixinApplicationRawType = Object with /*info:STRICT_RAW_TYPE*/M;
-
-class ClassWithNumBound<T extends num> {}
-class ClassWithObjectBound<T extends Object> {}
-class ClassWithDynamicBound<T extends dynamic> {}
-
-class ClassWithRawTypeBound<T extends /*info:STRICT_RAW_TYPE*/List> {}
-
-/*info:STRICT_RAW_TYPE*/C topLevelField;
-/*info:STRICT_RAW_TYPE*/C get topLevelGetter => null;
-set topLevelSetter(/*info:STRICT_RAW_TYPE*/C c) {}
-
-/*info:STRICT_RAW_TYPE*/C returnType() => null;
-parameterType(/*info:STRICT_RAW_TYPE*/C c) {}
-
-C<int> explicitTypeArgsAreOK;
-
-main() {
- {
- ClassWithNumBound classWithNumBoundOK;
- ClassWithObjectBound classWithObjectBoundOK;
- /*info:STRICT_RAW_TYPE*/ClassWithDynamicBound classWithDynamicBound;
- /*info:STRICT_RAW_TYPE*/C rawConstructorCallFromType = C();
- }
-
- {
- // These should be allowed:
- List<int> downwardsInferenceIsOK = [];
- List<dynamic> downwardsInferenceDynamicIsOK = [];
- var upwardsInferNonDynamicIsOK = [42];
- var explicitDynamicIsOK = <dynamic>[42];
-
- var rawListOfLists = </*info:STRICT_RAW_TYPE*/List>[];
- /*info:STRICT_RAW_TYPE*/List rawListFromType = [];
- }
-
- {
- // These should be allowed:
- List<int> downwardsInferenceIsOK = [];
- List<dynamic> downwardsInferenceDynamicIsOK = [];
- var upwardsInferNonDynamicIsOK = [42];
- var explicitDynamicIsOK = <dynamic>[42];
-
- var rawListOfLists = </*info:STRICT_RAW_TYPE*/List>[];
- /*info:STRICT_RAW_TYPE*/List rawListFromType = [];
- }
-
- {
- // These should be allowed:
- Set<int> downwardsInferenceIsOK = {};
- Set<dynamic> downwardsInferenceDynamicIsOK = {};
- var upwardsInferNonDynamicIsOK = {42};
- var explicitDynamicIsOK = <dynamic>{42};
-
- var rawSetOfSets = </*info:STRICT_RAW_TYPE*/Set>{};
- /*info:STRICT_RAW_TYPE*/Set rawSetFromType = {};
- }
-
- {
- // These should be allowed:
- Map<int, int> downwardsInferenceIsOK = {};
- Map<dynamic, int> downwardsInferenceDynamicIsOK1 = {};
- Map<int, dynamic> downwardsInferenceDynamicIsOK2 = {};
- Map<dynamic, dynamic> downwardsInferenceDynamicIsOK3 = {};
-
- var upwardsInferNonDynamicIsOK = {4: 2};
- var explicitDynamicIsOK = <dynamic, dynamic>{4: 2};
-
- var rawMapOfMaps = </*info:STRICT_RAW_TYPE*/Map>{};
- /*info:STRICT_RAW_TYPE*/Map rawMapFromType = {};
- }
-
- {
- Object isCheck;
- if (isCheck is /*info:STRICT_RAW_TYPE_IN_IS*/List) {}
- if (isCheck is List</*info:STRICT_RAW_TYPE_IN_IS*/List>) {}
- if (isCheck is /*info:STRICT_RAW_TYPE_IN_IS*/C) {}
-
- if (isCheck is List<dynamic>) {}
- if (isCheck is List<int>) {}
- if (isCheck is C<dynamic>) {}
- if (isCheck is C<int>) {}
- }
-
- {
- Object asCheck;
- var asList = asCheck as /*info:STRICT_RAW_TYPE_IN_AS*/List;
- var asMap = asCheck as Map<dynamic, /*info:STRICT_RAW_TYPE_IN_AS*/List>;
- var asC = asCheck as /*info:STRICT_RAW_TYPE_IN_AS*/C;
- }
-}
- ''');
- await check(strictRawTypes: true);
- }
-
- test_strictRawTypes_classes_optionalTypeArgs() async {
- addMetaPackage();
- addFile(r'''
-import 'package:meta/meta.dart';
-@optionalTypeArgs
-class C<T> {
- C([T t]);
-}
-
-@optionalTypeArgs
-class M<T> {}
-
-class ExtendRawType extends C {}
-class MixinRawType extends Object with M {}
-class ImplementRawType implements C {}
-class MixinApplicationRawType = Object with M;
-
-C topLevelField;
-C get topLevelGetter => null;
-set topLevelSetter(C c) {}
-
-C returnType() => null;
-parameterType(C c) {}
-
-C<int> explicitTypeArgsAreOK;
-
-main() {
- // These should be allowed:
- C<int> downwardsInferenceIsOK = C();
- C<dynamic> downwardsInferenceDynamicIsOK = C();
- var inferredFromConstructorParameterIsOK = C(42);
- var explicitDynamicIsOK = C<dynamic>(42);
-
- var rawConstructorCall = C();
- C rawConstructorCallFromType = C();
- var upwardsInfersDynamic = C(42 as dynamic);
-
- Object isChecksAreAllowed;
- if (isChecksAreAllowed is C) {}
-}
- ''');
-
- await check(strictRawTypes: true);
- }
-
- test_strictRawTypes_typedefs() async {
- addFile(r'''
-typedef T F1<T>(T _);
-typedef F2<T> = T Function(T);
-typedef G1<T> = S Function<S>(T);
-typedef G2<T> = S Function<S>(S); // right side does not use `T`
-
-typedef G3 = T Function<T>(T); // typedef has no type params.
-
-testTypedefs() {
- /*info:STRICT_RAW_TYPE*/F1 rawTypedefDart1Syntax;
- /*info:STRICT_RAW_TYPE*/F2 rawTypedefDart2Syntax;
- /*info:STRICT_RAW_TYPE*/G1 rawTypedefGenericFunction;
- /*info:STRICT_RAW_TYPE*/G2 rawTypedefGenericFunction2;
- {
- F1<dynamic> explicitTypedefDart1SyntaxIsOK;
- F2<dynamic> explicitTypedefDart2SyntaxIsOK;
- G1<dynamic> explicitTypedefGenericFunctionIsOK;
- G2<dynamic> explicitTypedefGenericFunction2IsOK;
- G3 typedefWithoutTypeParamsIsOK;
- }
- {
- F1<int> explicitTypedefDart1SyntaxIsOK;
- F2<int> explicitTypedefDart2SyntaxIsOK;
- G1<int> explicitTypedefGenericFunctionIsOK;
- G2<int> explicitTypedefGenericFunction2IsOK;
- }
-}
- ''');
- await check(strictRawTypes: true);
- }
-
- test_strictRawTypes_typedefs_optionalTypeArgs() async {
- addMetaPackage();
- addFile(r'''
-import 'package:meta/meta.dart';
-
-@optionalTypeArgs typedef T F1<T>(T _);
-@optionalTypeArgs typedef F2<T> = T Function(T);
-@optionalTypeArgs typedef G1<T> = S Function<S>(T);
-@optionalTypeArgs typedef G2<T> = S Function<S>(S);
-
-testTypedefs() {
- F1 rawTypedefDart1Syntax;
- F2 rawTypedefDart2Syntax;
- G1 rawTypedefGenericFunction;
- G2 rawTypedefGenericFunction2;
-}
- ''');
- await check(strictRawTypes: true);
- }
-
test_superCallPlacement() async {
await checkFile('''
class Base {
@@ -5174,7 +4888,7 @@
}
class B extends A {
- /*error:INVALID_OVERRIDE*/T method<T>(T x) => x;
+ T /*error:INVALID_OVERRIDE*/method<T>(T x) => x;
}
''');
}
diff --git a/pkg/analyzer/test/src/task/strong/inferred_type_test.dart b/pkg/analyzer/test/src/task/strong/inferred_type_test.dart
index 94feba2..db5ceab 100644
--- a/pkg/analyzer/test/src/task/strong/inferred_type_test.dart
+++ b/pkg/analyzer/test/src/task/strong/inferred_type_test.dart
@@ -429,12 +429,12 @@
}
class C1 implements A, B {
- /*error:INVALID_OVERRIDE,error:INVALID_OVERRIDE*/get a => null;
+ get /*error:INVALID_OVERRIDE,error:INVALID_OVERRIDE*/a => null;
}
// Still ambiguous
class C2 implements B, A {
- /*error:INVALID_OVERRIDE,error:INVALID_OVERRIDE*/get a => null;
+ get /*error:INVALID_OVERRIDE,error:INVALID_OVERRIDE*/a => null;
}
''');
}
@@ -466,7 +466,7 @@
}
class C2 implements A, B {
- /*error:INVALID_OVERRIDE,error:INVALID_OVERRIDE*/get a => null;
+ get /*error:INVALID_OVERRIDE,error:INVALID_OVERRIDE*/a => null;
}
''');
}
@@ -751,7 +751,7 @@
}
class B implements A {
- /*error:INVALID_OVERRIDE*/dynamic get x => 3;
+ dynamic get /*error:INVALID_OVERRIDE*/x => 3;
}
foo() {
@@ -1955,8 +1955,8 @@
dynamic g(int x) => x;
}
class D extends C {
- /*error:INVALID_OVERRIDE*/T m<T>(T x) => x;
- /*error:INVALID_OVERRIDE*/T g<T>(T x) => x;
+ T /*error:INVALID_OVERRIDE*/m<T>(T x) => x;
+ T /*error:INVALID_OVERRIDE*/g<T>(T x) => x;
}
main() {
int y = /*info:DYNAMIC_CAST*/(/*info:UNNECESSARY_CAST*/new D() as C).m(42);
@@ -2488,56 +2488,6 @@
''');
}
- test_inferredType_usesSyntheticFunctionType() async {
- var mainUnit = await checkFileElement('''
-int f() => null;
-String g() => null;
-var v = /*info:INFERRED_TYPE_LITERAL*/[f, g];
-''');
- var v = mainUnit.topLevelVariables[0];
- expect(v.type.toString(), 'List<Object Function()>');
- }
-
- test_inferredType_usesSyntheticFunctionType_functionTypedParam() async {
- var mainUnit = await checkFileElement('''
-int f(int x(String y)) => null;
-String g(int x(String y)) => null;
-var v = /*info:INFERRED_TYPE_LITERAL*/[f, g];
-''');
- var v = mainUnit.topLevelVariables[0];
- expect(v.type.toString(), 'List<Object Function(int Function(String))>');
- }
-
- test_inferredType_usesSyntheticFunctionType_namedParam() async {
- var mainUnit = await checkFileElement('''
-int f({int x}) => null;
-String g({int x}) => null;
-var v = /*info:INFERRED_TYPE_LITERAL*/[f, g];
-''');
- var v = mainUnit.topLevelVariables[0];
- expect(v.type.toString(), 'List<Object Function({x: int})>');
- }
-
- test_inferredType_usesSyntheticFunctionType_positionalParam() async {
- var mainUnit = await checkFileElement('''
-int f([int x]) => null;
-String g([int x]) => null;
-var v = /*info:INFERRED_TYPE_LITERAL*/[f, g];
-''');
- var v = mainUnit.topLevelVariables[0];
- expect(v.type.toString(), 'List<Object Function([int])>');
- }
-
- test_inferredType_usesSyntheticFunctionType_requiredParam() async {
- var mainUnit = await checkFileElement('''
-int f(int x) => null;
-String g(int x) => null;
-var v = /*info:INFERRED_TYPE_LITERAL*/[f, g];
-''');
- var v = mainUnit.topLevelVariables[0];
- expect(v.type.toString(), 'List<Object Function(int)>');
- }
-
test_inferFromComplexExpressionsIfOuterMostValueIsPrecise() async {
await checkFileElement('''
class A { int x; B operator+(other) => null; }
@@ -3077,6 +3027,56 @@
expect(x.type.toString(), 'Map<String, int Function()>');
}
+ test_inferredType_usesSyntheticFunctionType() async {
+ var mainUnit = await checkFileElement('''
+int f() => null;
+String g() => null;
+var v = /*info:INFERRED_TYPE_LITERAL*/[f, g];
+''');
+ var v = mainUnit.topLevelVariables[0];
+ expect(v.type.toString(), 'List<Object Function()>');
+ }
+
+ test_inferredType_usesSyntheticFunctionType_functionTypedParam() async {
+ var mainUnit = await checkFileElement('''
+int f(int x(String y)) => null;
+String g(int x(String y)) => null;
+var v = /*info:INFERRED_TYPE_LITERAL*/[f, g];
+''');
+ var v = mainUnit.topLevelVariables[0];
+ expect(v.type.toString(), 'List<Object Function(int Function(String))>');
+ }
+
+ test_inferredType_usesSyntheticFunctionType_namedParam() async {
+ var mainUnit = await checkFileElement('''
+int f({int x}) => null;
+String g({int x}) => null;
+var v = /*info:INFERRED_TYPE_LITERAL*/[f, g];
+''');
+ var v = mainUnit.topLevelVariables[0];
+ expect(v.type.toString(), 'List<Object Function({x: int})>');
+ }
+
+ test_inferredType_usesSyntheticFunctionType_positionalParam() async {
+ var mainUnit = await checkFileElement('''
+int f([int x]) => null;
+String g([int x]) => null;
+var v = /*info:INFERRED_TYPE_LITERAL*/[f, g];
+''');
+ var v = mainUnit.topLevelVariables[0];
+ expect(v.type.toString(), 'List<Object Function([int])>');
+ }
+
+ test_inferredType_usesSyntheticFunctionType_requiredParam() async {
+ var mainUnit = await checkFileElement('''
+int f(int x) => null;
+String g(int x) => null;
+var v = /*info:INFERRED_TYPE_LITERAL*/[f, g];
+''');
+ var v = mainUnit.topLevelVariables[0];
+ expect(v.type.toString(), 'List<Object Function(int)>');
+ }
+
test_inferredType_viaClosure_multipleLevelsOfNesting() async {
var mainUnit = await checkFileElement('''
class C {
@@ -3400,7 +3400,7 @@
}
class B implements A<int> {
- /*error:INVALID_OVERRIDE*/dynamic get x => 3;
+ dynamic get /*error:INVALID_OVERRIDE*/x => 3;
}
foo() {
diff --git a/pkg/analyzer/test/src/task/strong/strong_test_helper.dart b/pkg/analyzer/test/src/task/strong/strong_test_helper.dart
index 2edf77f..0a8d7ee 100644
--- a/pkg/analyzer/test/src/task/strong/strong_test_helper.dart
+++ b/pkg/analyzer/test/src/task/strong/strong_test_helper.dart
@@ -224,7 +224,6 @@
class AbstractStrongTest with ResourceProviderMixin {
bool _checkCalled = true;
- AnalysisContext _context = null;
AnalysisDriver _driver = null;
Map<String, List<Folder>> packageMap;
@@ -323,8 +322,6 @@
return code.errorSeverity.ordinal > ErrorSeverity.INFO.ordinal ||
code == HintCode.INFERENCE_FAILURE_ON_COLLECTION_LITERAL ||
code == HintCode.INFERENCE_FAILURE_ON_INSTANCE_CREATION ||
- code == HintCode.STRICT_RAW_TYPE_IN_AS ||
- code == HintCode.STRICT_RAW_TYPE_IN_IS ||
code == HintCode.STRICT_RAW_TYPE;
}
return true;
@@ -374,7 +371,6 @@
void tearDown() {
// This is a sanity check, in case only addFile is called.
expect(_checkCalled, true, reason: 'must call check() method in test case');
- _context?.dispose();
_driver?.dispose();
AnalysisEngine.instance.clearCaches();
}
diff --git a/pkg/analyzer/test/test_all.dart b/pkg/analyzer/test/test_all.dart
index 7694f2f..1daab29 100644
--- a/pkg/analyzer/test/test_all.dart
+++ b/pkg/analyzer/test/test_all.dart
@@ -4,7 +4,6 @@
import 'package:test_reflective_loader/test_reflective_loader.dart';
-import 'cancelable_future_test.dart' as cancelable_future;
import 'dart/test_all.dart' as dart;
import 'error/test_all.dart' as error;
import 'file_system/test_all.dart' as file_system;
@@ -19,7 +18,6 @@
main() {
defineReflectiveSuite(() {
- cancelable_future.main();
dart.main();
error.main();
file_system.main();
diff --git a/pkg/analyzer/test/utils.dart b/pkg/analyzer/test/utils.dart
index 9681e6c..bfb9fe1 100644
--- a/pkg/analyzer/test/utils.dart
+++ b/pkg/analyzer/test/utils.dart
@@ -6,8 +6,8 @@
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/dart/element/type.dart';
import 'package:analyzer/src/generated/resolver.dart' show TypeProvider;
-import 'package:analyzer/src/generated/testing/element_search.dart';
import 'package:analyzer/src/generated/source.dart';
+import 'package:analyzer/src/generated/testing/element_search.dart';
import 'package:test/test.dart';
/**
@@ -237,12 +237,12 @@
/**
* Primitive assertion for the list type
*/
- Asserter<DartType> get isList => hasElementOf(_typeProvider.listType);
+ Asserter<DartType> get isList => hasElement(_typeProvider.listElement);
/**
* Primitive assertion for the map type
*/
- Asserter<DartType> get isMap => hasElementOf(_typeProvider.mapType);
+ Asserter<DartType> get isMap => hasElement(_typeProvider.mapElement);
/**
* Primitive assertion for the Null type
@@ -271,12 +271,6 @@
(DartType type) => expect(expected, type.element);
/**
- * Assert that a type has the element that is equal to the element of the
- * given [type].
- */
- Asserter<DartType> hasElementOf(DartType type) => hasElement(type.element);
-
- /**
* Given assertions for the argument and return types, produce an
* assertion over unary function types.
*/
diff --git a/pkg/analyzer/test/verify_diagnostics_test.dart b/pkg/analyzer/test/verify_diagnostics_test.dart
index b8ce223..1340172 100644
--- a/pkg/analyzer/test/verify_diagnostics_test.dart
+++ b/pkg/analyzer/test/verify_diagnostics_test.dart
@@ -9,42 +9,35 @@
import 'package:analyzer/dart/ast/token.dart';
import 'package:analyzer/error/error.dart';
import 'package:analyzer/file_system/physical_file_system.dart';
+import 'package:analyzer/src/generated/engine.dart';
+import 'package:analyzer/src/test_utilities/package_mixin.dart';
import 'package:path/path.dart';
+import 'package:pub_semver/src/version_constraint.dart';
import 'package:test/test.dart';
import '../tool/diagnostics/generate.dart';
import 'src/dart/resolution/driver_resolution.dart';
-import 'utils/package_root.dart' as package_root;
/// Validate the documentation associated with the declarations of the error
/// codes.
void main() async {
Context pathContext = PhysicalResourceProvider.INSTANCE.pathContext;
+ List<CodePath> codePaths = computeCodePaths();
//
// Validate that the input to the generator is correct.
//
- String packageRoot = pathContext.normalize(package_root.packageRoot);
- String analyzerPath = pathContext.join(packageRoot, 'analyzer');
- List<String> docPaths = [
- pathContext.join(
- analyzerPath, 'lib', 'src', 'dart', 'error', 'hint_codes.dart'),
- pathContext.join(analyzerPath, 'lib', 'src', 'error', 'codes.dart'),
- ];
-
- DocumentationValidator validator = DocumentationValidator(docPaths);
- validator.validate();
+ DocumentationValidator validator = DocumentationValidator(codePaths);
+ await validator.validate();
//
// Validate that the generator has been run.
//
if (pathContext.style != Style.windows) {
- String outputPath =
- pathContext.join(analyzerPath, 'tool', 'diagnostics', 'diagnostics.md');
String actualContent = PhysicalResourceProvider.INSTANCE
- .getFile(outputPath)
+ .getFile(computeOutputPath())
.readAsStringSync();
StringBuffer sink = StringBuffer();
- DocumentationGenerator generator = DocumentationGenerator(docPaths);
+ DocumentationGenerator generator = DocumentationGenerator(codePaths);
generator.writeDocumentation(sink);
String expectedContent = sink.toString();
@@ -63,9 +56,18 @@
/// The sequence used to mark the end of an error range.
static const String errorRangeEnd = '!]';
+ /// A list of the diagnostic codes that are not being verified. These should
+ /// ony include docs that cannot be verified because of missing support in the
+ /// verifier.
+ static const List<String> unverifiedDocs = ['HintCode.DEPRECATED_MEMBER_USE'];
+
+ /// The prefix used on directive lines to indicate the uri of an auxiliary
+ /// file that is needed for testing purposes.
+ static const String uriDirectivePrefix = '%uri="';
+
/// The absolute paths of the files containing the declarations of the error
/// codes.
- final List<String> docPaths;
+ final List<CodePath> codePaths;
/// The buffer to which validation errors are written.
final StringBuffer buffer = StringBuffer();
@@ -85,15 +87,16 @@
bool hasWrittenCodeName = false;
/// Initialize a newly created documentation validator.
- DocumentationValidator(this.docPaths);
+ DocumentationValidator(this.codePaths);
/// Validate the documentation.
- void validate() async {
+ Future<void> validate() async {
AnalysisContextCollection collection = new AnalysisContextCollection(
- includedPaths: docPaths,
+ includedPaths:
+ codePaths.map((codePath) => codePath.documentationPath).toList(),
resourceProvider: PhysicalResourceProvider.INSTANCE);
- for (String docPath in docPaths) {
- _validateFile(_parse(collection, docPath));
+ for (CodePath codePath in codePaths) {
+ await _validateFile(_parse(collection, codePath.documentationPath));
}
if (buffer.isNotEmpty) {
fail(buffer.toString());
@@ -124,36 +127,68 @@
return docs;
}
- _SnippetData _extractSnippetData(String snippet) {
+ _SnippetData _extractSnippetData(
+ String snippet, bool errorRequired, Map<String, String> auxiliaryFiles) {
int rangeStart = snippet.indexOf(errorRangeStart);
if (rangeStart < 0) {
- _reportProblem('No error range in example');
- return _SnippetData(snippet, -1, 0);
+ if (errorRequired) {
+ _reportProblem('No error range in example');
+ }
+ return _SnippetData(snippet, -1, 0, auxiliaryFiles);
}
int rangeEnd = snippet.indexOf(errorRangeEnd, rangeStart + 1);
if (rangeEnd < 0) {
_reportProblem('No end of error range in example');
- return _SnippetData(snippet, -1, 0);
+ return _SnippetData(snippet, -1, 0, auxiliaryFiles);
} else if (snippet.indexOf(errorRangeStart, rangeEnd) > 0) {
_reportProblem('More than one error range in example');
}
+ if (snippet.indexOf('extension') >= 0) {
+ DateTime.now();
+ }
return _SnippetData(
snippet.substring(0, rangeStart) +
- snippet.substring(rangeStart + 1, rangeEnd) +
- snippet.substring(rangeEnd + 1),
+ snippet.substring(rangeStart + errorRangeStart.length, rangeEnd) +
+ snippet.substring(rangeEnd + errorRangeEnd.length),
rangeStart,
- rangeEnd - rangeStart - 1);
+ rangeEnd - rangeStart - 2,
+ auxiliaryFiles);
}
/// Extract the snippets of Dart code between the start (inclusive) and end
/// (exclusive) indexes.
- List<String> _extractSnippets(List<String> lines, int start, int end) {
- List<String> snippets = [];
- int snippetStart = lines.indexOf('```dart', start);
- while (snippetStart >= 0 && snippetStart < end) {
- int snippetEnd = lines.indexOf('```', snippetStart + 1);
- snippets.add(lines.sublist(snippetStart + 1, snippetEnd).join('\n'));
- snippetStart = lines.indexOf('```dart', snippetEnd + 1);
+ List<_SnippetData> _extractSnippets(
+ List<String> lines, int start, int end, bool errorRequired) {
+ List<_SnippetData> snippets = [];
+ Map<String, String> auxiliaryFiles = <String, String>{};
+ int currentStart = -1;
+ for (int i = start; i < end; i++) {
+ String line = lines[i];
+ if (line == '```') {
+ if (currentStart < 0) {
+ _reportProblem('Snippet without file type on line $i.');
+ return snippets;
+ }
+ String secondLine = lines[currentStart + 1];
+ if (secondLine.startsWith(uriDirectivePrefix)) {
+ String name = secondLine.substring(
+ uriDirectivePrefix.length, secondLine.length - 1);
+ String content = lines.sublist(currentStart + 2, i).join('\n');
+ auxiliaryFiles[name] = content;
+ } else if (lines[currentStart] == '```dart') {
+ String content = lines.sublist(currentStart + 1, i).join('\n');
+ snippets
+ .add(_extractSnippetData(content, errorRequired, auxiliaryFiles));
+ auxiliaryFiles = <String, String>{};
+ }
+ currentStart = -1;
+ } else if (line.startsWith('```')) {
+ if (currentStart >= 0) {
+ _reportProblem('Snippet before line $i was not closed.');
+ return snippets;
+ }
+ currentStart = i;
+ }
}
return snippets;
}
@@ -185,6 +220,7 @@
}
buffer.writeln(' $problem');
for (AnalysisError error in errors) {
+ buffer.write(' ');
buffer.write(error.errorCode);
buffer.write(' (');
buffer.write(error.offset);
@@ -197,7 +233,7 @@
/// Extract documentation from the file that was parsed to produce the given
/// [result].
- void _validateFile(ParsedUnitResult result) {
+ Future<void> _validateFile(ParsedUnitResult result) async {
filePath = result.path;
hasWrittenFilePath = false;
CompilationUnit unit = result.unit;
@@ -211,22 +247,24 @@
VariableDeclaration variable = member.fields.variables[0];
String variableName = variable.name.name;
codeName = '$className.$variableName';
+ if (unverifiedDocs.contains(codeName)) {
+ continue;
+ }
hasWrittenCodeName = false;
int exampleStart = docs.indexOf('#### Example');
int fixesStart = docs.indexOf('#### Common fixes');
- List<String> exampleSnippets =
- _extractSnippets(docs, exampleStart + 1, fixesStart);
- for (String snippet in exampleSnippets) {
- _SnippetData data = _extractSnippetData(snippet);
- _validateSnippet(data.snippet, data.offset, data.length);
+ List<_SnippetData> exampleSnippets =
+ _extractSnippets(docs, exampleStart + 1, fixesStart, true);
+ for (_SnippetData snippet in exampleSnippets) {
+ await _validateSnippet(snippet);
}
- List<String> fixesSnippets =
- _extractSnippets(docs, fixesStart + 1, docs.length);
- for (String snippet in fixesSnippets) {
- _validateSnippet(snippet, -1, 0);
+ List<_SnippetData> fixesSnippets =
+ _extractSnippets(docs, fixesStart + 1, docs.length, false);
+ for (_SnippetData snippet in fixesSnippets) {
+ await _validateSnippet(snippet);
}
}
}
@@ -235,21 +273,19 @@
}
}
- /// Resolve the [snippet]. If the [offset] is less than zero, then verify that
- /// no diagnostics are reported. If the [offset] is greater than or equal to
- /// zero, verify that one error whose name matches the current code is
- /// reported at that offset with the given [length].
- void _validateSnippet(String snippet, int offset, int length) async {
- // TODO(brianwilkerson) Implement this.
- DriverResolutionTest test = DriverResolutionTest();
+ /// Resolve the [snippet]. If the snippet's offset is less than zero, then
+ /// verify that no diagnostics are reported. If the offset is greater than or
+ /// equal to zero, verify that one error whose name matches the current code
+ /// is reported at that offset with the expected length.
+ Future<void> _validateSnippet(_SnippetData snippet) async {
+ _SnippetTest test = _SnippetTest(snippet);
test.setUp();
- test.addTestFile(snippet);
await test.resolveTestFile();
List<AnalysisError> errors = test.result.errors;
int errorCount = errors.length;
- if (offset < 0) {
+ if (snippet.offset < 0) {
if (errorCount > 0) {
- _reportProblem('Expected no errors but found $errorCount.',
+ _reportProblem('Expected no errors but found $errorCount:',
errors: errors);
}
} else {
@@ -257,20 +293,20 @@
_reportProblem('Expected one error but found none.');
} else if (errorCount == 1) {
AnalysisError error = errors[0];
- if (error.errorCode != codeName) {
+ if (error.errorCode.uniqueName != codeName) {
_reportProblem(
'Expected an error with code $codeName, found ${error.errorCode}.');
}
- if (error.offset != offset) {
+ if (error.offset != snippet.offset) {
_reportProblem(
- 'Expected an error at $offset, found ${error.offset}.');
+ 'Expected an error at ${snippet.offset}, found ${error.offset}.');
}
- if (error.length != length) {
+ if (error.length != snippet.length) {
_reportProblem(
- 'Expected an error of length $length, found ${error.length}.');
+ 'Expected an error of length ${snippet.length}, found ${error.length}.');
}
} else {
- _reportProblem('Expected one error but found $errorCount.',
+ _reportProblem('Expected one error but found $errorCount:',
errors: errors);
}
}
@@ -280,9 +316,60 @@
/// A data holder used to return multiple values when extracting an error range
/// from a snippet.
class _SnippetData {
- final String snippet;
+ final String content;
final int offset;
final int length;
+ final Map<String, String> auxiliaryFiles;
- _SnippetData(this.snippet, this.offset, this.length);
+ _SnippetData(this.content, this.offset, this.length, this.auxiliaryFiles);
+}
+
+/// A test class that creates an environment suitable for analyzing the
+/// snippets.
+class _SnippetTest extends DriverResolutionTest with PackageMixin {
+ /// The snippet being tested.
+ final _SnippetData snippet;
+
+ @override
+ AnalysisOptionsImpl analysisOptions = AnalysisOptionsImpl();
+
+ /// Initialize a newly created test to test the given [snippet].
+ _SnippetTest(this.snippet) {
+ analysisOptions.enabledExperiments = ['extension-methods'];
+ String pubspecContent = snippet.auxiliaryFiles['pubspec.yaml'];
+ if (pubspecContent != null) {
+ for (String line in pubspecContent.split('\n')) {
+ if (line.indexOf('sdk:') > 0) {
+ int start = line.indexOf("'") + 1;
+ String constraint = line.substring(start, line.indexOf("'", start));
+ analysisOptions.sdkVersionConstraint =
+ VersionConstraint.parse(constraint);
+ }
+ }
+ }
+ }
+
+ @override
+ void setUp() {
+ super.setUp();
+ addMetaPackage();
+ _createAuxiliaryFiles(snippet.auxiliaryFiles);
+ addTestFile(snippet.content);
+ }
+
+ void _createAuxiliaryFiles(Map<String, String> auxiliaryFiles) {
+ Map<String, String> packageMap = {};
+ for (String uri in auxiliaryFiles.keys) {
+ if (uri.startsWith('package:')) {
+ int slash = uri.indexOf('/');
+ String packageName = uri.substring(8, slash);
+ String libPath = packageMap.putIfAbsent(
+ packageName, () => addPubPackage(packageName).path);
+ String relativePath = uri.substring(slash + 1);
+ newFile('$libPath/$relativePath', content: auxiliaryFiles[uri]);
+ } else {
+ newFile('/test/$uri', content: auxiliaryFiles[uri]);
+ }
+ }
+ }
}
diff --git a/pkg/analyzer/tool/diagnostics/diagnostics.md b/pkg/analyzer/tool/diagnostics/diagnostics.md
index aa77a12..46b5264 100644
--- a/pkg/analyzer/tool/diagnostics/diagnostics.md
+++ b/pkg/analyzer/tool/diagnostics/diagnostics.md
@@ -62,6 +62,66 @@
doesn't conform to the language specification or
that might work in unexpected ways.
+### ambiguous_extension_member_access
+
+_A member named '{0}' is defined in extensions '{1}' and '{2}' and neither is
+more specific._
+
+#### Description
+
+When code refers to a member of an object (for example, `o.m()` or `o.m` or
+`o[i]`) where the static type of `o` doesn't declare the member (`m` or
+`[]`, for example), then the analyzer tries to find the member in an
+extension. For example, if the member is `m`, then the analyzer looks for
+extensions that declare a member named `m` and have an extended type that
+the static type of `o` can be assigned to. When there's more than one such
+extension in scope, the extension whose extended type is most specific is
+selected.
+
+The analyzer produces this diagnostic when none of the extensions has an
+extended type that's more specific than the extended types of all of the
+other extensions, making the reference to the member ambiguous.
+
+#### Example
+
+The following code produces this diagnostic because there's no way to
+choose between the member in `E1` and the member in `E2`:
+
+{% prettify dart %}
+extension E1 on String {
+ int get charCount => 1;
+}
+
+extension E2 on String {
+ int get charCount => 2;
+}
+
+void f(String s) {
+ print(s.[!charCount!]);
+}
+{% endprettify %}
+
+#### Common fixes
+
+If you don't need both extensions, then you can delete or hide one of them.
+
+If you need both, then explicitly select the one you want to use by using
+an extension override:
+
+{% prettify dart %}
+extension E1 on String {
+ int get charCount => length;
+}
+
+extension E2 on String {
+ int get charCount => length;
+}
+
+void f(String s) {
+ print(E2(s).charCount);
+}
+{% endprettify %}
+
### ambiguous_set_or_map_literal_both
_This literal contains both 'Map' and 'Iterable' spreads, which makes it
@@ -175,7 +235,7 @@
{% prettify dart %}
union(a, b) {
- var x = {...a, ...b};
+ var x = [!{...a, ...b}!];
return x;
}
{% endprettify %}
@@ -203,8 +263,8 @@
The following code produces this diagnostic:
{% prettify dart %}
-int f(int x) => x;
-num g(num y) => f([!y!]);
+String f(String x) => x;
+String g(num y) => f([!y!]);
{% endprettify %}
#### Common fixes
@@ -213,8 +273,8 @@
example above you might be able to change the type of the parameter `y`:
{% prettify dart %}
-int f(int x) => x;
-int g(int y) => f(y);
+String f(String x) => x;
+String g(String y) => f(y);
{% endprettify %}
If that fix isn't possible, then add code to handle the case where the
@@ -222,15 +282,15 @@
types to the required type:
{% prettify dart %}
-int f(int x) => x;
-num g(num y) => f(y.floor());
+String f(String x) => x;
+String g(num y) => f(y.toString());
{% endprettify %}
Another approach is to add explicit type tests and fallback code:
{% prettify dart %}
-int f(int x) => x;
-num g(num y) => f(y is int ? y : 0);
+String f(String x) => x;
+String g(num y) => f(y is String ? y : '');
{% endprettify %}
If you believe that the runtime type of the argument will always be the
@@ -238,8 +298,8 @@
an exception thrown at runtime if you're wrong, then add an explicit cast:
{% prettify dart %}
-int f(int x) => x;
-num g(num y) => f(y as int);
+String f(String x) => x;
+String g(num y) => f(y as String);
{% endprettify %}
### const_initialized_with_non_constant_value
@@ -380,7 +440,7 @@
var map = <String, int>{'a': 0, 'b': 1, [!'c'!]};
{% endprettify %}
-#### Common fix
+#### Common fixes
If the expression is intended to compute either a key or a value in an
entry, fix the issue by replacing the expression with the key or the value.
@@ -390,6 +450,335 @@
var map = <String, int>{'a': 0, 'b': 1, 'c': 2};
{% endprettify %}
+### extension_conflicting_static_and_instance
+
+_Extension '{0}' can't define static member '{1}' and an instance member with
+the same name._
+
+#### Description
+
+The analyzer produces this diagnostic when an extension declaration
+contains both an instance member and a static member that have the same
+name. The instance member and the static member can't have the same name
+because it's unclear which member is being referenced by an unqualified use
+of the name within the body of the extension.
+
+#### Example
+
+The following code produces this diagnostic:
+
+{% prettify dart %}
+extension E on Object {
+ int get a => 0;
+ static int [!a!]() => 0;
+}
+{% endprettify %}
+
+#### Common fixes
+
+Rename or remove one of the members:
+
+{% prettify dart %}
+extension E on Object {
+ int get a => 0;
+ static int b() => 0;
+}
+{% endprettify %}
+
+### extension_declares_abstract_member
+
+_Extensions can't declare abstract members._
+
+#### Description
+
+The analyzer produces this diagnostic when an abstract declaration is
+declared in an extension. Extensions can declare only concrete members.
+
+#### Example
+
+The following code produces this diagnostic:
+
+{% prettify dart %}
+extension E on String {
+ int [!a!]();
+}
+{% endprettify %}
+
+#### Common fixes
+
+Either provide an implementation for the member or remove it.
+
+### extension_declares_constructor
+
+_Extensions can't declare constructors._
+
+#### Description
+
+The analyzer produces this diagnostic when a constructor declaration is
+found in an extension. It isn't valid to define a constructor because
+extensions aren't classes, and it isn't possible to create an instance of
+an extension.
+
+#### Example
+
+The following code produces this diagnostic:
+
+{% prettify dart %}
+extension E on String {
+ [!E!]() : super();
+}
+{% endprettify %}
+
+#### Common fixes
+
+Remove the constructor or replace it with a static method.
+
+### extension_declares_instance_field
+
+_Extensions can't declare instance fields_
+
+#### Description
+
+The analyzer produces this diagnostic when an instance field declaration is
+found in an extension. It isn't valid to define an instance field because
+extensions can only add behavior, not state.
+
+#### Example
+
+The following code produces this diagnostic:
+
+{% prettify dart %}
+extension E on String {
+ String [!s!];
+}
+{% endprettify %}
+
+#### Common fixes
+
+Remove the field, make it a static field, or convert it to be a getter,
+setter, or method.
+
+### extension_declares_member_of_object
+
+_Extensions can't declare members with the same name as a member declared by
+'Object'._
+
+#### Description
+
+The analyzer produces this diagnostic when an extension declaration
+declares a member with the same name as a member declared in the class
+`Object`. Such a member can never be used because the member in `Object` is
+always found first.
+
+#### Example
+
+The following code produces this diagnostic:
+
+{% prettify dart %}
+extension E on String {
+ String [!toString!]() => this;
+}
+{% endprettify %}
+
+#### Common fixes
+
+Remove the member or rename it so that the name doesn't conflict with the
+member in `Object`:
+
+{% prettify dart %}
+extension E on String {
+ String displayString() => this;
+}
+{% endprettify %}
+
+### extension_override_access_to_static_member
+
+_An extension override can't be used to access a static member from an
+extension._
+
+#### Description
+
+The analyzer produces this diagnostic when an extension override is the
+target of the invocation of a static member. Similar to static members in
+classes, the static members of an extension should be accessed using the
+name of the extension, not an extension override.
+
+#### Example
+
+The following code produces this diagnostic:
+
+{% prettify dart %}
+extension E on String {
+ static void staticMethod() {}
+}
+
+void f() {
+ E('').[!staticMethod!]();
+}
+{% endprettify %}
+
+#### Common fixes
+
+Replace the extension override with the name of the extension:
+
+{% prettify dart %}
+extension E on String {
+ static void staticMethod() {}
+}
+
+void f() {
+ E.staticMethod();
+}
+{% endprettify %}
+
+### extension_override_argument_not_assignable
+
+_The type of the argument to the extension override '{0}' isn't assignable to
+the extended type '{1}'._
+
+#### Description
+
+The analyzer produces this diagnostic when the argument to an extension
+override isn't assignable to the type being extended by the extension.
+
+#### Example
+
+The following code produces this diagnostic:
+
+{% prettify dart %}
+extension E on String {
+ void method() {}
+}
+
+void f() {
+ E([!3!]).method();
+}
+{% endprettify %}
+
+#### Common fixes
+
+If you're using the correct extension, then update the argument to have the
+correct type:
+
+{% prettify dart %}
+extension E on String {
+ void method() {}
+}
+
+void f() {
+ E(3.toString()).method();
+}
+{% endprettify %}
+
+If there's a different extension that's valid for the type of the argument,
+then either replace the name of the extension or unwrap the target so that
+the correct extension is found.
+
+### extension_override_without_access
+
+_An extension override can only be used to access instance members._
+
+#### Description
+
+The analyzer produces this diagnostic when an extension override is found
+that isn't being used to access one of the members of the extension. The
+extension override syntax doesn't have any runtime semantics; it only
+controls which member is selected at compile time.
+
+#### Example
+
+The following code produces this diagnostic:
+
+{% prettify dart %}
+extension E on int {
+ int get a => 0;
+}
+
+void f(int i) {
+ print([!E(i)!]);
+}
+{% endprettify %}
+
+#### Common fixes
+
+If you want to invoke one of the members of the extension, then add the
+invocation:
+
+{% prettify dart %}
+extension E on int {
+ int get a => 0;
+}
+
+void f(int i) {
+ print(E(i).a);
+}
+{% endprettify %}
+
+If you don't want to invoke a member, then unwrap the target:
+
+{% prettify dart %}
+extension E on int {
+ int get a => 0;
+}
+
+void f(int i) {
+ print(i);
+}
+{% endprettify %}
+
+### invalid_extension_argument_count
+
+_Extension overrides must have exactly one argument: the value of 'this' in the
+extension method._
+
+#### Description
+
+The analyzer produces this diagnostic when an extension override doesn't
+have exactly one argument. The argument is the expression used to compute
+the value of `this` within the extension method, so there must be one
+argument.
+
+#### Example
+
+The following code produces this diagnostic because there are no arguments:
+
+{% prettify dart %}
+extension E on String {
+ String join(String other) => '$this $other';
+}
+
+void f() {
+ E[!()!].join('b');
+}
+{% endprettify %}
+
+And, the following code produces this diagnostic because there's more than
+one argument:
+
+{% prettify dart %}
+extension E on String {
+ String join(String other) => '$this $other';
+}
+
+void f() {
+ E[!('a', 'b')!].join('c');
+}
+{% endprettify %}
+
+#### Common fixes
+
+Provide one argument for the extension override:
+
+{% prettify dart %}
+extension E on String {
+ String join(String other) => '$this $other';
+}
+
+void f() {
+ E('a').join('b');
+}
+{% endprettify %}
+
### invalid_literal_annotation
_Only const constructors can have the `@literal` annotation._
@@ -404,6 +793,8 @@
The following code produces this diagnostic:
{% prettify dart %}
+import 'package:meta/meta.dart';
+
[!@literal!]
var x;
{% endprettify %}
@@ -416,6 +807,37 @@
var x;
{% endprettify %}
+### invalid_use_of_covariant_in_extension
+
+_The 'covariant' keyword can't be used in an extension._
+
+#### Description
+
+The analyzer produces this diagnostic when a member declared inside an
+extension uses the keyword `covariant` in the declaration of a parameter.
+Extensions aren't classes and don't have subclasses, so the keyword serves
+no purpose.
+
+#### Example
+
+The following code produces this diagnostic:
+
+{% prettify dart %}
+extension E on String {
+ void a([!covariant!] int i) {}
+}
+{% endprettify %}
+
+#### Common fixes
+
+Remove the 'covariant' keyword:
+
+{% prettify dart %}
+extension E on String {
+ void a(int i) {}
+}
+{% endprettify %}
+
### invocation_of_non_function
_'{0}' isn't a function._
@@ -449,7 +871,7 @@
#### Description
-Any function or method that doesn’t end with either an explicit return or a
+Any function or method that doesn't end with either an explicit return or a
throw implicitly returns `null`. This is rarely the desired behavior. The
analyzer produces this diagnostic when it finds an implicit return.
@@ -487,8 +909,8 @@
even though it appears in an implicitly constant list literal:
{% prettify dart %}
-int x = 2;
-const y = <int>[0, 1, [!x!]];
+var x = 2;
+var y = const <int>[0, 1, [!x!]];
{% endprettify %}
#### Common fixes
@@ -498,17 +920,17 @@
declaration of `x`:
{% prettify dart %}
-const int x = 2;
-const y = <int>[0, 1, x];
+const x = 2;
+var y = const <int>[0, 1, x];
{% endprettify %}
If the expression can't be made a constant, then the list can't be a
constant either, so you must change the code so that the list isn't a
-constant. In the example above this means removing the `const` keyword from
-the declaration of `y`:
+constant. In the example above this means removing the `const` keyword
+before the list literal:
{% prettify dart %}
-int x = 2;
+var x = 2;
var y = <int>[0, 1, x];
{% endprettify %}
@@ -555,9 +977,7 @@
{% prettify dart %}
f() {}
-main() {
- [!f!] v = null;
-}
+g([!f!] v) {}
{% endprettify %}
#### Common fixes
@@ -583,7 +1003,7 @@
var s = <String>{...[!m!]};
{% endprettify %}
-#### Common fix
+#### Common fixes
The most common fix is to replace the expression with one that produces an
iterable object:
@@ -609,7 +1029,7 @@
The following code produces this diagnostic because `f` is a function:
{% prettify dart %}
-C f() {}
+C f() => null;
class C {
factory C() = [!f!];
@@ -628,13 +1048,328 @@
the constructor to return the value from the constructor's body:
{% prettify dart %}
-C f() {}
+C f() => null;
class C {
factory C() => f();
}
{% endprettify %}
+### sdk_version_async_exported_from_core
+
+_The class '{0}' wasn't exported from 'dart:core' until version 2.1, but this
+code is required to be able to run on earlier versions._
+
+#### Description
+
+The analyzer produces this diagnostic when either the class `Future` or
+`Stream` is referenced in a library that doesn't import `dart:async` in
+code that has an SDK constraint whose lower bound is less than 2.1.0. In
+earlier versions, these classes weren't defined in `dart:core`, so the
+import was necessary.
+
+#### Example
+
+Here's an example of a pubspec that defines an SDK constraint with a lower
+bound of less than 2.1.0:
+
+```yaml
+environment:
+ sdk: '>=2.0.0 <2.4.0'
+```
+
+In the package that has that pubspec, code like the following produces this
+diagnostic:
+
+{% prettify dart %}
+void f([!Future!] f) {}
+{% endprettify %}
+
+#### Common fixes
+
+If you don't need to support older versions of the SDK, then you can
+increase the SDK constraint to allow the classes to be referenced:
+
+```yaml
+environment:
+ sdk: '>=2.1.0 <2.4.0'
+```
+
+If you need to support older versions of the SDK, then import the
+`dart:async` library.
+
+{% prettify dart %}
+import 'dart:async';
+
+void f(Future f) {}
+{% endprettify %}
+
+### sdk_version_as_expression_in_const_context
+
+_The use of an as expression in a constant expression wasn't supported until
+version 2.3.2, but this code is required to be able to run on earlier versions._
+
+#### Description
+
+The analyzer produces this diagnostic when an as expression inside a
+[constant context](#constant-context) is found in code that has an SDK
+constraint whose lower bound is less than 2.3.2. Using an as expression in
+a [constant context](#constant-context) wasn't supported in earlier
+versions, so this code won't be able to run against earlier versions of the
+SDK.
+
+#### Example
+
+Here's an example of a pubspec that defines an SDK constraint with a lower
+bound of less than 2.3.2:
+
+```yaml
+environment:
+ sdk: '>=2.1.0 <2.4.0'
+```
+
+In the package that has that pubspec, code like the following generates
+this diagnostic:
+
+{% prettify dart %}
+const num n = 3;
+const int i = [!n as int!];
+{% endprettify %}
+
+#### Common fixes
+
+If you don't need to support older versions of the SDK, then you can
+ncrease the SDK constraint to allow the expression to be used:
+
+```yaml
+environment:
+ sdk: '>=2.3.2 <2.4.0'
+```
+
+If you need to support older versions of the SDK, then either rewrite the
+code to not use an as expression, or change the code so that the as
+expression is not in a [constant context](#constant-context).:
+
+{% prettify dart %}
+num x = 3;
+int y = x as int;
+{% endprettify %}
+
+### sdk_version_bool_operator_in_const_context
+
+_The use of the operator '{0}' for 'bool' operands in a constant context wasn't
+supported until version 2.3.2, but this code is required to be able to run on earlier versions._
+
+#### Description
+
+The analyzer produces this diagnostic when any use of the `&`, `|` or `^`
+operators on the class `bool` inside a
+[constant context](#constant-context) is found in code that has an SDK
+constraint whose lower bound is less than 2.3.2. Using these operators in a
+[constant context](#constant-context) wasn't supported in earlier versions,
+so this code won't be able to run against earlier versions of the SDK.
+
+#### Example
+
+Here's an example of a pubspec that defines an SDK constraint with a lower
+bound of less than 2.3.2:
+
+```yaml
+environment:
+ sdk: '>=2.1.0 <2.4.0'
+```
+
+In the package that has that pubspec, code like the following produces this
+diagnostic:
+
+{% prettify dart %}
+const bool a = true;
+const bool b = false;
+const bool c = a [!&!] b;
+{% endprettify %}
+
+#### Common fixes
+
+If you don't need to support older versions of the SDK, then you can
+increase the SDK constraint to allow the operators to be used:
+
+```yaml
+environment:
+ sdk: '>=2.3.2 <2.4.0'
+```
+
+If you need to support older versions of the SDK, then either rewrite the
+code to not use these operators, or change the code so that the expression
+is not in a [constant context](#constant-context).:
+
+{% prettify dart %}
+const bool a = true;
+const bool b = false;
+bool c = a & b;
+{% endprettify %}
+
+### sdk_version_eq_eq_operator_in_const_context
+
+_Using the operator '==' for non-primitive types wasn't supported until version
+2.3.2, but this code is required to be able to run on earlier versions._
+
+#### Description
+
+The analyzer produces this diagnostic when the operator `==` is used on a
+non-primitive type inside a [constant context](#constant-context) is found
+in code that has an SDK constraint whose lower bound is less than 2.3.2.
+Using this operator in a [constant context](#constant-context) wasn't
+supported in earlier versions, so this code won't be able to run against
+earlier versions of the SDK.
+
+#### Example
+
+Here's an example of a pubspec that defines an SDK constraint with a lower
+bound of less than 2.3.2:
+
+```yaml
+environment:
+ sdk: '>=2.1.0 <2.4.0'
+```
+
+In the package that has that pubspec, code like the following produces this
+diagnostic:
+
+{% prettify dart %}
+class C {}
+const C a = null;
+const C b = null;
+const bool same = a [!==!] b;
+{% endprettify %}
+
+#### Common fixes
+
+If you don't need to support older versions of the SDK, then you can
+increase the SDK constraint to allow the operator to be used:
+
+```yaml
+environment:
+ sdk: '>=2.3.2 <2.4.0'
+```
+
+If you need to support older versions of the SDK, then either rewrite the
+code to not use the `==` operator, or change the code so that the
+expression is not in a [constant context](#constant-context).:
+
+{% prettify dart %}
+class C {}
+const C a = null;
+const C b = null;
+bool same = a == b;
+{% endprettify %}
+
+### sdk_version_extension_methods
+
+_Extension methods weren't supported until version 2.6.0, but this code is
+required to be able to run on earlier versions._
+
+#### Description
+
+The analyzer produces this diagnostic when an extension declaration or an
+extension override is found in code that has an SDK constraint whose lower
+bound is less than 2.6.0. Using extensions wasn't supported in earlier
+versions, so this code won't be able to run against earlier versions of the
+SDK.
+
+#### Example
+
+Here's an example of a pubspec that defines an SDK constraint with a lower
+bound of less than 2.6.0:
+
+```yaml
+environment:
+ sdk: '>=2.4.0 <2.7.0'
+```
+
+In the package that has that pubspec, code like the following generates
+this diagnostic:
+
+{% prettify dart %}
+[!extension!] E on String {
+ void sayHello() {
+ print('Hello $this');
+ }
+}
+{% endprettify %}
+
+#### Common fixes
+
+If you don't need to support older versions of the SDK, then you can
+increase the SDK constraint to allow the syntax to be used:
+
+```yaml
+environment:
+ sdk: '>=2.6.0 <2.7.0'
+```
+
+If you need to support older versions of the SDK, then rewrite the code to
+not make use of extensions. The most common way to do this is to rewrite
+the members of the extension as top-level functions (or methods) that take
+the value that would have been bound to `this` as a parameter:
+
+{% prettify dart %}
+void sayHello(String s) {
+ print('Hello $s');
+}
+{% endprettify %}
+
+### sdk_version_is_expression_in_const_context
+
+_The use of an is expression in a constant context wasn't supported until
+version 2.3.2, but this code is required to be able to run on earlier versions._
+
+#### Description
+
+The analyzer produces this diagnostic when an is expression inside a
+[constant context](#constant-context) is found in code that has an SDK
+constraint whose lower bound is less than 2.3.2. Using an is expression in
+a [constant context](#constant-context) wasn't supported in earlier
+versions, so this code won't be able to run against earlier versions of the
+SDK.
+
+#### Example
+
+Here's an example of a pubspec that defines an SDK constraint with a lower
+bound of less than 2.3.2:
+
+```yaml
+environment:
+ sdk: '>=2.1.0 <2.4.0'
+```
+
+In the package that has that pubspec, code like the following generates
+this diagnostic:
+
+{% prettify dart %}
+const x = 4;
+const y = [!x is int!] ? 0 : 1;
+{% endprettify %}
+
+#### Common fixes
+
+If you don't need to support older versions of the SDK, then you can
+increase the SDK constraint to allow the expression to be used:
+
+```yaml
+environment:
+ sdk: '>=2.3.2 <2.4.0'
+```
+
+If you need to support older versions of the SDK, then either rewrite the
+code to not use the is operator, or, if that's not possible, change the
+code so that the is expression is not in a
+[constant context](#constant-context).:
+
+{% prettify dart %}
+const x = 4;
+var y = x is int ? 0 : 1;
+{% endprettify %}
+
### sdk_version_set_literal
_Set literals weren't supported until version 2.2, but this code is required to
@@ -643,21 +1378,22 @@
#### Description
The analyzer produces this diagnostic when a set literal is found in code
-that has an SDK constraint whose lower bound is less than 2.2. Set literals
-weren't supported in earlier versions, so this code won't be able to run
-against earlier versions of the SDK.
+that has an SDK constraint whose lower bound is less than 2.2.0. Set
+literals weren't supported in earlier versions, so this code won't be able
+to run against earlier versions of the SDK.
#### Example
-In a package that defines the SDK constraint (in the pubspec.yaml file),
-with a lower bound of less than 2.2. For example:
+Here's an example of a pubspec that defines an SDK constraint with a lower
+bound of less than 2.2.0:
```yaml
environment:
sdk: '>=2.1.0 <2.4.0'
```
-The following code generates this diagnostic:
+In the package that has that pubspec, code like the following produces this
+diagnostic:
{% prettify dart %}
var s = [!<int>{}!];
@@ -680,6 +1416,150 @@
var s = new Set<int>();
{% endprettify %}
+### sdk_version_ui_as_code
+
+_The for, if, and spread elements weren't supported until version 2.2.2, but
+this code is required to be able to run on earlier versions._
+
+#### Description
+
+The analyzer produces this diagnostic when a for, if, or spread element is
+found in code that has an SDK constraint whose lower bound is less than
+2.3.0. Using a for, if, or spread element wasn't supported in earlier
+versions, so this code won't be able to run against earlier versions of the
+SDK.
+
+#### Example
+
+Here's an example of a pubspec that defines an SDK constraint with a lower
+bound of less than 2.3.0:
+
+```yaml
+environment:
+ sdk: '>=2.2.0 <2.4.0'
+```
+
+In the package that has that pubspec, code like the following generates
+this diagnostic:
+
+{% prettify dart %}
+var digits = [[!for (int i = 0; i < 10; i++) i!]];
+{% endprettify %}
+
+#### Common fixes
+
+If you don't need to support older versions of the SDK, then you can
+increase the SDK constraint to allow the syntax to be used:
+
+```yaml
+environment:
+ sdk: '>=2.3.0 <2.4.0'
+```
+
+If you need to support older versions of the SDK, then rewrite the code to
+not make use of those elements:
+
+{% prettify dart %}
+var digits = _initializeDigits();
+
+List<int> _initializeDigits() {
+ var digits = <int>[];
+ for (int i = 0; i < 10; i++) {
+ digits.add(i);
+ }
+ return digits;
+}
+{% endprettify %}
+
+### sdk_version_ui_as_code_in_const_context
+
+_The if and spread elements weren't supported in constant expressions until
+version 2.5.0, but this code is required to be able to run on earlier versions._
+
+#### Description
+
+The analyzer produces this diagnostic when an if or spread element inside
+a [constant context](#constant-context) is found in code that has an
+SDK constraint whose lower bound is less than 2.5.0. Using an if or
+spread element inside a [constant context](#constant-context) wasn't
+supported in earlier versions, so this code won't be able to run against
+earlier versions of the SDK.
+
+#### Example
+
+Here's an example of a pubspec that defines an SDK constraint with a lower
+bound of less than 2.5.0:
+
+```yaml
+environment:
+ sdk: '>=2.4.0 <2.6.0'
+```
+
+In the package that has that pubspec, code like the following generates
+this diagnostic:
+
+{% prettify dart %}
+const a = [1, 2];
+const b = [[!...a!]];
+{% endprettify %}
+
+#### Common fixes
+
+If you don't need to support older versions of the SDK, then you can
+increase the SDK constraint to allow the syntax to be used:
+
+```yaml
+environment:
+ sdk: '>=2.5.0 <2.6.0'
+```
+
+If you need to support older versions of the SDK, then rewrite the code to
+not make use of those elements:
+
+{% prettify dart %}
+const a = [1, 2];
+const b = [1, 2];
+{% endprettify %}
+
+If that's not possible, change the code so that the element is not in a
+[constant context](#constant-context).:
+
+{% prettify dart %}
+const a = [1, 2];
+var b = [...a];
+{% endprettify %}
+
+### super_in_extension
+
+_The 'super' keyword can't be used in an extension because an extension doesn't
+have a superclass._
+
+#### Description
+
+The analyzer produces this diagnostic when a member declared inside an
+extension uses the `super` keyword . Extensions aren't classes and don't
+have superclasses, so the `super` keyword serves no purpose.
+
+#### Example
+
+The following code produces this diagnostic:
+
+{% prettify dart %}
+extension E on Object {
+ String get displayString => [!super!].toString();
+}
+{% endprettify %}
+
+#### Common fixes
+
+Remove the `super` keyword :
+
+{% prettify dart %}
+extension E on Object {
+ String get displayString => toString();
+}
+{% endprettify %}
+
### type_argument_not_matching_bounds
_'{0}' doesn't extend '{1}'._
@@ -726,9 +1606,7 @@
{% prettify dart %}
class Point {}
-void main() {
- [!Piont!] p;
-}
+void f([!Piont!] p) {}
{% endprettify %}
#### Common fixes
@@ -740,14 +1618,293 @@
{% prettify dart %}
class Point {}
-void main() {
- Point p;
-}
+void f(Point p) {}
{% endprettify %}
If the class is defined but isn't visible, then you probably need to add an
import.
+### undefined_extension_getter
+
+_The getter '{0}' isn't defined for the extension '{1}'._
+
+#### Description
+
+The analyzer produces this diagnostic when an extension override is used to
+invoke a getter, but the getter isn't defined by the specified extension.
+The analyzer also produces this diagnostic when a static getter is
+referenced but isn't defined by the specified extension.
+
+#### Example
+
+The following code produces this diagnostic because the extension `E`
+doesn't declare an instance getter named `b`:
+
+{% prettify dart %}
+extension E on String {
+ String get a => 'a';
+}
+
+extension F on String {
+ String get b => 'b';
+}
+
+void f() {
+ E('c').[!b!];
+}
+{% endprettify %}
+
+The following code produces this diagnostic because the extension `E`
+doesn't declare a static getter named `a`:
+
+{% prettify dart %}
+extension E on String {}
+
+var x = E.[!a!];
+{% endprettify %}
+
+#### Common fixes
+
+If the name of the getter is incorrect, then change it to the name of an
+existing getter:
+
+{% prettify dart %}
+extension E on String {
+ String get a => 'a';
+}
+
+extension F on String {
+ String get b => 'b';
+}
+
+void f() {
+ E('c').a;
+}
+{% endprettify %}
+
+If the name of the getter is correct but the name of the extension is
+wrong, then change the name of the extension to the correct name:
+
+{% prettify dart %}
+extension E on String {
+ String get a => 'a';
+}
+
+extension F on String {
+ String get b => 'b';
+}
+
+void f() {
+ F('c').b;
+}
+{% endprettify %}
+
+If the name of the getter and extension are both correct, but the getter
+isn't defined, then define the getter:
+
+{% prettify dart %}
+extension E on String {
+ String get a => 'a';
+ String get b => 'z';
+}
+
+extension F on String {
+ String get b => 'b';
+}
+
+void f() {
+ E('c').b;
+}
+{% endprettify %}
+
+### undefined_extension_method
+
+_The method '{0}' isn't defined for the extension '{1}'._
+
+#### Description
+
+The analyzer produces this diagnostic when an extension override is used to
+invoke a method, but the method isn't defined by the specified extension.
+The analyzer also produces this diagnostic when a static method is
+referenced but isn't defined by the specified extension.
+
+#### Example
+
+The following code produces this diagnostic because the extension `E`
+doesn't declare an instance method named `b`:
+
+{% prettify dart %}
+extension E on String {
+ String a() => 'a';
+}
+
+extension F on String {
+ String b() => 'b';
+}
+
+void f() {
+ E('c').[!b!]();
+}
+{% endprettify %}
+
+The following code produces this diagnostic because the extension `E`
+doesn't declare a static method named `a`:
+
+{% prettify dart %}
+extension E on String {}
+
+var x = E.[!a!]();
+{% endprettify %}
+
+#### Common fixes
+
+If the name of the method is incorrect, then change it to the name of an
+existing method:
+
+{% prettify dart %}
+extension E on String {
+ String a() => 'a';
+}
+
+extension F on String {
+ String b() => 'b';
+}
+
+void f() {
+ E('c').a();
+}
+{% endprettify %}
+
+If the name of the method is correct, but the name of the extension is
+wrong, then change the name of the extension to the correct name:
+
+{% prettify dart %}
+extension E on String {
+ String a() => 'a';
+}
+
+extension F on String {
+ String b() => 'b';
+}
+
+void f() {
+ F('c').b();
+}
+{% endprettify %}
+
+If the name of the method and extension are both correct, but the method
+isn't defined, then define the method:
+
+{% prettify dart %}
+extension E on String {
+ String a() => 'a';
+ String b() => 'z';
+}
+
+extension F on String {
+ String b() => 'b';
+}
+
+void f() {
+ E('c').b();
+}
+{% endprettify %}
+
+### undefined_extension_setter
+
+_The setter '{0}' isn't defined for the extension '{1}'._
+
+#### Description
+
+The analyzer produces this diagnostic when an extension override is used to
+invoke a setter, but the setter isn't defined by the specified extension.
+The analyzer also produces this diagnostic when a static setter is
+referenced but isn't defined by the specified extension.
+
+#### Example
+
+The following code produces this diagnostic because the extension `E`
+doesn't declare an instance setter named `b`:
+
+{% prettify dart %}
+extension E on String {
+ set a(String v) {}
+}
+
+extension F on String {
+ set b(String v) {}
+}
+
+void f() {
+ E('c').[!b!] = 'd';
+}
+{% endprettify %}
+
+The following code produces this diagnostic because the extension `E`
+doesn't declare a static setter named `a`:
+
+{% prettify dart %}
+extension E on String {}
+
+void f() {
+ E.[!a!] = 3;
+}
+{% endprettify %}
+
+#### Common fixes
+
+If the name of the setter is incorrect, then change it to the name of an
+existing setter:
+
+{% prettify dart %}
+extension E on String {
+ set a(String v) {}
+}
+
+extension F on String {
+ set b(String v) {}
+}
+
+void f() {
+ E('c').a = 'd';
+}
+{% endprettify %}
+
+If the name of the setter is correct, but the name of the extension is
+wrong, then change the name of the extension to the correct name:
+
+{% prettify dart %}
+extension E on String {
+ set a(String v) {}
+}
+
+extension F on String {
+ set b(String v) {}
+}
+
+void f() {
+ F('c').b = 'd';
+}
+{% endprettify %}
+
+If the name of the setter and extension are both correct, but the setter
+isn't defined, then define the setter:
+
+{% prettify dart %}
+extension E on String {
+ set a(String v) {}
+ set b(String v) {}
+}
+
+extension F on String {
+ set b(String v) {}
+}
+
+void f() {
+ E('c').b = 'd';
+}
+{% endprettify %}
+
### undefined_function
_The function '{0}' isn't defined._
@@ -805,7 +1962,7 @@
int f(String s) => s.[!len!];
{% endprettify %}
-#### Common fix
+#### Common fixes
If the identifier isn't defined, then either define it or replace it with
the name of a getter that is defined. The example above can be corrected by
@@ -864,7 +2021,7 @@
int f(List<int> l) => l.[!removeMiddle!]();
{% endprettify %}
-#### Common fix
+#### Common fixes
If the identifier isn't defined, then either define it or replace it with
the name of a method that is defined. The example above can be corrected by
@@ -881,7 +2038,7 @@
#### Description
The analyzer produces this diagnostic when a method or function invocation
-has a named argument, but the method or function being invoked doesn’t
+has a named argument, but the method or function being invoked doesn't
define a parameter with the same name.
#### Example
@@ -957,31 +2114,25 @@
The following code produces this diagnostic:
{% prettify dart %}
-class Point {
- int x;
- int y;
- Point(this.x, this.y);
- void shiftBy(Point other) {
- this.x += other.x;
- this.[!z!] += other.y;
+class C {
+ int x = 0;
+ void m(int y) {
+ this.[!z!] = y;
}
}
{% endprettify %}
-#### Common fix
+#### Common fixes
If the identifier isn't defined, then either define it or replace it with
the name of a setter that is defined. The example above can be corrected by
fixing the spelling of the setter:
{% prettify dart %}
-class Point {
- int x;
- int y;
- Point(this.x, this.y);
- void shiftBy(Point other) {
- this.x += other.x;
- this.y += other.y;
+class C {
+ int x = 0;
+ void m(int y) {
+ this.x = y;
}
}
{% endprettify %}
diff --git a/pkg/analyzer/tool/diagnostics/generate.dart b/pkg/analyzer/tool/diagnostics/generate.dart
index 36b166e..7f51a0d 100644
--- a/pkg/analyzer/tool/diagnostics/generate.dart
+++ b/pkg/analyzer/tool/diagnostics/generate.dart
@@ -17,36 +17,84 @@
/// Generate the file `diagnostics.md` based on the documentation associated
/// with the declarations of the error codes.
void main() async {
- Context pathContext = PhysicalResourceProvider.INSTANCE.pathContext;
- String packageRoot = pathContext.normalize(package_root.packageRoot);
- String analyzerPath = pathContext.join(packageRoot, 'analyzer');
- List<String> docPaths = [
- pathContext.join(
- analyzerPath, 'lib', 'src', 'dart', 'error', 'hint_codes.dart'),
- pathContext.join(analyzerPath, 'lib', 'src', 'error', 'codes.dart'),
- ];
- String outputPath =
- pathContext.join(analyzerPath, 'tool', 'diagnostics', 'diagnostics.md');
-
- IOSink sink = File(outputPath).openWrite();
- DocumentationGenerator generator = DocumentationGenerator(docPaths);
+ IOSink sink = File(computeOutputPath()).openWrite();
+ DocumentationGenerator generator = DocumentationGenerator(computeCodePaths());
generator.writeDocumentation(sink);
await sink.flush();
await sink.close();
}
+/// Compute a list of the code paths for the files containing diagnostics that
+/// have been documented.
+List<CodePath> computeCodePaths() {
+ Context pathContext = PhysicalResourceProvider.INSTANCE.pathContext;
+ String packageRoot = pathContext.normalize(package_root.packageRoot);
+ String analyzerPath = pathContext.join(packageRoot, 'analyzer');
+ return CodePath.from([
+ [analyzerPath, 'lib', 'src', 'dart', 'error', 'hint_codes.dart'],
+ [analyzerPath, 'lib', 'src', 'dart', 'error', 'syntactic_errors.dart'],
+ [analyzerPath, 'lib', 'src', 'error', 'codes.dart'],
+ ], [
+ null,
+ [analyzerPath, 'lib', 'src', 'dart', 'error', 'syntactic_errors.g.dart'],
+ null,
+ ]);
+}
+
+/// Compute the path to the file into which documentation is being generated.
+String computeOutputPath() {
+ Context pathContext = PhysicalResourceProvider.INSTANCE.pathContext;
+ String packageRoot = pathContext.normalize(package_root.packageRoot);
+ String analyzerPath = pathContext.join(packageRoot, 'analyzer');
+ return pathContext.join(
+ analyzerPath, 'tool', 'diagnostics', 'diagnostics.md');
+}
+
+/// A representation of the paths to the documentation and declaration of a set
+/// of diagnostic codes.
+class CodePath {
+ /// The path to the file containing the declarations of the diagnostic codes
+ /// that might have documentation associated with them.
+ final String documentationPath;
+
+ /// The path to the file containing the generated definition of the diagnostic
+ /// codes that include the message, or `null` if the
+ final String declarationPath;
+
+ /// Initialize a newly created code path from the [documentationPath] and
+ /// [declarationPath].
+ CodePath(this.documentationPath, this.declarationPath);
+
+ /// Return a list of code paths computed by joining the path segments in the
+ /// corresponding lists from [documentationPaths] and [declarationPaths].
+ static List<CodePath> from(List<List<String>> documentationPaths,
+ List<List<String>> declarationPaths) {
+ Context pathContext = PhysicalResourceProvider.INSTANCE.pathContext;
+ List<CodePath> paths = [];
+ for (int i = 0; i < documentationPaths.length; i++) {
+ String docPath = pathContext.joinAll(documentationPaths[i]);
+ String declPath = null;
+ if (declarationPaths[i] != null) {
+ declPath = pathContext.joinAll(declarationPaths[i]);
+ }
+ paths.add(CodePath(docPath, declPath));
+ }
+ return paths;
+ }
+}
+
/// A class used to generate diagnostic documentation.
class DocumentationGenerator {
/// The absolute paths of the files containing the declarations of the error
/// codes.
- final List<String> docPaths;
+ final List<CodePath> codePaths;
/// A map from the name of a diagnostic code to the lines of the documentation
/// for that code.
Map<String, List<String>> docsByCode = {};
/// Initialize a newly created documentation generator.
- DocumentationGenerator(this.docPaths) {
+ DocumentationGenerator(this.codePaths) {
_extractAllDocs();
}
@@ -66,11 +114,30 @@
/// Extract documentation from all of the files containing the definitions of
/// diagnostics.
void _extractAllDocs() {
+ List<String> includedPaths = [];
+ for (CodePath codePath in codePaths) {
+ includedPaths.add(codePath.documentationPath);
+ if (codePath.declarationPath != null) {
+ includedPaths.add(codePath.declarationPath);
+ }
+ }
AnalysisContextCollection collection = new AnalysisContextCollection(
- includedPaths: docPaths,
+ includedPaths: includedPaths,
resourceProvider: PhysicalResourceProvider.INSTANCE);
- for (String docPath in docPaths) {
- _extractDocs(_parse(collection, docPath));
+ for (CodePath codePath in codePaths) {
+ String docPath = codePath.documentationPath;
+ String declPath = codePath.declarationPath;
+ if (declPath == null) {
+ _extractDocs(_parse(collection, docPath), null);
+ } else {
+ File file = File(declPath);
+ if (file.existsSync()) {
+ _extractDocs(
+ _parse(collection, docPath), _parse(collection, declPath));
+ } else {
+ _extractDocs(_parse(collection, docPath), null);
+ }
+ }
}
}
@@ -86,6 +153,8 @@
String lexeme = comments.lexeme;
if (lexeme.startsWith('// TODO')) {
break;
+ } else if (lexeme.startsWith('// %')) {
+ // Ignore lines containing directives for testing support.
} else if (lexeme.startsWith('// ')) {
String trimmedLine = lexeme.substring(3);
if (trimmedLine == '```dart') {
@@ -113,8 +182,9 @@
}
/// Extract documentation from the file that was parsed to produce the given
- /// [result].
- void _extractDocs(ParsedUnitResult result) {
+ /// [result]. If a [generatedResult] is provided, then the messages might be
+ /// in the file parsed to produce the result.
+ void _extractDocs(ParsedUnitResult result, ParsedUnitResult generatedResult) {
CompilationUnit unit = result.unit;
for (CompilationUnitMember declaration in unit.declarations) {
if (declaration is ClassDeclaration) {
@@ -128,10 +198,7 @@
throw StateError('Duplicate diagnostic code');
}
String message =
- ((variable.initializer as InstanceCreationExpression)
- .argumentList
- .arguments[1] as StringLiteral)
- .stringValue;
+ _extractMessage(variable.initializer, generatedResult);
docs = [
'### ${variableName.toLowerCase()}',
'',
@@ -147,6 +214,40 @@
}
}
+ /// Extract the message from the [expression]. If the expression is the name
+ /// of a generated code, then the [generatedResult] should have the unit in
+ /// which the message can be found.
+ String _extractMessage(
+ Expression expression, ParsedUnitResult generatedResult) {
+ if (expression is InstanceCreationExpression) {
+ return (expression.argumentList.arguments[1] as StringLiteral)
+ .stringValue;
+ } else if (expression is SimpleIdentifier && generatedResult != null) {
+ VariableDeclaration variable =
+ _findVariable(expression.name, generatedResult.unit);
+ if (variable != null) {
+ return _extractMessage(variable.initializer, null);
+ }
+ }
+ throw StateError(
+ 'Cannot extract a message from a ${expression.runtimeType}');
+ }
+
+ /// Return the declaration of the top-level variable with the [name] in the
+ /// compilation unit, or `null` if there is no such variable.
+ VariableDeclaration _findVariable(String name, CompilationUnit unit) {
+ for (CompilationUnitMember member in unit.declarations) {
+ if (member is TopLevelVariableDeclaration) {
+ for (VariableDeclaration variable in member.variables.variables) {
+ if (variable.name.name == name) {
+ return variable;
+ }
+ }
+ }
+ }
+ return null;
+ }
+
/// Use the analysis context [collection] to parse the file at the given
/// [path] and return the result.
ParsedUnitResult _parse(AnalysisContextCollection collection, String path) {
diff --git a/pkg/analyzer_cli/lib/src/analyzer_impl.dart b/pkg/analyzer_cli/lib/src/analyzer_impl.dart
index 2d88a91..c5e1bc2 100644
--- a/pkg/analyzer_cli/lib/src/analyzer_impl.dart
+++ b/pkg/analyzer_cli/lib/src/analyzer_impl.dart
@@ -11,7 +11,7 @@
import 'package:analyzer/exception/exception.dart';
import 'package:analyzer/src/dart/analysis/driver.dart';
import 'package:analyzer/src/dart/analysis/file_state.dart';
-import 'package:analyzer/src/generated/engine.dart' hide AnalysisResult;
+import 'package:analyzer/src/generated/engine.dart';
import 'package:analyzer/src/generated/source.dart';
import 'package:analyzer/src/generated/source_io.dart';
import 'package:analyzer/src/generated/utilities_general.dart';
diff --git a/pkg/analyzer_cli/lib/src/build_mode.dart b/pkg/analyzer_cli/lib/src/build_mode.dart
index be6d5f0..a4363fc 100644
--- a/pkg/analyzer_cli/lib/src/build_mode.dart
+++ b/pkg/analyzer_cli/lib/src/build_mode.dart
@@ -399,6 +399,16 @@
if (directive is PartDirective) {
var partUri = directive.uri.stringValue;
var partSource = sourceFactory.resolveUri(librarySource, partUri);
+
+ // Add empty synthetic units for unresolved `part` URIs.
+ if (partSource == null) {
+ var unit = analysisDriver.fsState.unresolvedFile.parse();
+ inputUnits.add(
+ summary2.LinkInputUnit(partUri, null, true, unit),
+ );
+ continue;
+ }
+
var partPath = partSource.fullName;
var partParseResult = inputParsedUnitResults[partPath];
if (partParseResult == null) {
diff --git a/pkg/analyzer_cli/lib/src/error_severity.dart b/pkg/analyzer_cli/lib/src/error_severity.dart
index e43d77c..198ff9a 100644
--- a/pkg/analyzer_cli/lib/src/error_severity.dart
+++ b/pkg/analyzer_cli/lib/src/error_severity.dart
@@ -5,7 +5,7 @@
import 'package:analyzer/error/error.dart';
import 'package:analyzer/source/error_processor.dart';
import 'package:analyzer/src/error/codes.dart';
-import 'package:analyzer/src/generated/engine.dart' hide AnalysisResult;
+import 'package:analyzer/src/generated/engine.dart';
import 'package:analyzer_cli/src/options.dart';
/// Compute the severity of the error; however:
diff --git a/pkg/analyzer_cli/test/driver_test.dart b/pkg/analyzer_cli/test/driver_test.dart
index 02d79d9..705be26 100644
--- a/pkg/analyzer_cli/test/driver_test.dart
+++ b/pkg/analyzer_cli/test/driver_test.dart
@@ -605,6 +605,34 @@
});
}
+ test_buildLinked_invalidPartUri() async {
+ await withTempDirAsync((tempDir) async {
+ var aDart = path.join(tempDir, 'a.dart');
+
+ var aUri = 'package:aaa/a.dart';
+
+ var aSum = path.join(tempDir, 'a.sum');
+
+ new File(aDart).writeAsStringSync('''
+part '[invalid]';
+''');
+
+ await _doDrive(aDart,
+ uri: aUri, additionalArgs: ['--build-summary-output=$aSum']);
+ expect(exitCode, ErrorSeverity.ERROR.ordinal);
+ var bytes = new File(aSum).readAsBytesSync();
+ var bundle = new PackageBundle.fromBuffer(bytes);
+ if (AnalysisDriver.useSummary2) {
+ var bundle2 = bundle.bundle2;
+ expect(_linkedLibraryUriList(bundle2), [aUri]);
+ expect(_linkedLibraryUnitUriList(bundle2, aUri), [aUri, '']);
+ } else {
+ expect(bundle.unlinkedUnitUris, equals([aUri]));
+ expect(bundle.linkedLibraryUris, equals([aUri]));
+ }
+ });
+ }
+
test_buildSuppressExitCode_fail_whenFileNotFound() async {
await _doDrive(path.join('data', 'non_existent_file.dart'),
additionalArgs: ['--build-suppress-exit-code']);
diff --git a/pkg/analyzer_plugin/lib/src/utilities/change_builder/change_builder_dart.dart b/pkg/analyzer_plugin/lib/src/utilities/change_builder/change_builder_dart.dart
index 6e1993b..d4a9061 100644
--- a/pkg/analyzer_plugin/lib/src/utilities/change_builder/change_builder_dart.dart
+++ b/pkg/analyzer_plugin/lib/src/utilities/change_builder/change_builder_dart.dart
@@ -18,7 +18,6 @@
import 'package:analyzer_plugin/protocol/protocol_common.dart'
hide Element, ElementKind;
import 'package:analyzer_plugin/src/utilities/change_builder/change_builder_core.dart';
-import 'package:analyzer_plugin/src/utilities/change_builder/dart/import_library_element.dart';
import 'package:analyzer_plugin/src/utilities/string_utilities.dart';
import 'package:analyzer_plugin/utilities/change_builder/change_builder_core.dart';
import 'package:analyzer_plugin/utilities/change_builder/change_builder_dart.dart';
@@ -26,7 +25,6 @@
import 'package:analyzer_plugin/utilities/range_factory.dart';
import 'package:charcode/ascii.dart';
import 'package:dart_style/dart_style.dart';
-import 'package:meta/meta.dart';
/**
* A [ChangeBuilder] used to build changes in Dart files.
@@ -1291,34 +1289,19 @@
}
@override
- ImportLibraryElementResult importLibraryElement({
- @required ResolvedLibraryResult targetLibrary,
- @required String targetPath,
- @required int targetOffset,
- @required LibraryElement requestedLibrary,
- @required Element requestedElement,
- }) {
- if (librariesToImport.isNotEmpty ||
- librariesToRelativelyImport.isNotEmpty) {
- throw StateError('Only one library can be safely imported.');
+ ImportLibraryElementResult importLibraryElement(Uri uri) {
+ if (resolvedUnit.libraryElement.source.uri == uri) {
+ return ImportLibraryElementResultImpl(null);
}
- var request = importLibraryElementImpl(
- targetResolvedLibrary: targetLibrary,
- targetPath: targetPath,
- targetOffset: targetOffset,
- requestedLibrary: requestedLibrary,
- requestedElement: requestedElement,
- );
-
- var prefix = request.prefix;
- if (request.uri != null) {
- var uriText = _getLibraryUriText(request.uri);
- (libraryChangeBuilder ?? this).librariesToImport[request.uri] =
- _LibraryToImport(uriText, prefix);
+ for (var import in resolvedUnit.libraryElement.imports) {
+ if (import.importedLibrary.source.uri == uri) {
+ return ImportLibraryElementResultImpl(import.prefix?.name);
+ }
}
- return ImportLibraryElementResultImpl(prefix);
+ importLibrary(uri);
+ return ImportLibraryElementResultImpl(null);
}
String importLibraryWithRelativeUri(String uriText, [String prefix = null]) {
@@ -1328,23 +1311,16 @@
@override
void replaceTypeWithFuture(
TypeAnnotation typeAnnotation, TypeProvider typeProvider) {
- InterfaceType futureType = typeProvider.futureType;
//
// Check whether the type needs to be replaced.
//
DartType type = typeAnnotation?.type;
- if (type == null ||
- type.isDynamic ||
- type is InterfaceType && type.element == futureType.element) {
+ if (type == null || type.isDynamic || type.isDartAsyncFuture) {
return;
}
- // TODO(brianwilkerson) Unconditionally execute the body of the 'if' when
- // Future<void> is fully supported.
- if (!type.isVoid) {
- futureType = futureType.instantiate(<DartType>[type]);
- }
- // prepare code for the types
+
addReplacement(range.node(typeAnnotation), (EditBuilder builder) {
+ var futureType = typeProvider.futureType2(type);
if (!(builder as DartEditBuilder).writeType(futureType)) {
builder.write('void');
}
diff --git a/pkg/analyzer_plugin/lib/src/utilities/change_builder/dart/import_library_element.dart b/pkg/analyzer_plugin/lib/src/utilities/change_builder/dart/import_library_element.dart
deleted file mode 100644
index f135dd8..0000000
--- a/pkg/analyzer_plugin/lib/src/utilities/change_builder/dart/import_library_element.dart
+++ /dev/null
@@ -1,193 +0,0 @@
-// Copyright (c) 2019, 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.
-
-import 'package:analyzer/dart/analysis/results.dart';
-import 'package:analyzer/dart/element/element.dart';
-import 'package:analyzer/dart/element/visitor.dart';
-import 'package:analyzer_plugin/src/utilities/change_builder/dart/syntactic_scope.dart';
-import 'package:meta/meta.dart';
-
-ImportLibraryRequest importLibraryElementImpl({
- @required ResolvedLibraryResult targetResolvedLibrary,
- @required String targetPath,
- @required int targetOffset,
- @required LibraryElement requestedLibrary,
- @required Element requestedElement,
-}) {
- var targetLibrary = targetResolvedLibrary.element;
-
- var requestedLibraryUri = requestedLibrary.source.uri;
- var requestedElementUri = requestedElement.librarySource.uri;
- var requestedName = requestedElement.displayName;
-
- // If the element is defined in this library, then no prefix needed.
- if (targetLibrary == requestedElement.library) {
- return ImportLibraryRequest(null, null);
- }
-
- var requestedElements = requestedLibrary.exportNamespace.definedNames;
- _removeEntriesForDynamicAndNever(requestedElements);
-
- // Find URIs of all libraries that import the requested name into the target.
- var unprefixedNameUriSet = Set<Uri>();
- for (var import in targetLibrary.imports) {
- var definedNames = import.namespace.definedNames;
- if (import.prefix == null) {
- var element = definedNames[requestedName];
- if (element != null) {
- unprefixedNameUriSet.add(element.librarySource.uri);
- }
- }
- }
-
- // Find names that will be shadowed by a new unprefixed import.
- var collector = NotSyntacticScopeReferencedNamesCollector(
- targetResolvedLibrary.element,
- requestedElements.keys.toSet(),
- );
- for (var resolvedUnit in targetResolvedLibrary.units) {
- resolvedUnit.unit.accept(collector);
- }
-
- // Find names that will shadow unprefixed references.
- var scopeNames = Set<String>();
- targetLibrary.accept(_TopLevelNamesCollector(scopeNames));
- for (var resolvedUnit in targetResolvedLibrary.units) {
- if (resolvedUnit.path == targetPath) {
- resolvedUnit.unit.accept(
- SyntacticScopeNamesCollector(scopeNames, targetOffset),
- );
- }
- }
-
- var canUseUnprefixedImport = true;
-
- // If a name is inherited, it will be shadowed by a new unprefixed import.
- if (collector.inheritedNames.isNotEmpty) {
- canUseUnprefixedImport = false;
- }
-
- // If a name is imported, and it is not the same as the one from the
- // requested library, then a new unprefixed import will cause ambiguity.
- for (var name in collector.importedNames.keys) {
- var importedUri = collector.importedNames[name];
- var requestedUri = requestedElements[name]?.librarySource?.uri;
- if (requestedUri != importedUri) {
- canUseUnprefixedImport = false;
- break;
- }
- }
-
- // If syntactic scope at the offset has the requested name, then the name
- // from an unprefixed import will be shadowed.
- if (scopeNames.contains(requestedName)) {
- canUseUnprefixedImport = false;
- }
-
- // If the requested name is ambiguous from existing unprefixed imports,
- // or is not the same element as the one from the requested library, then
- // we cannot use unprefixed import.
- if (unprefixedNameUriSet.isNotEmpty) {
- if (unprefixedNameUriSet.length > 1 ||
- unprefixedNameUriSet.first != requestedElementUri) {
- canUseUnprefixedImport = false;
- }
- }
-
- // Find import prefixes with which the name is ambiguous.
- var ambiguousWithImportPrefixes = Set<String>();
- for (var import in targetLibrary.imports) {
- var definedNames = import.namespace.definedNames;
- if (import.prefix != null) {
- var prefix = import.prefix.name;
- var prefixedName = '$prefix.$requestedName';
- var importedElement = definedNames[prefixedName];
- if (importedElement != null &&
- importedElement.librarySource.uri != requestedElementUri) {
- ambiguousWithImportPrefixes.add(prefix);
- }
- }
- }
-
- // Check for existing imports of the requested library.
- for (var import in targetLibrary.imports) {
- if (import.importedLibrary?.source?.uri == requestedLibraryUri) {
- var importedNames = import.namespace.definedNames;
- if (import.prefix == null) {
- if (canUseUnprefixedImport &&
- importedNames.containsKey(requestedName)) {
- return ImportLibraryRequest(null, null);
- }
- } else {
- var prefix = import.prefix.name;
- var prefixedName = '$prefix.$requestedName';
- if (importedNames.containsKey(prefixedName) &&
- !ambiguousWithImportPrefixes.contains(prefix)) {
- return ImportLibraryRequest(null, prefix);
- }
- }
- }
- }
-
- // If the name cannot be used without import prefix, generate one.
- String prefix;
- if (!canUseUnprefixedImport) {
- prefix = 'prefix';
- for (var index = 0;; index++) {
- prefix = 'prefix$index';
- if (!collector.referencedNames.contains(prefix)) {
- break;
- }
- }
- }
-
- return ImportLibraryRequest(requestedLibraryUri, prefix);
-}
-
-/// The types `dynamic` and `Never` are part of 'dart:core', but have no
-/// library.
-void _removeEntriesForDynamicAndNever(Map<String, Element> requestedElements) {
- requestedElements.removeWhere((_, element) {
- if (element.librarySource == null) {
- assert(
- element.displayName == 'dynamic' || element.displayName == 'Never');
- return true;
- }
- return false;
- });
-}
-
-/// Information about a library to import.
-class ImportLibraryRequest {
- /// The URI of the library to import, or `null` if the requested library is
- /// already imported, with the [prefix], so no new import is required.
- final Uri uri;
-
- /// The prefix with which ths requested library is already imported,
- /// or should be imported, or `null` is no prefix is necessary.
- final String prefix;
-
- ImportLibraryRequest(this.uri, this.prefix);
-}
-
-/// Element visitor that collects names of top-level elements.
-class _TopLevelNamesCollector extends GeneralizingElementVisitor<void> {
- final Set<String> names;
-
- _TopLevelNamesCollector(this.names);
-
- @override
- void visitElement(Element element) {
- if (element is LibraryElement || element is CompilationUnitElement) {
- super.visitElement(element);
- } else if (element is ImportElement) {
- var prefix = element.prefix?.displayName;
- if (prefix != null) {
- names.add(prefix);
- }
- } else if (element.enclosingElement is CompilationUnitElement) {
- names.add(element.displayName);
- }
- }
-}
diff --git a/pkg/analyzer_plugin/lib/src/utilities/change_builder/dart/syntactic_scope.dart b/pkg/analyzer_plugin/lib/src/utilities/change_builder/dart/syntactic_scope.dart
deleted file mode 100644
index 959d1f0..0000000
--- a/pkg/analyzer_plugin/lib/src/utilities/change_builder/dart/syntactic_scope.dart
+++ /dev/null
@@ -1,349 +0,0 @@
-// Copyright (c) 2019, 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.
-
-import 'package:analyzer/dart/ast/ast.dart';
-import 'package:analyzer/dart/ast/visitor.dart';
-import 'package:analyzer/dart/element/element.dart';
-
-/// AST visitor that collects names that are referenced, but the target element
-/// is not defined in the syntactic scope of the reference. Resolution of
-/// such names will change when the import scope of the library changes.
-class NotSyntacticScopeReferencedNamesCollector
- extends GeneralizingAstVisitor<void> {
- /// The library that contains resolved AST(s) being visited.
- final LibraryElement enclosingLibraryElement;
-
- /// The names that we need to check.
- final Set<String> interestingNames;
-
- /// All the referenced unqualified names.
- final Set<String> referencedNames = Set<String>();
-
- /// The subset of [interestingNames] that are resolved to a top-level
- /// element that is not in the syntactic scope of the reference, and the
- /// library [Uri] is the value in the mapping.
- final Map<String, Uri> importedNames = {};
-
- /// The subset of [interestingNames] that are resolved to inherited names.
- final Set<String> inheritedNames = Set<String>();
-
- Element enclosingUnitMemberElement;
-
- NotSyntacticScopeReferencedNamesCollector(
- this.enclosingLibraryElement,
- this.interestingNames,
- );
-
- @override
- void visitCombinator(Combinator node) {}
-
- @override
- void visitCompilationUnitMember(CompilationUnitMember node) {
- enclosingUnitMemberElement = node.declaredElement;
- super.visitCompilationUnitMember(node);
- enclosingUnitMemberElement = null;
- }
-
- @override
- void visitConstructorName(ConstructorName node) {
- node.type.accept(this);
- }
-
- @override
- void visitPrefixedIdentifier(PrefixedIdentifier node) {
- node.prefix.accept(this);
- }
-
- @override
- void visitSimpleIdentifier(SimpleIdentifier node) {
- var name = node.name;
- referencedNames.add(name);
-
- if (node.isQualified) return;
- if (!interestingNames.contains(name)) return;
-
- var element = node.staticElement;
- if (element == null) return;
-
- if (_inSyntacticScope(element)) return;
-
- if (element.enclosingElement is CompilationUnitElement) {
- importedNames[name] = element.librarySource.uri;
- } else {
- inheritedNames.add(name);
- }
- }
-
- bool _inSyntacticScope(Element element) {
- if (element.enclosingElement is CompilationUnitElement &&
- element.enclosingElement.enclosingElement == enclosingLibraryElement) {
- return true;
- }
-
- while (element != null) {
- if (element == enclosingUnitMemberElement) return true;
- element = element.enclosingElement;
- }
- return false;
- }
-}
-
-/// AST visitor that collects syntactic scope names visible at the [offset].
-///
-/// The AST does not need to be resolved.
-class SyntacticScopeNamesCollector extends RecursiveAstVisitor<void> {
- final Set<String> names;
- final int offset;
-
- SyntacticScopeNamesCollector(this.names, this.offset);
-
- @override
- void visitBlock(Block node) {
- if (!_isCoveredBy(node)) return;
-
- super.visitBlock(node);
-
- for (var statement in node.statements) {
- if (statement is FunctionDeclarationStatement) {
- _addName(statement.functionDeclaration.name);
- } else if (statement is VariableDeclarationStatement) {
- _addVariables(statement.variables);
- }
- }
- }
-
- @override
- void visitCatchClause(CatchClause node) {
- if (!_isCoveredBy(node)) return;
-
- if (node.exceptionParameter != null) {
- _addName(node.exceptionParameter);
- }
-
- if (node.stackTraceParameter != null) {
- _addName(node.stackTraceParameter);
- }
-
- node.body.accept(this);
- }
-
- @override
- void visitClassDeclaration(ClassDeclaration node) {
- if (!_isCoveredBy(node)) return;
-
- _addTypeParameters(node.typeParameters);
- _visitClassOrMixinMembers(node);
- }
-
- @override
- void visitClassTypeAlias(ClassTypeAlias node) {
- if (!_isCoveredBy(node)) return;
- _addTypeParameters(node.typeParameters);
- }
-
- @override
- void visitConstructorDeclaration(ConstructorDeclaration node) {
- if (!_isCoveredBy(node)) return;
-
- _addFormalParameters(node.parameters);
-
- node.body.accept(this);
- }
-
- @override
- void visitFieldDeclaration(FieldDeclaration node) {
- var variableList = node.fields;
-
- // `Foo^ Foo bar() {}` is recovered as `Foo Foo; bar() {}`, i.e. the
- // return type of `bar()` gets associated with a new variable declaration.
- if (node.semicolon.isSynthetic) {
- if (variableList.variables.length == 1) {
- var name = variableList.variables[0].name.name;
- names.remove(name);
- }
- }
-
- super.visitFieldDeclaration(node);
- }
-
- @override
- void visitForElement(ForElement node) {
- if (!_isCoveredBy(node)) return;
-
- _addForLoopParts(node.forLoopParts, node.body);
-
- super.visitForElement(node);
- }
-
- @override
- void visitForStatement(ForStatement node) {
- if (!_isCoveredBy(node)) return;
-
- _addForLoopParts(node.forLoopParts, node.body);
-
- super.visitForStatement(node);
- }
-
- @override
- void visitFunctionDeclaration(FunctionDeclaration node) {
- if (!_isCoveredBy(node)) return;
-
- var function = node.functionExpression;
- _addTypeParameters(function.typeParameters);
-
- if (function.parameters != null && offset > function.parameters.offset) {
- _addFormalParameters(function.parameters);
- }
-
- function.body.accept(this);
- }
-
- @override
- void visitFunctionTypeAlias(FunctionTypeAlias node) {
- if (!_isCoveredBy(node)) return;
-
- _addTypeParameters(node.typeParameters);
-
- if (offset > node.parameters.offset) {
- _addFormalParameters(node.parameters);
- }
- }
-
- @override
- void visitGenericFunctionType(GenericFunctionType node) {
- if (!_isCoveredBy(node)) return;
-
- _addTypeParameters(node.typeParameters);
-
- if (offset > node.parameters.offset) {
- _addFormalParameters(node.parameters);
- }
- }
-
- @override
- void visitGenericTypeAlias(GenericTypeAlias node) {
- if (!_isCoveredBy(node)) return;
-
- _addTypeParameters(node.typeParameters);
-
- node.functionType.accept(this);
- }
-
- @override
- void visitMethodDeclaration(MethodDeclaration node) {
- if (!_isCoveredBy(node)) return;
-
- _addTypeParameters(node.typeParameters);
-
- if (node.parameters != null && offset > node.parameters.offset) {
- _addFormalParameters(node.parameters);
- }
-
- node.body.accept(this);
- }
-
- @override
- void visitMixinDeclaration(MixinDeclaration node) {
- if (!_isCoveredBy(node)) return;
-
- _addTypeParameters(node.typeParameters);
- _visitClassOrMixinMembers(node);
- }
-
- @override
- void visitTopLevelVariableDeclaration(TopLevelVariableDeclaration node) {
- // `TypeName^` is recovered as `<noType> TypeName;`, remove the name.
- var variableList = node.variables;
- if (variableList.keyword == null && variableList.type == null) {
- for (var variable in variableList.variables) {
- names.remove(variable.name.name);
- }
- return;
- }
-
- // `Foo^ Foo bar() {}` is recovered as `Foo Foo; bar() {}`, i.e. the
- // return type of `bar()` gets associated with a new variable declaration.
- if (node.semicolon.isSynthetic) {
- if (variableList.variables.length == 1) {
- var name = variableList.variables[0].name.name;
- names.remove(name);
- }
- }
-
- super.visitTopLevelVariableDeclaration(node);
- }
-
- void _addForLoopParts(ForLoopParts forLoopParts, AstNode body) {
- if (forLoopParts is ForEachPartsWithDeclaration) {
- if (_isCoveredBy(body)) {
- _addName(forLoopParts.loopVariable.identifier);
- }
- } else if (forLoopParts is ForPartsWithDeclarations) {
- _addVariables(forLoopParts.variables);
- }
- }
-
- void _addFormalParameter(FormalParameter parameter) {
- if (parameter is DefaultFormalParameter) {
- _addFormalParameter(parameter.parameter);
- } else if (parameter is FieldFormalParameter) {
- _addName(parameter.identifier);
- } else if (parameter is FunctionTypedFormalParameter) {
- _addName(parameter.identifier);
- var parameters = parameter.parameters;
- if (parameters != null && _isCoveredBy(parameters)) {
- _addFormalParameters(parameters);
- }
- } else if (parameter is SimpleFormalParameter) {
- _addName(parameter.identifier);
- } else {
- throw UnimplementedError('(${parameter.runtimeType}) $parameter');
- }
- }
-
- void _addFormalParameters(FormalParameterList parameterList) {
- for (var parameter in parameterList.parameters) {
- _addFormalParameter(parameter);
- }
- }
-
- void _addName(SimpleIdentifier node) {
- if (node == null) return;
- if (node.offset <= offset && offset <= node.end) return;
-
- names.add(node.name);
- }
-
- void _addTypeParameters(TypeParameterList typeParameterList) {
- if (typeParameterList == null) return;
-
- for (var typeParameter in typeParameterList.typeParameters) {
- _addName(typeParameter.name);
- }
- }
-
- void _addVariables(VariableDeclarationList variableList) {
- for (var field in variableList.variables) {
- _addName(field.name);
- }
- }
-
- bool _isCoveredBy(AstNode node) {
- return node.offset < offset && offset < node.end;
- }
-
- void _visitClassOrMixinMembers(ClassOrMixinDeclaration node) {
- if (offset < node.leftBracket.offset) return;
-
- for (var member in node.members) {
- if (member is FieldDeclaration) {
- _addVariables(member.fields);
- } else if (member is MethodDeclaration) {
- _addName(member.name);
- }
- }
-
- node.members.accept(this);
- }
-}
diff --git a/pkg/analyzer_plugin/lib/src/utilities/visitors/local_declaration_visitor.dart b/pkg/analyzer_plugin/lib/src/utilities/visitors/local_declaration_visitor.dart
index 87c832c..d0a3556 100644
--- a/pkg/analyzer_plugin/lib/src/utilities/visitors/local_declaration_visitor.dart
+++ b/pkg/analyzer_plugin/lib/src/utilities/visitors/local_declaration_visitor.dart
@@ -29,6 +29,8 @@
void declaredEnum(EnumDeclaration declaration) {}
+ void declaredExtension(ExtensionDeclaration declaration);
+
void declaredField(FieldDeclaration fieldDecl, VariableDeclaration varDecl);
void declaredFunction(FunctionDeclaration declaration);
@@ -107,6 +109,9 @@
_visitTypeParameters(declaration, declaration.typeParameters);
} else if (declaration is EnumDeclaration) {
declaredEnum(declaration);
+ } else if (declaration is ExtensionDeclaration) {
+ declaredExtension(declaration);
+ _visitTypeParameters(declaration, declaration.typeParameters);
} else if (declaration is FunctionDeclaration) {
declaredFunction(declaration);
_visitTypeParameters(
diff --git a/pkg/analyzer_plugin/lib/utilities/change_builder/change_builder_dart.dart b/pkg/analyzer_plugin/lib/utilities/change_builder/change_builder_dart.dart
index 7780d46..2df3107 100644
--- a/pkg/analyzer_plugin/lib/utilities/change_builder/change_builder_dart.dart
+++ b/pkg/analyzer_plugin/lib/utilities/change_builder/change_builder_dart.dart
@@ -4,7 +4,6 @@
import 'dart:async';
-import 'package:analyzer/dart/analysis/results.dart';
import 'package:analyzer/dart/analysis/session.dart';
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/element/element.dart';
@@ -13,7 +12,6 @@
import 'package:analyzer/src/generated/source.dart';
import 'package:analyzer_plugin/src/utilities/change_builder/change_builder_dart.dart';
import 'package:analyzer_plugin/utilities/change_builder/change_builder_core.dart';
-import 'package:meta/meta.dart';
/**
* The optional generator for prefix that should be used for new imports.
@@ -383,32 +381,14 @@
String importLibrary(Uri uri);
/**
- * Ensure that the [requestedLibrary] is imported into the [targetLibrary],
- * and the top-level [requestedName] is accessible at the [targetOffset] of
- * the file with the [targetPath].
+ * Ensure that the library with the given [uri] is imported.
*
- * Parameters [targetPath] and [targetOffset] are used to determine if the
- * unprefixed reference to the [requestedName] will be shadowed by a local
- * declaration in the target syntactic scope.
+ * If there is already an import for the requested library, return the import
+ * prefix of the existing import directive.
*
- * If there is already an import for the [requestedLibrary], and the
- * [requestedName] refers to the same element in the namespace of the import
- * directive, and the name of the element is not ambiguous in existing import
- * directives, and the name does not conflict with existing declarations and
- * references, return the import prefix of the existing import directive.
- *
- * If there is no existing import, or there is a conflict, a new import is
- * added, possibly with an import prefix.
- *
- * This method can be used only alone, and only once.
+ * If there is no existing import, a new import is added.
*/
- ImportLibraryElementResult importLibraryElement({
- @required ResolvedLibraryResult targetLibrary,
- @required String targetPath,
- @required int targetOffset,
- @required LibraryElement requestedLibrary,
- @required Element requestedElement,
- });
+ ImportLibraryElementResult importLibraryElement(Uri uri);
/**
* Optionally create an edit to replace the given [typeAnnotation] with the
diff --git a/pkg/analyzer_plugin/lib/utilities/completion/type_member_contributor.dart b/pkg/analyzer_plugin/lib/utilities/completion/type_member_contributor.dart
index dd4a046..eb6ee1c 100644
--- a/pkg/analyzer_plugin/lib/utilities/completion/type_member_contributor.dart
+++ b/pkg/analyzer_plugin/lib/utilities/completion/type_member_contributor.dart
@@ -211,6 +211,9 @@
}
@override
+ void declaredExtension(ExtensionDeclaration declaration) {}
+
+ @override
void declaredField(FieldDeclaration fieldDecl, VariableDeclaration varDecl) {
if (varDecl.name.name == targetName) {
// Type provided by the element in computeFull above
diff --git a/pkg/analyzer_plugin/lib/utilities/range_factory.dart b/pkg/analyzer_plugin/lib/utilities/range_factory.dart
index f41003d..1f58ec2 100644
--- a/pkg/analyzer_plugin/lib/utilities/range_factory.dart
+++ b/pkg/analyzer_plugin/lib/utilities/range_factory.dart
@@ -70,6 +70,24 @@
}
/**
+ * Return a source range that covers the given [item] (including a leading or
+ * trailing comma as appropriate) in the containing [list].
+ */
+ SourceRange nodeInList<T extends AstNode>(NodeList<T> list, T item) {
+ if (list.length == 1) {
+ return node(item);
+ }
+ final index = list.indexOf(item);
+ // Remove trailing comma.
+ if (index == 0) {
+ return startStart(item, list[1]);
+ } else {
+ // Remove leading comma.
+ return endEnd(list[index - 1], item);
+ }
+ }
+
+ /**
* Return a source range that covers all of the given [nodes] (that is, from
* the start of the first node to the end of the last node.
*/
diff --git a/pkg/analyzer_plugin/test/src/utilities/change_builder/change_builder_dart_test.dart b/pkg/analyzer_plugin/test/src/utilities/change_builder/change_builder_dart_test.dart
index a0bfa57..5b4985f 100644
--- a/pkg/analyzer_plugin/test/src/utilities/change_builder/change_builder_dart_test.dart
+++ b/pkg/analyzer_plugin/test/src/utilities/change_builder/change_builder_dart_test.dart
@@ -7,6 +7,7 @@
import 'package:analyzer/dart/analysis/results.dart';
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/dart/element/nullability_suffix.dart';
import 'package:analyzer/dart/element/type.dart';
import 'package:analyzer/src/dart/analysis/driver.dart';
import 'package:analyzer/src/dart/element/inheritance_manager3.dart';
@@ -685,10 +686,16 @@
DartChangeBuilderImpl builder = newBuilder();
await builder.addFileEdit(path, (FileEditBuilder builder) {
builder.addInsertion(11, (EditBuilder builder) {
- (builder as DartEditBuilder).writeLocalVariableDeclaration('foo',
- initializerWriter: () {
- builder.write('null');
- }, type: A.declaredElement.type);
+ (builder as DartEditBuilder).writeLocalVariableDeclaration(
+ 'foo',
+ initializerWriter: () {
+ builder.write('null');
+ },
+ type: A.declaredElement.instantiate(
+ typeArguments: [],
+ nullabilitySuffix: NullabilitySuffix.star,
+ ),
+ );
});
});
SourceEdit edit = getEdit(builder);
@@ -710,8 +717,14 @@
DartChangeBuilderImpl builder = newBuilder();
await builder.addFileEdit(path, (FileEditBuilder builder) {
builder.addInsertion(11, (EditBuilder builder) {
- (builder as DartEditBuilder).writeLocalVariableDeclaration('foo',
- type: A.declaredElement.type, typeGroupName: 'type');
+ (builder as DartEditBuilder).writeLocalVariableDeclaration(
+ 'foo',
+ type: A.declaredElement.instantiate(
+ typeArguments: [],
+ nullabilitySuffix: NullabilitySuffix.star,
+ ),
+ typeGroupName: 'type',
+ );
});
});
SourceEdit edit = getEdit(builder);
@@ -740,8 +753,15 @@
DartChangeBuilderImpl builder = newBuilder();
await builder.addFileEdit(path, (FileEditBuilder builder) {
builder.addInsertion(11, (EditBuilder builder) {
- (builder as DartEditBuilder).writeLocalVariableDeclaration('foo',
- isFinal: true, type: A.declaredElement.type, typeGroupName: 'type');
+ (builder as DartEditBuilder).writeLocalVariableDeclaration(
+ 'foo',
+ isFinal: true,
+ type: A.declaredElement.instantiate(
+ typeArguments: [],
+ nullabilitySuffix: NullabilitySuffix.star,
+ ),
+ typeGroupName: 'type',
+ );
});
});
SourceEdit edit = getEdit(builder);
@@ -1245,12 +1265,12 @@
String content = 'class A {} class B<E> {}';
addSource(path, content);
InterfaceType typeA = await _getType(path, 'A');
- InterfaceType typeB = await _getType(path, 'B');
+ InterfaceType typeBofA = await _getType(path, 'B', typeArguments: [typeA]);
DartChangeBuilderImpl builder = newBuilder();
await builder.addFileEdit(path, (FileEditBuilder builder) {
builder.addInsertion(content.length - 1, (EditBuilder builder) {
- (builder as DartEditBuilder).writeType(typeB.instantiate([typeA]));
+ (builder as DartEditBuilder).writeType(typeBofA);
});
});
SourceEdit edit = getEdit(builder);
@@ -1317,8 +1337,10 @@
String content = 'class A<T> {}';
addSource(path, content);
- InterfaceType typeA = await _getType(path, 'A');
- DartType typeT = typeA.typeParameters.single.type;
+ var classA = await _getClassElement(path, 'A');
+ DartType typeT = classA.typeParameters.single.instantiate(
+ nullabilitySuffix: NullabilitySuffix.star,
+ );
var builder = newBuilder();
await builder.addFileEdit(path, (builder) {
@@ -1382,13 +1404,22 @@
var builder = newBuilder();
await builder.addFileEdit(path, (builder) {
builder.addInsertion(content.length - 1, (builder) {
- builder.writeType(a1.type);
+ builder.writeType(a1.instantiate(
+ typeArguments: [],
+ nullabilitySuffix: NullabilitySuffix.star,
+ ));
builder.write(' a1; ');
- builder.writeType(a2.type);
+ builder.writeType(a2.instantiate(
+ typeArguments: [],
+ nullabilitySuffix: NullabilitySuffix.star,
+ ));
builder.write(' a2; ');
- builder.writeType(b.type);
+ builder.writeType(b.instantiate(
+ typeArguments: [],
+ nullabilitySuffix: NullabilitySuffix.star,
+ ));
builder.write(' b;');
});
}, importPrefixGenerator: prefixGenerator);
@@ -1571,9 +1602,16 @@
return result.element.accessors.firstWhere((v) => v.name == name);
}
- Future<InterfaceType> _getType(String path, String name) async {
+ Future<InterfaceType> _getType(
+ String path,
+ String name, {
+ List<DartType> typeArguments = const [],
+ }) async {
ClassElement classElement = await _getClassElement(path, name);
- return classElement.type;
+ return classElement.instantiate(
+ typeArguments: typeArguments,
+ nullabilitySuffix: NullabilitySuffix.star,
+ );
}
}
@@ -1760,7 +1798,12 @@
CompilationUnit unit = (await driver.getResult(path))?.unit;
ClassDeclaration classC = unit.declarations[2] as ClassDeclaration;
DartLinkedEditBuilderImpl builder = new DartLinkedEditBuilderImpl(null);
- builder.addSuperTypesAsSuggestions(classC.declaredElement.type);
+ builder.addSuperTypesAsSuggestions(
+ classC.declaredElement.instantiate(
+ typeArguments: [],
+ nullabilitySuffix: NullabilitySuffix.star,
+ ),
+ );
List<LinkedEditSuggestion> suggestions = builder.suggestions;
expect(suggestions, hasLength(4));
expect(suggestions.map((s) => s.value),
@@ -2785,9 +2828,16 @@
}
}
+ var targetType = targetElement.instantiate(
+ typeArguments: targetElement.typeParameters
+ .map((e) => e.instantiate(nullabilitySuffix: NullabilitySuffix.star))
+ .toList(),
+ nullabilitySuffix: NullabilitySuffix.star,
+ );
+
TypeSystem typeSystem = await session.typeSystem;
var inherited = new InheritanceManager3(typeSystem).getInherited(
- targetElement.type,
+ targetType,
new Name(null, nameToOverride),
);
diff --git a/pkg/analyzer_plugin/test/src/utilities/change_builder/dart/import_library_element_test.dart b/pkg/analyzer_plugin/test/src/utilities/change_builder/dart/import_library_element_test.dart
index 51b5c38..fbf1131 100644
--- a/pkg/analyzer_plugin/test/src/utilities/change_builder/dart/import_library_element_test.dart
+++ b/pkg/analyzer_plugin/test/src/utilities/change_builder/dart/import_library_element_test.dart
@@ -16,9 +16,7 @@
defineReflectiveSuite(() {
defineReflectiveTests(ImportLibraryElementTest);
defineReflectiveTests(ImportLibraryElement_existingImport_Test);
- defineReflectiveTests(ImportLibraryElement_incompleteCode_Test);
defineReflectiveTests(ImportLibraryElement_newImport_withoutPrefix_Test);
- defineReflectiveTests(ImportLibraryElement_newImport_withPrefix_Test);
});
}
@@ -160,124 +158,6 @@
}
@reflectiveTest
-class ImportLibraryElement_incompleteCode_Test extends _Base {
- test_fieldDeclaration_atEnd() async {
- newFile('/home/test/lib/a.dart', content: 'class A {}');
- await _assertImportLibraryElement(
- initialCode: r'''
-class C {
- A^
-}
-''',
- uriStr: 'package:test/a.dart',
- name: 'A',
- expectedCode: r'''
-import 'package:test/a.dart';
-
-class C {
- A
-}
-''',
- );
- }
-
- test_fieldDeclaration_beforeReturnType() async {
- newFile('/home/test/lib/a.dart', content: 'class A {}');
- await _assertImportLibraryElement(
- initialCode: r'''
-class C {
- A^
-
- A foo() => null;
-}
-''',
- uriStr: 'package:test/a.dart',
- name: 'A',
- expectedCode: r'''
-import 'package:test/a.dart';
-
-class C {
- A
-
- A foo() => null;
-}
-''',
- );
- }
-
- test_formalParameter_end() async {
- newFile('/home/test/lib/a.dart', content: 'class AAA {}');
- await _assertImportLibraryElement(
- initialCode: r'''
-f(AAA^) {}
-''',
- uriStr: 'package:test/a.dart',
- name: 'AAA',
- expectedCode: r'''
-import 'package:test/a.dart';
-
-f(AAA) {}
-''',
- );
- }
-
- test_formalParameter_start() async {
- newFile('/home/test/lib/a.dart', content: 'class AAA {}');
- await _assertImportLibraryElement(
- initialCode: r'''
-f(^AAA) {}
-''',
- uriStr: 'package:test/a.dart',
- name: 'AAA',
- expectedCode: r'''
-import 'package:test/a.dart';
-
-f(AAA) {}
-''',
- );
- }
-
- test_topLevelVariable_atEnd() async {
- newFile('/home/test/lib/a.dart', content: 'class A {}');
- newFile('/home/test/lib/b.dart', content: r'''
-export 'a.dart';
-''');
- await _assertImportLibraryElement(
- initialCode: r'''
-A^
-''',
- uriStr: 'package:test/a.dart',
- name: 'A',
- expectedCode: r'''
-import 'package:test/a.dart';
-
-A
-''',
- );
- }
-
- test_topLevelVariable_beforeReturnType() async {
- newFile('/home/test/lib/a.dart', content: 'class A {}');
- await _assertImportLibraryElement(
- initialCode: r'''
-A^
-
-A foo() => null;
-''',
- uriStr: 'package:test/a.dart',
- name: 'A',
- expectedCode: r'''
-import 'package:test/a.dart';
-
-A
-
-A foo() => null;
-''',
- );
- }
-}
-
-@reflectiveTest
class ImportLibraryElement_newImport_withoutPrefix_Test extends _Base {
test_constructorName_name() async {
newFile('/home/test/lib/a.dart', content: r'''
@@ -540,369 +420,6 @@
}
@reflectiveTest
-class ImportLibraryElement_newImport_withPrefix_Test extends _Base {
- test_existingImport_nameIsAmbiguous() async {
- newFile('/home/test/lib/a.dart', content: 'class C {}');
- newFile('/home/test/lib/b.dart', content: 'class C {}');
- await _assertImportLibraryElement(
- initialCode: r'''
-import 'package:test/a.dart';
-import 'package:test/b.dart';
-''',
- uriStr: 'package:test/b.dart',
- name: 'C',
- expectedPrefix: 'prefix0',
- expectedCode: r'''
-import 'package:test/a.dart';
-import 'package:test/b.dart';
-import 'package:test/b.dart' as prefix0;
-''',
- );
- }
-
- test_existingImport_nameIsAmbiguous_prefixed() async {
- newFile('/home/test/lib/a.dart', content: 'class C {}');
- newFile('/home/test/lib/b.dart', content: 'class C {}');
- await _assertImportLibraryElement(
- initialCode: r'''
-import 'package:test/a.dart' as p;
-import 'package:test/b.dart' as p;
-''',
- uriStr: 'package:test/b.dart',
- name: 'C',
- expectedCode: r'''
-import 'package:test/a.dart' as p;
-import 'package:test/b.dart' as p;
-import 'package:test/b.dart';
-''',
- );
- }
-
- test_nameIsAmbiguous() async {
- newFile('/home/test/lib/a.dart', content: 'class C {}');
- newFile('/home/test/lib/b.dart', content: 'class C {}');
- await _assertImportLibraryElement(
- initialCode: r'''
-import 'package:test/a.dart';
-''',
- uriStr: 'package:test/b.dart',
- name: 'C',
- expectedPrefix: 'prefix0',
- expectedCode: r'''
-import 'package:test/a.dart';
-import 'package:test/b.dart' as prefix0;
-''',
- );
- }
-
- test_shadow_otherName_imported() async {
- newFile('/home/test/lib/a.dart', content: r'''
-class A {}
-''');
- newFile('/home/test/lib/b.dart', content: r'''
-class A {}
-class B {}
-''');
- await _assertImportLibraryElement(
- initialCode: r'''
-import 'package:test/a.dart';
-
-A a;
-''',
- uriStr: 'package:test/b.dart',
- name: 'B',
- expectedPrefix: 'prefix0',
- expectedCode: r'''
-import 'package:test/a.dart';
-import 'package:test/b.dart' as prefix0;
-
-A a;
-''',
- );
- }
-
- test_shadow_otherName_inherited() async {
- newFile('/home/test/lib/b.dart', content: '''
-int foo = 0;
-int bar = 0;
-''');
- await _assertImportLibraryElement(
- initialCode: r'''
-class A {
- void bar() {}
-}
-
-class X extends A {
- voif f() {
- bar();
- }
-}
-''',
- uriStr: 'package:test/b.dart',
- name: 'foo',
- expectedPrefix: 'prefix0',
- expectedCode: r'''
-import 'package:test/b.dart' as prefix0;
-
-class A {
- void bar() {}
-}
-
-class X extends A {
- voif f() {
- bar();
- }
-}
-''',
- );
- }
-
- test_shadowed_class() async {
- newFile('/home/test/lib/a.dart', content: 'class C {}');
- await _assertImportLibraryElement(
- initialCode: r'''
-import 'package:test/a.dart';
-
-class C {}
-''',
- uriStr: 'package:test/a.dart',
- name: 'C',
- expectedPrefix: 'prefix0',
- expectedCode: r'''
-import 'package:test/a.dart';
-import 'package:test/a.dart' as prefix0;
-
-class C {}
-''',
- );
- }
-
- test_shadowed_class_inPart() async {
- newFile('/home/test/lib/a.dart', content: 'class C {}');
- newFile('/home/test/lib/p.dart', content: 'class C {}');
- await _assertImportLibraryElement(
- initialCode: r'''
-part 'p.dart';
-''',
- uriStr: 'package:test/a.dart',
- name: 'C',
- expectedPrefix: 'prefix0',
- expectedCode: r'''
-import 'package:test/a.dart' as prefix0;
-
-part 'p.dart';
-''',
- );
- }
-
- test_shadowed_formalParameter() async {
- newFile('/home/test/lib/a.dart', content: r'''
-var foo = 0;
-''');
- await _assertImportLibraryElement(
- initialCode: r'''
-void f(int foo) {^}
-''',
- uriStr: 'package:test/a.dart',
- name: 'foo',
- expectedPrefix: 'prefix0',
- expectedCode: r'''
-import 'package:test/a.dart' as prefix0;
-
-void f(int foo) {}
-''',
- );
- }
-
- test_shadowed_function() async {
- newFile('/home/test/lib/a.dart', content: r'''
-var foo = 0;
-''');
- await _assertImportLibraryElement(
- initialCode: r'''
-void foo() {^}
-''',
- uriStr: 'package:test/a.dart',
- name: 'foo',
- expectedPrefix: 'prefix0',
- expectedCode: r'''
-import 'package:test/a.dart' as prefix0;
-
-void foo() {}
-''',
- );
- }
-
- test_shadowed_function_local_after() async {
- newFile('/home/test/lib/a.dart', content: r'''
-var foo = 0;
-''');
- await _assertImportLibraryElement(
- initialCode: r'''
-void f() {
- void foo() {}
-^}
-''',
- uriStr: 'package:test/a.dart',
- name: 'foo',
- expectedPrefix: 'prefix0',
- expectedCode: r'''
-import 'package:test/a.dart' as prefix0;
-
-void f() {
- void foo() {}
-}
-''',
- );
- }
-
- test_shadowed_function_local_before() async {
- newFile('/home/test/lib/a.dart', content: r'''
-var foo = 0;
-''');
- await _assertImportLibraryElement(
- initialCode: r'''
-void f() {^
- void foo() {}
-}
-''',
- uriStr: 'package:test/a.dart',
- name: 'foo',
- expectedPrefix: 'prefix0',
- expectedCode: r'''
-import 'package:test/a.dart' as prefix0;
-
-void f() {
- void foo() {}
-}
-''',
- );
- }
-
- test_shadowed_importPrefix() async {
- newFile('/home/test/lib/a.dart', content: 'int foo = 0;');
- await _assertImportLibraryElement(
- initialCode: r'''
-import 'dart:math' as foo;
-''',
- uriStr: 'package:test/a.dart',
- name: 'foo',
- expectedPrefix: 'prefix0',
- expectedCode: r'''
-import 'dart:math' as foo;
-
-import 'package:test/a.dart' as prefix0;
-''',
- );
- }
-
- test_shadowed_localVariable_after() async {
- newFile('/home/test/lib/a.dart', content: 'int foo = 0;');
- await _assertImportLibraryElement(
- initialCode: r'''
-main() {
- var foo = '';
-^}
-''',
- uriStr: 'package:test/a.dart',
- name: 'foo',
- expectedPrefix: 'prefix0',
- expectedCode: r'''
-import 'package:test/a.dart' as prefix0;
-
-main() {
- var foo = '';
-}
-''',
- );
- }
-
- test_shadowed_localVariable_before() async {
- newFile('/home/test/lib/a.dart', content: 'int foo = 0;');
- await _assertImportLibraryElement(
- initialCode: r'''
-main() {^
- var foo = '';
-}
-''',
- uriStr: 'package:test/a.dart',
- name: 'foo',
- expectedPrefix: 'prefix0',
- expectedCode: r'''
-import 'package:test/a.dart' as prefix0;
-
-main() {
- var foo = '';
-}
-''',
- );
- }
-
- test_shadowed_method() async {
- newFile('/home/test/lib/a.dart', content: 'int foo = 0;');
- await _assertImportLibraryElement(
- initialCode: r'''
-class A {
- void foo() {}
-
- void bar() {^}
-}
-''',
- uriStr: 'package:test/a.dart',
- name: 'foo',
- expectedPrefix: 'prefix0',
- expectedCode: r'''
-import 'package:test/a.dart' as prefix0;
-
-class A {
- void foo() {}
-
- void bar() {}
-}
-''',
- );
- }
-
- test_shadowed_typeParameter_class() async {
- newFile('/home/test/lib/a.dart', content: r'''
-class A {}
-''');
- await _assertImportLibraryElement(
- initialCode: r'''
-class C<A> {^}
-''',
- uriStr: 'package:test/a.dart',
- name: 'A',
- expectedPrefix: 'prefix0',
- expectedCode: r'''
-import 'package:test/a.dart' as prefix0;
-
-class C<A> {}
-''',
- );
- }
-
- test_shadowed_typeParameter_function() async {
- newFile('/home/test/lib/a.dart', content: r'''
-class A {}
-''');
- await _assertImportLibraryElement(
- initialCode: r'''
-void f<A>() {^}
-''',
- uriStr: 'package:test/a.dart',
- name: 'A',
- expectedPrefix: 'prefix0',
- expectedCode: r'''
-import 'package:test/a.dart' as prefix0;
-
-void f<A>() {}
-''',
- );
- }
-}
-
-@reflectiveTest
class ImportLibraryElementTest extends _Base {
test_thisLibrary() async {
await _assertImportLibraryElement(
@@ -939,21 +456,14 @@
var path = convertPath('/home/test/lib/test.dart');
newFile(path, content: initialCode);
- var resolvedLibrary = await session.getResolvedLibrary(path);
var requestedLibrary = await session.getLibraryByUri(uriStr);
-
var requestedElement = requestedLibrary.exportNamespace.get(name);
expect(requestedElement, isNotNull, reason: '`$name` in $uriStr');
var builder = newBuilder();
await builder.addFileEdit(path, (builder) {
- var result = builder.importLibraryElement(
- targetLibrary: resolvedLibrary,
- targetPath: path,
- targetOffset: offset,
- requestedLibrary: requestedLibrary,
- requestedElement: requestedElement,
- );
+ var uri = Uri.parse(uriStr);
+ var result = builder.importLibraryElement(uri);
expect(result.prefix, expectedPrefix);
});
diff --git a/pkg/analyzer_plugin/test/src/utilities/change_builder/dart/syntactic_scope_test.dart b/pkg/analyzer_plugin/test/src/utilities/change_builder/dart/syntactic_scope_test.dart
deleted file mode 100644
index 1a39dee..0000000
--- a/pkg/analyzer_plugin/test/src/utilities/change_builder/dart/syntactic_scope_test.dart
+++ /dev/null
@@ -1,689 +0,0 @@
-// Copyright (c) 2019, 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.
-
-import 'package:analyzer/src/dart/analysis/experiments.dart';
-import 'package:analyzer_plugin/src/utilities/change_builder/dart/syntactic_scope.dart';
-import 'package:test/test.dart';
-import 'package:test_reflective_loader/test_reflective_loader.dart';
-
-import '../../../../support/abstract_context.dart';
-
-main() {
- defineReflectiveSuite(() {
- defineReflectiveTests(NotSyntacticScopeReferencedNamesCollectorTest);
- defineReflectiveTests(SyntacticScopeNamesCollectorTest);
- });
-}
-
-@reflectiveTest
-class NotSyntacticScopeReferencedNamesCollectorTest
- extends AbstractContextTest {
- test_notSyntacticScopeNames() async {
- var path = convertPath('/home/test/lib/test.dart');
-
- newFile('/home/test/lib/a.dart', content: r'''
-var N1;
-''');
-
- newFile(path, content: r'''
-import 'package:test/a.dart';
-
-class A {
- var N2;
-
- void N3() {}
-
- get N4 => null;
-
- set N5(_) {}
-}
-
-var S1;
-
-class B<S2> extends A {
- var S3;
-
- void S4() {}
-
- get S5 => null;
-
- set S6(_) {}
-
- void f<S7>(S8) {
- var S9;
- N1;
- N1 = 0;
- N2;
- N3;
- N4;
- N5 = 0;
- B;
- S1;
- S1 = 0;
- S2;
- S3;
- S4;
- S5;
- S6 = 0;
- S7;
- S8;
- S9;
- }
-}
-''');
-
- var resolvedUnit = await session.getResolvedUnit(path);
- var collector = NotSyntacticScopeReferencedNamesCollector(
- resolvedUnit.libraryElement,
- (<String>[]
- ..addAll(List.generate(20, (i) => 'N$i'))
- ..addAll(List.generate(20, (i) => 'S$i')))
- .toSet(),
- );
- resolvedUnit.unit.accept(collector);
-
- expect(
- collector.importedNames,
- containsPair('N1', Uri.parse('package:test/a.dart')),
- );
-
- expect(
- collector.inheritedNames,
- unorderedEquals(['N2', 'N3', 'N4', 'N5']),
- );
- }
-
- test_notSyntacticScopeNames_constructorName_name() async {
- var path = convertPath('/home/test/lib/test.dart');
-
- newFile('/home/test/lib/a.dart', content: r'''
-class N1 {
- N1.N2();
-}
-''');
-
- newFile(path, content: r'''
-import 'package:test/a.dart';
-
-void f() {
- N1.N2();
-}
-''');
-
- var resolvedUnit = await session.getResolvedUnit(path);
- var collector = NotSyntacticScopeReferencedNamesCollector(
- resolvedUnit.libraryElement,
- ['N1', 'N2'].toSet(),
- );
- resolvedUnit.unit.accept(collector);
-
- expect(
- collector.importedNames,
- containsPair('N1', Uri.parse('package:test/a.dart')),
- );
-
- expect(collector.inheritedNames, isEmpty);
- }
-
- test_referencedNames() async {
- var path = convertPath('/home/test/lib/test.dart');
- newFile(path, content: r'''
-class N1 {}
-
-N2 N3<N4>(N5 N6, N7) {
- N7.N8(N9);
-}
-''');
-
- var resolvedUnit = await session.getResolvedUnit(path);
- var collector = NotSyntacticScopeReferencedNamesCollector(
- resolvedUnit.libraryElement,
- <String>[].toSet(),
- );
- resolvedUnit.unit.accept(collector);
-
- expect(
- collector.referencedNames,
- unorderedEquals(['N1', 'N2', 'N3', 'N4', 'N5', 'N6', 'N7', 'N8', 'N9']),
- );
- }
-}
-
-@reflectiveTest
-class SyntacticScopeNamesCollectorTest extends AbstractContextTest {
- test_Block() {
- _assertScopeNames(code: r'''
-N1() {
- ^1
- N2 N3, N4;
- ^2
- {
- ^3
- var N5;
- ^4
- }
- ^5
- var N6;
- ^6
- {
- ^7
- var N7;
- ^8
- }
- ^9
-}
-''', expected: r'''
-1: N3, N4, N6
-2: N3, N4, N6
-3: N3, N4, N5, N6
-4: N3, N4, N5, N6
-5: N3, N4, N6
-6: N3, N4, N6
-7: N3, N4, N6, N7
-8: N3, N4, N6, N7
-9: N3, N4, N6
-''');
- }
-
- test_CatchClause() {
- _assertScopeNames(code: r'''
-N1() {
- ^1
- try {
- var N2;
- ^2
- } on N3 catch (N4, N5) {
- ^3
- } catch (N6) {
- ^4
- }
- ^5
-}
-''', expected: r'''
-1: {}
-2: N2
-3: N4, N5
-4: N6
-5: {}
-''');
- }
-
- test_ClassDeclaration() {
- _assertScopeNames(code: r'''
-class N1<N2 ^1> extends ^2 N3<N4 ^3> with ^4 N5, N6 implements ^5 N7, N8 {
- ^6
- N9 N10, N11;
-
- N1.N12() {}
-
- N13 N14<N15>() {}
-
- ^7
-}
-
-class N16<N17> {
- ^8
-}
-''', expected: r'''
-1: N2
-2: N2
-3: N2
-4: N2
-5: N2
-6: N2, N10, N11, N14
-7: N2, N10, N11, N14
-8: N17
-''');
- }
-
- test_ClassTypeAlias() {
- _assertScopeNames(code: r'''
-class N1<N2 ^1> = N3<N4 ^2> with N5<N6 ^3> implements N7;
-''', expected: r'''
-1: N2
-2: N2
-3: N2
-''');
- }
-
- test_CollectionForElement_ForEachPartsWithDeclaration() {
- _enableExperiments();
- _assertScopeNames(code: r'''
-N1() {
- [
- 0 ^1,
- for (var N2 in N3 ^2) {
- ^3
- },
- ^4
- for (var N4 in N5) {
- ^5
- },
- ^6
- ];
- ^7
-}
-''', expected: r'''
-1: {}
-2: {}
-3: N2
-4: {}
-5: N4
-6: {}
-7: {}
-''');
- }
-
- test_CollectionForElement_ForPartsWithDeclarations() {
- _enableExperiments();
- _assertScopeNames(code: r'''
-N1() {
- [
- 0 ^1,
- for (var N2 = 0 ^2; ^3; ^4) {
- ^5
- },
- ^6
- for (var N3 = 0 ^7; ^8; ^9) {
- ^10
- },
- ^11
- ];
- ^12
-}
-''', expected: r'''
-1: {}
-2: N2
-3: N2
-4: N2
-5: N2
-6: {}
-7: N3
-8: N3
-9: N3
-10: N3
-11: {}
-12: {}
-''');
- }
-
- test_ConstructorDeclaration() {
- _assertScopeNames(code: r'''
-class N1<N2> extends N3 {
- N1.N4(N5, this.N6, ^1) {
- ^2
- }
- ^3
-}
-''', expected: r'''
-1: N2, N5, N6
-2: N2, N5, N6
-3: N2
-''');
- }
-
- test_ForEachStatement_identifier() {
- _assertScopeNames(code: r'''
-N1() {
- ^1
- for (N2 in N3 ^2) {
- ^3
- }
- ^4
-}
-''', expected: r'''
-1: {}
-2: {}
-3: {}
-4: {}
-''');
- }
-
- test_ForEachStatement_iterable() {
- _assertScopeNames(code: r'''
-N1() {
- for (var N2 in (){ var N3; ^1 }()) {
- ^2
- }
- ^3
-}
-''', expected: r'''
-1: N3
-2: N2
-3: {}
-''');
- }
-
- test_ForEachStatement_loopVariable() {
- _assertScopeNames(code: r'''
-N1() {
- ^1
- for (var N2 in N3 ^2) {
- ^3
- }
- ^4
-}
-''', expected: r'''
-1: {}
-2: {}
-3: N2
-4: {}
-''');
- }
-
- test_FormalParameter_functionTyped() {
- _assertScopeNames(code: r'''
-N1 N2(N3 N4(N5 N6 ^1, N7), N8 ^2) {
- ^3
-}
-''', expected: r'''
-1: N4, N6, N7, N8
-2: N4, N8
-3: N4, N8
-''');
- }
-
- test_FormalParameter_nameOnly() {
- _assertScopeNames(code: r'''
-N1 N2(^1N3^2) {
- ^3
-}
-''', expected: r'''
-1: {}
-2: {}
-3: N3
-''');
- }
-
- test_ForStatement2_ForEachPartsWithDeclaration() {
- _enableExperiments();
- _assertScopeNames(code: r'''
-N1() {
- ^1
- for (var N2 in N3 ^2) {
- ^3
- }
- ^4
-}
-''', expected: r'''
-1: {}
-2: {}
-3: N2
-4: {}
-''');
- }
-
- test_ForStatement2_ForEachPartsWithIdentifier() {
- _enableExperiments();
- _assertScopeNames(code: r'''
-N1() {
- ^1
- for (N2 in N3 ^2) {
- ^3
- }
- ^4
-}
-''', expected: r'''
-1: {}
-2: {}
-3: {}
-4: {}
-''');
- }
-
- test_ForStatement2_ForPartsWithDeclarations_condition() {
- _enableExperiments();
- _assertScopeNames(code: r'''
-N1() {
- ^1
- for (N1 N2; (){ var N3; ^2 }(); ^3) {
- ^4
- }
- ^5
-}
-''', expected: r'''
-1: {}
-2: N2, N3
-3: N2
-4: N2
-5: {}
-''');
- }
-
- test_ForStatement2_ForPartsWithDeclarations_updaters() {
- _enableExperiments();
- _assertScopeNames(code: r'''
-N1() {
- ^1
- for (N1 N2; ^2; (){ var N3; ^3 }()) {
- ^4
- }
- ^5
-}
-''', expected: r'''
-1: {}
-2: N2
-3: N2, N3
-4: N2
-5: {}
-''');
- }
-
- test_ForStatement2_ForPartsWithDeclarations_variables() {
- _enableExperiments();
- _assertScopeNames(code: r'''
-N1() {
- ^1
- for (N2 N3, N4 ^2; N5 ^3; N6 ^4) {
- ^5
- }
- ^6
-}
-''', expected: r'''
-1: {}
-2: N3, N4
-3: N3, N4
-4: N3, N4
-5: N3, N4
-6: {}
-''');
- }
-
- test_ForStatement_condition() {
- _assertScopeNames(code: r'''
-N1() {
- ^1
- for (N1 N2; (){ var N3; ^2 }(); ^3) {
- ^4
- }
- ^5
-}
-''', expected: r'''
-1: {}
-2: N2, N3
-3: N2
-4: N2
-5: {}
-''');
- }
-
- test_ForStatement_updaters() {
- _assertScopeNames(code: r'''
-N1() {
- ^1
- for (N1 N2; ^2; (){ var N3; ^3 }()) {
- ^4
- }
- ^5
-}
-''', expected: r'''
-1: {}
-2: N2
-3: N2, N3
-4: N2
-5: {}
-''');
- }
-
- test_ForStatement_variables() {
- _assertScopeNames(code: r'''
-N1() {
- ^1
- for (N2 N3, N4 ^2; N5 ^3; N6 ^4) {
- ^5
- }
- ^6
-}
-''', expected: r'''
-1: {}
-2: N3, N4
-3: N3, N4
-4: N3, N4
-5: N3, N4
-6: {}
-''');
- }
-
- test_FunctionDeclaration() {
- _assertScopeNames(code: r'''
-N1 N2<N3 extends N4 ^1>(N5 N6 ^2, [N7 N8 = N9, N10]) {
- ^3
-}
-''', expected: r'''
-1: N3
-2: N3, N6, N8, N10
-3: N3, N6, N8, N10
-''');
- }
-
- test_FunctionTypeAlias() {
- _assertScopeNames(code: r'''
-typedef N1 N2<N3 ^1>(N3 N4, N5 ^2);
-''', expected: r'''
-1: N3
-2: N3, N4, N5
-''');
- }
-
- test_GenericFunctionType() {
- _assertScopeNames(code: r'''
-N1 Function<N2 ^1>(N3, N4 N5 ^2) N6;
-''', expected: r'''
-1: N2
-2: N2, N5
-''');
- }
-
- test_GenericTypeAlias() {
- _assertScopeNames(code: r'''
-typedef N1<N2 ^1> = Function<N3 ^2>(N4 N5, N6 ^3);
-''', expected: r'''
-1: N2
-2: N2, N3
-3: N2, N3, N5
-''');
- }
-
- test_MethodDeclaration() {
- _assertScopeNames(code: r'''
-class N1<N2> {
- N3 N4, N5;
-
- ^1
-
- N6 ^2 N7<N8 ^3>(N9 N10, N11 ^4) {
- ^5
- }
-}
-''', expected: r'''
-1: N2, N4, N5, N7
-2: N2, N4, N5, N7, N8
-3: N2, N4, N5, N7, N8
-4: N2, N4, N5, N7, N8, N10, N11
-5: N2, N4, N5, N7, N8, N10, N11
-''');
- }
-
- test_MixinDeclaration() {
- _assertScopeNames(code: r'''
-mixin N1<N2> on N3, N4 ^1 implements N5 ^2 {
- ^3
- N6 N7, N8;
- ^4
-
- N9(N10 ^5) {
- ^6
- }
-
- ^7
-}
-''', expected: r'''
-1: N2
-2: N2
-3: N2, N7, N8, N9
-4: N2, N7, N8, N9
-5: N2, N7, N8, N9, N10
-6: N2, N7, N8, N9, N10
-7: N2, N7, N8, N9
-''');
- }
-
- void _assertScopeNames({String code, String expected}) {
- var matches = RegExp(r'\^\d{1,2}').allMatches(code).toList();
-
- var matchOffsets = <String, int>{};
- var delta = 0;
- for (var match in matches) {
- var newStart = match.start - delta;
- var newEnd = match.end - delta;
- matchOffsets[code.substring(newStart + 1, newEnd)] = newStart;
- delta += match.end - match.start;
- code = code.substring(0, newStart) + code.substring(newEnd);
- }
-
- var path = convertPath('/home/test/lib/a.dart');
- newFile(path, content: code);
-
- var parsedResult = session.getParsedUnit(path);
- expect(parsedResult.errors, isEmpty);
-
- var unit = parsedResult.unit;
- var buffer = StringBuffer();
- for (var offsetName in matchOffsets.keys) {
- var offset = matchOffsets[offsetName];
- var nameSet = Set<String>();
-
- unit.accept(SyntacticScopeNamesCollector(nameSet, offset));
-
- var nameList = nameSet.toList();
- nameList.sort((a, b) {
- expect(a.startsWith('N'), isTrue);
- expect(b.startsWith('N'), isTrue);
- return int.parse(a.substring(1)) - int.parse(b.substring(1));
- });
-
- buffer.write('$offsetName: ');
- if (nameList.isEmpty) {
- buffer.writeln('{}');
- } else {
- buffer.writeln(nameList.join(', '));
- }
- }
-
- var actual = buffer.toString();
- if (actual != expected) {
- print(actual);
- }
- expect(actual, expected);
- }
-
- void _enableExperiments() {
- createAnalysisOptionsFile(
- experiments: [
- EnableString.control_flow_collections,
- EnableString.spread_collections,
- ],
- );
- }
-}
diff --git a/pkg/analyzer_plugin/test/src/utilities/change_builder/dart/test_all.dart b/pkg/analyzer_plugin/test/src/utilities/change_builder/dart/test_all.dart
index 9d53f53..06a0484 100644
--- a/pkg/analyzer_plugin/test/src/utilities/change_builder/dart/test_all.dart
+++ b/pkg/analyzer_plugin/test/src/utilities/change_builder/dart/test_all.dart
@@ -5,12 +5,10 @@
import 'package:test_reflective_loader/test_reflective_loader.dart';
import 'import_library_element_test.dart' as import_library_element;
-import 'syntactic_scope_test.dart' as syntactic_scope;
/// Utility for manually running all tests.
main() {
defineReflectiveSuite(() {
import_library_element.main();
- syntactic_scope.main();
});
}
diff --git a/pkg/analyzer_plugin/test/src/utilities/visitors/local_declaration_visitor_test.dart b/pkg/analyzer_plugin/test/src/utilities/visitors/local_declaration_visitor_test.dart
index 673e646..f19508e 100644
--- a/pkg/analyzer_plugin/test/src/utilities/visitors/local_declaration_visitor_test.dart
+++ b/pkg/analyzer_plugin/test/src/utilities/visitors/local_declaration_visitor_test.dart
@@ -64,6 +64,9 @@
void declaredClassTypeAlias(ClassTypeAlias declaration) {}
@override
+ void declaredExtension(ExtensionDeclaration declaration) {}
+
+ @override
void declaredField(FieldDeclaration fieldDecl, VariableDeclaration varDecl) {}
@override
diff --git a/pkg/compiler/lib/src/constants/constant_system.dart b/pkg/compiler/lib/src/constants/constant_system.dart
index 2d154b7..47aa5ed 100644
--- a/pkg/compiler/lib/src/constants/constant_system.dart
+++ b/pkg/compiler/lib/src/constants/constant_system.dart
@@ -636,7 +636,7 @@
BigInt foldNums(num left, num right) {
num ratio = left / right;
if (ratio.isNaN || ratio.isInfinite) return null;
- return new BigInt.from(ratio.truncate().toInt());
+ return new BigInt.from(ratio.truncateToDouble());
}
@override
diff --git a/pkg/compiler/lib/src/ir/static_type.dart b/pkg/compiler/lib/src/ir/static_type.dart
index ba35b89..0ec782d 100644
--- a/pkg/compiler/lib/src/ir/static_type.dart
+++ b/pkg/compiler/lib/src/ir/static_type.dart
@@ -180,7 +180,7 @@
// subtypes of Object (not just interface types), and function types are
// considered subtypes of Function.
if (superclass.typeParameters.isEmpty) {
- return superclass.rawType;
+ return typeEnvironment.coreTypes.legacyRawType(superclass);
}
while (type is ir.TypeParameterType) {
type = (type as ir.TypeParameterType).parameter.bound;
@@ -196,7 +196,7 @@
return superclass.bottomType;
}
// TODO(johnniwinther): Should we assert that this doesn't happen?
- return superclass.rawType;
+ return typeEnvironment.coreTypes.legacyRawType(superclass);
}
/// Computes the result type of the property access [node] on a receiver of
@@ -781,7 +781,8 @@
ir.DartType visitConstructorInvocation(ir.ConstructorInvocation node) {
ArgumentTypes argumentTypes = _visitArguments(node.arguments);
ir.DartType resultType = node.arguments.types.isEmpty
- ? new ExactInterfaceType.from(node.target.enclosingClass.rawType)
+ ? new ExactInterfaceType.from(
+ typeEnvironment.coreTypes.legacyRawType(node.target.enclosingClass))
: new ExactInterfaceType(
node.target.enclosingClass, node.arguments.types);
_expressionTypeCache[node] = resultType;
diff --git a/pkg/compiler/lib/src/js_backend/namer.dart b/pkg/compiler/lib/src/js_backend/namer.dart
index 8b4374b..c797e3b 100644
--- a/pkg/compiler/lib/src/js_backend/namer.dart
+++ b/pkg/compiler/lib/src/js_backend/namer.dart
@@ -2603,6 +2603,8 @@
return runtimeTypeName(_commonElements.objectClass);
case JsGetName.FUNCTION_CLASS_TYPE_NAME:
return runtimeTypeName(_commonElements.functionClass);
+ case JsGetName.JS_FUNCTION_CLASS_TYPE_NAME:
+ return runtimeTypeName(_commonElements.jsJavaScriptFunctionClass);
case JsGetName.FUTURE_CLASS_TYPE_NAME:
return runtimeTypeName(_commonElements.futureClass);
case JsGetName.BOOL_RECIPE:
diff --git a/pkg/compiler/lib/src/js_backend/runtime_types_new.dart b/pkg/compiler/lib/src/js_backend/runtime_types_new.dart
index 9a56acf..0dfdaf9 100644
--- a/pkg/compiler/lib/src/js_backend/runtime_types_new.dart
+++ b/pkg/compiler/lib/src/js_backend/runtime_types_new.dart
@@ -299,14 +299,12 @@
// TODO(sra): We might be in a context where the class type variable has an
// index, even though in the general case it is not at a specific index.
- if (_closedWorld.isUsedAsMixin(cls)) return null;
-
- // TODO(fishythefish): We should only check strict subclasses for
- // non-trivial substitutions in the general case. We should check all strict
- // subtypes only when [cls] is a mixin (above) or when [cls] is a type
- // argument to `extractTypeArguments`.
ClassHierarchy classHierarchy = _closedWorld.classHierarchy;
- if (classHierarchy.anyStrictSubtypeOf(cls, (ClassEntity subclass) {
+ var test = mustCheckAllSubtypes(_closedWorld, cls)
+ ? classHierarchy.anyStrictSubtypeOf
+ : classHierarchy.anyStrictSubclassOf;
+
+ if (test(cls, (ClassEntity subclass) {
return !_rtiSubstitutions.isTrivialSubstitution(subclass, cls);
})) {
return null;
@@ -470,6 +468,10 @@
}
}
+bool mustCheckAllSubtypes(JClosedWorld world, ClassEntity cls) =>
+ world.isUsedAsMixin(cls) ||
+ world.extractTypeArgumentsInterfacesNewRti.contains(cls);
+
class _RulesetEntry {
final InterfaceType _targetType;
List<InterfaceType> _supertypes;
diff --git a/pkg/compiler/lib/src/js_emitter/program_builder/program_builder.dart b/pkg/compiler/lib/src/js_emitter/program_builder/program_builder.dart
index 704c07a..871cdd2 100644
--- a/pkg/compiler/lib/src/js_emitter/program_builder/program_builder.dart
+++ b/pkg/compiler/lib/src/js_emitter/program_builder/program_builder.dart
@@ -30,6 +30,7 @@
show RuntimeTypesChecks, RuntimeTypesEncoder;
import '../../js_backend/runtime_types_new.dart'
show RecipeEncoder, RecipeEncoding;
+import '../../js_backend/runtime_types_new.dart' as newRti;
import '../../js_backend/runtime_types_resolution.dart' show RuntimeTypesNeed;
import '../../js_model/elements.dart' show JGeneratorBody, JSignatureMethod;
import '../../js_model/type_recipe.dart'
@@ -852,8 +853,12 @@
void associateNamedTypeVariablesNewRti() {
for (TypeVariableType typeVariable in _codegenWorld.namedTypeVariablesNewRti
.union(_lateNamedTypeVariablesNewRti)) {
- for (ClassEntity entity
- in _classHierarchy.subtypesOf(typeVariable.element.typeDeclaration)) {
+ ClassEntity declaration = typeVariable.element.typeDeclaration;
+ Iterable<ClassEntity> subtypes =
+ newRti.mustCheckAllSubtypes(_closedWorld, declaration)
+ ? _classHierarchy.subtypesOf(declaration)
+ : _classHierarchy.subclassesOf(declaration);
+ for (ClassEntity entity in subtypes) {
Class cls = _classes[entity];
if (cls == null) continue;
cls.namedTypeVariablesNewRti.add(typeVariable);
diff --git a/pkg/compiler/lib/src/js_model/js_world.dart b/pkg/compiler/lib/src/js_model/js_world.dart
index c24c3a9..ca2f1be 100644
--- a/pkg/compiler/lib/src/js_model/js_world.dart
+++ b/pkg/compiler/lib/src/js_model/js_world.dart
@@ -76,6 +76,9 @@
final Set<MemberEntity> processedMembers;
@override
+ final Set<ClassEntity> extractTypeArgumentsInterfacesNewRti;
+
+ @override
final ClassHierarchy classHierarchy;
final JsKernelToElementMap elementMap;
@@ -109,6 +112,7 @@
this.liveInstanceMembers,
this.assignedInstanceMembers,
this.processedMembers,
+ this.extractTypeArgumentsInterfacesNewRti,
this.mixinUses,
this.typesImplementedBySubclasses,
this.classHierarchy,
@@ -154,6 +158,8 @@
Set<ClassEntity> implementedClasses = source.readClasses().toSet();
Set<ClassEntity> liveNativeClasses = source.readClasses().toSet();
+ Set<ClassEntity> extractTypeArgumentsInterfacesNewRti =
+ source.readClasses().toSet();
Set<MemberEntity> liveInstanceMembers = source.readMembers().toSet();
Set<MemberEntity> assignedInstanceMembers = source.readMembers().toSet();
Set<MemberEntity> processedMembers = source.readMembers().toSet();
@@ -191,6 +197,7 @@
liveInstanceMembers,
assignedInstanceMembers,
processedMembers,
+ extractTypeArgumentsInterfacesNewRti,
mixinUses,
typesImplementedBySubclasses,
classHierarchy,
@@ -217,6 +224,7 @@
noSuchMethodData.writeToDataSink(sink);
sink.writeClasses(implementedClasses);
sink.writeClasses(liveNativeClasses);
+ sink.writeClasses(extractTypeArgumentsInterfacesNewRti);
sink.writeMembers(liveInstanceMembers);
sink.writeMembers(assignedInstanceMembers);
sink.writeMembers(processedMembers);
@@ -558,6 +566,11 @@
MemberAccess getMemberAccess(MemberEntity member) {
return memberAccess[member];
}
+
+ @override
+ void registerExtractTypeArguments(ClassEntity interface) {
+ extractTypeArgumentsInterfacesNewRti.add(interface);
+ }
}
class KernelSorter implements Sorter {
diff --git a/pkg/compiler/lib/src/js_model/js_world_builder.dart b/pkg/compiler/lib/src/js_model/js_world_builder.dart
index 1bf43b4..1c8687b 100644
--- a/pkg/compiler/lib/src/js_model/js_world_builder.dart
+++ b/pkg/compiler/lib/src/js_model/js_world_builder.dart
@@ -130,6 +130,8 @@
Set<MemberEntity> processedMembers =
map.toBackendMemberSet(closedWorld.liveMemberUsage.keys);
+ Set<ClassEntity> extractTypeArgumentsInterfacesNewRti = {};
+
RuntimeTypesNeed rtiNeed;
List<FunctionEntity> callMethods = <FunctionEntity>[];
@@ -223,6 +225,7 @@
liveInstanceMembers /*..addAll(callMethods)*/,
assignedInstanceMembers,
processedMembers,
+ extractTypeArgumentsInterfacesNewRti,
mixinUses,
typesImplementedBySubclasses,
new ClassHierarchyImpl(
diff --git a/pkg/compiler/lib/src/kernel/dart2js_target.dart b/pkg/compiler/lib/src/kernel/dart2js_target.dart
index 5dcee7e..cd8c5b9 100644
--- a/pkg/compiler/lib/src/kernel/dart2js_target.dart
+++ b/pkg/compiler/lib/src/kernel/dart2js_target.dart
@@ -51,10 +51,7 @@
Dart2jsTarget(this.name, this.flags);
@override
- bool get legacyMode => flags.legacyMode;
-
- @override
- bool get enableNoSuchMethodForwarders => !flags.legacyMode;
+ bool get enableNoSuchMethodForwarders => true;
@override
List<String> get extraRequiredLibraries => _requiredLibraries[name];
@@ -120,7 +117,7 @@
new ir.StringLiteral(arg.name)..fileOffset = arg.fileOffset,
arg.value)
..fileOffset = arg.fileOffset;
- })), keyType: coreTypes.stringClass.rawType)
+ })), keyType: coreTypes.stringLegacyRawType)
..isConst = (arguments.named.length == 0)
..fileOffset = arguments.fileOffset,
new ir.IntLiteral(kind)..fileOffset = offset,
diff --git a/pkg/compiler/lib/src/ssa/builder_kernel.dart b/pkg/compiler/lib/src/ssa/builder_kernel.dart
index ab3bc02..2e65567 100644
--- a/pkg/compiler/lib/src/ssa/builder_kernel.dart
+++ b/pkg/compiler/lib/src/ssa/builder_kernel.dart
@@ -4040,6 +4040,7 @@
List<DartType> typeArguments = <DartType>[];
if (options.experimentNewRti) {
+ closedWorld.registerExtractTypeArguments(cls);
HInstruction instanceType =
HInstanceEnvironment(object, _abstractValueDomain.dynamicType);
add(instanceType);
diff --git a/pkg/compiler/lib/src/ssa/codegen.dart b/pkg/compiler/lib/src/ssa/codegen.dart
index 77b1dac..1197751 100644
--- a/pkg/compiler/lib/src/ssa/codegen.dart
+++ b/pkg/compiler/lib/src/ssa/codegen.dart
@@ -3478,8 +3478,6 @@
js.Expression recipe = encoding.recipe;
for (TypeVariableType typeVariable in encoding.typeVariables) {
- // TODO(fishythefish): Constraint the type variable to only be emitted on
- // (subtypes of) the environment type.
_registry.registerTypeUse(TypeUse.namedTypeVariableNewRti(typeVariable));
}
diff --git a/pkg/compiler/lib/src/world.dart b/pkg/compiler/lib/src/world.dart
index e7f5930..89c2271 100644
--- a/pkg/compiler/lib/src/world.dart
+++ b/pkg/compiler/lib/src/world.dart
@@ -70,6 +70,10 @@
Iterable<MemberEntity> get processedMembers;
+ /// Returns the set of interfaces passed as type arguments to the internal
+ /// `extractTypeArguments` function.
+ Set<ClassEntity> get extractTypeArgumentsInterfacesNewRti;
+
ClassHierarchy get classHierarchy;
AnnotationsData get annotationsData;
@@ -202,6 +206,9 @@
/// Returns the set of read, write, and invocation accesses found on [member]
/// during the closed world computation.
MemberAccess getMemberAccess(MemberEntity member);
+
+ /// Registers [interface] as a type argument to `extractTypeArguments`.
+ void registerExtractTypeArguments(ClassEntity interface);
}
abstract class OpenWorld implements World {
diff --git a/pkg/compiler/tool/generate_kernel.dart b/pkg/compiler/tool/generate_kernel.dart
index 817ba97..1201ae8 100644
--- a/pkg/compiler/tool/generate_kernel.dart
+++ b/pkg/compiler/tool/generate_kernel.dart
@@ -25,7 +25,7 @@
main(List<String> args) async {
ArgResults flags = _argParser.parse(args);
var options = new CompilerOptions()
- ..target = new Dart2jsTarget("dart2js", new TargetFlags(legacyMode: true))
+ ..target = new Dart2jsTarget("dart2js", new TargetFlags())
..packagesFileUri = Uri.base.resolve('.packages')
..setExitCodeOnProblem = true
..linkedDependencies = [
diff --git a/pkg/dart_internal/pubspec.yaml b/pkg/dart_internal/pubspec.yaml
index 2ffe0ee..a411212 100644
--- a/pkg/dart_internal/pubspec.yaml
+++ b/pkg/dart_internal/pubspec.yaml
@@ -1,5 +1,5 @@
name: dart_internal
-version: 0.1.6
+version: 0.1.7
author: "Dart Team <misc@dartlang.org>"
homepage: http://www.dartlang.org
description: >
@@ -16,4 +16,4 @@
environment:
# Restrict the upper bound so that we can remove support for this in a later
# version of the SDK without it being a breaking change.
- sdk: ">=2.0.0-dev.12.0 <2.6.0"
+ sdk: ">=2.0.0-dev.12.0 <2.7.0"
diff --git a/pkg/dartfix/lib/src/driver.dart b/pkg/dartfix/lib/src/driver.dart
index fa4c91a..ee93476 100644
--- a/pkg/dartfix/lib/src/driver.dart
+++ b/pkg/dartfix/lib/src/driver.dart
@@ -16,6 +16,7 @@
import 'package:dartfix/src/context.dart';
import 'package:dartfix/src/options.dart';
import 'package:dartfix/src/util.dart';
+import 'package:path/path.dart' as path;
import 'package:pub_semver/pub_semver.dart';
class Driver {
@@ -127,6 +128,14 @@
if (options.pedanticFixes) {
params.includePedanticFixes = true;
}
+ String dir = options.outputDir;
+ if (dir != null) {
+ if (!path.isAbsolute(dir)) {
+ dir = path.absolute(dir);
+ }
+ dir = path.canonicalize(dir);
+ params.outputDir = dir;
+ }
Map<String, dynamic> json =
await server.send(EDIT_REQUEST_DARTFIX, params.toJson());
diff --git a/pkg/dartfix/lib/src/options.dart b/pkg/dartfix/lib/src/options.dart
index 545196a..02bcf3a 100644
--- a/pkg/dartfix/lib/src/options.dart
+++ b/pkg/dartfix/lib/src/options.dart
@@ -9,19 +9,20 @@
import 'package:dartfix/src/context.dart';
import 'package:path/path.dart' as path;
+const excludeFixOption = 'excludeFix';
const forceOption = 'force';
const includeFixOption = 'fix';
-const excludeFixOption = 'excludeFix';
+const outputDirOption = 'outputDir';
const overwriteOption = 'overwrite';
const pedanticOption = 'pedantic';
const requiredOption = 'required';
const _binaryName = 'dartfix';
const _colorOption = 'color';
-const _serverSnapshot = 'server';
+const _helpOption = 'help';
// options only supported by server 1.22.2 and greater
-const _helpOption = 'help';
+const _serverSnapshot = 'server';
const _verboseOption = 'verbose';
/// Command line options for `dartfix`.
@@ -40,6 +41,7 @@
final bool force;
final bool showHelp;
+ final String outputDir;
final bool overwrite;
final bool useColor;
final bool verbose;
@@ -48,6 +50,7 @@
: force = results[forceOption] as bool,
includeFixes = (results[includeFixOption] as List ?? []).cast<String>(),
excludeFixes = (results[excludeFixOption] as List ?? []).cast<String>(),
+ outputDir = results[outputDirOption] as String,
overwrite = results[overwriteOption] as bool,
pedanticFixes = results[pedanticOption] as bool,
requiredFixes = results[requiredOption] as bool,
@@ -104,7 +107,12 @@
negatable: false)
..addFlag(_colorOption,
help: 'Use ansi colors when printing messages.',
- defaultsTo: Ansi.terminalSupportsAnsi);
+ defaultsTo: Ansi.terminalSupportsAnsi)
+ //
+ // Hidden options.
+ //
+ ..addOption(outputDirOption,
+ help: 'Path to the output directory', hide: true);
context ??= Context();
diff --git a/pkg/dartfix/test/src/options_test.dart b/pkg/dartfix/test/src/options_test.dart
index c6c87ed..beb90d0 100644
--- a/pkg/dartfix/test/src/options_test.dart
+++ b/pkg/dartfix/test/src/options_test.dart
@@ -30,6 +30,7 @@
String normalOut,
bool pedanticFixes = false,
bool requiredFixes = false,
+ String outputDir,
bool overwrite = false,
String serverSnapshot,
List<String> targetSuffixes,
@@ -55,6 +56,7 @@
expect(options.force, force);
expect(options.pedanticFixes, pedanticFixes);
expect(options.requiredFixes, requiredFixes);
+ expect(options.outputDir, outputDir);
expect(options.overwrite, overwrite);
expect(options.serverSnapshot, serverSnapshot);
expect(options.showHelp, showHelp);
@@ -115,6 +117,10 @@
errorOut: 'Expected directory, but found', exitCode: 21);
});
+ test('outputDir', () {
+ parse(['--outputDir=bar', 'foo'], outputDir: 'bar');
+ });
+
test('overwrite', () {
parse(['--overwrite', 'foo'], overwrite: true, targetSuffixes: ['foo']);
});
@@ -145,12 +151,6 @@
});
}
-void expectOneFileTarget(Options options, String fileName) {
- expect(options.targets, hasLength(1));
- final target = options.targets[0];
- expect(target.endsWith(fileName), isTrue);
-}
-
void expectContains(Iterable<String> collection, String suffix) {
for (String elem in collection) {
if (elem.endsWith(suffix)) {
@@ -159,3 +159,9 @@
}
fail('Expected one of $collection\n to end with "$suffix"');
}
+
+void expectOneFileTarget(Options options, String fileName) {
+ expect(options.targets, hasLength(1));
+ final target = options.targets[0];
+ expect(target.endsWith(fileName), isTrue);
+}
diff --git a/pkg/dev_compiler/lib/src/analyzer/code_generator.dart b/pkg/dev_compiler/lib/src/analyzer/code_generator.dart
index 6ae1c24..e521784 100644
--- a/pkg/dev_compiler/lib/src/analyzer/code_generator.dart
+++ b/pkg/dev_compiler/lib/src/analyzer/code_generator.dart
@@ -1003,10 +1003,10 @@
}
}
if (classElem.library.isDartAsync) {
- if (classElem == types.futureOrType.element) {
+ if (classElem == types.futureOrElement) {
var typeParamT = classElem.typeParameters[0].type;
var typeT = _emitType(typeParamT);
- var futureOfT = _emitType(types.futureType.instantiate([typeParamT]));
+ var futureOfT = _emitType(types.futureType2(typeParamT));
body.add(js.statement('''
#.is = function is_FutureOr(o) {
return #.is(o) || #.is(o);
@@ -1207,7 +1207,7 @@
List<js_ast.Method> methods,
List<js_ast.Statement> body,
List<js_ast.Statement> deferredSupertypes) {
- if (classElem.type.isObject) {
+ if (classElem.isDartCoreObject) {
body.add(_emitClassStatement(classElem, className, null, methods));
return;
}
@@ -1423,7 +1423,7 @@
bool hasJsPeer = _extensionTypes.isNativeClass(classElem);
bool hasIterator = false;
- if (type.isObject) {
+ if (classElem.isDartCoreObject) {
// Dart does not use ES6 constructors.
// Add an error to catch any invalid usage.
jsMethods.add(
@@ -1788,7 +1788,7 @@
}
bool _implementsIterable(InterfaceType t) =>
- t.interfaces.any((i) => i.element.type == types.iterableType);
+ t.interfaces.any((i) => i.element == types.iterableElement);
/// Support for adapting dart:core Iterable to ES6 versions.
///
@@ -2005,7 +2005,7 @@
/// Ensure `dartx.` symbols we will use are present.
void _initExtensionSymbols(ClassElement classElem) {
if (_extensionTypes.hasNativeSubtype(classElem.type) ||
- classElem.type.isObject) {
+ classElem.isDartCoreObject) {
for (var members in [classElem.methods, classElem.accessors]) {
for (var m in members) {
if (!m.isAbstract && !m.isStatic && m.isPublic) {
@@ -2055,7 +2055,7 @@
if (elements.isEmpty) return;
if (!name.startsWith('Static')) {
- var proto = classElem.type.isObject
+ var proto = classElem.isDartCoreObject
? js.call('Object.create(null)')
: runtimeCall('get${name}s(#.__proto__)', [className]);
elements.insert(0, js_ast.Property(propertyName('__proto__'), proto));
@@ -2347,7 +2347,7 @@
// Get the supertype's unnamed constructor.
superCtor ??= element.supertype?.element?.unnamedConstructor;
if (superCtor == null) {
- assert(element.type.isObject ||
+ assert(element.isDartCoreObject ||
element.isMixin ||
options.unsafeForceCompile);
return null;
@@ -2381,7 +2381,7 @@
}
bool _hasUnnamedConstructor(ClassElement e) {
- if (e.type.isObject) return false;
+ if (e.isDartCoreObject) return false;
var ctor = e.unnamedConstructor;
if (ctor != null && !ctor.isSynthetic) return true;
return e.fields.any((f) => !f.isStatic && !f.isSynthetic);
@@ -2966,7 +2966,7 @@
//
// In the body of an `async`, `await` is generated simply as `yield`.
var gen = emitGeneratorFn([]);
- var dartAsync = types.futureType.element.library;
+ var dartAsync = types.futureElement.library;
return js.call('#.async(#, #)',
[emitLibraryName(dartAsync), _emitType(returnType), gen]);
}
@@ -4458,15 +4458,15 @@
return _emitType(value.toTypeValue());
}
if (type is InterfaceType) {
- if (type.element == types.listType.element) {
+ if (type.element == types.listElement) {
return _emitConstList(type.typeArguments[0],
value.toListValue().map(_emitDartObject).toList());
}
- if (type.element == types.setType.element) {
+ if (type.element == types.setElement) {
return _emitConstSet(type.typeArguments[0],
value.toSetValue().map(_emitDartObject).toList());
}
- if (type.element == types.mapType.element) {
+ if (type.element == types.mapElement) {
var entries = <js_ast.Expression>[];
value.toMapValue().forEach((key, value) {
entries.add(_emitDartObject(key));
@@ -5866,7 +5866,7 @@
body.accept(finder);
if (finder.hasYield) {
var genFn = js_ast.Fun([], body, isGenerator: true);
- var asyncLibrary = emitLibraryName(types.futureType.element.library);
+ var asyncLibrary = emitLibraryName(types.futureElement.library);
return js_ast.Yield(js.call(
'#.async(#, #)', [asyncLibrary, _emitType(yieldType), genFn]));
}
@@ -6278,19 +6278,19 @@
}
var type = functionType.returnType;
- InterfaceType expectedType;
+ ClassElement expectedElement;
if (element.isAsynchronous) {
if (element.isGenerator) {
// Stream<T> -> T
- expectedType = types.streamType;
+ expectedElement = types.streamElement;
} else {
// Future<T> -> T
- expectedType = types.futureType;
+ expectedElement = types.futureElement;
}
} else {
if (element.isGenerator) {
// Iterable<T> -> T
- expectedType = types.iterableType;
+ expectedElement = types.iterableElement;
} else {
// T -> T
return type;
@@ -6298,9 +6298,9 @@
}
if (type.isDynamic) return type;
if (type is InterfaceType &&
- (type.element == expectedType.element ||
- expectedType == types.futureType &&
- type.element == types.futureOrType.element)) {
+ (type.element == expectedElement ||
+ expectedElement == types.futureElement &&
+ type.element == types.futureOrElement)) {
return type.typeArguments[0];
}
// TODO(leafp): The above only handles the case where the return type
@@ -6311,8 +6311,12 @@
js_ast.Expression _throwUnsafe(String message) => runtimeCall(
'throw(Error(#))', [js.escapedString("compile error: $message")]);
- Null _unreachable(Object node) {
- throw UnsupportedError('tried to generate an unreachable node: `$node`');
+ js_ast.Expression _unreachable(Object node) {
+ var message = 'tried to generate an unreachable node: `$node`';
+ if (options.unsafeForceCompile) {
+ return _throwUnsafe(message);
+ }
+ throw UnsupportedError(message);
}
/// Unused, see methods for emitting declarations.
@@ -6584,7 +6588,7 @@
return _emitAwaitFor(forParts, jsBody);
}
}
- return _unreachable(forParts);
+ return _unreachable(forParts).toStatement();
}
@override
diff --git a/pkg/dev_compiler/lib/src/analyzer/element_helpers.dart b/pkg/dev_compiler/lib/src/analyzer/element_helpers.dart
index 98c7b54..a306bfb 100644
--- a/pkg/dev_compiler/lib/src/analyzer/element_helpers.dart
+++ b/pkg/dev_compiler/lib/src/analyzer/element_helpers.dart
@@ -227,7 +227,7 @@
var method = classElement.lookUpMethod(
FunctionElement.NO_SUCH_METHOD_METHOD_NAME, classElement.library);
var definingClass = method?.enclosingElement;
- return definingClass is ClassElement && !definingClass.type.isObject;
+ return definingClass is ClassElement && !definingClass.isDartCoreObject;
}
/// Returns true if this class is of the form:
diff --git a/pkg/dev_compiler/lib/src/analyzer/extension_types.dart b/pkg/dev_compiler/lib/src/analyzer/extension_types.dart
index d0e80e6..833a968 100644
--- a/pkg/dev_compiler/lib/src/analyzer/extension_types.dart
+++ b/pkg/dev_compiler/lib/src/analyzer/extension_types.dart
@@ -168,7 +168,7 @@
/// For example for dart:_interceptors `JSArray` this will return "Array",
/// referring to the JavaScript built-in `Array` type.
List<String> getNativePeers(ClassElement classElem) {
- if (classElem.type.isObject) return ['Object'];
+ if (classElem.isDartCoreObject) return ['Object'];
var names = getAnnotationName(
classElem,
(a) =>
diff --git a/pkg/dev_compiler/lib/src/compiler/shared_compiler.dart b/pkg/dev_compiler/lib/src/compiler/shared_compiler.dart
index 2024848..01d77e4 100644
--- a/pkg/dev_compiler/lib/src/compiler/shared_compiler.dart
+++ b/pkg/dev_compiler/lib/src/compiler/shared_compiler.dart
@@ -252,6 +252,7 @@
/// runtime call.
js_ast.TemporaryId initPrivateNameSymbol() {
var idName = name.endsWith('=') ? name.replaceAll('=', '_') : name;
+ idName = idName.replaceAll('.', '_');
var id = js_ast.TemporaryId(idName);
moduleItems.add(js.statement('const # = #.privateName(#, #)',
[id, runtimeModule, emitLibraryName(library), js.string(name)]));
@@ -262,6 +263,16 @@
return privateNames.putIfAbsent(name, initPrivateNameSymbol);
}
+ /// Emits a private name JS Symbol for [name] unique to a Dart class [cls].
+ ///
+ /// This is now required for fields of constant objects that may be
+ /// overridden within the same library.
+ @protected
+ js_ast.TemporaryId emitClassPrivateNameSymbol(
+ Library library, String className, String memberName) {
+ return emitPrivateNameSymbol(library, '$className.$memberName');
+ }
+
/// Emits an expression to set the property [nameExpr] on the class [className],
/// with [value].
///
diff --git a/pkg/dev_compiler/lib/src/kernel/analyzer_to_kernel.dart b/pkg/dev_compiler/lib/src/kernel/analyzer_to_kernel.dart
index d90fa57..4f1d80b 100644
--- a/pkg/dev_compiler/lib/src/kernel/analyzer_to_kernel.dart
+++ b/pkg/dev_compiler/lib/src/kernel/analyzer_to_kernel.dart
@@ -121,9 +121,6 @@
return result;
}
- /// Dispose the Analysis Context used for summary conversion.
- void dispose() => _resynth.context.dispose();
-
void verifyReferences() {
_references.forEach((element, reference) {
// Ensure each reference has a corresponding node.
@@ -799,11 +796,11 @@
return TypeLiteral(_visitDartType(obj.toTypeValue()));
}
if (type is a.InterfaceType) {
- if (type.element == types.listType.element) {
+ if (type.element == types.listElement) {
return ListLiteral(obj.toListValue().map(_visitConstant).toList(),
typeArgument: _visitDartType(type.typeArguments[0]), isConst: true);
}
- if (type.element == types.mapType.element) {
+ if (type.element == types.mapElement) {
var entries = obj
.toMapValue()
.entries
@@ -898,7 +895,6 @@
as a.AnalysisContextImpl;
context.sourceFactory = a.SourceFactory(
[a.DartUriResolver(sdk), a.InSummaryUriResolver(null, summaryData)]);
- context.useSdkCachePartition = false;
// TODO(jmesserly): do we need to set analysisOptions or declaredVariables?
return context;
}
diff --git a/pkg/dev_compiler/lib/src/kernel/command.dart b/pkg/dev_compiler/lib/src/kernel/command.dart
index bf38ecb..c741457 100644
--- a/pkg/dev_compiler/lib/src/kernel/command.dart
+++ b/pkg/dev_compiler/lib/src/kernel/command.dart
@@ -312,7 +312,6 @@
var converter = AnalyzerToKernel(sdkSummaryPath, summaryPaths);
opts.sdkSummaryComponent = converter.convertSdk();
opts.inputSummariesComponents = converter.convertSummaries();
- converter.dispose();
}
fe.DdcResult result;
diff --git a/pkg/dev_compiler/lib/src/kernel/compiler.dart b/pkg/dev_compiler/lib/src/kernel/compiler.dart
index fd5a3de..396b0ae 100644
--- a/pkg/dev_compiler/lib/src/kernel/compiler.dart
+++ b/pkg/dev_compiler/lib/src/kernel/compiler.dart
@@ -263,11 +263,12 @@
FunctionNode get currentFunction => _currentFunction;
@override
- InterfaceType get privateSymbolType => _privateSymbolClass.rawType;
+ InterfaceType get privateSymbolType =>
+ _coreTypes.legacyRawType(_privateSymbolClass);
@override
InterfaceType get internalSymbolType =>
- _coreTypes.internalSymbolClass.rawType;
+ _coreTypes.legacyRawType(_coreTypes.internalSymbolClass);
js_ast.Program emitModule(Component component, List<Component> summaries,
List<Uri> summaryUris, Map<Uri, String> moduleImportForSummary) {
@@ -794,7 +795,7 @@
getBaseClass(isMixinAliasClass(c) ? 0 : mixins.length),
emitDeferredType(supertype),
]));
- supertype = supertype.classNode.rawType;
+ supertype = _coreTypes.legacyRawType(supertype.classNode);
}
var baseClass = emitClassRef(supertype);
@@ -1351,7 +1352,7 @@
for (var ctor in allConstructors) {
var memberName = _constructorName(ctor.name.name);
var type = _emitAnnotatedFunctionType(
- ctor.function.functionType.withoutTypeParameters, ctor);
+ ctor.function.thisFunctionType.withoutTypeParameters, ctor);
constructors.add(js_ast.Property(memberName, type));
}
emitSignature('Constructor', constructors);
@@ -1392,7 +1393,7 @@
FunctionType result;
if (!f.positionalParameters.any(isCovariantParameter) &&
!f.namedParameters.any(isCovariantParameter)) {
- result = f.functionType;
+ result = f.thisFunctionType;
} else {
reifyParameter(VariableDeclaration p) =>
isCovariantParameter(p) ? _coreTypes.objectClass.thisType : p.type;
@@ -1405,7 +1406,7 @@
f.positionalParameters.map(reifyParameter).toList(), f.returnType,
namedParameters: f.namedParameters.map(reifyNamedParameter).toList()
..sort(),
- typeParameters: f.functionType.typeParameters,
+ typeParameters: f.thisFunctionType.typeParameters,
requiredParameterCount: f.requiredParameterCount);
}
return _getTypeFromClass(result, member.enclosingClass, fromClass)
@@ -1846,7 +1847,7 @@
assert(!member.isAccessor);
var superMethodType =
- substituteType(superMember.function.functionType) as FunctionType;
+ substituteType(superMember.function.thisFunctionType) as FunctionType;
var function = member.function;
var body = <js_ast.Statement>[];
@@ -2058,7 +2059,7 @@
void _registerExtensionType(
Class c, String jsPeerName, List<js_ast.Statement> body) {
var className = _emitTopLevelName(c);
- if (_typeRep.isPrimitive(c.rawType)) {
+ if (_typeRep.isPrimitive(_coreTypes.legacyRawType(c))) {
body.add(runtimeStatement(
'definePrimitiveHashCode(#.prototype)', [className]));
}
@@ -2285,7 +2286,7 @@
if (c == null) {
return _isObjectMember(name);
}
- c = _typeRep.getImplementationClass(c.rawType) ?? c;
+ c = _typeRep.getImplementationClass(_coreTypes.legacyRawType(c)) ?? c;
if (_extensionTypes.isNativeClass(c)) {
var member = _lookupForwardedMember(c, name);
@@ -2461,9 +2462,9 @@
// TODO(jmesserly): do we even need this for mirrors, since statics are not
// commonly reflected on?
if (_options.emitMetadata && _reifyFunctionType(p.function)) {
- body.add(
- _emitFunctionTagged(nameExpr, p.function.functionType, topLevel: true)
- .toStatement());
+ body.add(_emitFunctionTagged(nameExpr, p.function.thisFunctionType,
+ topLevel: true)
+ .toStatement());
}
_currentUri = savedUri;
@@ -2795,10 +2796,9 @@
void _emitVirtualFieldSymbols(Class c, List<js_ast.Statement> body) {
_classProperties.virtualFields.forEach((field, virtualField) {
- body.add(js.statement('const # = Symbol(#);', [
- virtualField,
- js.string('${getLocalClassName(c)}.${field.name.name}')
- ]));
+ var symbol = emitClassPrivateNameSymbol(
+ c.enclosingLibrary, getLocalClassName(c), field.name.name);
+ body.add(js.statement('const # = #;', [virtualField, symbol]));
});
}
@@ -2916,14 +2916,14 @@
var gen = emitGeneratorFn((_) => []);
// Return type of an async body is `Future<flatten(T)>`, where T is the
// declared return type.
- var returnType = _types.unfutureType(function.functionType.returnType);
+ var returnType = _types.unfutureType(function.thisFunctionType.returnType);
return js.call('#.async(#, #)',
[emitLibraryName(_coreTypes.asyncLibrary), _emitType(returnType), gen]);
}
/// Gets the expected return type of a `sync*` or `async*` body.
DartType _getExpectedReturnType(FunctionNode f, Class expected) {
- var type = f.functionType.returnType;
+ var type = f.thisFunctionType.returnType;
if (type is InterfaceType) {
var match = _hierarchy.getTypeAsInstanceOf(type, expected);
if (match != null) return match.typeArguments[0];
@@ -3276,7 +3276,7 @@
var conditionType = condition.getStaticType(_types);
var jsCondition = _visitExpression(condition);
- var boolType = _coreTypes.boolClass.rawType;
+ var boolType = _coreTypes.boolLegacyRawType;
if (conditionType is FunctionType &&
conditionType.requiredParameterCount == 0 &&
conditionType.returnType == boolType) {
@@ -3516,7 +3516,7 @@
//
// TODO(jmesserly): we may want a helper if these become common. For now the
// full desugaring seems okay.
- var streamIterator = _asyncStreamIteratorClass.rawType;
+ var streamIterator = _coreTypes.legacyRawType(_asyncStreamIteratorClass);
var createStreamIter = js_ast.Call(
_emitConstructorName(
streamIterator,
@@ -3819,7 +3819,8 @@
if (_reifyFunctionType(func)) {
declareFn = js_ast.Block([
declareFn,
- _emitFunctionTagged(_emitVariableRef(node.variable), func.functionType)
+ _emitFunctionTagged(
+ _emitVariableRef(node.variable), func.thisFunctionType)
.toStatement()
]);
}
@@ -4006,7 +4007,7 @@
// TODO(jmesserly): we could tag static/top-level function types once
// in the module initialization, rather than at the point where they
// escape.
- return _emitFunctionTagged(result, target.function.functionType);
+ return _emitFunctionTagged(result, target.function.thisFunctionType);
}
return result;
}
@@ -4136,13 +4137,13 @@
}
bool _isDynamicOrFunction(DartType t) =>
- t == _coreTypes.functionClass.rawType || t == const DynamicType();
+ t == _coreTypes.functionLegacyRawType || t == const DynamicType();
js_ast.Expression _emitUnaryOperator(
Expression expr, Member target, InvocationExpression node) {
var op = node.name.name;
if (target != null) {
- var dispatchType = target.enclosingClass.rawType;
+ var dispatchType = _coreTypes.legacyRawType(target.enclosingClass);
if (_typeRep.unaryOperationIsPrimitive(dispatchType)) {
if (op == '~') {
if (_typeRep.isNumber(dispatchType)) {
@@ -4312,7 +4313,7 @@
// https://github.com/dart-lang/sdk/issues/33293
if (target != null) {
var targetClass = target.enclosingClass;
- var leftType = targetClass.rawType;
+ var leftType = _coreTypes.legacyRawType(targetClass);
var rightType = right.getStaticType(_types);
if (_typeRep.binaryOperationIsPrimitive(leftType, rightType) ||
@@ -4411,7 +4412,9 @@
Expression left, Member target, Expression right,
{bool negated = false}) {
var targetClass = target?.enclosingClass;
- var leftType = targetClass?.rawType ?? left.getStaticType(_types);
+ var leftType = targetClass != null
+ ? _coreTypes.legacyRawType(targetClass)
+ : left.getStaticType(_types);
// Conceptually `x == y` in Dart is defined as:
//
@@ -4710,8 +4713,7 @@
}
bool _isNull(Expression expr) =>
- expr is NullLiteral ||
- expr.getStaticType(_types) == _coreTypes.nullClass.rawType;
+ expr is NullLiteral || expr.getStaticType(_types) == _coreTypes.nullType;
bool _doubleEqIsIdentity(Expression left, Expression right) {
// If we statically know LHS or RHS is null we can use ==.
@@ -4789,7 +4791,7 @@
}
var type = ctorClass.typeParameters.isEmpty
- ? ctorClass.rawType
+ ? _coreTypes.legacyRawType(ctorClass)
: InterfaceType(ctorClass, args.types);
if (isFromEnvironmentInvocation(_coreTypes, node)) {
@@ -4841,7 +4843,8 @@
js_ast.Expression _emitJSInteropNew(Member ctor, Arguments args) {
var ctorClass = ctor.enclosingClass;
if (isJSAnonymousType(ctorClass)) return _emitObjectLiteral(args);
- return js_ast.New(_emitConstructorName(ctorClass.rawType, ctor),
+ return js_ast.New(
+ _emitConstructorName(_coreTypes.legacyRawType(ctorClass), ctor),
_emitArgumentList(args, types: false));
}
@@ -5000,8 +5003,8 @@
// All Dart number types map to a JS double.
if (_typeRep.isNumber(from) && _typeRep.isNumber(to)) {
// Make sure to check when converting to int.
- if (from != _coreTypes.intClass.rawType &&
- to == _coreTypes.intClass.rawType) {
+ if (from != _coreTypes.intLegacyRawType &&
+ to == _coreTypes.intLegacyRawType) {
// TODO(jmesserly): fuse this with notNull check.
// TODO(jmesserly): this does not correctly distinguish user casts from
// required-for-soundness casts.
@@ -5404,8 +5407,15 @@
entryToProperty(MapEntry<Reference, Constant> entry) {
var constant = visitConstant(entry.value);
var member = entry.key.asField;
- return js_ast.Property(
- _emitMemberName(member.name.name, member: member), constant);
+ var cls = member.enclosingClass;
+ // Enums cannot be overridden, so we can safely use the field name
+ // directly. Otherwise, use a private symbol in case the field
+ // was overridden.
+ var symbol = cls.isEnum
+ ? _emitMemberName(member.name.name, member: member)
+ : emitClassPrivateNameSymbol(
+ cls.enclosingLibrary, getLocalClassName(cls), member.name.name);
+ return js_ast.Property(symbol, constant);
}
var type = visitInterfaceType(node.getType(_types) as InterfaceType);
diff --git a/pkg/dev_compiler/lib/src/kernel/nullable_inference.dart b/pkg/dev_compiler/lib/src/kernel/nullable_inference.dart
index 07810f3..c49ba46 100644
--- a/pkg/dev_compiler/lib/src/kernel/nullable_inference.dart
+++ b/pkg/dev_compiler/lib/src/kernel/nullable_inference.dart
@@ -119,7 +119,7 @@
if (target == null) return true; // dynamic call
if (target.name.name == 'toString' &&
receiver != null &&
- receiver.getStaticType(types) == coreTypes.stringClass.rawType) {
+ receiver.getStaticType(types) == coreTypes.stringLegacyRawType) {
// TODO(jmesserly): `class String` in dart:core does not explicitly
// declare `toString`, which results in a target of `Object.toString` even
// when the reciever type is known to be `String`. So we work around it.
@@ -143,7 +143,8 @@
// implementation class in dart:_interceptors, for example `JSString`.
//
// This allows us to find the `@notNull` annotation if it exists.
- var implClass = jsTypeRep.getImplementationClass(targetClass.rawType);
+ var implClass = jsTypeRep
+ .getImplementationClass(coreTypes.legacyRawType(targetClass));
if (implClass != null) {
var member =
jsTypeRep.hierarchy.getDispatchTarget(implClass, target.name);
diff --git a/pkg/dev_compiler/lib/src/kernel/property_model.dart b/pkg/dev_compiler/lib/src/kernel/property_model.dart
index 5eca899..f1ced92 100644
--- a/pkg/dev_compiler/lib/src/kernel/property_model.dart
+++ b/pkg/dev_compiler/lib/src/kernel/property_model.dart
@@ -161,6 +161,13 @@
if (_extensiblePrivateClasses.contains(class_)) return true;
}
+ if (class_.constructors.any((c) => c.isConst)) {
+ // Always virtualize fields of a (might be) non-enum (see above) const
+ // class. The way these are lowered by the CFE, they need to be
+ // writable from different modules even if overridden.
+ return true;
+ }
+
// Otherwise, the field is effectively private and we only need to make it
// virtual if it's overridden.
return _overriddenPrivateFields.contains(field);
diff --git a/pkg/dev_compiler/lib/src/kernel/target.dart b/pkg/dev_compiler/lib/src/kernel/target.dart
index 1eb6b62..5ae85a5 100644
--- a/pkg/dev_compiler/lib/src/kernel/target.dart
+++ b/pkg/dev_compiler/lib/src/kernel/target.dart
@@ -21,9 +21,6 @@
WidgetCreatorTracker _widgetTracker;
@override
- bool get legacyMode => false;
-
- @override
bool get enableSuperMixins => true;
@override
@@ -163,7 +160,7 @@
arguments.named
.map((n) => MapEntry(SymbolLiteral(n.name), n.value))
.toList(),
- keyType: coreTypes.symbolClass.rawType));
+ keyType: coreTypes.symbolLegacyRawType));
}
return createInvocation('method', ctorArgs);
}
diff --git a/pkg/dev_compiler/test/modular_ddc_suite.dart b/pkg/dev_compiler/test/modular_ddc_suite.dart
new file mode 100644
index 0000000..3d75a07
--- /dev/null
+++ b/pkg/dev_compiler/test/modular_ddc_suite.dart
@@ -0,0 +1,313 @@
+// Copyright (c) 2019, 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.
+
+/// Test the modular compilation pipeline of ddc.
+///
+/// This is a shell that runs multiple tests, one per folder under `data/`.
+import 'dart:io';
+
+import 'package:modular_test/src/io_pipeline.dart';
+import 'package:modular_test/src/pipeline.dart';
+import 'package:modular_test/src/suite.dart';
+import 'package:modular_test/src/runner.dart';
+
+// TODO(vsm): Hack until we have either:
+// (1) an NNBD version of the below
+// (2) the ability to compile the primary version with NNBD
+List<String> _nnbdOptOut = ['sdk'];
+String _test_package = 'ddc_modular_test';
+
+Uri sdkRoot = Platform.script.resolve("../../../");
+Options _options;
+String _dartdevcScript;
+String _buildSdkScript;
+String _patchSdkScript;
+String _sdkDevRuntime;
+
+main(List<String> args) async {
+ _options = Options.parse(args);
+ await _resolveScripts();
+ await runSuite(
+ sdkRoot.resolve('tests/modular/'),
+ 'tests/modular',
+ _options,
+ IOPipeline([
+ DDCStep(),
+ RunD8(),
+ ], cacheSharedModules: true, saveIntermediateResultsForTesting: false));
+}
+
+const sumId = DataId("sum");
+const jsId = DataId("js");
+const txtId = DataId("txt");
+
+class DDCStep implements IOModularStep {
+ @override
+ List<DataId> get resultData => const [sumId, jsId];
+
+ @override
+ bool get needsSources => true;
+
+ @override
+ List<DataId> get dependencyDataNeeded => const [sumId];
+
+ @override
+ List<DataId> get moduleDataNeeded => const [];
+
+ @override
+ bool get onlyOnMain => false;
+
+ @override
+ Future<void> execute(Module module, Uri root, ModuleDataToRelativeUri toUri,
+ List<String> flags) async {
+ if (_options.verbose) print("\nstep: ddc on $module");
+
+ Set<Module> transitiveDependencies = computeTransitiveDependencies(module);
+ await _createPackagesFile(module, root, transitiveDependencies);
+
+ ProcessResult result;
+
+ bool nnbd = flags.contains('non-nullable');
+ bool allowErrors = nnbd && _nnbdOptOut.contains(module.name);
+
+ if (module.isSdk) {
+ assert(transitiveDependencies.isEmpty);
+
+ // Apply patches.
+ result = await _runProcess(
+ Platform.resolvedExecutable,
+ [
+ _patchSdkScript,
+ sdkRoot.toFilePath(),
+ _sdkDevRuntime,
+ 'patched_sdk',
+ if (nnbd) 'sdk_nnbd'
+ ],
+ root.toFilePath());
+ _checkExitCode(result, this, module);
+
+ // Build the SDK.
+ result = await _runProcess(
+ Platform.resolvedExecutable,
+ [
+ _buildSdkScript,
+ '--dart-sdk',
+ 'patched_sdk',
+ '--dart-sdk-summary=build',
+ '--summary-out',
+ '${toUri(module, sumId)}',
+ '--modules=es6',
+ if (allowErrors) '--unsafe-force-compile',
+ for (String flag in flags) '--enable-experiment=$flag',
+ '-o',
+ '${toUri(module, jsId)}',
+ ],
+ root.toFilePath());
+ _checkExitCode(result, this, module);
+ } else {
+ Module sdkModule = module.dependencies.firstWhere((m) => m.isSdk);
+ List<String> sources = module.sources
+ .map((relativeUri) => _sourceToImportUri(module, relativeUri))
+ .toList();
+ Map<String, String> _urlMappings = {};
+ if (!module.isPackage) {
+ for (var source in module.sources) {
+ var importUri = _sourceToImportUri(module, source);
+ _urlMappings[importUri] = '$source';
+ }
+ }
+ for (var dependency in transitiveDependencies) {
+ if (!dependency.isPackage && !dependency.isSdk) {
+ for (var source in dependency.sources) {
+ var importUri = _sourceToImportUri(dependency, source);
+ _urlMappings[importUri] = '$source';
+ }
+ }
+ }
+ var extraArgs = [
+ '--dart-sdk-summary',
+ '${toUri(sdkModule, sumId)}',
+ '--packages',
+ '.packages',
+ ];
+
+ Uri output = toUri(module, jsId);
+
+ List<String> args = [
+ '--packages=${sdkRoot.toFilePath()}/.packages',
+ _dartdevcScript,
+ '--modules=es6',
+ '--summarize',
+ '--no-source-map',
+ ...sources,
+ if (_urlMappings.isNotEmpty)
+ '--url-mapping=${_urlMappings.entries.map((entry) => '${entry.key},${entry.value}').join(',')}',
+ ...extraArgs,
+ for (String flag in flags) '--enable-experiment=$flag',
+ ...(transitiveDependencies
+ .where((m) => !m.isSdk)
+ .expand((m) => ['-s', '${toUri(m, sumId)}'])),
+ '-o',
+ '$output',
+ ];
+ result = await _runProcess(
+ Platform.resolvedExecutable, args, root.toFilePath());
+ _checkExitCode(result, this, module);
+ }
+ }
+
+ @override
+ void notifyCached(Module module) {
+ if (_options.verbose) print("\ncached step: ddc on $module");
+ }
+}
+
+class RunD8 implements IOModularStep {
+ @override
+ List<DataId> get resultData => const [txtId];
+
+ @override
+ bool get needsSources => false;
+
+ @override
+ List<DataId> get dependencyDataNeeded => const [jsId];
+
+ @override
+ List<DataId> get moduleDataNeeded => const [jsId];
+
+ @override
+ bool get onlyOnMain => true;
+
+ @override
+ Future<void> execute(Module module, Uri root, ModuleDataToRelativeUri toUri,
+ List<String> flags) async {
+ if (_options.verbose) print("\nstep: d8 on $module");
+
+ // Rename sdk.js to dart_sdk.js (the alternative, but more hermetic solution
+ // would be to rename the import on all other .js files, but seems
+ // overkill/unnecessary.
+ if (await File.fromUri(root.resolve('dart_sdk.js')).exists()) {
+ throw 'error: dart_sdk.js already exists.';
+ }
+
+ await File.fromUri(root.resolve('sdk.js'))
+ .copy(root.resolve('dart_sdk.js').toFilePath());
+ var runjs = '''
+ import { dart, _isolate_helper } from 'dart_sdk.js';
+ import { main } from 'main.js';
+ _isolate_helper.startRootIsolate(() => {}, []);
+ main.main();
+ ''';
+
+ var wrapper =
+ root.resolveUri(toUri(module, jsId)).toFilePath() + ".wrapper.js";
+ await File(wrapper).writeAsString(runjs);
+ List<String> d8Args = ['--module', wrapper];
+ var result = await _runProcess(
+ sdkRoot.resolve(_d8executable).toFilePath(), d8Args, root.toFilePath());
+
+ _checkExitCode(result, this, module);
+
+ await File.fromUri(root.resolveUri(toUri(module, txtId)))
+ .writeAsString(result.stdout as String);
+ }
+
+ @override
+ void notifyCached(Module module) {
+ if (_options.verbose) print("\ncached step: d8 on $module");
+ }
+}
+
+void _checkExitCode(ProcessResult result, IOModularStep step, Module module) {
+ if (result.exitCode != 0 || _options.verbose) {
+ stdout.write(result.stdout);
+ stderr.write(result.stderr);
+ }
+ if (result.exitCode != 0) {
+ throw "${step.runtimeType} failed on $module:\n\n"
+ "stdout:\n${result.stdout}\n\n"
+ "stderr:\n${result.stderr}";
+ }
+}
+
+Future<ProcessResult> _runProcess(
+ String command, List<String> arguments, String workingDirectory) {
+ if (_options.verbose) {
+ print('command:\n$command ${arguments.join(' ')} from $workingDirectory');
+ }
+ return Process.run(command, arguments, workingDirectory: workingDirectory);
+}
+
+String get _d8executable {
+ if (Platform.isWindows) {
+ return 'third_party/d8/windows/d8.exe';
+ } else if (Platform.isLinux) {
+ return 'third_party/d8/linux/d8';
+ } else if (Platform.isMacOS) {
+ return 'third_party/d8/macos/d8';
+ }
+ throw UnsupportedError('Unsupported platform.');
+}
+
+Future<void> _createPackagesFile(
+ Module module, Uri root, Set<Module> transitiveDependencies) async {
+ // We create a .packages file which defines the location of this module if
+ // it is a package. The CFE requires that if a `package:` URI of a
+ // dependency is used in an import, then we need that package entry in the
+ // .packages file. However, after it checks that the definition exists, the
+ // CFE will not actually use the resolved URI if a library for the import
+ // URI is already found in one of the provided .dill files of the
+ // dependencies. For that reason, and to ensure that a step only has access
+ // to the files provided in a module, we generate a .packages with invalid
+ // folders for other packages.
+ // TODO(sigmund): follow up with the CFE to see if we can remove the need
+ // for the .packages entry altogether if they won't need to read the
+ // sources.
+ var packagesContents = StringBuffer();
+ if (module.isPackage) {
+ packagesContents.write('${module.name}:${module.packageBase}\n');
+ }
+ for (Module dependency in transitiveDependencies) {
+ if (dependency.isPackage) {
+ packagesContents.write('${dependency.name}:unused\n');
+ }
+ }
+
+ await File.fromUri(root.resolve('.packages'))
+ .writeAsString('$packagesContents');
+}
+
+String _sourceToImportUri(Module module, Uri relativeUri) {
+ if (module.isPackage) {
+ var basePath = module.packageBase.path;
+ var packageRelativePath = basePath == "./"
+ ? relativeUri.path
+ : relativeUri.path.substring(basePath.length);
+ return 'package:${module.name}/$packageRelativePath';
+ } else {
+ return 'package:${_test_package}/$relativeUri';
+ }
+}
+
+Future<void> _resolveScripts() async {
+ Future<String> resolve(String sdkSourcePath,
+ [String relativeSnapshotPath]) async {
+ String result = sdkRoot.resolve(sdkSourcePath).toFilePath();
+ if (_options.useSdk && relativeSnapshotPath != null) {
+ String snapshot = Uri.file(Platform.resolvedExecutable)
+ .resolve(relativeSnapshotPath)
+ .toFilePath();
+ if (await File(snapshot).exists()) {
+ return snapshot;
+ }
+ }
+ return result;
+ }
+
+ _dartdevcScript = await resolve(
+ 'pkg/dev_compiler/bin/dartdevc.dart', 'snapshots/dartdevc.dart.snapshot');
+ _buildSdkScript = await resolve('pkg/dev_compiler/tool/build_sdk.dart');
+ _patchSdkScript = await resolve('pkg/dev_compiler/tool/patch_sdk.dart');
+ _sdkDevRuntime = await resolve('sdk/lib/_internal/js_dev_runtime');
+}
diff --git a/pkg/dev_compiler/test/nullable_inference_test.dart b/pkg/dev_compiler/test/nullable_inference_test.dart
index fe8f787..d79ce0b 100644
--- a/pkg/dev_compiler/test/nullable_inference_test.dart
+++ b/pkg/dev_compiler/test/nullable_inference_test.dart
@@ -43,7 +43,7 @@
});
test('Map', () async {
await expectNotNull('main() { print({"x": null}); }',
- '<dart.core::String*, dart.core::Null*>{"x": null}, "x"');
+ '<dart.core::String*, dart.core::Null?>{"x": null}, "x"');
});
test('Symbol', () async {
@@ -249,7 +249,7 @@
test('function expression', () async {
await expectNotNull('main() { () => null; f() {}; f; }',
- '() → dart.core::Null* => null, f');
+ '() → dart.core::Null? => null, f');
});
test('cascades (kernel let)', () async {
@@ -391,7 +391,7 @@
var x = () => 42;
var y = (() => x = null);
}''',
- '() → dart.core::int* => 42, 42, () → dart.core::Null* => x = null');
+ '() → dart.core::int* => 42, 42, () → dart.core::Null? => x = null');
});
test('do not depend on unrelated variables', () async {
await expectNotNull('''main() {
@@ -495,7 +495,19 @@
var actualNotNull = collector.notNullExpressions
// ConstantExpressions print the table offset - we want to compare
// against the underlying constant value instead.
- .map((e) => (e is ConstantExpression ? e.constant : e).toString())
+ .map((e) {
+ if (e is ConstantExpression) {
+ Constant c = e.constant;
+ if (c is DoubleConstant &&
+ c.value.isFinite &&
+ c.value.truncateToDouble() == c.value) {
+ // Print integer values as integers
+ return BigInt.from(c.value).toString();
+ }
+ return c.toString();
+ }
+ return e.toString();
+ })
// Filter out our own NotNull annotations. The library prefix changes
// per test, so just filter on the suffix.
.where((s) => !s.endsWith('::_NotNull {}'))
diff --git a/pkg/dev_compiler/tool/ddb b/pkg/dev_compiler/tool/ddb
index ff8e482..2a73fd9 100755
--- a/pkg/dev_compiler/tool/ddb
+++ b/pkg/dev_compiler/tool/ddb
@@ -25,7 +25,7 @@
}
// Parse flags.
- var parser = new ArgParser()
+ var parser = ArgParser()
..addFlag('help', abbr: 'h', help: 'Display this message.')
..addFlag('kernel',
abbr: 'k', help: 'Compile with the new kernel-based front end.')
@@ -37,6 +37,12 @@
abbr: 'd',
help: 'Use current source instead of built SDK.',
defaultsTo: false)
+ ..addFlag('observe',
+ help:
+ 'Run the compiler in the Dart VM with --observe. Implies --debug.',
+ defaultsTo: false)
+ ..addOption('vm-service-port',
+ help: 'Specify the observatory port. Implied --observe.')
..addFlag('summarize-text',
help: 'Emit API summary in a .js.txt file.\n'
'Ignored when not passed with --kernel.',
@@ -59,7 +65,7 @@
defaultsTo: 'all');
var options = parser.parse(args);
- if (options['help']) {
+ if (options['help'] as bool) {
printUsage();
print('Available options:');
print(parser.usage);
@@ -70,7 +76,9 @@
printUsage();
exit(1);
}
- var debug = options['debug'] as bool;
+ var debug = options['debug'] as bool ||
+ options['observe'] as bool ||
+ options.wasParsed('vm-service-port');
var kernel = options['kernel'] as bool;
var summarizeText = options['summarize-text'] as bool;
var binary = options['binary'] as String;
@@ -106,35 +114,37 @@
var ddcPath = p.dirname(p.dirname(toolPath));
var dartCheckoutPath = p.dirname(p.dirname(ddcPath));
- ProcessResult runDdc(String command, List<String> args) {
+ Future<void> runDdc(String command, List<String> args) async {
if (debug) {
// Use unbuilt script. This only works from a source checkout.
- args.insertAll(
- 0, ['--enable-asserts', p.join(ddcPath, 'bin', '$command.dart')]);
+ var vmServicePort = options.wasParsed('vm-service-port')
+ ? '=${options['vm-service-port']}'
+ : '';
+ var observe =
+ options.wasParsed('vm-service-port') || options['observe'] as bool;
+ args.insertAll(0, [
+ if (observe) ...[
+ '--enable-vm-service$vmServicePort',
+ '--pause-isolates-on-start',
+ ],
+ '--enable-asserts',
+ p.join(ddcPath, 'bin', '$command.dart')
+ ]);
command = dartBinary;
} else {
// Use built snapshot.
command = p.join(dartSdk, 'bin', command);
}
- return Process.runSync(command, args);
- }
-
- /// Writes stdout and stderr from [result] to this process.
- ///
- /// Will exit with the exit code from [result] when it's not zero.
- void echoResult(ProcessResult result) async {
- stdout.write(result.stdout);
- await stdout.flush();
- stderr.write(result.stderr);
- await stderr.flush();
- if (result.exitCode != 0) exit(result.exitCode);
+ var process =
+ await Process.start(command, args, mode: ProcessStartMode.inheritStdio);
+ if (await process.exitCode != 0) exit(await process.exitCode);
}
String mod;
bool chrome = false;
bool node = false;
bool d8 = false;
- switch (options['runtime']) {
+ switch (options['runtime'] as String) {
case 'node':
node = true;
mod = 'common';
@@ -163,7 +173,6 @@
ddcSdk = p.join(
dartSdk, 'lib', '_internal', kernel ? 'ddc_sdk.dill' : 'ddc_sdk.sum');
- ProcessResult result;
if (compile) {
var ddcArgs = [
if (kernel) '--kernel',
@@ -181,8 +190,7 @@
entry
];
- result = runDdc('dartdevc', ddcArgs);
- await echoResult(result);
+ await runDdc('dartdevc', ddcArgs);
}
if (run) {
@@ -219,16 +227,20 @@
</script>
''';
var htmlFile = p.setExtension(entry, '.html');
- new File(htmlFile).writeAsStringSync(html);
+ File(htmlFile).writeAsStringSync(html);
var tmp = p.join(Directory.systemTemp.path, 'ddc');
- result = Process.runSync(chromeBinary, [
- '--auto-open-devtools-for-tabs',
- '--allow-file-access-from-files',
- '--remote-debugging-port=$port',
- '--user-data-dir=$tmp',
- htmlFile
- ]);
+ var process = await Process.start(
+ chromeBinary,
+ [
+ '--auto-open-devtools-for-tabs',
+ '--allow-file-access-from-files',
+ '--remote-debugging-port=$port',
+ '--user-data-dir=$tmp',
+ htmlFile
+ ],
+ mode: ProcessStartMode.inheritStdio);
+ if (await process.exitCode != 0) exit(await process.exitCode);
} else if (node) {
var nodePath = '$sdkJsPath:$libRoot';
var runjs = '''
@@ -251,11 +263,13 @@
}
''';
var nodeFile = p.setExtension(entry, '.run.js');
- new File(nodeFile).writeAsStringSync(runjs);
+ File(nodeFile).writeAsStringSync(runjs);
var nodeBinary = binary ?? 'node';
- result = Process.runSync(
+ var process = await Process.start(
nodeBinary, ['--inspect=localhost:$port', nodeFile],
- environment: {'NODE_PATH': nodePath});
+ environment: {'NODE_PATH': nodePath},
+ mode: ProcessStartMode.inheritStdio);
+ if (await process.exitCode != 0) exit(await process.exitCode);
} else if (d8) {
// Fix SDK import. `d8` doesn't let us set paths, so we need a full path
// to the SDK.
@@ -278,11 +292,12 @@
}
''';
var d8File = p.setExtension(entry, '.d8.js');
- new File(d8File).writeAsStringSync(runjs);
+ File(d8File).writeAsStringSync(runjs);
var d8Binary = binary ?? p.join(dartCheckoutPath, _d8executable);
- result = Process.runSync(d8Binary, ['--module', d8File]);
+ var process = await Process.start(d8Binary, ['--module', d8File],
+ mode: ProcessStartMode.inheritStdio);
+ if (await process.exitCode != 0) exit(await process.exitCode);
}
- await echoResult(result);
}
}
@@ -294,5 +309,5 @@
} else if (Platform.isMacOS) {
return p.join('third_party', 'd8', 'macos', 'd8');
}
- throw new UnsupportedError('Unsupported platform.');
+ throw UnsupportedError('Unsupported platform.');
}
diff --git a/pkg/dev_compiler/tool/kernel_sdk.dart b/pkg/dev_compiler/tool/kernel_sdk.dart
index 004097b..81eb813 100755
--- a/pkg/dev_compiler/tool/kernel_sdk.dart
+++ b/pkg/dev_compiler/tool/kernel_sdk.dart
@@ -7,6 +7,7 @@
import 'dart:convert' show json;
import 'dart:io';
import 'package:args/args.dart' show ArgParser;
+import 'package:build_integration/file_system/multi_root.dart';
import 'package:dev_compiler/src/compiler/module_builder.dart';
import 'package:dev_compiler/src/compiler/shared_command.dart'
show SharedCompilerOptions;
@@ -16,10 +17,11 @@
import 'package:front_end/src/api_unstable/ddc.dart'
show
CompilerOptions,
- kernelForModule,
DiagnosticMessage,
- printDiagnosticMessage,
- Severity;
+ Severity,
+ StandardFileSystem,
+ kernelForModule,
+ printDiagnosticMessage;
import 'package:kernel/kernel.dart';
import 'package:kernel/target/targets.dart';
import 'package:path/path.dart' as p;
@@ -55,17 +57,33 @@
}
}
+ String customScheme = "org-dartlang-sdk";
+ var fileSystem = MultiRootFileSystem(
+ customScheme, [Uri.base], StandardFileSystem.instance);
+ Uri sdkRoot = Uri.parse("$customScheme:/");
+ Uri packagesFileUri = sdkRoot
+ .resolve(p.relative(Uri.file(packagesPath).path, from: Uri.base.path));
+ if (packagesFileUri.scheme != customScheme) {
+ throw "packagesPath has to be under ${Uri.base}";
+ }
+ Uri librariesSpecificationUri = sdkRoot
+ .resolve(p.relative(Uri.file(librarySpecPath).path, from: Uri.base.path));
+ if (librariesSpecificationUri.scheme != customScheme) {
+ throw "librarySpecPath has to be under ${Uri.base}";
+ }
+
var options = CompilerOptions()
..compileSdk = true
- // TODO(sigmund): remove these two unnecessary options when possible.
- ..sdkRoot = Uri.base
- ..packagesFileUri = Uri.base.resolveUri(Uri.file(packagesPath))
- ..librariesSpecificationUri = Uri.base.resolveUri(Uri.file(librarySpecPath))
+ ..fileSystem = fileSystem
+ ..sdkRoot = sdkRoot
+ ..packagesFileUri = packagesFileUri
+ ..librariesSpecificationUri = librariesSpecificationUri
..target = target
..onDiagnostic = onDiagnostic
..environmentDefines = {};
var inputs = target.extraRequiredLibraries.map(Uri.parse).toList();
+
var compilerResult = await kernelForModule(inputs, options);
var component = compilerResult.component;
@@ -92,7 +110,10 @@
var mapPath = '$jsPath.map';
await Directory(jsDir).create();
var jsCode = jsProgramToCode(jsModule, format,
- jsUrl: jsPath, mapUrl: mapPath, buildSourceMap: true);
+ jsUrl: jsPath,
+ mapUrl: mapPath,
+ buildSourceMap: true,
+ customScheme: customScheme);
await File(jsPath).writeAsString(jsCode.code);
await File(mapPath).writeAsString(json.encode(jsCode.sourceMap));
}
diff --git a/pkg/dev_compiler/tool/patch_sdk.dart b/pkg/dev_compiler/tool/patch_sdk.dart
index 5b268a8..543e90d 100755
--- a/pkg/dev_compiler/tool/patch_sdk.dart
+++ b/pkg/dev_compiler/tool/patch_sdk.dart
@@ -34,11 +34,16 @@
exit(1);
}
+ var sdk = 'sdk';
+ if (argv.length > 3) {
+ sdk = argv[3];
+ }
+
var selfModifyTime = File(self).lastModifiedSync().millisecondsSinceEpoch;
var repoDir = argv[0];
var patchDir = argv[1];
- var sdkLibIn = p.join(repoDir, 'sdk', 'lib');
+ var sdkLibIn = p.join(repoDir, sdk, 'lib');
var patchIn = p.join(patchDir, 'patch');
var privateIn = p.join(patchDir, 'private');
var sdkOut = p.join(argv[2], 'lib');
diff --git a/pkg/expect/lib/expect.dart b/pkg/expect/lib/expect.dart
index 954a653..9d1d5ea 100644
--- a/pkg/expect/lib/expect.dart
+++ b/pkg/expect/lib/expect.dart
@@ -540,10 +540,11 @@
*/
static void throws<T>(void f(),
[bool check(T error) = _defaultCheck, String reason = ""]) {
- // TODO(vsm): Make check nullable. Existing tests pass null to set
- // a reason.
- check = check ?? _defaultCheck;
- reason = reason ?? "";
+ // TODO(vsm): Make check and reason nullable or change call sites.
+ // Existing tests pass null to set a reason and/or pass them through
+ // via helpers.
+ check ??= _defaultCheck;
+ reason ??= "";
String msg = reason.isEmpty ? "" : "($reason)";
if (f is! Function()) {
// Only throws from executing the function body should count as throwing.
diff --git a/pkg/front_end/lib/src/api_prototype/compiler_options.dart b/pkg/front_end/lib/src/api_prototype/compiler_options.dart
index c2c76e5..301536d 100644
--- a/pkg/front_end/lib/src/api_prototype/compiler_options.dart
+++ b/pkg/front_end/lib/src/api_prototype/compiler_options.dart
@@ -110,9 +110,6 @@
@deprecated
bool chaseDependencies;
- /// True if enabling legacy mode (Dart 1 compatibility).
- bool legacyMode = false;
-
/// Patch files to apply on the core libraries for a specific target platform.
///
/// Keys in the map are the name of the library with no `dart:` prefix, for
diff --git a/pkg/front_end/lib/src/api_prototype/experimental_flags.dart b/pkg/front_end/lib/src/api_prototype/experimental_flags.dart
index 1c72931..052e2dd 100644
--- a/pkg/front_end/lib/src/api_prototype/experimental_flags.dart
+++ b/pkg/front_end/lib/src/api_prototype/experimental_flags.dart
@@ -15,6 +15,7 @@
setLiterals,
spreadCollections,
tripleShift,
+ variance,
}
ExperimentalFlag parseExperimentalFlag(String flag) {
@@ -33,6 +34,8 @@
return ExperimentalFlag.spreadCollections;
case "triple-shift":
return ExperimentalFlag.tripleShift;
+ case "variance":
+ return ExperimentalFlag.variance;
}
return null;
}
@@ -45,6 +48,7 @@
ExperimentalFlag.setLiterals: true,
ExperimentalFlag.spreadCollections: true,
ExperimentalFlag.tripleShift: false,
+ ExperimentalFlag.variance: false,
};
const Map<ExperimentalFlag, bool> expiredExperimentalFlags = {
@@ -55,4 +59,5 @@
ExperimentalFlag.setLiterals: true,
ExperimentalFlag.spreadCollections: true,
ExperimentalFlag.tripleShift: false,
+ ExperimentalFlag.variance: false,
};
diff --git a/pkg/front_end/lib/src/api_unstable/dart2js.dart b/pkg/front_end/lib/src/api_unstable/dart2js.dart
index 860f99f..fd6e8f0 100644
--- a/pkg/front_end/lib/src/api_unstable/dart2js.dart
+++ b/pkg/front_end/lib/src/api_unstable/dart2js.dart
@@ -132,7 +132,6 @@
CompilerOptions options = new CompilerOptions()
..target = target
- ..legacyMode = target.legacyMode
..linkedDependencies = linkedDependencies
..librariesSpecificationUri = librariesSpecificationUri
..packagesFileUri = packagesFileUri
diff --git a/pkg/front_end/lib/src/base/processed_options.dart b/pkg/front_end/lib/src/base/processed_options.dart
index 1f89337..28c54a7 100644
--- a/pkg/front_end/lib/src/base/processed_options.dart
+++ b/pkg/front_end/lib/src/base/processed_options.dart
@@ -298,8 +298,6 @@
/// effect.
void clearFileSystemCache() => _fileSystem = null;
- bool get legacyMode => _raw.legacyMode;
-
/// Whether to generate bytecode.
bool get bytecode => _raw.bytecode;
@@ -312,8 +310,8 @@
String get currentSdkVersion => _raw.currentSdkVersion;
Target _target;
- Target get target => _target ??=
- _raw.target ?? new NoneTarget(new TargetFlags(legacyMode: legacyMode));
+ Target get target =>
+ _target ??= _raw.target ?? new NoneTarget(new TargetFlags());
bool isExperimentEnabled(ExperimentalFlag flag) {
assert(defaultExperimentalFlags.containsKey(flag),
@@ -646,7 +644,6 @@
'(provided: ${_raw.librariesSpecificationUri})');
sb.writeln('SDK summary: ${_sdkSummary} (provided: ${_raw.sdkSummary})');
- sb.writeln('Legacy mode: ${legacyMode}');
sb.writeln('Target: ${_target?.name} (provided: ${_raw.target?.name})');
sb.writeln('throwOnErrorsForDebugging: ${throwOnErrorsForDebugging}');
diff --git a/pkg/front_end/lib/src/fasta/builder/class_builder.dart b/pkg/front_end/lib/src/fasta/builder/class_builder.dart
index 481328b..1687f79 100644
--- a/pkg/front_end/lib/src/fasta/builder/class_builder.dart
+++ b/pkg/front_end/lib/src/fasta/builder/class_builder.dart
@@ -44,6 +44,7 @@
import 'package:kernel/src/bounds_checks.dart'
show TypeArgumentIssue, findTypeArgumentIssues, getGenericTypeName;
+import 'package:kernel/text/text_serialization_verifier.dart';
import 'package:kernel/type_algebra.dart' show Substitution, substitute;
@@ -390,6 +391,10 @@
/// For a patch class the origin class is returned.
Class get cls;
+ InterfaceType _legacyRawType;
+ InterfaceType _nullableRawType;
+ InterfaceType _nonNullableRawType;
+
// Deliberately unrelated return type to statically detect more accidental
// use until Builder.target is fully retired.
UnrelatedTarget get target => unsupported(
@@ -406,12 +411,50 @@
@override
InterfaceType get thisType => cls.thisType;
+ InterfaceType get legacyRawType {
+ // TODO(dmitryas): Use computeBound instead of DynamicType here?
+ return _legacyRawType ??= new InterfaceType(
+ cls,
+ new List<DartType>.filled(typeVariablesCount, const DynamicType()),
+ Nullability.legacy);
+ }
+
+ InterfaceType get nullableRawType {
+ // TODO(dmitryas): Use computeBound instead of DynamicType here?
+ return _nullableRawType ??= new InterfaceType(
+ cls,
+ new List<DartType>.filled(typeVariablesCount, const DynamicType()),
+ Nullability.nullable);
+ }
+
+ InterfaceType get nonNullableRawType {
+ // TODO(dmitryas): Use computeBound instead of DynamicType here?
+ return _nonNullableRawType ??= new InterfaceType(
+ cls,
+ new List<DartType>.filled(typeVariablesCount, const DynamicType()),
+ Nullability.nonNullable);
+ }
+
+ InterfaceType rawType(Nullability nullability) {
+ switch (nullability) {
+ case Nullability.legacy:
+ return legacyRawType;
+ case Nullability.nullable:
+ return nullableRawType;
+ case Nullability.nonNullable:
+ return nonNullableRawType;
+ case Nullability.neither:
+ default:
+ return unhandled("$nullability", "rawType", noOffset, noUri);
+ }
+ }
+
/// [arguments] have already been built.
InterfaceType buildTypesWithBuiltArguments(LibraryBuilder library,
Nullability nullability, List<DartType> arguments) {
assert(arguments == null || cls.typeParameters.length == arguments.length);
return arguments == null
- ? cls.rawType
+ ? rawType(nullability)
: new InterfaceType(cls, arguments, nullability);
}
@@ -436,11 +479,11 @@
return result;
}
- if (arguments != null && arguments.length != (typeVariables?.length ?? 0)) {
+ if (arguments != null && arguments.length != typeVariablesCount) {
// That should be caught and reported as a compile-time error earlier.
return unhandled(
templateTypeArgumentMismatch
- .withArguments(typeVariables.length)
+ .withArguments(typeVariablesCount)
.message,
"buildTypeArguments",
-1,
@@ -1040,8 +1083,7 @@
interfaceMember.fileOffset, noLength)
] +
inheritedContext(isInterfaceCheck, declaredMember));
- } else if (!library.loader.target.backendTarget.legacyMode &&
- declaredFunction?.typeParameters != null) {
+ } else if (declaredFunction?.typeParameters != null) {
Map<TypeParameter, DartType> substitutionMap =
<TypeParameter, DartType>{};
for (int i = 0; i < declaredFunction.typeParameters.length; ++i) {
@@ -1109,8 +1151,6 @@
VariableDeclaration declaredParameter,
bool isInterfaceCheck,
{bool asIfDeclaredParameter = false}) {
- if (library.loader.target.backendTarget.legacyMode) return;
-
if (interfaceSubstitution != null) {
interfaceType = interfaceSubstitution.substituteType(interfaceType);
}
@@ -1619,7 +1659,7 @@
// its enclosing class, because constructors cannot specify type parameters
// of their own.
FunctionType factoryType =
- factory.procedure.function.functionType.withoutTypeParameters;
+ factory.procedure.function.thisFunctionType.withoutTypeParameters;
FunctionType redirecteeType =
computeRedirecteeType(factory, typeEnvironment);
diff --git a/pkg/front_end/lib/src/fasta/builder/enum_builder.dart b/pkg/front_end/lib/src/fasta/builder/enum_builder.dart
index dcb82cb..df6cd20 100644
--- a/pkg/front_end/lib/src/fasta/builder/enum_builder.dart
+++ b/pkg/front_end/lib/src/fasta/builder/enum_builder.dart
@@ -265,8 +265,7 @@
InterfaceType buildType(LibraryBuilder library, Nullability nullability,
List<TypeBuilder> arguments) {
- // TODO(dmitryas): Use [nullability].
- return cls.rawType;
+ return rawType(nullability);
}
@override
@@ -300,8 +299,8 @@
}
FieldBuilder valuesBuilder = firstMemberNamed("values");
valuesBuilder.build(libraryBuilder);
- valuesBuilder.initializer =
- new ListLiteral(values, typeArgument: cls.rawType, isConst: true);
+ valuesBuilder.initializer = new ListLiteral(values,
+ typeArgument: rawType(library.nonNullable), isConst: true);
ConstructorBuilder constructorBuilder = constructorScopeBuilder[""];
Constructor constructor = constructorBuilder.build(libraryBuilder);
constructor.initializers.insert(
diff --git a/pkg/front_end/lib/src/fasta/builder/field_builder.dart b/pkg/front_end/lib/src/fasta/builder/field_builder.dart
index 44bba27..6ef5385 100644
--- a/pkg/front_end/lib/src/fasta/builder/field_builder.dart
+++ b/pkg/front_end/lib/src/fasta/builder/field_builder.dart
@@ -91,9 +91,7 @@
}
bool get isEligibleForInference {
- return !library.legacyMode &&
- type == null &&
- (hasInitializer || isClassInstanceMember);
+ return type == null && (hasInitializer || isClassInstanceMember);
}
Field build(SourceLibraryBuilder libraryBuilder) {
@@ -167,7 +165,7 @@
.createBodyBuilderForOutlineExpression(
library, classBuilder, this, scope, fileUri);
bodyBuilder.constantContext =
- isConst ? ConstantContext.inferred : ConstantContext.none;
+ isConst ? ConstantContext.inferred : ConstantContext.required;
initializer = bodyBuilder.parseFieldInitializer(constInitializerToken)
..parent = field;
bodyBuilder.typeInferrer
diff --git a/pkg/front_end/lib/src/fasta/builder/formal_parameter_builder.dart b/pkg/front_end/lib/src/fasta/builder/formal_parameter_builder.dart
index 4e7e8c3..3083665 100644
--- a/pkg/front_end/lib/src/fasta/builder/formal_parameter_builder.dart
+++ b/pkg/front_end/lib/src/fasta/builder/formal_parameter_builder.dart
@@ -41,7 +41,7 @@
MetadataBuilder,
TypeBuilder;
-import '../kernel/kernel_shadow_ast.dart' show VariableDeclarationJudgment;
+import '../kernel/kernel_shadow_ast.dart' show VariableDeclarationImpl;
/// A builder for a formal parameter, i.e. a parameter on a method or
/// constructor.
@@ -99,7 +99,7 @@
VariableDeclaration build(
SourceLibraryBuilder library, int functionNestingLevel) {
if (variable == null) {
- variable = new VariableDeclarationJudgment(name, functionNestingLevel,
+ variable = new VariableDeclarationImpl(name, functionNestingLevel,
type: type?.build(library),
isFinal: isFinal,
isConst: isConst,
diff --git a/pkg/front_end/lib/src/fasta/builder/function_type_builder.dart b/pkg/front_end/lib/src/fasta/builder/function_type_builder.dart
index 16c1282..f591207 100644
--- a/pkg/front_end/lib/src/fasta/builder/function_type_builder.dart
+++ b/pkg/front_end/lib/src/fasta/builder/function_type_builder.dart
@@ -4,7 +4,8 @@
library fasta.function_type_builder;
-import 'builder.dart' show LibraryBuilder, TypeBuilder, TypeVariableBuilder;
+import 'builder.dart'
+ show LibraryBuilder, NullabilityBuilder, TypeBuilder, TypeVariableBuilder;
import 'package:kernel/ast.dart'
show
@@ -32,8 +33,10 @@
final TypeBuilder returnType;
final List<TypeVariableBuilder> typeVariables;
final List<FormalParameterBuilder> formals;
+ final NullabilityBuilder nullabilityBuilder;
- FunctionTypeBuilder(this.returnType, this.typeVariables, this.formals);
+ FunctionTypeBuilder(this.returnType, this.typeVariables, this.formals,
+ this.nullabilityBuilder);
@override
String get name => null;
@@ -68,7 +71,9 @@
buffer.write(t?.fullNameForErrors);
}
}
- buffer.write(") -> ");
+ buffer.write(") ->");
+ nullabilityBuilder.writeNullabilityOn(buffer);
+ buffer.write(" ");
buffer.write(returnType?.fullNameForErrors);
return buffer;
}
@@ -106,7 +111,8 @@
namedParameters: namedParameters ?? const <NamedType>[],
typeParameters: typeParameters ?? const <TypeParameter>[],
requiredParameterCount: requiredParameterCount,
- typedefType: origin);
+ typedefType: origin,
+ nullability: nullabilityBuilder.build(library));
}
Supertype buildSupertype(
@@ -143,7 +149,10 @@
}
}
FunctionTypeBuilder newType = new FunctionTypeBuilder(
- returnType?.clone(newTypes), clonedTypeVariables, clonedFormals);
+ returnType?.clone(newTypes),
+ clonedTypeVariables,
+ clonedFormals,
+ nullabilityBuilder);
newTypes.add(newType);
return newType;
}
diff --git a/pkg/front_end/lib/src/fasta/builder/library_builder.dart b/pkg/front_end/lib/src/fasta/builder/library_builder.dart
index 44d9beb..27f7bbf 100644
--- a/pkg/front_end/lib/src/fasta/builder/library_builder.dart
+++ b/pkg/front_end/lib/src/fasta/builder/library_builder.dart
@@ -4,7 +4,7 @@
library fasta.library_builder;
-import 'package:kernel/ast.dart' show Library;
+import 'package:kernel/ast.dart' show Library, Nullability;
import '../combinator.dart' show Combinator;
@@ -60,8 +60,6 @@
exportScopeBuilder = new ScopeBuilder(exportScope),
super(null, -1, fileUri);
- bool get legacyMode => false;
-
bool get isSynthetic => false;
// Deliberately unrelated return type to statically detect more accidental
@@ -274,9 +272,26 @@
List<FieldBuilder> takeImplicitlyTypedFields() => null;
- // TODO(dmitryas): Compute the predicate using the library version instead.
+ // TODO(38287): Compute the predicate using the library version instead.
bool get isNonNullableByDefault => loader.target.enableNonNullable;
+ Nullability get nullable {
+ return isNonNullableByDefault ? Nullability.nullable : Nullability.legacy;
+ }
+
+ Nullability get nonNullable {
+ return isNonNullableByDefault
+ ? Nullability.nonNullable
+ : Nullability.legacy;
+ }
+
+ Nullability nullableIfTrue(bool isNullable) {
+ if (isNonNullableByDefault) {
+ return isNullable ? Nullability.nullable : Nullability.nonNullable;
+ }
+ return Nullability.legacy;
+ }
+
NullabilityBuilder computeNullabilityFromToken(bool markedAsNullable) {
if (!isNonNullableByDefault) {
return const NullabilityBuilder.legacy();
diff --git a/pkg/front_end/lib/src/fasta/builder/nullability_builder.dart b/pkg/front_end/lib/src/fasta/builder/nullability_builder.dart
index dbe2ed7..4f67b7c 100644
--- a/pkg/front_end/lib/src/fasta/builder/nullability_builder.dart
+++ b/pkg/front_end/lib/src/fasta/builder/nullability_builder.dart
@@ -35,6 +35,19 @@
const NullabilityBuilder.omitted()
: _syntacticNullability = SyntacticNullability.omitted;
+ factory NullabilityBuilder.fromNullability(Nullability nullability) {
+ switch (nullability) {
+ case Nullability.nullable:
+ return const NullabilityBuilder.nullable();
+ case Nullability.legacy:
+ return const NullabilityBuilder.legacy();
+ case Nullability.nonNullable:
+ case Nullability.neither:
+ default:
+ return const NullabilityBuilder.omitted();
+ }
+ }
+
/// Used temporarily in the places that need proper handling of NNBD features.
///
/// Over time the uses of [NullabilityBuilder.pendingImplementation] should be
@@ -42,7 +55,7 @@
/// it redirects to [NullabilityBuilder.legacy] as a conservative safety
/// measure for the pre-NNBD code and as a visible reminder of the feature
/// implementation being in progress in the NNBD code.
- // TODO(dmitryas): Remove this constructor.
+ // TODO(38286): Remove this constructor.
const NullabilityBuilder.pendingImplementation() : this.legacy();
Nullability build(LibraryBuilder libraryBuilder, {Nullability ifOmitted}) {
diff --git a/pkg/front_end/lib/src/fasta/builder/procedure_builder.dart b/pkg/front_end/lib/src/fasta/builder/procedure_builder.dart
index e39c9c2..bf45b08 100644
--- a/pkg/front_end/lib/src/fasta/builder/procedure_builder.dart
+++ b/pkg/front_end/lib/src/fasta/builder/procedure_builder.dart
@@ -45,7 +45,7 @@
TypeVariableBuilder,
isRedirectingGenerativeConstructorImplementation;
-import '../kernel/kernel_shadow_ast.dart' show VariableDeclarationJudgment;
+import '../kernel/kernel_shadow_ast.dart' show VariableDeclarationImpl;
import '../kernel/redirecting_factory_body.dart' show RedirectingFactoryBody;
@@ -301,7 +301,7 @@
// Do this after building the parameters, since the diet listener
// assumes that parameters are built, even if illegal in number.
VariableDeclaration parameter =
- new VariableDeclarationJudgment("#synthetic", 0);
+ new VariableDeclarationImpl("#synthetic", 0);
result.positionalParameters.clear();
result.positionalParameters.add(parameter);
parameter.parent = result;
@@ -515,7 +515,7 @@
List<Statement> statements = [];
Block block = new Block(statements);
VariableDeclaration variableDeclaration =
- new VariableDeclarationJudgment.forValue(
+ new VariableDeclarationImpl.forValue(
new VariableGet(value)..fileOffset = procedure.fileOffset)
..type = value.type;
statements.add(variableDeclaration);
@@ -549,7 +549,6 @@
}
bool get isEligibleForTopLevelInference {
- if (library.legacyMode) return false;
if (isDeclarationInstanceMember) {
if (returnType == null) return true;
if (formals != null) {
@@ -864,7 +863,6 @@
}
bool get isEligibleForTopLevelInference {
- if (library.legacyMode) return false;
if (formals != null) {
for (FormalParameterBuilder formal in formals) {
if (formal.type == null && formal.isInitializingFormal) return true;
@@ -907,7 +905,7 @@
BodyBuilder bodyBuilder = library.loader
.createBodyBuilderForOutlineExpression(
library, classBuilder, this, classBuilder.scope, fileUri);
- bodyBuilder.constantContext = ConstantContext.inferred;
+ bodyBuilder.constantContext = ConstantContext.required;
bodyBuilder.parseInitializers(beginInitializers);
bodyBuilder.resolveRedirectingFactoryTargets();
}
diff --git a/pkg/front_end/lib/src/fasta/command_line_reporting.dart b/pkg/front_end/lib/src/fasta/command_line_reporting.dart
index 8aad521..3b00c71 100644
--- a/pkg/front_end/lib/src/fasta/command_line_reporting.dart
+++ b/pkg/front_end/lib/src/fasta/command_line_reporting.dart
@@ -180,7 +180,7 @@
return true;
case Severity.errorLegacyWarning:
- return !CompilerContext.current.options.legacyMode;
+ return true;
case Severity.warning:
case Severity.context:
diff --git a/pkg/front_end/lib/src/fasta/dill/dill_library_builder.dart b/pkg/front_end/lib/src/fasta/dill/dill_library_builder.dart
index 56c203ae..e227553 100644
--- a/pkg/front_end/lib/src/fasta/dill/dill_library_builder.dart
+++ b/pkg/front_end/lib/src/fasta/dill/dill_library_builder.dart
@@ -96,8 +96,6 @@
/// [../kernel/kernel_library_builder.dart].
Map<String, String> unserializableExports;
- bool exportsAlreadyFinalized = false;
-
// TODO(jensj): These 4 booleans could potentially be merged into a single
// state field.
bool isReadyToBuild = false;
@@ -116,6 +114,11 @@
void ensureLoaded() {
if (!isReadyToBuild) throw new StateError("Not ready to build.");
+ if (isBuilt && !isBuiltAndMarked) {
+ isBuiltAndMarked = true;
+ finalizeExports();
+ return;
+ }
isBuiltAndMarked = true;
if (isBuilt) return;
isBuilt = true;
@@ -251,8 +254,6 @@
}
void finalizeExports() {
- if (exportsAlreadyFinalized) return;
- exportsAlreadyFinalized = true;
unserializableExports?.forEach((String name, String messageText) {
Builder declaration;
switch (name) {
diff --git a/pkg/front_end/lib/src/fasta/fasta_codes_generated.dart b/pkg/front_end/lib/src/fasta/fasta_codes_generated.dart
index d5482bf..a2a2622 100644
--- a/pkg/front_end/lib/src/fasta/fasta_codes_generated.dart
+++ b/pkg/front_end/lib/src/fasta/fasta_codes_generated.dart
@@ -5806,30 +5806,6 @@
r"""Are calls to the compiler wrapped in CompilerContext.runInContext?""");
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
-const Template<Message Function(String name)>
- templateInternalProblemNoInferredTypeStored =
- const Template<Message Function(String name)>(
- messageTemplate: r"""There's no inferred type for '#name'.""",
- withArguments: _withArgumentsInternalProblemNoInferredTypeStored);
-
-// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
-const Code<Message Function(String name)>
- codeInternalProblemNoInferredTypeStored =
- const Code<Message Function(String name)>(
- "InternalProblemNoInferredTypeStored",
- templateInternalProblemNoInferredTypeStored,
- severity: Severity.internalProblem);
-
-// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
-Message _withArgumentsInternalProblemNoInferredTypeStored(String name) {
- if (name.isEmpty) throw 'No name provided';
- name = demangleMixinApplicationName(name);
- return new Message(codeInternalProblemNoInferredTypeStored,
- message: """There's no inferred type for '${name}'.""",
- arguments: {'name': name});
-}
-
-// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
const Template<Message Function(String name)> templateInternalProblemNotFound =
const Template<Message Function(String name)>(
messageTemplate: r"""Couldn't find '#name'.""",
@@ -5944,38 +5920,6 @@
}
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
-const Template<Message Function(DartType _type, String name)>
- templateInternalProblemStoringMultipleInferredTypes =
- const Template<Message Function(DartType _type, String name)>(
- messageTemplate:
- r"""There's already an inferred type, '#type', for '#name'.""",
- withArguments:
- _withArgumentsInternalProblemStoringMultipleInferredTypes);
-
-// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
-const Code<Message Function(DartType _type, String name)>
- codeInternalProblemStoringMultipleInferredTypes =
- const Code<Message Function(DartType _type, String name)>(
- "InternalProblemStoringMultipleInferredTypes",
- templateInternalProblemStoringMultipleInferredTypes,
- severity: Severity.internalProblem);
-
-// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
-Message _withArgumentsInternalProblemStoringMultipleInferredTypes(
- DartType _type, String name) {
- TypeLabeler labeler = new TypeLabeler();
- List<Object> typeParts = labeler.labelType(_type);
- if (name.isEmpty) throw 'No name provided';
- name = demangleMixinApplicationName(name);
- String type = typeParts.join();
- return new Message(codeInternalProblemStoringMultipleInferredTypes,
- message:
- """There's already an inferred type, '${type}', for '${name}'.""" +
- labeler.originMessages,
- arguments: {'type': _type, 'name': name});
-}
-
-// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
const Template<Message Function(String string, String string2)>
templateInternalProblemUnexpected =
const Template<Message Function(String string, String string2)>(
@@ -6982,6 +6926,16 @@
r"""Try adding the name of the type of the variable or the keyword 'var'.""");
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Code<Null> codeMissingExplicitConst = messageMissingExplicitConst;
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const MessageCode messageMissingExplicitConst = const MessageCode(
+ "MissingExplicitConst",
+ analyzerCodes: <String>["NOT_CONSTANT_EXPRESSION"],
+ message: r"""Constant expression expected.""",
+ tip: r"""Try inserting 'const'.""");
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
const Template<Message Function(int count)>
templateMissingExplicitTypeArguments =
const Template<Message Function(int count)>(
@@ -7731,6 +7685,19 @@
}
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Code<Null> codeNullAwareCascadeOutOfOrder =
+ messageNullAwareCascadeOutOfOrder;
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const MessageCode messageNullAwareCascadeOutOfOrder = const MessageCode(
+ "NullAwareCascadeOutOfOrder",
+ index: 96,
+ message:
+ r"""The '?..' cascade operator must be first in the cascade sequence.""",
+ tip:
+ r"""Try moving the '?..' operator to be the first cascade operator in the sequence.""");
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
const Code<Null> codeObjectExtends = messageObjectExtends;
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
diff --git a/pkg/front_end/lib/src/fasta/flow_analysis/flow_analysis.dart b/pkg/front_end/lib/src/fasta/flow_analysis/flow_analysis.dart
index 202fd66..aa2b361 100644
--- a/pkg/front_end/lib/src/fasta/flow_analysis/flow_analysis.dart
+++ b/pkg/front_end/lib/src/fasta/flow_analysis/flow_analysis.dart
@@ -407,10 +407,15 @@
/// - Call [forEach_end].
///
/// [loopAssigned] should be the set of variables that are assigned anywhere
- /// in the loop's body.
- void forEach_bodyBegin(Set<Variable> loopAssigned) {
+ /// in the loop's body. [loopVariable] should be the loop variable, if it's a
+ /// local variable, or `null` otherwise.
+ void forEach_bodyBegin(Set<Variable> loopAssigned, Variable loopVariable) {
_stack.add(_current);
_current = _current.removePromotedAll(loopAssigned, _referencedVariables);
+ if (loopVariable != null) {
+ assert(loopAssigned.contains(loopVariable));
+ _current = _current.write(typeOperations, loopVariable);
+ }
}
/// Call this method just before visiting the body of a "for-in" statement or
diff --git a/pkg/front_end/lib/src/fasta/incremental_compiler.dart b/pkg/front_end/lib/src/fasta/incremental_compiler.dart
index 1288b94..43af7e5 100644
--- a/pkg/front_end/lib/src/fasta/incremental_compiler.dart
+++ b/pkg/front_end/lib/src/fasta/incremental_compiler.dart
@@ -6,6 +6,9 @@
import 'dart:async' show Future;
+import 'package:front_end/src/fasta/dill/dill_class_builder.dart'
+ show DillClassBuilder;
+
import 'package:kernel/binary/ast_from_binary.dart' show BinaryBuilder;
import 'package:kernel/binary/ast_from_binary.dart'
@@ -48,7 +51,7 @@
import '../api_prototype/memory_file_system.dart' show MemoryFileSystem;
-import 'builder/builder.dart' show ClassBuilder, LibraryBuilder;
+import 'builder/builder.dart' show Builder, ClassBuilder, LibraryBuilder;
import 'builder_graph.dart' show BuilderGraph;
@@ -74,7 +77,7 @@
import 'kernel/kernel_builder.dart' show ClassHierarchyBuilder;
-import 'kernel/kernel_shadow_ast.dart' show VariableDeclarationJudgment;
+import 'kernel/kernel_shadow_ast.dart' show VariableDeclarationImpl;
import 'kernel/kernel_target.dart' show KernelTarget;
@@ -311,7 +314,17 @@
// Reset dill loaders and kernel class hierarchy.
for (LibraryBuilder builder in dillLoadedData.loader.builders.values) {
if (builder is DillLibraryBuilder) {
- builder.isBuiltAndMarked = false;
+ if (builder.isBuiltAndMarked) {
+ // Clear cached calculations in classes which upon calculation can
+ // mark things as needed.
+ for (Builder builder in builder.scope.local.values) {
+ if (builder is DillClassBuilder) {
+ builder.supertype = null;
+ builder.interfaces = null;
+ }
+ }
+ builder.isBuiltAndMarked = false;
+ }
}
}
@@ -717,7 +730,8 @@
if (summaryBytes != null) {
ticker.logMs("Read ${c.options.sdkSummary}");
data.component = c.options.target.configureComponent(new Component());
- new BinaryBuilder(summaryBytes, disableLazyReading: false)
+ new BinaryBuilder(summaryBytes,
+ disableLazyReading: false, disableLazyClassReading: true)
.readComponent(data.component);
ticker.logMs("Deserialized ${c.options.sdkSummary}");
bytesLength += summaryBytes.length;
@@ -905,7 +919,7 @@
FunctionNode parameters = new FunctionNode(null,
typeParameters: typeDefinitions,
positionalParameters: definitions.keys
- .map((name) => new VariableDeclarationJudgment(name, 0))
+ .map((name) => new VariableDeclarationImpl(name, 0))
.toList());
debugLibrary.build(userCode.loader.coreLibrary, modifyTarget: false);
diff --git a/pkg/front_end/lib/src/fasta/kernel/body_builder.dart b/pkg/front_end/lib/src/fasta/kernel/body_builder.dart
index e9bb860..8a82cd2 100644
--- a/pkg/front_end/lib/src/fasta/kernel/body_builder.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/body_builder.dart
@@ -6,6 +6,8 @@
import 'dart:core' hide MapEntry;
+import 'package:kernel/ast.dart';
+
import '../builder/declaration_builder.dart';
import '../constant_context.dart' show ConstantContext;
@@ -169,9 +171,6 @@
@override
final TypePromoter typePromoter;
- @override
- final bool legacyMode;
-
/// Only used when [member] is a constructor. It tracks if an implicit super
/// initializer is needed.
///
@@ -290,7 +289,6 @@
needsImplicitSuperInitializer = declarationBuilder is ClassBuilder &&
coreTypes?.objectClass != declarationBuilder.cls,
typePromoter = typeInferrer?.typePromoter,
- legacyMode = libraryBuilder.legacyMode,
super(enclosingScope);
BodyBuilder.withParents(FieldBuilder field, SourceLibraryBuilder part,
@@ -349,8 +347,7 @@
TypeEnvironment get typeEnvironment => typeInferrer?.typeSchemaEnvironment;
- DartType get implicitTypeArgument =>
- legacyMode ? const DynamicType() : const ImplicitTypeArgument();
+ DartType get implicitTypeArgument => const ImplicitTypeArgument();
@override
void push(Object node) {
@@ -818,15 +815,7 @@
// For async, async*, and sync* functions with declared return types, we
// need to determine whether those types are valid.
- // TODO(hillerstrom): currently, we need to check whether [legacyMode] is
- // enabled for two reasons:
- // 1) the [isSubtypeOf] predicate produces false-negatives when
- // [legacyMode] is enabled.
- // 2) the member [typeEnvironment] might be null when [legacyMode] is
- // enabled.
- // This particular behavior can be observed when running the fasta perf
- // benchmarks.
- if (!legacyMode && builder.returnType != null) {
+ if (builder.returnType != null) {
DartType returnType = builder.function.returnType;
// We use the same trick in each case below. For example to decide whether
// Future<T> <: [returnType] for every T, we rely on Future<Bot> and
@@ -926,9 +915,8 @@
} else {
if (body != null) {
builder.body = new Block(<Statement>[
- new ExpressionStatementJudgment(desugarSyntheticExpression(
- buildProblem(fasta.messageExternalMethodWithBody, body.fileOffset,
- noLength)))
+ new ExpressionStatement(desugarSyntheticExpression(buildProblem(
+ fasta.messageExternalMethodWithBody, body.fileOffset, noLength)))
..fileOffset = body.fileOffset,
body,
])
@@ -997,7 +985,7 @@
if (invocation.parent == null) continue;
if (typeInferrer != null) {
if (invocation is FactoryConstructorInvocationJudgment &&
- invocation.inferredType == null) {
+ !invocation.hasBeenInferred) {
continue;
}
} else {
@@ -1012,7 +1000,7 @@
Expression replacementNode;
RedirectionTarget redirectionTarget =
- getRedirectionTarget(initialTarget, this, legacyMode: legacyMode);
+ getRedirectionTarget(initialTarget, this);
Member resolvedTarget = redirectionTarget?.target;
if (resolvedTarget == null) {
@@ -1209,7 +1197,7 @@
.withLocation(uri, eof.charOffset, eof.length));
}
- ReturnJudgment fakeReturn = new ReturnJudgment(true, expression);
+ ReturnStatementImpl fakeReturn = new ReturnStatementImpl(true, expression);
typeInferrer?.inferFunctionBody(
this, const DynamicType(), AsyncMarker.Sync, fakeReturn);
@@ -1431,14 +1419,14 @@
void beginCascade(Token token) {
debugEvent("beginCascade");
Expression expression = popForValue();
- if (expression is CascadeJudgment) {
+ if (expression is Cascade) {
push(expression);
push(new VariableUseGenerator(this, token, expression.variable));
expression.extend();
} else {
VariableDeclaration variable = forest.createVariableDeclarationForValue(
expression.fileOffset, expression);
- push(new CascadeJudgment(variable)..fileOffset = expression.fileOffset);
+ push(new Cascade(variable)..fileOffset = expression.fileOffset);
push(new VariableUseGenerator(this, token, variable));
}
}
@@ -1447,7 +1435,7 @@
void endCascade() {
debugEvent("endCascade");
Expression expression = popForEffect();
- CascadeJudgment cascadeReceiver = pop();
+ Cascade cascadeReceiver = pop();
cascadeReceiver.finalize(expression);
push(cascadeReceiver);
}
@@ -1631,20 +1619,6 @@
.withLocation(uri, charOffset, length);
}
}
- if (legacyMode && constantContext == ConstantContext.none) {
- addProblem(message.messageObject, message.charOffset, message.length,
- wasHandled: true, context: context);
- return forest.createThrow(
- null,
- libraryBuilder.loader.instantiateNoSuchMethodError(
- receiver, name, arguments, charOffset,
- isMethod: !isGetter && !isSetter,
- isGetter: isGetter,
- isSetter: isSetter,
- isStatic: isStatic,
- isTopLevel: !isStatic && !isSuper))
- ..fileOffset = charOffset;
- }
return desugarSyntheticExpression(buildProblem(
message.messageObject, message.charOffset, message.length,
context: context));
@@ -1774,8 +1748,7 @@
Object fact =
typePromoter?.getFactForAccess(variable, functionNestingLevel);
Object scope = typePromoter?.currentScope;
- return new VariableGetJudgment(variable, fact, scope)
- ..fileOffset = charOffset;
+ return new VariableGetImpl(variable, fact, scope)..fileOffset = charOffset;
}
/// Helper method to create a [ReadOnlyAccessGenerator] on the [variable]
@@ -2072,15 +2045,6 @@
void handleLiteralInt(Token token) {
debugEvent("LiteralInt");
int value = int.tryParse(token.lexeme);
- if (legacyMode) {
- if (value == null) {
- push(unhandled(
- 'large integer', 'handleLiteralInt', token.charOffset, uri));
- } else {
- push(forest.createIntLiteral(value, token));
- }
- return;
- }
// Postpone parsing of literals resulting in a negative value
// (hex literals >= 2^63). These are only allowed when not negated.
if (value == null || value < 0) {
@@ -2186,7 +2150,7 @@
bool isFinal = (currentLocalVariableModifiers & finalMask) != 0;
bool isLate = (currentLocalVariableModifiers & lateMask) != 0;
assert(isConst == (constantContext == ConstantContext.inferred));
- VariableDeclaration variable = new VariableDeclarationJudgment(
+ VariableDeclaration variable = new VariableDeclarationImpl(
identifier.name, functionNestingLevel,
forSyntheticToken: deprecated_extractToken(identifier).isSynthetic,
initializer: initializer,
@@ -2362,12 +2326,12 @@
if (variableOrExpression is VariableDeclaration) {
return <VariableDeclaration>[variableOrExpression];
} else if (variableOrExpression is Expression) {
- VariableDeclaration variable = new VariableDeclarationJudgment.forEffect(
- variableOrExpression, functionNestingLevel);
+ VariableDeclaration variable =
+ new VariableDeclarationImpl.forEffect(variableOrExpression);
return <VariableDeclaration>[variable];
} else if (variableOrExpression is ExpressionStatement) {
- VariableDeclaration variable = new VariableDeclarationJudgment.forEffect(
- variableOrExpression.expression, functionNestingLevel);
+ VariableDeclaration variable = new VariableDeclarationImpl.forEffect(
+ variableOrExpression.expression);
return <VariableDeclaration>[variable];
} else if (forest.isVariablesDeclaration(variableOrExpression)) {
return forest
@@ -2527,6 +2491,11 @@
int count, Token leftBracket, Token constKeyword, Token rightBracket) {
debugEvent("LiteralList");
+ if (constantContext == ConstantContext.required && constKeyword == null) {
+ addProblem(fasta.messageMissingExplicitConst, offsetForToken(leftBracket),
+ noLength);
+ }
+
// TODO(danrubel): Replace this with popListForValue
// when control flow and spread collections have been enabled by default
List<Expression> expressions =
@@ -2552,10 +2521,7 @@
typeArgument = const InvalidType();
} else {
typeArgument = buildDartType(typeArguments.single);
- if (!legacyMode) {
- typeArgument =
- instantiateToBounds(typeArgument, coreTypes.objectClass);
- }
+ typeArgument = instantiateToBounds(typeArgument, coreTypes.objectClass);
}
} else {
typeArgument = implicitTypeArgument;
@@ -2578,9 +2544,7 @@
DartType typeArgument;
if (typeArguments != null) {
typeArgument = buildDartType(typeArguments.single);
- if (!libraryBuilder.loader.target.legacyMode) {
- typeArgument = instantiateToBounds(typeArgument, coreTypes.objectClass);
- }
+ typeArgument = instantiateToBounds(typeArgument, coreTypes.objectClass);
} else {
typeArgument = implicitTypeArgument;
}
@@ -2624,6 +2588,11 @@
) {
debugEvent("LiteralSetOrMap");
+ if (constantContext == ConstantContext.required && constKeyword == null) {
+ addProblem(fasta.messageMissingExplicitConst, offsetForToken(leftBrace),
+ noLength);
+ }
+
List<dynamic> setOrMapEntries =
new List<dynamic>.filled(count, null, growable: true);
for (int i = count - 1; i >= 0; i--) {
@@ -2708,10 +2677,8 @@
} else {
keyType = buildDartType(typeArguments[0]);
valueType = buildDartType(typeArguments[1]);
- if (!legacyMode) {
- keyType = instantiateToBounds(keyType, coreTypes.objectClass);
- valueType = instantiateToBounds(valueType, coreTypes.objectClass);
- }
+ keyType = instantiateToBounds(keyType, coreTypes.objectClass);
+ valueType = instantiateToBounds(valueType, coreTypes.objectClass);
}
} else {
DartType implicitTypeArgument = this.implicitTypeArgument;
@@ -2878,7 +2845,10 @@
FormalParameters formals = pop();
UnresolvedType returnType = pop();
List<TypeVariableBuilder> typeVariables = pop();
- UnresolvedType type = formals.toFunctionType(returnType, typeVariables);
+ UnresolvedType type = formals.toFunctionType(
+ returnType,
+ libraryBuilder.computeNullabilityFromToken(questionMark != null),
+ typeVariables);
exitLocalScope();
push(type);
}
@@ -3099,7 +3069,10 @@
if (!libraryBuilder.loader.target.enableNonNullable) {
reportErrorIfNullableType(question);
}
- UnresolvedType type = formals.toFunctionType(returnType, typeVariables);
+ UnresolvedType type = formals.toFunctionType(
+ returnType,
+ libraryBuilder.computeNullabilityFromToken(question != null),
+ typeVariables);
exitLocalScope();
push(type);
functionNestingLevel--;
@@ -3210,7 +3183,7 @@
if (parameterCount > 1) {
stackTrace = catchParameters.parameters[1];
stackTrace.build(libraryBuilder, functionNestingLevel).type =
- coreTypes.stackTraceClass.rawType;
+ coreTypes.stackTraceRawType(libraryBuilder.nonNullable);
}
}
if (parameterCount > 2) {
@@ -3232,7 +3205,7 @@
catchKeyword,
exception?.target,
stackTrace?.target,
- coreTypes.stackTraceClass.rawType,
+ coreTypes.stackTraceRawType(libraryBuilder.nonNullable),
body));
if (compileTimeErrors == null) {
push(NullValue.Block);
@@ -3463,33 +3436,33 @@
int charLength: noLength}) {
// The argument checks for the initial target of redirecting factories
// invocations are skipped in Dart 1.
- if (!legacyMode || !isRedirectingFactory(target, helper: this)) {
- List<TypeParameter> typeParameters = target.function.typeParameters;
- if (target is Constructor) {
- assert(!target.enclosingClass.isAbstract);
- typeParameters = target.enclosingClass.typeParameters;
- }
- LocatedMessage argMessage = checkArgumentsForFunction(
- target.function, arguments, charOffset, typeParameters);
- if (argMessage != null) {
- return wrapSyntheticExpression(
- throwNoSuchMethodError(
- forest.createNullLiteral(null)..fileOffset = charOffset,
- target.name.name,
- arguments,
- charOffset,
- candidate: target,
- message: argMessage),
- charOffset);
- }
+ List<TypeParameter> typeParameters = target.function.typeParameters;
+ if (target is Constructor) {
+ assert(!target.enclosingClass.isAbstract);
+ typeParameters = target.enclosingClass.typeParameters;
+ }
+ LocatedMessage argMessage = checkArgumentsForFunction(
+ target.function, arguments, charOffset, typeParameters);
+ if (argMessage != null) {
+ return wrapSyntheticExpression(
+ throwNoSuchMethodError(
+ forest.createNullLiteral(null)..fileOffset = charOffset,
+ target.name.name,
+ arguments,
+ charOffset,
+ candidate: target,
+ message: argMessage),
+ charOffset);
}
- bool isConst = constness == Constness.explicitConst;
+ bool isConst = constness == Constness.explicitConst ||
+ constantContext != ConstantContext.none;
if (target is Constructor) {
- isConst =
- isConst || constantContext != ConstantContext.none && target.isConst;
- if ((isConst || constantContext == ConstantContext.inferred) &&
- !target.isConst) {
+ if (constantContext == ConstantContext.required &&
+ constness == Constness.implicit) {
+ addProblem(fasta.messageMissingExplicitConst, charOffset, charLength);
+ }
+ if (isConst && !target.isConst) {
return wrapInvalidConstructorInvocation(
desugarSyntheticExpression(buildProblem(
fasta.messageNonConstConstructor, charOffset, charLength)),
@@ -3506,10 +3479,11 @@
} else {
Procedure procedure = target;
if (procedure.isFactory) {
- isConst = isConst ||
- constantContext != ConstantContext.none && procedure.isConst;
- if ((isConst || constantContext == ConstantContext.inferred) &&
- !procedure.isConst) {
+ if (constantContext == ConstantContext.required &&
+ constness == Constness.implicit) {
+ addProblem(fasta.messageMissingExplicitConst, charOffset, charLength);
+ }
+ if (isConst && !procedure.isConst) {
return wrapInvalidConstructorInvocation(
desugarSyntheticExpression(buildProblem(
fasta.messageNonConstFactory, charOffset, charLength)),
@@ -3525,8 +3499,9 @@
node, typeEnvironment, uri);
return node;
} else {
+ assert(constness == Constness.implicit);
StaticInvocation node =
- new StaticInvocation(target, arguments, isConst: isConst)
+ new StaticInvocation(target, arguments, isConst: false)
..fileOffset = charOffset;
libraryBuilder.checkBoundsInStaticInvocation(
node, typeEnvironment, uri);
@@ -3594,12 +3569,7 @@
if (typeParameters.length != types.length) {
if (types.length == 0) {
// Expected `typeParameters.length` type arguments, but none given, so
- // we fill in dynamic in legacy mode, and use type inference otherwise.
- if (legacyMode) {
- for (int i = 0; i < typeParameters.length; i++) {
- types.add(const DynamicType());
- }
- }
+ // we use type inference.
} else {
// A wrong (non-zero) amount of type arguments given. That's an error.
// TODO(jensj): Position should be on type arguments instead.
@@ -3813,31 +3783,10 @@
(target is Procedure && target.kind == ProcedureKind.Factory)) {
Expression invocation;
- if (legacyMode && isRedirectingFactory(target, helper: this)) {
- // In legacy mode the checks that are done in [buildStaticInvocation]
- // on the initial target of a redirecting factory invocation should
- // be skipped. So we build the invocation nodes directly here without
- // doing any checks.
- if (target.function.typeParameters != null &&
- target.function.typeParameters.length !=
- forest.argumentsTypeArguments(arguments).length) {
- arguments = forest.createArguments(
- noLocation, forest.argumentsPositional(arguments),
- named: forest.argumentsNamed(arguments),
- types: new List<DartType>.filled(
- target.function.typeParameters.length, const DynamicType(),
- growable: true));
- }
- invocation = new FactoryConstructorInvocationJudgment(
- target, arguments,
- isConst: constness == Constness.explicitConst)
- ..fileOffset = nameToken.charOffset;
- } else {
- invocation = buildStaticInvocation(target, arguments,
- constness: constness,
- charOffset: nameToken.charOffset,
- charLength: nameToken.length);
- }
+ invocation = buildStaticInvocation(target, arguments,
+ constness: constness,
+ charOffset: nameToken.charOffset,
+ charLength: nameToken.length);
if (invocation is StaticInvocation &&
isRedirectingFactory(target, helper: this)) {
@@ -4041,7 +3990,7 @@
debugEvent("FunctionName");
Identifier name = pop();
Token nameToken = deprecated_extractToken(name);
- VariableDeclaration variable = new VariableDeclarationJudgment(
+ VariableDeclaration variable = new VariableDeclarationImpl(
name.name, functionNestingLevel,
forSyntheticToken: nameToken.isSynthetic,
isFinal: true,
@@ -4053,7 +4002,7 @@
if (existing != null) {
reportDuplicatedDeclaration(existing, name.name, name.charOffset);
}
- push(new FunctionDeclarationJudgment(
+ push(new FunctionDeclarationImpl(
variable,
// The function node is created later.
null)
@@ -4117,8 +4066,14 @@
if (!isFunctionExpression) {
annotations = pop(); // Metadata.
}
- FunctionNode function = formals.buildFunctionNode(libraryBuilder,
- returnType, typeParameters, asyncModifier, body, token.charOffset);
+ FunctionNode function = formals.buildFunctionNode(
+ libraryBuilder,
+ returnType,
+ typeParameters,
+ asyncModifier,
+ body,
+ const NullabilityBuilder.pendingImplementation(),
+ token.charOffset);
if (declaration is FunctionDeclaration) {
VariableDeclaration variable = declaration.variable;
@@ -4127,7 +4082,7 @@
variable.addAnnotation(annotation);
}
}
- FunctionDeclarationJudgment.setHasImplicitReturnType(
+ FunctionDeclarationImpl.setHasImplicitReturnType(
declaration, hasImplicitReturnType);
variable.type = function.functionType;
@@ -4199,28 +4154,16 @@
FormalParameters formals = pop();
exitFunction();
List<TypeVariableBuilder> typeParameters = pop();
- FunctionNode function = formals.buildFunctionNode(libraryBuilder, null,
- typeParameters, asyncModifier, body, token.charOffset)
+ FunctionNode function = formals.buildFunctionNode(
+ libraryBuilder,
+ null,
+ typeParameters,
+ asyncModifier,
+ body,
+ const NullabilityBuilder.pendingImplementation(),
+ token.charOffset)
..fileOffset = beginToken.charOffset;
- if (libraryBuilder.legacyMode && asyncModifier != AsyncMarker.Sync) {
- DartType returnType;
- switch (asyncModifier) {
- case AsyncMarker.Async:
- returnType = coreTypes.futureClass.rawType;
- break;
- case AsyncMarker.AsyncStar:
- returnType = coreTypes.streamClass.rawType;
- break;
- case AsyncMarker.SyncStar:
- returnType = coreTypes.iterableClass.rawType;
- break;
- default:
- returnType = const DynamicType();
- break;
- }
- function.returnType = returnType;
- }
if (constantContext != ConstantContext.none) {
push(buildProblem(fasta.messageNotAConstantExpression, formals.charOffset,
formals.length));
@@ -4349,7 +4292,7 @@
typePromoter?.getFactForAccess(variable, functionNestingLevel);
TypePromotionScope scope = typePromoter?.currentScope;
Expression syntheticAssignment = lvalue.buildAssignment(
- new VariableGetJudgment(variable, fact, scope)
+ new VariableGetImpl(variable, fact, scope)
..fileOffset = inKeyword.offset,
voidContext: true);
if (syntheticAssignment is shadow.SyntheticExpressionJudgment) {
@@ -4482,10 +4425,8 @@
if (inCatchBlock) {
push(forest.createRethrowStatement(rethrowToken, endToken));
} else {
- push(new ExpressionStatementJudgment(buildProblem(
- fasta.messageRethrowNotCatch,
- offsetForToken(rethrowToken),
- lengthForToken(rethrowToken)))
+ push(new ExpressionStatement(buildProblem(fasta.messageRethrowNotCatch,
+ offsetForToken(rethrowToken), lengthForToken(rethrowToken)))
..fileOffset = offsetForToken(rethrowToken));
}
}
@@ -4638,7 +4579,7 @@
for (Expression expression in expressions) {
expressionOffsets.add(forest.readOffset(expression));
}
- push(new SwitchCaseJudgment(expressions, expressionOffsets, block,
+ push(new SwitchCase(expressions, expressionOffsets, block,
isDefault: defaultKeyword != null)
..fileOffset = firstToken.charOffset);
push(labels ?? NullValue.Labels);
@@ -4653,7 +4594,7 @@
exitSwitchScope();
exitLocalScope();
Expression expression = popForValue();
- Statement result = new SwitchStatementJudgment(expression, cases)
+ Statement result = new SwitchStatement(expression, cases)
..fileOffset = switchKeyword.charOffset;
if (target.hasUsers) {
result = forest.createLabeledStatement(result);
@@ -4799,7 +4740,7 @@
}
if (target.isGotoTarget &&
target.functionNestingLevel == functionNestingLevel) {
- ContinueSwitchStatement statement = new ContinueSwitchJudgment(null)
+ ContinueSwitchStatement statement = new ContinueSwitchStatement(null)
..fileOffset = continueKeyword.charOffset;
target.addGoto(statement);
push(statement);
@@ -4869,32 +4810,19 @@
// Peek to leave type parameters on top of stack.
List<TypeVariableBuilder> typeVariables = peek();
- if (!legacyMode) {
- List<TypeBuilder> calculatedBounds = calculateBounds(
- typeVariables,
- libraryBuilder.loader.target.dynamicType,
- libraryBuilder.loader.target.bottomType,
- libraryBuilder.loader.target.objectClassBuilder);
- for (int i = 0; i < typeVariables.length; ++i) {
- typeVariables[i].defaultType = calculatedBounds[i];
- typeVariables[i].defaultType.resolveIn(
- scope,
- typeVariables[i].charOffset,
- typeVariables[i].fileUri,
- libraryBuilder);
- typeVariables[i].finish(
- libraryBuilder,
- libraryBuilder.loader.target.objectClassBuilder,
- libraryBuilder.loader.target.dynamicType);
- }
- } else {
- for (int i = 0; i < typeVariables.length; ++i) {
- typeVariables[i].defaultType = libraryBuilder.loader.target.dynamicType;
- typeVariables[i].finish(
- libraryBuilder,
- libraryBuilder.loader.target.objectClassBuilder,
- libraryBuilder.loader.target.dynamicType);
- }
+ List<TypeBuilder> calculatedBounds = calculateBounds(
+ typeVariables,
+ libraryBuilder.loader.target.dynamicType,
+ libraryBuilder.loader.target.bottomType,
+ libraryBuilder.loader.target.objectClassBuilder);
+ for (int i = 0; i < typeVariables.length; ++i) {
+ typeVariables[i].defaultType = calculatedBounds[i];
+ typeVariables[i].defaultType.resolveIn(scope, typeVariables[i].charOffset,
+ typeVariables[i].fileUri, libraryBuilder);
+ typeVariables[i].finish(
+ libraryBuilder,
+ libraryBuilder.loader.target.objectClassBuilder,
+ libraryBuilder.loader.target.dynamicType);
}
}
@@ -4927,15 +4855,20 @@
@override
Expression buildProblem(Message message, int charOffset, int length,
- {List<LocatedMessage> context, bool suppressMessage: false}) {
+ {List<LocatedMessage> context,
+ bool suppressMessage: false,
+ bool wrapInSyntheticExpression: true}) {
if (!suppressMessage) {
addProblem(message, charOffset, length,
wasHandled: true, context: context);
}
String text = libraryBuilder.loader.target.context
.format(message.withLocation(uri, charOffset, length), Severity.error);
- return wrapSyntheticExpression(
- new InvalidExpression(text)..fileOffset = charOffset, charOffset);
+ InvalidExpression expression = new InvalidExpression(text)
+ ..fileOffset = charOffset;
+ return wrapInSyntheticExpression
+ ? wrapSyntheticExpression(expression, charOffset)
+ : expression;
}
@override
@@ -4943,8 +4876,7 @@
{List<LocatedMessage> context}) {
int charOffset = forest.readOffset(expression);
Severity severity = message.code.severity;
- if (severity == Severity.error ||
- severity == Severity.errorLegacyWarning && !legacyMode) {
+ if (severity == Severity.error || severity == Severity.errorLegacyWarning) {
return wrapInLocatedProblem(
expression, message.withLocation(uri, charOffset, length),
context: context);
@@ -4993,6 +4925,7 @@
forest.createIntLiteral(location?.line ?? 0, null)
..fileOffset = charOffset,
]),
+ constness: Constness.explicitNew,
charOffset: charOffset))
..fileOffset = charOffset;
}
@@ -5009,6 +4942,7 @@
forest.createArguments(charOffset, <Expression>[
forest.createStringLiteral(className, null)..fileOffset = charOffset
]),
+ constness: Constness.explicitNew,
charOffset: charOffset);
if (invocation is shadow.SyntheticExpressionJudgment) {
invocation = desugarSyntheticExpression(invocation);
@@ -5019,8 +4953,7 @@
Statement buildProblemStatement(Message message, int charOffset,
{List<LocatedMessage> context, int length, bool suppressMessage: false}) {
length ??= noLength;
- return new ExpressionStatementJudgment(buildProblem(
- message, charOffset, length,
+ return new ExpressionStatement(buildProblem(message, charOffset, length,
context: context, suppressMessage: suppressMessage));
}
@@ -5040,7 +4973,7 @@
}
Initializer buildInvalidSuperInitializer(
- Constructor target, ArgumentsJudgment arguments, Expression expression,
+ Constructor target, ArgumentsImpl arguments, Expression expression,
[int charOffset = -1]) {
needsImplicitSuperInitializer = false;
return new InvalidSuperInitializerJudgment(
@@ -5113,6 +5046,7 @@
forest.createStringLiteral(name, null)
..fileOffset = assignmentOffset
]),
+ constness: Constness.explicitNew,
charOffset: assignmentOffset);
if (invocation is shadow.SyntheticExpressionJudgment) {
invocation = desugarSyntheticExpression(invocation);
@@ -5125,8 +5059,7 @@
..fileOffset = assignmentOffset))
..fileOffset = assignmentOffset;
} else {
- if (!legacyMode &&
- formalType != null &&
+ if (formalType != null &&
!typeEnvironment.isSubtypeOf(formalType, builder.field.type)) {
libraryBuilder.addProblem(
fasta.templateInitializingFormalTypeMismatch
@@ -5139,7 +5072,7 @@
.withLocation(builder.fileUri, builder.charOffset, noLength)
]);
}
- return new ShadowFieldInitializer(builder.field, expression)
+ return new FieldInitializer(builder.field, expression)
..fileOffset = assignmentOffset
..isSynthetic = isSynthetic;
}
@@ -5168,7 +5101,7 @@
charOffset);
}
needsImplicitSuperInitializer = false;
- return new SuperInitializerJudgment(constructor, arguments)
+ return new SuperInitializer(constructor, arguments)
..fileOffset = charOffset
..isSynthetic = isSynthetic;
}
@@ -5185,7 +5118,7 @@
// TODO(askesc): Produce invalid initializer.
}
needsImplicitSuperInitializer = false;
- return new RedirectingInitializerJudgment(constructor, arguments)
+ return new RedirectingInitializer(constructor, arguments)
..fileOffset = charOffset;
}
@@ -5262,7 +5195,8 @@
for (Expression argument in expressions.reversed) {
expression = new Let(
new VariableDeclaration.forValue(argument,
- isFinal: true, type: coreTypes.objectClass.rawType),
+ isFinal: true,
+ type: coreTypes.objectRawType(libraryBuilder.nullable)),
expression);
}
return expression;
@@ -5302,14 +5236,12 @@
offset,
name.name.length);
}
- return new SuperMethodInvocationJudgment(name, arguments,
- interfaceTarget: target)
+ return new SuperMethodInvocation(name, arguments, target)
..fileOffset = offset;
}
- receiver = new SuperPropertyGetJudgment(name, interfaceTarget: target)
- ..fileOffset = offset;
- MethodInvocation node = new MethodInvocationJudgment(
+ receiver = new SuperPropertyGet(name, target)..fileOffset = offset;
+ MethodInvocation node = new MethodInvocationImpl(
receiver, callName, arguments,
isImplicitCall: true)
..fileOffset = forest.readOffset(arguments);
@@ -5317,24 +5249,18 @@
}
if (isNullAware) {
- VariableDeclaration variable = new VariableDeclaration.forValue(receiver);
- return new NullAwareMethodInvocationJudgment(
+ VariableDeclaration variable = forest.createVariableDeclarationForValue(
+ receiver.fileOffset, receiver);
+ return new NullAwareMethodInvocation(
variable,
- forest.createConditionalExpression(
- buildIsNull(new VariableGet(variable), offset, this),
- null,
- forest.createNullLiteral(null)..fileOffset = offset,
- null,
- new MethodInvocation(
- new VariableGet(variable), name, arguments, interfaceTarget)
- ..fileOffset = offset)
- ..fileOffset = offset)
- ..fileOffset = offset;
+ forest.createMethodInvocation(offset,
+ createVariableGet(variable, receiver.fileOffset), name, arguments,
+ isImplicitCall: isImplicitCall, interfaceTarget: interfaceTarget))
+ ..fileOffset = receiver.fileOffset;
} else {
- MethodInvocation node = new MethodInvocationJudgment(
- receiver, name, arguments,
- isImplicitCall: isImplicitCall, interfaceTarget: interfaceTarget)
- ..fileOffset = offset;
+ MethodInvocation node = forest.createMethodInvocation(
+ offset, receiver, name, arguments,
+ isImplicitCall: isImplicitCall, interfaceTarget: interfaceTarget);
return node;
}
}
@@ -5394,7 +5320,7 @@
VariableDeclaration check = new VariableDeclaration.forValue(
forest.checkLibraryIsLoaded(prefix.dependency))
..fileOffset = charOffset;
- return new DeferredCheckJudgment(check, expression);
+ return new DeferredCheck(check, expression);
}
/// TODO(ahe): This method is temporarily implemented. Once type promotion is
@@ -5446,14 +5372,12 @@
@override
Expression wrapSyntheticExpression(Expression desugared, int charOffset) {
- if (legacyMode) return desugared;
return shadow.SyntheticWrapper.wrapSyntheticExpression(desugared)
..fileOffset = charOffset;
}
@override
Expression desugarSyntheticExpression(Expression node) {
- if (legacyMode) return node;
shadow.SyntheticExpressionJudgment shadowNode = node;
return shadowNode.desugared;
}
@@ -5461,7 +5385,6 @@
@override
Expression wrapInvalidConstructorInvocation(Expression desugared,
Member constructor, Arguments arguments, int charOffset) {
- if (legacyMode) return desugared;
return shadow.SyntheticWrapper.wrapInvalidConstructorInvocation(
desugared, constructor, arguments)
..fileOffset = charOffset;
@@ -5470,7 +5393,6 @@
@override
Expression wrapInvalidWrite(
Expression desugared, Expression expression, int charOffset) {
- if (legacyMode) return desugared;
return shadow.SyntheticWrapper.wrapInvalidWrite(desugared, expression)
..fileOffset = charOffset;
}
@@ -5478,7 +5400,6 @@
@override
Expression wrapUnresolvedTargetInvocation(
Expression desugared, Arguments arguments, int charOffset) {
- if (legacyMode) return desugared;
return shadow.SyntheticWrapper.wrapUnresolvedTargetInvocation(
desugared, arguments)
..fileOffset = charOffset;
@@ -5487,7 +5408,6 @@
@override
Expression wrapUnresolvedVariableAssignment(
Expression desugared, bool isCompound, Expression rhs, int charOffset) {
- if (legacyMode) return desugared;
return shadow.SyntheticWrapper.wrapUnresolvedVariableAssignment(
desugared, isCompound, rhs)
..fileOffset = charOffset;
@@ -5660,9 +5580,12 @@
List<TypeVariableBuilder> typeParameters,
AsyncMarker asyncModifier,
Statement body,
+ NullabilityBuilder nullabilityBuilder,
int fileEndOffset) {
FunctionType type =
- toFunctionType(returnType, typeParameters).builder.build(library);
+ toFunctionType(returnType, nullabilityBuilder, typeParameters)
+ .builder
+ .build(library);
List<VariableDeclaration> positionalParameters = <VariableDeclaration>[];
List<VariableDeclaration> namedParameters = <VariableDeclaration>[];
if (parameters != null) {
@@ -5677,7 +5600,7 @@
return a.name.compareTo(b.name);
});
}
- return new FunctionNodeJudgment(body,
+ return new FunctionNode(body,
typeParameters: type.typeParameters,
positionalParameters: positionalParameters,
namedParameters: namedParameters,
@@ -5688,11 +5611,12 @@
..fileEndOffset = fileEndOffset;
}
- UnresolvedType toFunctionType(UnresolvedType returnType,
+ UnresolvedType toFunctionType(
+ UnresolvedType returnType, NullabilityBuilder nullabilityBuilder,
[List<TypeVariableBuilder> typeParameters]) {
return new UnresolvedType(
- new FunctionTypeBuilder(
- returnType?.builder, typeParameters, parameters),
+ new FunctionTypeBuilder(returnType?.builder, typeParameters, parameters,
+ nullabilityBuilder),
charOffset,
uri);
}
@@ -5738,7 +5662,7 @@
statement.parent = body;
return body;
} else {
- return new BlockJudgment(<Statement>[statement, body])
+ return new Block(<Statement>[statement, body])
..fileOffset = statement.fileOffset;
}
}
diff --git a/pkg/front_end/lib/src/fasta/kernel/class_hierarchy_builder.dart b/pkg/front_end/lib/src/fasta/kernel/class_hierarchy_builder.dart
index 075dc56..39d84cb 100644
--- a/pkg/front_end/lib/src/fasta/kernel/class_hierarchy_builder.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/class_hierarchy_builder.dart
@@ -215,7 +215,7 @@
final List<DelayedMember> delayedMemberChecks = <DelayedMember>[];
- // TODO(ahe): Remove this.
+ // TODO(dmitryas): Consider removing this.
final CoreTypes coreTypes;
Types types;
@@ -275,20 +275,20 @@
if (kernelClass == superclass) return type;
if (kernelClass == nullClass) {
if (superclass.typeParameters.isEmpty) {
- return superclass.rawType;
+ return coreTypes.legacyRawType(superclass);
} else {
// This is a safe fall-back for dealing with `Null`. It will likely be
// faster to check for `Null` before calling this method.
return new InterfaceType(
superclass,
new List<DartType>.filled(
- superclass.typeParameters.length, nullClass.rawType));
+ superclass.typeParameters.length, coreTypes.nullType));
}
}
NamedTypeBuilder supertype = asSupertypeOf(kernelClass, superclass);
if (supertype == null) return null;
if (supertype.arguments == null && superclass.typeParameters.isEmpty) {
- return superclass.rawType;
+ return coreTypes.legacyRawType(superclass);
}
return Substitution.fromInterfaceType(type)
.substituteType(supertype.build(null));
@@ -317,7 +317,7 @@
}
}
- if (common.length == 1) return objectClass.rawType;
+ if (common.length == 1) return coreTypes.objectLegacyRawType;
common.sort(ClassHierarchyNode.compareMaxInheritancePath);
for (int i = 0; i < common.length - 1; i++) {
@@ -330,7 +330,7 @@
} while (node.maxInheritancePath == common[i + 1].maxInheritancePath);
}
}
- return objectClass.rawType;
+ return coreTypes.objectLegacyRawType;
}
Member getInterfaceMemberKernel(Class cls, Name name, bool isSetter) {
@@ -1961,13 +1961,14 @@
Class get nullClass => hierarchy.nullClass;
@override
- InterfaceType get nullType => nullClass.rawType;
+ InterfaceType get nullType => hierarchy.coreTypes.nullType;
@override
- InterfaceType get objectType => objectClass.rawType;
+ InterfaceType get objectType => hierarchy.coreTypes.objectLegacyRawType;
@override
- InterfaceType get rawFunctionType => functionClass.rawType;
+ InterfaceType get rawFunctionType =>
+ hierarchy.coreTypes.functionLegacyRawType;
@override
void addLowerBound(TypeConstraint constraint, DartType lower) {
diff --git a/pkg/front_end/lib/src/fasta/kernel/constant_evaluator.dart b/pkg/front_end/lib/src/fasta/kernel/constant_evaluator.dart
index 73b8e87..fa0afb1 100644
--- a/pkg/front_end/lib/src/fasta/kernel/constant_evaluator.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/constant_evaluator.dart
@@ -60,11 +60,12 @@
templateConstEvalInvalidStringInterpolationOperand,
templateConstEvalInvalidSymbolName,
templateConstEvalKeyImplementsEqual,
- templateConstEvalNegativeShift,
templateConstEvalNonConstantLiteral,
templateConstEvalNonConstantVariableGet,
templateConstEvalZeroDivisor;
+import 'constant_int_folder.dart';
+
part 'constant_collection_builders.dart';
Component transformComponent(Component component, ConstantsBackend backend,
@@ -116,22 +117,6 @@
}
}
-class JavaScriptIntConstant extends DoubleConstant {
- final BigInt bigIntValue;
- JavaScriptIntConstant(int value) : this.fromBigInt(new BigInt.from(value));
- JavaScriptIntConstant.fromDouble(double value)
- : bigIntValue = new BigInt.from(value),
- super(value);
- JavaScriptIntConstant.fromBigInt(this.bigIntValue)
- : super(bigIntValue.toDouble());
- JavaScriptIntConstant.fromUInt64(int value)
- : this.fromBigInt(new BigInt.from(value).toUnsigned(64));
-
- DartType getType(TypeEnvironment types) => types.intType;
-
- String toString() => '$bigIntValue';
-}
-
class ConstantsTransformer extends Transformer {
final ConstantsBackend backend;
final ConstantEvaluator constantEvaluator;
@@ -499,6 +484,7 @@
class ConstantEvaluator extends RecursiveVisitor<Constant> {
final ConstantsBackend backend;
final NumberSemantics numberSemantics;
+ ConstantIntFolder intFolder;
Map<String, String> environmentDefines;
final bool errorOnUnevaluatedConstant;
final CoreTypes coreTypes;
@@ -552,6 +538,7 @@
"No 'environmentDefines' passed to the constant evaluator but the "
"ConstantsBackend does not support unevaluated constants.");
}
+ intFolder = new ConstantIntFolder.forSemantics(this, numberSemantics);
primitiveEqualCache = <Class, bool>{
coreTypes.boolClass: true,
coreTypes.doubleClass: false,
@@ -795,14 +782,12 @@
Constant visitIntLiteral(IntLiteral node) {
// The frontend ensures that integer literals are valid according to the
// target representation.
- return targetingJavaScript
- ? canonicalize(new JavaScriptIntConstant.fromUInt64(node.value))
- : canonicalize(new IntConstant(node.value));
+ return canonicalize(intFolder.makeIntConstant(node.value, unsigned: true));
}
@override
Constant visitDoubleLiteral(DoubleLiteral node) {
- return canonicalize(makeDoubleConstant(node.value));
+ return canonicalize(new DoubleConstant(node.value));
}
@override
@@ -824,14 +809,6 @@
result = runInsideContext(constant.expression, () {
return _evaluateSubexpression(constant.expression);
});
- } else if (targetingJavaScript) {
- if (constant is DoubleConstant) {
- double value = constant.value;
- // TODO(askesc, fishythefish): Handle infinite integers.
- if (value.isFinite && value.truncateToDouble() == value) {
- result = new JavaScriptIntConstant.fromDouble(value);
- }
- }
}
// If there were already constants in the AST then we make sure we
// re-canonicalize them. After running the transformer we will therefore
@@ -1293,25 +1270,16 @@
if (arguments.length == 1 && op == '==') {
final Constant right = arguments[0];
- // [DoubleConstant] uses [identical] to determine equality, so we need two
- // special cases:
- // Two NaNs are always unequal even if [identical] returns `true`.
- if (isNaN(receiver) || isNaN(right)) {
- return falseConstant;
- }
-
- // Two zero values are always equal regardless of sign.
- if (isZero(receiver)) {
- return makeBoolConstant(isZero(right));
- }
-
if (receiver is NullConstant ||
receiver is BoolConstant ||
receiver is IntConstant ||
receiver is DoubleConstant ||
receiver is StringConstant ||
right is NullConstant) {
- return makeBoolConstant(receiver == right);
+ // [DoubleConstant] uses [identical] to determine equality, so we need
+ // to take the special cases into account.
+ return doubleSpecialCases(receiver, right) ??
+ makeBoolConstant(receiver == right);
} else {
return report(
node,
@@ -1339,112 +1307,14 @@
other.getType(typeEnvironment)));
}
}
- } else if (receiver is IntConstant || receiver is JavaScriptIntConstant) {
+ } else if (intFolder.isInt(receiver)) {
if (arguments.length == 0) {
- switch (op) {
- case 'unary-':
- if (targetingJavaScript) {
- BigInt value = (receiver as JavaScriptIntConstant).bigIntValue;
- if (value == BigInt.zero) {
- return canonicalize(new DoubleConstant(-0.0));
- }
- return canonicalize(new JavaScriptIntConstant.fromBigInt(-value));
- }
- int value = (receiver as IntConstant).value;
- return canonicalize(new IntConstant(-value));
- case '~':
- if (targetingJavaScript) {
- BigInt value = (receiver as JavaScriptIntConstant).bigIntValue;
- return canonicalize(new JavaScriptIntConstant.fromBigInt(
- (~value).toUnsigned(32)));
- }
- int value = (receiver as IntConstant).value;
- return canonicalize(new IntConstant(~value));
- }
+ return canonicalize(intFolder.foldUnaryOperator(node, op, receiver));
} else if (arguments.length == 1) {
final Constant other = arguments[0];
- if (other is IntConstant || other is JavaScriptIntConstant) {
- if ((op == '<<' || op == '>>' || op == '>>>')) {
- Object receiverValue = receiver is IntConstant
- ? receiver.value
- : (receiver as JavaScriptIntConstant).bigIntValue;
- int otherValue = other is IntConstant
- ? other.value
- : (other as JavaScriptIntConstant).bigIntValue.toInt();
- if (otherValue < 0) {
- return report(
- node.arguments.positional.first,
- // TODO(askesc): Change argument types in template to
- // constants.
- templateConstEvalNegativeShift.withArguments(
- op, '${receiverValue}', '${otherValue}'));
- }
- }
-
- if ((op == '%' || op == '~/')) {
- Object receiverValue = receiver is IntConstant
- ? receiver.value
- : (receiver as JavaScriptIntConstant).bigIntValue;
- int otherValue = other is IntConstant
- ? other.value
- : (other as JavaScriptIntConstant).bigIntValue.toInt();
- if (otherValue == 0) {
- return report(
- node.arguments.positional.first,
- // TODO(askesc): Change argument type in template to constant.
- templateConstEvalZeroDivisor.withArguments(
- op, '${receiverValue}'));
- }
- }
-
- switch (op) {
- case '|':
- case '&':
- case '^':
- int receiverValue = receiver is IntConstant
- ? receiver.value
- : (receiver as JavaScriptIntConstant)
- .bigIntValue
- .toUnsigned(32)
- .toInt();
- int otherValue = other is IntConstant
- ? other.value
- : (other as JavaScriptIntConstant)
- .bigIntValue
- .toUnsigned(32)
- .toInt();
- return evaluateBinaryBitOperation(
- op, receiverValue, otherValue, node);
- case '<<':
- case '>>':
- case '>>>':
- bool negative = false;
- int receiverValue;
- if (receiver is IntConstant) {
- receiverValue = receiver.value;
- } else {
- BigInt bigIntValue =
- (receiver as JavaScriptIntConstant).bigIntValue;
- receiverValue = bigIntValue.toUnsigned(32).toInt();
- negative = bigIntValue.isNegative;
- }
- int otherValue = other is IntConstant
- ? other.value
- : (other as JavaScriptIntConstant).bigIntValue.toInt();
-
- return evaluateBinaryShiftOperation(
- op, receiverValue, otherValue, node,
- negativeReceiver: negative);
- default:
- num receiverValue = receiver is IntConstant
- ? receiver.value
- : (receiver as DoubleConstant).value;
- num otherValue = other is IntConstant
- ? other.value
- : (other as DoubleConstant).value;
- return evaluateBinaryNumericOperation(
- op, receiverValue, otherValue, node);
- }
+ if (intFolder.isInt(other)) {
+ return canonicalize(
+ intFolder.foldBinaryOperator(node, op, receiver, other));
} else if (other is DoubleConstant) {
if ((op == '|' || op == '&' || op == '^') ||
(op == '<<' || op == '>>' || op == '>>>')) {
@@ -1456,11 +1326,9 @@
typeEnvironment.intType,
other.getType(typeEnvironment)));
}
- num receiverValue = receiver is IntConstant
- ? receiver.value
- : (receiver as DoubleConstant).value;
- return evaluateBinaryNumericOperation(
- op, receiverValue, other.value, node);
+ num receiverValue = (receiver as PrimitiveConstant<num>).value;
+ return canonicalize(evaluateBinaryNumericOperation(
+ op, receiverValue, other.value, node));
}
return report(
node,
@@ -1484,17 +1352,15 @@
if (arguments.length == 0) {
switch (op) {
case 'unary-':
- return canonicalize(makeDoubleConstant(-receiver.value));
+ return canonicalize(new DoubleConstant(-receiver.value));
}
} else if (arguments.length == 1) {
final Constant other = arguments[0];
if (other is IntConstant || other is DoubleConstant) {
- final num value = (other is IntConstant)
- ? other.value
- : (other as DoubleConstant).value;
- return evaluateBinaryNumericOperation(
- op, receiver.value, value, node);
+ final num value = (other as PrimitiveConstant<num>).value;
+ return canonicalize(
+ evaluateBinaryNumericOperation(op, receiver.value, value, node));
}
return report(
node,
@@ -1636,10 +1502,7 @@
final Constant receiver = _evaluateSubexpression(node.receiver);
if (receiver is StringConstant && node.name.name == 'length') {
- if (targetingJavaScript) {
- return canonicalize(new JavaScriptIntConstant(receiver.value.length));
- }
- return canonicalize(new IntConstant(receiver.value.length));
+ return canonicalize(intFolder.makeIntConstant(receiver.value.length));
} else if (shouldBeUnevaluated) {
return unevaluated(node,
new PropertyGet(extract(receiver), node.name, node.interfaceTarget));
@@ -1717,7 +1580,12 @@
for (int i = 0; i < node.expressions.length; i++) {
Constant constant = _evaluateSubexpression(node.expressions[i]);
if (constant is PrimitiveConstant<Object>) {
- String value = constant.toString();
+ String value;
+ if (constant is DoubleConstant && intFolder.isInt(constant)) {
+ value = new BigInt.from(constant.value).toString();
+ } else {
+ value = constant.toString();
+ }
Object last = concatenated.last;
if (last is StringBuffer) {
last.write(value);
@@ -1793,16 +1661,17 @@
return boolConstant;
} else if (target.enclosingClass == coreTypes.intClass) {
int intValue = value != null ? int.tryParse(value) : null;
- intValue ??= defaultValue is IntConstant
- ? defaultValue.value
- : defaultValue is JavaScriptIntConstant
- ? defaultValue.bigIntValue.toInt()
- : null;
- if (intValue == null) return nullConstant;
- if (targetingJavaScript) {
- return canonicalize(new JavaScriptIntConstant(intValue));
+ Constant intConstant;
+ if (intValue != null) {
+ bool negated = value.startsWith('-');
+ intConstant =
+ intFolder.makeIntConstant(intValue, unsigned: !negated);
+ } else if (intFolder.isInt(defaultValue)) {
+ intConstant = defaultValue;
+ } else {
+ intConstant = nullConstant;
}
- return canonicalize(new IntConstant(intValue));
+ return canonicalize(intConstant);
} else if (target.enclosingClass == coreTypes.stringClass) {
value ??=
defaultValue is StringConstant ? defaultValue.value : null;
@@ -1829,16 +1698,10 @@
final Constant right = positionals[1];
if (targetingJavaScript) {
- // In JavaScript, we lower [identical] to `===`, so any comparison
- // against NaN yields `false`.
- if (isNaN(left) || isNaN(right)) {
- return falseConstant;
- }
-
- // In JavaScript, `-0.0 === 0.0`.
- if (isZero(left)) {
- return makeBoolConstant(isZero(right));
- }
+ // In JavaScript, we lower [identical] to `===`, so we need to take
+ // the double special cases into account.
+ return doubleSpecialCases(left, right) ??
+ makeBoolConstant(identical(left, right));
}
// Since we canonicalize constants during the evaluation, we can use
@@ -1948,16 +1811,19 @@
// Helper methods:
- bool isZero(Constant value) =>
- (value is IntConstant && value.value == 0) ||
- (value is JavaScriptIntConstant && value.bigIntValue == BigInt.zero) ||
- (value is DoubleConstant && value.value == 0);
-
- bool isNaN(Constant value) => value is DoubleConstant && value.value.isNaN;
+ /// If both constants are DoubleConstant whose values would give different
+ /// results from == and [identical], return the result of ==. Otherwise
+ /// return null.
+ Constant doubleSpecialCases(Constant a, Constant b) {
+ if (a is DoubleConstant && b is DoubleConstant) {
+ if (a.value.isNaN && b.value.isNaN) return falseConstant;
+ if (a.value == 0.0 && b.value == 0.0) return trueConstant;
+ }
+ return null;
+ }
bool hasPrimitiveEqual(Constant constant) {
- // TODO(askesc, fishythefish): Make sure the correct class is inferred
- // when we clean up JavaScript int constant handling.
+ if (intFolder.isInt(constant)) return true;
DartType type = constant.getType(typeEnvironment);
return !(type is InterfaceType && !classHasPrimitiveEqual(type.classNode));
}
@@ -1981,18 +1847,6 @@
BoolConstant makeBoolConstant(bool value) =>
value ? trueConstant : falseConstant;
- DoubleConstant makeDoubleConstant(double value) {
- if (targetingJavaScript) {
- // Convert to an integer when possible (matching the runtime behavior
- // of `is int`).
- if (value.isFinite && !identical(value, -0.0)) {
- int i = value.toInt();
- if (value == i.toDouble()) return new JavaScriptIntConstant(i);
- }
- }
- return new DoubleConstant(value);
- }
-
bool isSubtype(Constant constant, DartType type) {
DartType constantType = constant.getType(typeEnvironment);
if (targetingJavaScript) {
@@ -2106,88 +1960,26 @@
}
}
- Constant evaluateBinaryBitOperation(String op, int a, int b, TreeNode node) {
- int result;
- switch (op) {
- case '|':
- result = a | b;
- break;
- case '&':
- result = a & b;
- break;
- case '^':
- result = a ^ b;
- break;
- }
-
- if (targetingJavaScript) {
- return canonicalize(new JavaScriptIntConstant(result));
- }
- return canonicalize(new IntConstant(result));
- }
-
- Constant evaluateBinaryShiftOperation(String op, int a, int b, TreeNode node,
- {negativeReceiver: false}) {
- int result;
- switch (op) {
- case '<<':
- result = a << b;
- break;
- case '>>':
- if (targetingJavaScript) {
- if (negativeReceiver) {
- const int signBit = 0x80000000;
- a -= (a & signBit) << 1;
- }
- result = a >> b;
- } else {
- result = a >> b;
- }
- break;
- case '>>>':
- // TODO(fishythefish): Implement JS semantics for `>>>`.
- result = b >= 64 ? 0 : (a >> b) & ((1 << (64 - b)) - 1);
- break;
- }
-
- if (targetingJavaScript) {
- return canonicalize(new JavaScriptIntConstant(result.toUnsigned(32)));
- }
- return canonicalize(new IntConstant(result));
- }
-
+ /// Binary operation between two operands, at least one of which is a double.
Constant evaluateBinaryNumericOperation(
String op, num a, num b, TreeNode node) {
- num result;
switch (op) {
case '+':
- result = a + b;
- break;
+ return new DoubleConstant(a + b);
case '-':
- result = a - b;
- break;
+ return new DoubleConstant(a - b);
case '*':
- result = a * b;
- break;
+ return new DoubleConstant(a * b);
case '/':
- result = a / b;
- break;
+ return new DoubleConstant(a / b);
case '~/':
- result = a ~/ b;
- break;
+ if (b == 0) {
+ return report(
+ node, templateConstEvalZeroDivisor.withArguments(op, '$a'));
+ }
+ return intFolder.truncatingDivide(a, b);
case '%':
- result = a % b;
- break;
- }
-
- if (result is int) {
- if (targetingJavaScript) {
- return canonicalize(new JavaScriptIntConstant(result));
- }
- return canonicalize(new IntConstant(result.toSigned(64)));
- }
- if (result is double) {
- return canonicalize(makeDoubleConstant(result));
+ return new DoubleConstant(a % b);
}
switch (op) {
diff --git a/pkg/front_end/lib/src/fasta/kernel/constant_int_folder.dart b/pkg/front_end/lib/src/fasta/kernel/constant_int_folder.dart
new file mode 100644
index 0000000..e28900f
--- /dev/null
+++ b/pkg/front_end/lib/src/fasta/kernel/constant_int_folder.dart
@@ -0,0 +1,238 @@
+// Copyright (c) 2019, 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.
+
+import 'dart:core' hide MapEntry;
+
+import 'package:kernel/ast.dart';
+import 'package:kernel/target/targets.dart';
+
+import 'constant_evaluator.dart';
+
+import '../fasta_codes.dart'
+ show
+ templateConstEvalInvalidMethodInvocation,
+ templateConstEvalNegativeShift,
+ templateConstEvalZeroDivisor;
+
+abstract class ConstantIntFolder {
+ final ConstantEvaluator evaluator;
+
+ ConstantIntFolder(this.evaluator);
+
+ factory ConstantIntFolder.forSemantics(
+ ConstantEvaluator evaluator, NumberSemantics semantics) {
+ if (semantics == NumberSemantics.js) {
+ return new JsConstantIntFolder(evaluator);
+ } else {
+ return new VmConstantIntFolder(evaluator);
+ }
+ }
+
+ bool isInt(Constant constant);
+
+ Constant makeIntConstant(int value, {bool unsigned: false});
+
+ Constant foldUnaryOperator(
+ MethodInvocation node, String op, covariant Constant operand);
+
+ Constant foldBinaryOperator(MethodInvocation node, String op,
+ covariant Constant left, covariant Constant right);
+
+ Constant truncatingDivide(num left, num right);
+
+ void _checkOperands(MethodInvocation node, String op, num left, num right) {
+ if ((op == '<<' || op == '>>' || op == '>>>') && right < 0) {
+ evaluator.report(node,
+ templateConstEvalNegativeShift.withArguments(op, '$left', '$right'));
+ }
+ if ((op == '%' || op == '~/') && right == 0) {
+ evaluator.report(
+ node, templateConstEvalZeroDivisor.withArguments(op, '$left'));
+ }
+ }
+}
+
+class VmConstantIntFolder extends ConstantIntFolder {
+ VmConstantIntFolder(ConstantEvaluator evaluator) : super(evaluator);
+
+ @override
+ bool isInt(Constant constant) => constant is IntConstant;
+
+ @override
+ IntConstant makeIntConstant(int value, {bool unsigned: false}) {
+ return new IntConstant(value);
+ }
+
+ @override
+ Constant foldUnaryOperator(
+ MethodInvocation node, String op, IntConstant operand) {
+ switch (op) {
+ case 'unary-':
+ return new IntConstant(-operand.value);
+ case '~':
+ return new IntConstant(~operand.value);
+ default:
+ return evaluator.report(
+ node,
+ templateConstEvalInvalidMethodInvocation.withArguments(
+ op, operand));
+ }
+ }
+
+ @override
+ Constant foldBinaryOperator(
+ MethodInvocation node, String op, IntConstant left, IntConstant right) {
+ int a = left.value;
+ int b = right.value;
+ _checkOperands(node, op, a, b);
+ switch (op) {
+ case '+':
+ return new IntConstant(a + b);
+ case '-':
+ return new IntConstant(a - b);
+ case '*':
+ return new IntConstant(a * b);
+ case '/':
+ return new DoubleConstant(a / b);
+ case '~/':
+ return new IntConstant(a ~/ b);
+ case '%':
+ return new IntConstant(a % b);
+ case '|':
+ return new IntConstant(a | b);
+ case '&':
+ return new IntConstant(a & b);
+ case '^':
+ return new IntConstant(a ^ b);
+ case '<<':
+ return new IntConstant(a << b);
+ case '>>':
+ return new IntConstant(a >> b);
+ case '>>>':
+ int result = b >= 64 ? 0 : (a >> b) & ((1 << (64 - b)) - 1);
+ return new IntConstant(result);
+ case '<':
+ return evaluator.makeBoolConstant(a < b);
+ case '<=':
+ return evaluator.makeBoolConstant(a <= b);
+ case '>=':
+ return evaluator.makeBoolConstant(a >= b);
+ case '>':
+ return evaluator.makeBoolConstant(a > b);
+ default:
+ return evaluator.report(node,
+ templateConstEvalInvalidMethodInvocation.withArguments(op, left));
+ }
+ }
+
+ @override
+ Constant truncatingDivide(num left, num right) {
+ return new IntConstant(left ~/ right);
+ }
+}
+
+class JsConstantIntFolder extends ConstantIntFolder {
+ JsConstantIntFolder(ConstantEvaluator evaluator) : super(evaluator);
+
+ static bool _valueIsInteger(double value) {
+ return value.isFinite && value.truncateToDouble() == value;
+ }
+
+ static int _truncate32(int value) => value & 0xFFFFFFFF;
+
+ static int _toUint32(double value) {
+ return new BigInt.from(value).toUnsigned(32).toInt();
+ }
+
+ @override
+ bool isInt(Constant constant) {
+ return constant is DoubleConstant && _valueIsInteger(constant.value);
+ }
+
+ @override
+ DoubleConstant makeIntConstant(int value, {bool unsigned: false}) {
+ double doubleValue = value.toDouble();
+ assert(doubleValue.toInt() == value);
+ if (unsigned) {
+ const double twoTo64 = 18446744073709551616.0;
+ if (value < 0) doubleValue += twoTo64;
+ }
+ return new DoubleConstant(doubleValue);
+ }
+
+ @override
+ Constant foldUnaryOperator(
+ MethodInvocation node, String op, DoubleConstant operand) {
+ switch (op) {
+ case 'unary-':
+ return new DoubleConstant(-operand.value);
+ case '~':
+ int intValue = _toUint32(operand.value);
+ return new DoubleConstant(_truncate32(~intValue).toDouble());
+ default:
+ return evaluator.report(
+ node,
+ templateConstEvalInvalidMethodInvocation.withArguments(
+ op, operand));
+ }
+ }
+
+ @override
+ Constant foldBinaryOperator(MethodInvocation node, String op,
+ DoubleConstant left, DoubleConstant right) {
+ double a = left.value;
+ double b = right.value;
+ _checkOperands(node, op, a, b);
+ switch (op) {
+ case '+':
+ return new DoubleConstant(a + b);
+ case '-':
+ return new DoubleConstant(a - b);
+ case '*':
+ return new DoubleConstant(a * b);
+ case '/':
+ return new DoubleConstant(a / b);
+ case '~/':
+ return truncatingDivide(a, b);
+ case '%':
+ return new DoubleConstant(a % b);
+ case '|':
+ return new DoubleConstant((_toUint32(a) | _toUint32(b)).toDouble());
+ case '&':
+ return new DoubleConstant((_toUint32(a) & _toUint32(b)).toDouble());
+ case '^':
+ return new DoubleConstant((_toUint32(a) ^ _toUint32(b)).toDouble());
+ case '<<':
+ int ai = _toUint32(a);
+ return new DoubleConstant(_truncate32(ai << b.toInt()).toDouble());
+ case '>>':
+ int ai = _toUint32(a);
+ if (a < 0) {
+ const int signBit = 0x80000000;
+ ai -= (ai & signBit) << 1;
+ }
+ return new DoubleConstant(_truncate32(ai >> b.toInt()).toDouble());
+ case '>>>':
+ int ai = _toUint32(a);
+ return new DoubleConstant(_truncate32(ai >> b.toInt()).toDouble());
+ case '<':
+ return evaluator.makeBoolConstant(a < b);
+ case '<=':
+ return evaluator.makeBoolConstant(a <= b);
+ case '>=':
+ return evaluator.makeBoolConstant(a >= b);
+ case '>':
+ return evaluator.makeBoolConstant(a > b);
+ default:
+ return evaluator.report(node,
+ templateConstEvalInvalidMethodInvocation.withArguments(op, left));
+ }
+ }
+
+ @override
+ Constant truncatingDivide(num left, num right) {
+ double result = (left / right).truncateToDouble();
+ return new DoubleConstant(result == 0.0 ? 0.0 : result);
+ }
+}
diff --git a/pkg/front_end/lib/src/fasta/kernel/expression_generator.dart b/pkg/front_end/lib/src/fasta/kernel/expression_generator.dart
index 69994cc..de53658 100644
--- a/pkg/front_end/lib/src/fasta/kernel/expression_generator.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/expression_generator.dart
@@ -7,23 +7,7 @@
import 'dart:core' hide MapEntry;
-import 'package:kernel/ast.dart'
- show
- Constructor,
- Field,
- IntLiteral,
- InvalidExpression,
- Let,
- Node,
- PropertyGet,
- PropertySet,
- StaticSet,
- SuperMethodInvocation,
- SuperPropertySet,
- TreeNode,
- TypeParameter,
- VariableGet,
- VariableSet;
+import 'package:kernel/ast.dart';
import '../../scanner/token.dart' show Token;
@@ -99,19 +83,7 @@
UnlinkedDeclaration,
UnresolvedType;
-import 'kernel_shadow_ast.dart'
- show
- ComplexAssignmentJudgment,
- LoadLibraryTearOffJudgment,
- MethodInvocationJudgment,
- NullAwarePropertyGetJudgment,
- PropertyAssignmentJudgment,
- SuperMethodInvocationJudgment,
- SuperPropertyGetJudgment,
- SyntheticWrapper,
- VariableDeclarationJudgment,
- VariableGetJudgment,
- getExplicitTypeArguments;
+import 'kernel_shadow_ast.dart';
/// A generator represents a subexpression for which we can't yet build an
/// expression because we don't yet know the context in which it's used.
@@ -196,8 +168,7 @@
/// [voidContext] is true, in which case it may evaluate to anything.
///
/// [type] is the static type of the RHS.
- Expression buildNullAwareAssignment(
- Expression value, DartType type, int offset,
+ Expression buildIfNullAssignment(Expression value, DartType type, int offset,
{bool voidContext: false}) {
ComplexAssignmentJudgment complexAssignment = startComplexAssignment(value);
if (voidContext) {
@@ -281,9 +252,8 @@
offset: offset);
complexAssignment?.combiner = combiner;
complexAssignment?.isPostIncDec = true;
- VariableDeclarationJudgment dummy =
- new VariableDeclarationJudgment.forValue(
- _makeWrite(combiner, true, complexAssignment));
+ VariableDeclarationImpl dummy = new VariableDeclarationImpl.forValue(
+ _makeWrite(combiner, true, complexAssignment));
return _finish(
makeLet(value, makeLet(dummy, valueAccess())), complexAssignment);
}
@@ -372,7 +342,7 @@
Expression _finish(
Expression body, ComplexAssignmentJudgment complexAssignment) {
- if (!_helper.legacyMode && complexAssignment != null) {
+ if (complexAssignment != null) {
complexAssignment.desugared = body;
return complexAssignment;
} else {
@@ -517,17 +487,85 @@
String get _plainNameForRead => variable.name;
@override
+ Expression buildSimpleRead() {
+ return _createRead();
+ }
+
+ Expression _createRead() {
+ return _helper.createVariableGet(variable, fileOffset);
+ }
+
+ @override
Expression _makeRead(ComplexAssignmentJudgment complexAssignment) {
TypePromotionFact fact = _helper.typePromoter
?.getFactForAccess(variable, _helper.functionNestingLevel);
TypePromotionScope scope = _helper.typePromoter?.currentScope;
- VariableGetJudgment read = new VariableGetJudgment(variable, fact, scope)
+ VariableGetImpl read = new VariableGetImpl(variable, fact, scope)
..fileOffset = fileOffset;
complexAssignment?.read = read;
return read;
}
@override
+ Expression buildAssignment(Expression value, {bool voidContext: false}) {
+ return _createWrite(fileOffset, value);
+ }
+
+ Expression _createWrite(int offset, Expression value) {
+ _helper.typePromoter
+ ?.mutateVariable(variable, _helper.functionNestingLevel);
+ Expression write;
+ if (variable.isFinal || variable.isConst) {
+ write = _makeInvalidWrite(value);
+ } else {
+ write = new VariableSet(variable, value)..fileOffset = offset;
+ }
+ return write;
+ }
+
+ Expression buildCompoundAssignment(Name binaryOperator, Expression value,
+ {int offset: TreeNode.noOffset,
+ bool voidContext: false,
+ Procedure interfaceTarget,
+ bool isPreIncDec: false,
+ bool isPostIncDec: false}) {
+ MethodInvocation binary = _helper.forest.createMethodInvocation(
+ offset,
+ _createRead(),
+ binaryOperator,
+ _helper.forest.createArguments(offset, <Expression>[value]),
+ interfaceTarget: interfaceTarget);
+ return _createWrite(fileOffset, binary);
+ }
+
+ @override
+ Expression buildPostfixIncrement(Name binaryOperator,
+ {int offset = TreeNode.noOffset,
+ bool voidContext = false,
+ Procedure interfaceTarget}) {
+ Expression value = _forest.createIntLiteral(1, null)..fileOffset = offset;
+ if (voidContext) {
+ return buildCompoundAssignment(binaryOperator, value,
+ offset: offset,
+ voidContext: voidContext,
+ interfaceTarget: interfaceTarget,
+ isPostIncDec: true);
+ }
+ VariableDeclaration read = _helper.forest
+ .createVariableDeclarationForValue(fileOffset, _createRead());
+ MethodInvocation binary = _helper.forest.createMethodInvocation(
+ offset,
+ _helper.createVariableGet(read, fileOffset),
+ binaryOperator,
+ _helper.forest.createArguments(offset, <Expression>[value]),
+ interfaceTarget: interfaceTarget);
+ VariableDeclaration write = _helper.forest
+ .createVariableDeclarationForValue(
+ offset, _createWrite(offset, binary));
+ return new LocalPostIncDec(read, write)..fileOffset = offset;
+ }
+
+ @override
Expression _makeWrite(Expression value, bool voidContext,
ComplexAssignmentJudgment complexAssignment) {
_helper.typePromoter
@@ -646,6 +684,87 @@
}
@override
+ Expression buildAssignment(Expression value, {bool voidContext: false}) {
+ return new PropertySet(receiver, name, value, setter)
+ ..fileOffset = fileOffset;
+ }
+
+ @override
+ Expression buildIfNullAssignment(Expression value, DartType type, int offset,
+ {bool voidContext = false}) {
+ VariableDeclaration variable = _helper.forest
+ .createVariableDeclarationForValue(receiver.fileOffset, receiver);
+ PropertyGet read = new PropertyGet(
+ _helper.createVariableGet(variable, receiver.fileOffset), name)
+ ..fileOffset = fileOffset;
+ PropertySet write = new PropertySet(
+ _helper.createVariableGet(variable, receiver.fileOffset), name, value)
+ ..fileOffset = fileOffset;
+ return new IfNullPropertySet(variable, read, write, forEffect: voidContext)
+ ..fileOffset = offset;
+ }
+
+ @override
+ Expression buildCompoundAssignment(Name binaryOperator, Expression value,
+ {int offset: TreeNode.noOffset,
+ bool voidContext: false,
+ Procedure interfaceTarget,
+ bool isPreIncDec: false,
+ bool isPostIncDec: false}) {
+ VariableDeclaration variable = _helper.forest
+ .createVariableDeclarationForValue(receiver.fileOffset, receiver);
+ MethodInvocation binary = _helper.forest.createMethodInvocation(
+ offset,
+ new PropertyGet(
+ _helper.createVariableGet(variable, receiver.fileOffset), name)
+ ..fileOffset = fileOffset,
+ binaryOperator,
+ _helper.forest.createArguments(offset, <Expression>[value]),
+ interfaceTarget: interfaceTarget);
+ PropertySet write = new PropertySet(
+ _helper.createVariableGet(variable, receiver.fileOffset), name, binary)
+ ..fileOffset = fileOffset;
+ return new CompoundPropertySet(variable, write)..fileOffset = offset;
+ }
+
+ @override
+ Expression buildPostfixIncrement(Name binaryOperator,
+ {int offset = TreeNode.noOffset,
+ bool voidContext = false,
+ Procedure interfaceTarget}) {
+ Expression value = _forest.createIntLiteral(1, null)..fileOffset = offset;
+ if (voidContext) {
+ return buildCompoundAssignment(binaryOperator, value,
+ offset: offset,
+ voidContext: voidContext,
+ interfaceTarget: interfaceTarget,
+ isPostIncDec: true);
+ }
+ VariableDeclaration variable = _helper.forest
+ .createVariableDeclarationForValue(receiver.fileOffset, receiver);
+ VariableDeclaration read = _helper.forest.createVariableDeclarationForValue(
+ fileOffset,
+ new PropertyGet(
+ _helper.createVariableGet(variable, receiver.fileOffset), name)
+ ..fileOffset = fileOffset);
+ MethodInvocation binary = _helper.forest.createMethodInvocation(
+ offset,
+ _helper.createVariableGet(read, fileOffset),
+ binaryOperator,
+ _helper.forest.createArguments(offset, <Expression>[value]),
+ interfaceTarget: interfaceTarget);
+ VariableDeclaration write = _helper.forest
+ .createVariableDeclarationForValue(
+ offset,
+ new PropertySet(
+ _helper.createVariableGet(variable, receiver.fileOffset),
+ name,
+ binary)
+ ..fileOffset = fileOffset);
+ return new PropertyPostIncDec(variable, read, write)..fileOffset = offset;
+ }
+
+ @override
Expression _makeSimpleWrite(Expression value, bool voidContext,
ComplexAssignmentJudgment complexAssignment) {
PropertySet write = new PropertySet(receiver, name, value, setter)
@@ -760,6 +879,41 @@
String get _plainNameForRead => name.name;
@override
+ Expression buildSimpleRead() {
+ return _createRead();
+ }
+
+ Expression _createRead() {
+ if (getter == null) {
+ _helper.warnUnresolvedGet(name, fileOffset);
+ }
+ return new PropertyGet(_forest.createThisExpression(token), name, getter)
+ ..fileOffset = fileOffset;
+ }
+
+ @override
+ Expression buildAssignment(Expression value, {bool voidContext: false}) {
+ return _createWrite(fileOffset, value);
+ }
+
+ Expression _createWrite(int offset, Expression value) {
+ if (setter == null) {
+ _helper.warnUnresolvedSet(name, fileOffset);
+ }
+ return new PropertySet(
+ _forest.createThisExpression(token), name, value, setter)
+ ..fileOffset = fileOffset;
+ }
+
+ @override
+ Expression buildIfNullAssignment(Expression value, DartType type, int offset,
+ {bool voidContext: false}) {
+ return new IfNullSet(_createRead(), _createWrite(offset, value),
+ forEffect: voidContext)
+ ..fileOffset = offset;
+ }
+
+ @override
Expression _makeRead(ComplexAssignmentJudgment complexAssignment) {
if (getter == null) {
_helper.warnUnresolvedGet(name, fileOffset);
@@ -849,6 +1003,33 @@
String get _plainNameForRead => name.name;
@override
+ Expression buildSimpleRead() {
+ VariableDeclaration variable = _helper.forest
+ .createVariableDeclarationForValue(
+ receiverExpression.fileOffset, receiverExpression);
+ PropertyGet read = new PropertyGet(
+ _helper.createVariableGet(variable, receiverExpression.fileOffset),
+ name)
+ ..fileOffset = fileOffset;
+ return new NullAwarePropertyGet(variable, read)
+ ..fileOffset = receiverExpression.fileOffset;
+ }
+
+ @override
+ Expression buildAssignment(Expression value, {bool voidContext = false}) {
+ VariableDeclaration variable = _helper.forest
+ .createVariableDeclarationForValue(
+ receiverExpression.fileOffset, receiverExpression);
+ PropertySet read = new PropertySet(
+ _helper.createVariableGet(variable, receiverExpression.fileOffset),
+ name,
+ value)
+ ..fileOffset = fileOffset;
+ return new NullAwarePropertySet(variable, read)
+ ..fileOffset = receiverExpression.fileOffset;
+ }
+
+ @override
Expression _makeRead(ComplexAssignmentJudgment complexAssignment) {
PropertyGet read = new PropertyGet(receiverAccess(), name, getter)
..fileOffset = fileOffset;
@@ -877,14 +1058,12 @@
..fileOffset = fileOffset;
if (complexAssignment != null) {
body = makeLet(receiver, nullAwareGuard);
- if (_helper.legacyMode) return body;
PropertyAssignmentJudgment kernelPropertyAssign = complexAssignment;
kernelPropertyAssign.nullAwareGuard = nullAwareGuard;
kernelPropertyAssign.desugared = body;
return kernelPropertyAssign;
} else {
- return new NullAwarePropertyGetJudgment(receiver, nullAwareGuard)
- ..fileOffset = fileOffset;
+ return unhandled('${runtimeType}', "_finish", fileOffset, _uri);
}
}
@@ -933,19 +1112,95 @@
String get _plainNameForRead => name.name;
@override
+ Expression buildSimpleRead() {
+ return _createRead();
+ }
+
+ Expression _createRead() {
+ if (getter == null) {
+ _helper.warnUnresolvedGet(name, fileOffset, isSuper: true);
+ }
+ return new SuperPropertyGet(name, getter)..fileOffset = fileOffset;
+ }
+
+ @override
Expression _makeRead(ComplexAssignmentJudgment complexAssignment) {
if (getter == null) {
_helper.warnUnresolvedGet(name, fileOffset, isSuper: true);
}
// TODO(ahe): Use [DirectPropertyGet] when possible.
- SuperPropertyGetJudgment read =
- new SuperPropertyGetJudgment(name, interfaceTarget: getter)
- ..fileOffset = fileOffset;
+ SuperPropertyGet read = new SuperPropertyGet(name, getter)
+ ..fileOffset = fileOffset;
complexAssignment?.read = read;
return read;
}
@override
+ Expression buildAssignment(Expression value, {bool voidContext = false}) {
+ return _createWrite(fileOffset, value);
+ }
+
+ Expression _createWrite(int offset, Expression value) {
+ if (setter == null) {
+ _helper.warnUnresolvedSet(name, offset, isSuper: true);
+ }
+ SuperPropertySet write = new SuperPropertySet(name, value, setter)
+ ..fileOffset = offset;
+ return write;
+ }
+
+ @override
+ Expression buildCompoundAssignment(Name binaryOperator, Expression value,
+ {int offset = TreeNode.noOffset,
+ bool voidContext = false,
+ Procedure interfaceTarget,
+ bool isPreIncDec = false,
+ bool isPostIncDec = false}) {
+ MethodInvocation binary = _helper.forest.createMethodInvocation(
+ offset,
+ _createRead(),
+ binaryOperator,
+ _helper.forest.createArguments(offset, <Expression>[value]),
+ interfaceTarget: interfaceTarget);
+ return _createWrite(fileOffset, binary);
+ }
+
+ @override
+ Expression buildPostfixIncrement(Name binaryOperator,
+ {int offset = TreeNode.noOffset,
+ bool voidContext = false,
+ Procedure interfaceTarget}) {
+ Expression value = _forest.createIntLiteral(1, null)..fileOffset = offset;
+ if (voidContext) {
+ return buildCompoundAssignment(binaryOperator, value,
+ offset: offset,
+ voidContext: voidContext,
+ interfaceTarget: interfaceTarget,
+ isPostIncDec: true);
+ }
+ VariableDeclaration read = _helper.forest
+ .createVariableDeclarationForValue(fileOffset, _createRead());
+ MethodInvocation binary = _helper.forest.createMethodInvocation(
+ offset,
+ _helper.createVariableGet(read, fileOffset),
+ binaryOperator,
+ _helper.forest.createArguments(offset, <Expression>[value]),
+ interfaceTarget: interfaceTarget);
+ VariableDeclaration write = _helper.forest
+ .createVariableDeclarationForValue(
+ offset, _createWrite(fileOffset, binary));
+ return new StaticPostIncDec(read, write)..fileOffset = offset;
+ }
+
+ @override
+ Expression buildIfNullAssignment(Expression value, DartType type, int offset,
+ {bool voidContext: false}) {
+ return new IfNullSet(_createRead(), _createWrite(fileOffset, value),
+ forEffect: voidContext)
+ ..fileOffset = offset;
+ }
+
+ @override
Expression _makeWrite(Expression value, bool voidContext,
ComplexAssignmentJudgment complexAssignment) {
if (setter == null) {
@@ -1017,6 +1272,66 @@
@override
String get _debugName => "IndexedAccessGenerator";
+ @override
+ Expression buildSimpleRead() {
+ return _helper.buildMethodInvocation(
+ receiver,
+ new Name('[]'),
+ _helper.forest.createArguments(fileOffset, <Expression>[index]),
+ fileOffset,
+ interfaceTarget: getter);
+ }
+
+ @override
+ Expression buildAssignment(Expression value, {bool voidContext: false}) {
+ if (voidContext) {
+ return _helper.buildMethodInvocation(
+ receiver,
+ new Name('[]='),
+ _helper.forest
+ .createArguments(fileOffset, <Expression>[index, value]),
+ fileOffset,
+ interfaceTarget: setter);
+ } else {
+ return new IndexSet(receiver, index, value)..fileOffset = fileOffset;
+ }
+ }
+
+ @override
+ Expression buildIfNullAssignment(Expression value, DartType type, int offset,
+ {bool voidContext: false}) {
+ return new IfNullIndexSet(receiver, index, value, fileOffset,
+ forEffect: voidContext)
+ ..fileOffset = offset;
+ }
+
+ Expression buildCompoundAssignment(Name binaryOperator, Expression value,
+ {int offset: TreeNode.noOffset,
+ bool voidContext: false,
+ Procedure interfaceTarget,
+ bool isPreIncDec: false,
+ bool isPostIncDec: false}) {
+ return new CompoundIndexSet(receiver, index, binaryOperator, value,
+ readOffset: fileOffset,
+ binaryOffset: offset,
+ writeOffset: fileOffset,
+ forEffect: voidContext,
+ forPostIncDec: isPostIncDec);
+ }
+
+ @override
+ Expression buildPostfixIncrement(Name binaryOperator,
+ {int offset = TreeNode.noOffset,
+ bool voidContext = false,
+ Procedure interfaceTarget}) {
+ Expression value = _forest.createIntLiteral(1, null)..fileOffset = offset;
+ return buildCompoundAssignment(binaryOperator, value,
+ offset: offset,
+ voidContext: voidContext,
+ interfaceTarget: interfaceTarget,
+ isPostIncDec: true);
+ }
+
Expression indexAccess() {
indexVariable ??= new VariableDeclaration.forValue(index);
return new VariableGet(indexVariable)..fileOffset = fileOffset;
@@ -1031,8 +1346,8 @@
@override
Expression _makeSimpleRead() {
- MethodInvocationJudgment read = new MethodInvocationJudgment(receiver,
- indexGetName, _forest.createArguments(fileOffset, <Expression>[index]),
+ MethodInvocationImpl read = new MethodInvocationImpl(receiver, indexGetName,
+ _forest.createArguments(fileOffset, <Expression>[index]),
interfaceTarget: getter)
..fileOffset = fileOffset;
return read;
@@ -1042,7 +1357,7 @@
Expression _makeSimpleWrite(Expression value, bool voidContext,
ComplexAssignmentJudgment complexAssignment) {
if (!voidContext) return _makeWriteAndReturn(value, complexAssignment);
- MethodInvocationJudgment write = new MethodInvocationJudgment(
+ MethodInvocationImpl write = new MethodInvocationImpl(
receiver,
indexSetName,
_forest.createArguments(fileOffset, <Expression>[index, value]),
@@ -1054,7 +1369,7 @@
@override
Expression _makeRead(ComplexAssignmentJudgment complexAssignment) {
- MethodInvocationJudgment read = new MethodInvocationJudgment(
+ MethodInvocationImpl read = new MethodInvocationImpl(
receiverAccess(),
indexGetName,
_forest.createArguments(fileOffset, <Expression>[indexAccess()]),
@@ -1068,7 +1383,7 @@
Expression _makeWrite(Expression value, bool voidContext,
ComplexAssignmentJudgment complexAssignment) {
if (!voidContext) return _makeWriteAndReturn(value, complexAssignment);
- MethodInvocationJudgment write = new MethodInvocationJudgment(
+ MethodInvocationImpl write = new MethodInvocationImpl(
receiverAccess(),
indexSetName,
_forest.createArguments(fileOffset, <Expression>[indexAccess(), value]),
@@ -1085,7 +1400,7 @@
// The call to []= does not return the value like direct-style assignments
// do. We need to bind the value in a let.
VariableDeclaration valueVariable = new VariableDeclaration.forValue(value);
- MethodInvocationJudgment write = new MethodInvocationJudgment(
+ MethodInvocationImpl write = new MethodInvocationImpl(
receiverAccess(),
indexSetName,
_forest.createArguments(fileOffset,
@@ -1093,8 +1408,7 @@
interfaceTarget: setter)
..fileOffset = fileOffset;
complexAssignment?.write = write;
- VariableDeclarationJudgment dummy =
- new VariableDeclarationJudgment.forValue(write);
+ VariableDeclarationImpl dummy = new VariableDeclarationImpl.forValue(write);
return makeLet(
valueVariable, makeLet(dummy, new VariableGet(valueVariable)));
}
@@ -1183,7 +1497,7 @@
Expression _makeWriteAndReturn(
Expression value, ComplexAssignmentJudgment complexAssignment) {
VariableDeclaration valueVariable = new VariableDeclaration.forValue(value);
- MethodInvocationJudgment write = new MethodInvocationJudgment(
+ MethodInvocationImpl write = new MethodInvocationImpl(
_forest.createThisExpression(token),
indexSetName,
_forest.createArguments(fileOffset,
@@ -1198,7 +1512,7 @@
@override
Expression _makeSimpleRead() {
- return new MethodInvocationJudgment(_forest.createThisExpression(token),
+ return new MethodInvocationImpl(_forest.createThisExpression(token),
indexGetName, _forest.createArguments(fileOffset, <Expression>[index]),
interfaceTarget: getter)
..fileOffset = fileOffset;
@@ -1208,7 +1522,7 @@
Expression _makeSimpleWrite(Expression value, bool voidContext,
ComplexAssignmentJudgment complexAssignment) {
if (!voidContext) return _makeWriteAndReturn(value, complexAssignment);
- MethodInvocationJudgment write = new MethodInvocationJudgment(
+ MethodInvocationImpl write = new MethodInvocationImpl(
_forest.createThisExpression(token),
indexSetName,
_forest.createArguments(fileOffset, <Expression>[index, value]),
@@ -1220,7 +1534,7 @@
@override
Expression _makeRead(ComplexAssignmentJudgment complexAssignment) {
- MethodInvocationJudgment read = new MethodInvocationJudgment(
+ MethodInvocationImpl read = new MethodInvocationImpl(
_forest.createThisExpression(token),
indexGetName,
_forest.createArguments(fileOffset, <Expression>[indexAccess()]),
@@ -1234,7 +1548,7 @@
Expression _makeWrite(Expression value, bool voidContext,
ComplexAssignmentJudgment complexAssignment) {
if (!voidContext) return _makeWriteAndReturn(value, complexAssignment);
- MethodInvocationJudgment write = new MethodInvocationJudgment(
+ MethodInvocationImpl write = new MethodInvocationImpl(
_forest.createThisExpression(token),
indexSetName,
_forest.createArguments(fileOffset, <Expression>[indexAccess(), value]),
@@ -1321,9 +1635,8 @@
_helper.warnUnresolvedMethod(indexGetName, fileOffset, isSuper: true);
}
// TODO(ahe): Use [DirectMethodInvocation] when possible.
- return new SuperMethodInvocationJudgment(
- indexGetName, _forest.createArguments(fileOffset, <Expression>[index]),
- interfaceTarget: getter)
+ return new SuperMethodInvocation(indexGetName,
+ _forest.createArguments(fileOffset, <Expression>[index]), getter)
..fileOffset = fileOffset;
}
@@ -1488,6 +1801,87 @@
String get _plainNameForRead => (readTarget ?? writeTarget).name.name;
@override
+ Expression buildSimpleRead() {
+ return _createRead();
+ }
+
+ Expression _createRead() {
+ Expression read;
+ if (readTarget == null) {
+ read = _makeInvalidRead();
+ } else {
+ read = _helper.makeStaticGet(readTarget, token);
+ }
+ return read;
+ }
+
+ @override
+ Expression buildAssignment(Expression value, {bool voidContext = false}) {
+ return _createWrite(fileOffset, value);
+ }
+
+ Expression _createWrite(int offset, Expression value) {
+ Expression write;
+ if (writeTarget == null) {
+ write = _makeInvalidWrite(value);
+ } else {
+ write = new StaticSet(writeTarget, value)..fileOffset = offset;
+ }
+ return write;
+ }
+
+ @override
+ Expression buildIfNullAssignment(Expression value, DartType type, int offset,
+ {bool voidContext: false}) {
+ return new IfNullSet(_createRead(), _createWrite(offset, value),
+ forEffect: voidContext)
+ ..fileOffset = offset;
+ }
+
+ @override
+ Expression buildCompoundAssignment(Name binaryOperator, Expression value,
+ {int offset = TreeNode.noOffset,
+ bool voidContext = false,
+ Procedure interfaceTarget,
+ bool isPreIncDec = false,
+ bool isPostIncDec = false}) {
+ MethodInvocation binary = _helper.forest.createMethodInvocation(
+ offset,
+ _createRead(),
+ binaryOperator,
+ _helper.forest.createArguments(offset, <Expression>[value]),
+ interfaceTarget: interfaceTarget);
+ return _createWrite(fileOffset, binary);
+ }
+
+ @override
+ Expression buildPostfixIncrement(Name binaryOperator,
+ {int offset = TreeNode.noOffset,
+ bool voidContext = false,
+ Procedure interfaceTarget}) {
+ Expression value = _forest.createIntLiteral(1, null)..fileOffset = offset;
+ if (voidContext) {
+ return buildCompoundAssignment(binaryOperator, value,
+ offset: offset,
+ voidContext: voidContext,
+ interfaceTarget: interfaceTarget,
+ isPostIncDec: true);
+ }
+ VariableDeclaration read = _helper.forest
+ .createVariableDeclarationForValue(fileOffset, _createRead());
+ MethodInvocation binary = _helper.forest.createMethodInvocation(
+ offset,
+ _helper.createVariableGet(read, fileOffset),
+ binaryOperator,
+ _helper.forest.createArguments(offset, <Expression>[value]),
+ interfaceTarget: interfaceTarget);
+ VariableDeclaration write = _helper.forest
+ .createVariableDeclarationForValue(
+ offset, _createWrite(offset, binary));
+ return new StaticPostIncDec(read, write)..fileOffset = offset;
+ }
+
+ @override
Expression _makeRead(ComplexAssignmentJudgment complexAssignment) {
Expression read;
if (readTarget == null) {
@@ -2070,7 +2464,7 @@
@override
Expression _makeRead(ComplexAssignmentJudgment complexAssignment) {
builder.importDependency.targetLibrary;
- LoadLibraryTearOffJudgment read = new LoadLibraryTearOffJudgment(
+ LoadLibraryTearOff read = new LoadLibraryTearOff(
builder.importDependency, builder.createTearoffMethod(_helper.forest))
..fileOffset = fileOffset;
complexAssignment?.read = read;
@@ -2593,8 +2987,7 @@
}
@override
- Expression buildNullAwareAssignment(
- Expression value, DartType type, int offset,
+ Expression buildIfNullAssignment(Expression value, DartType type, int offset,
{bool voidContext: false}) {
return buildError(_forest.createArguments(fileOffset, <Expression>[value]),
isSetter: true);
@@ -2789,8 +3182,7 @@
}
@override
- Expression buildNullAwareAssignment(
- Expression value, DartType type, int offset,
+ Expression buildIfNullAssignment(Expression value, DartType type, int offset,
{bool voidContext: false}) {
return _makeInvalidWrite(value);
}
@@ -2886,7 +3278,7 @@
return generator.buildCompoundAssignment(tripleShiftName, value,
offset: fileOffset, voidContext: voidContext);
} else if (identical("??=", assignmentOperator)) {
- return generator.buildNullAwareAssignment(
+ return generator.buildIfNullAssignment(
value, const DynamicType(), fileOffset,
voidContext: voidContext);
} else if (identical("^=", assignmentOperator)) {
@@ -3134,8 +3526,7 @@
return buildProblem();
}
- Expression buildNullAwareAssignment(
- Expression value, DartType type, int offset,
+ Expression buildIfNullAssignment(Expression value, DartType type, int offset,
{bool voidContext: false}) {
return buildProblem();
}
@@ -3395,8 +3786,7 @@
return buildAssignmentError();
}
- Expression buildNullAwareAssignment(
- Expression value, DartType type, int offset,
+ Expression buildIfNullAssignment(Expression value, DartType type, int offset,
{bool voidContext: false}) {
return buildAssignmentError();
}
@@ -3526,8 +3916,7 @@
isNullAware: isNullAware);
}
- Expression buildNullAwareAssignment(
- Expression value, DartType type, int offset,
+ Expression buildIfNullAssignment(Expression value, DartType type, int offset,
{bool voidContext: false}) {
return unsupported("buildNullAwareAssignment", offset, _uri);
}
@@ -3601,8 +3990,7 @@
_helper.toValue(receiver), name, null, null, isNullAware);
}
- Expression buildNullAwareAssignment(
- Expression value, DartType type, int offset,
+ Expression buildIfNullAssignment(Expression value, DartType type, int offset,
{bool voidContext: false}) {
return unsupported("buildNullAwareAssignment", offset, _uri);
}
@@ -3673,7 +4061,7 @@
Expression makeBinary(Expression left, Name operator, Procedure interfaceTarget,
Expression right, ExpressionGeneratorHelper helper,
{int offset: TreeNode.noOffset}) {
- return new MethodInvocationJudgment(left, operator,
+ return new MethodInvocationImpl(left, operator,
helper.forest.createArguments(offset, <Expression>[right]),
interfaceTarget: interfaceTarget)
..fileOffset = offset;
diff --git a/pkg/front_end/lib/src/fasta/kernel/expression_generator_helper.dart b/pkg/front_end/lib/src/fasta/kernel/expression_generator_helper.dart
index c847440..53d1baf 100644
--- a/pkg/front_end/lib/src/fasta/kernel/expression_generator_helper.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/expression_generator_helper.dart
@@ -53,8 +53,6 @@
Forest get forest;
- bool get legacyMode;
-
Constructor lookupConstructor(Name name, {bool isSuper});
Expression toValue(node);
diff --git a/pkg/front_end/lib/src/fasta/kernel/forest.dart b/pkg/front_end/lib/src/fasta/kernel/forest.dart
index f63bfbc..37926f6 100644
--- a/pkg/front_end/lib/src/fasta/kernel/forest.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/forest.dart
@@ -28,34 +28,14 @@
import 'kernel_shadow_ast.dart'
show
- ArgumentsJudgment,
- AssertInitializerJudgment,
- AssertStatementJudgment,
- BlockJudgment,
- CatchJudgment,
- DoJudgment,
- DoubleJudgment,
- EmptyStatementJudgment,
- ExpressionStatementJudgment,
- ForJudgment,
- FunctionNodeJudgment,
- IfJudgment,
+ ArgumentsImpl,
IntJudgment,
- ListLiteralJudgment,
- LoadLibraryJudgment,
- MapLiteralJudgment,
- MethodInvocationJudgment,
- ReturnJudgment,
- SetLiteralJudgment,
+ LoadLibraryImpl,
+ MethodInvocationImpl,
+ ReturnStatementImpl,
ShadowLargeIntLiteral,
- SymbolLiteralJudgment,
SyntheticExpressionJudgment,
- TryCatchJudgment,
- TryFinallyJudgment,
- TypeLiteralJudgment,
- VariableDeclarationJudgment,
- WhileJudgment,
- YieldJudgment;
+ VariableDeclarationImpl;
/// A shadow tree factory.
class Forest {
@@ -63,7 +43,7 @@
Arguments createArguments(int fileOffset, List<Expression> positional,
{List<DartType> types, List<NamedExpression> named}) {
- return new ArgumentsJudgment(positional, types: types, named: named)
+ return new ArgumentsImpl(positional, types: types, named: named)
..fileOffset = fileOffset ?? TreeNode.noOffset;
}
@@ -76,7 +56,7 @@
List<DartType> typeArguments = const <DartType>[],
List<Expression> positionalArguments = const <Expression>[],
List<NamedExpression> namedArguments = const <NamedExpression>[]}) {
- return new ArgumentsJudgment.forExtensionMethod(
+ return new ArgumentsImpl.forExtensionMethod(
extensionTypeParameterCount, typeParameterCount, receiver,
extensionTypeArguments: extensionTypeArguments,
typeArguments: typeArguments,
@@ -102,7 +82,7 @@
}
void argumentsSetTypeArguments(Arguments arguments, List<DartType> types) {
- ArgumentsJudgment.setNonInferrableArgumentTypes(arguments, types);
+ ArgumentsImpl.setNonInferrableArgumentTypes(arguments, types);
}
StringLiteral asLiteralString(Expression value) => value;
@@ -116,7 +96,7 @@
/// Return a representation of a double literal at the given [location]. The
/// literal has the given [value].
DoubleLiteral createDoubleLiteral(double value, Token token) {
- return new DoubleJudgment(value)..fileOffset = offsetForToken(token);
+ return new DoubleLiteral(value)..fileOffset = offsetForToken(token);
}
/// Return a representation of an integer literal at the given [location]. The
@@ -151,7 +131,7 @@
Token rightBracket) {
// TODO(brianwilkerson): The file offset computed below will not be correct
// if there are type arguments but no `const` keyword.
- return new ListLiteralJudgment(expressions,
+ return new ListLiteral(expressions,
typeArgument: typeArgument, isConst: isConst)
..fileOffset = offsetForToken(constKeyword ?? leftBracket);
}
@@ -177,7 +157,7 @@
Token rightBrace) {
// TODO(brianwilkerson): The file offset computed below will not be correct
// if there are type arguments but no `const` keyword.
- return new SetLiteralJudgment(expressions,
+ return new SetLiteral(expressions,
typeArgument: typeArgument, isConst: isConst)
..fileOffset = offsetForToken(constKeyword ?? leftBrace);
}
@@ -206,7 +186,7 @@
Token rightBrace) {
// TODO(brianwilkerson): The file offset computed below will not be correct
// if there are type arguments but no `const` keyword.
- return new MapLiteralJudgment(entries,
+ return new MapLiteral(entries,
keyType: keyType, valueType: valueType, isConst: isConst)
..fileOffset = offsetForToken(constKeyword ?? leftBrace);
}
@@ -225,11 +205,11 @@
/// Return a representation of a symbol literal defined by [value].
SymbolLiteral createSymbolLiteral(String value, Token token) {
- return new SymbolLiteralJudgment(value)..fileOffset = offsetForToken(token);
+ return new SymbolLiteral(value)..fileOffset = offsetForToken(token);
}
TypeLiteral createTypeLiteral(DartType type, Token token) {
- return new TypeLiteralJudgment(type)..fileOffset = offsetForToken(token);
+ return new TypeLiteral(type)..fileOffset = offsetForToken(token);
}
/// Return a representation of a key/value pair in a literal map. The [key] is
@@ -244,7 +224,7 @@
Expression createLoadLibrary(
LibraryDependency dependency, Arguments arguments) {
- return new LoadLibraryJudgment(dependency, arguments);
+ return new LoadLibraryImpl(dependency, arguments);
}
Expression checkLibraryIsLoaded(LibraryDependency dependency) {
@@ -328,7 +308,7 @@
Expression condition,
Token comma,
Expression message) {
- return new AssertInitializerJudgment(createAssertStatement(
+ return new AssertInitializer(createAssertStatement(
assertKeyword, leftParenthesis, condition, comma, message, null));
}
@@ -368,7 +348,7 @@
endOffset = conditionLastToken.offset + conditionLastToken.length;
}
}
- return new AssertStatementJudgment(condition,
+ return new AssertStatement(condition,
conditionStartOffset: startOffset,
conditionEndOffset: endOffset,
message: message);
@@ -392,7 +372,7 @@
copy.add(statement);
}
}
- return new BlockJudgment(copy ?? statements)
+ return new Block(copy ?? statements)
..fileOffset = offsetForToken(openBrace);
}
@@ -411,7 +391,7 @@
VariableDeclaration stackTraceParameter,
DartType stackTraceType,
Statement body) {
- return new CatchJudgment(exceptionParameter, body,
+ return new Catch(exceptionParameter, body,
guard: exceptionType, stackTrace: stackTraceParameter)
..fileOffset = offsetForToken(onKeyword ?? catchKeyword);
}
@@ -437,19 +417,19 @@
/// Return a representation of a do statement.
Statement createDoStatement(Token doKeyword, Statement body,
Token whileKeyword, Expression condition, Token semicolon) {
- return new DoJudgment(body, condition)..fileOffset = doKeyword.charOffset;
+ return new DoStatement(body, condition)..fileOffset = doKeyword.charOffset;
}
/// Return a representation of an expression statement composed from the
/// [expression] and [semicolon].
Statement createExpressionStatement(Expression expression, Token semicolon) {
- return new ExpressionStatementJudgment(expression);
+ return new ExpressionStatement(expression);
}
/// Return a representation of an empty statement consisting of the given
/// [semicolon].
Statement createEmptyStatement(Token semicolon) {
- return new EmptyStatementJudgment();
+ return new EmptyStatement();
}
/// Return a representation of a for statement.
@@ -463,14 +443,14 @@
List<Expression> updaters,
Token rightParenthesis,
Statement body) {
- return new ForJudgment(variables, condition, updaters, body)
+ return new ForStatement(variables ?? [], condition, updaters, body)
..fileOffset = forKeyword.charOffset;
}
/// Return a representation of an `if` statement.
Statement createIfStatement(Token ifKeyword, Expression condition,
Statement thenStatement, Token elseKeyword, Statement elseStatement) {
- return new IfJudgment(condition, thenStatement, elseStatement)
+ return new IfStatement(condition, thenStatement, elseStatement)
..fileOffset = ifKeyword.charOffset;
}
@@ -511,14 +491,14 @@
/// Return a representation of a rethrow statement consisting of the
/// [rethrowKeyword] followed by the [semicolon].
Statement createRethrowStatement(Token rethrowKeyword, Token semicolon) {
- return new ExpressionStatementJudgment(
+ return new ExpressionStatement(
new Rethrow()..fileOffset = offsetForToken(rethrowKeyword));
}
/// Return a representation of a return statement.
Statement createReturnStatement(int fileOffset, Expression expression,
{bool isArrow: true}) {
- return new ReturnJudgment(isArrow, expression)
+ return new ReturnStatementImpl(isArrow, expression)
..fileOffset = fileOffset ?? TreeNode.noOffset;
}
@@ -559,10 +539,10 @@
List<Catch> catchClauses, Token finallyKeyword, Statement finallyBlock) {
Statement result = body;
if (catchClauses != null) {
- result = new TryCatchJudgment(result, catchClauses);
+ result = new TryCatch(result, catchClauses);
}
if (finallyBlock != null) {
- result = new TryFinallyJudgment(result, finallyBlock);
+ result = new TryFinally(result, finallyBlock);
}
return result;
}
@@ -579,11 +559,11 @@
Statement wrapVariables(Statement statement) {
if (statement is _VariablesDeclaration) {
- return new BlockJudgment(
+ return new Block(
new List<Statement>.from(statement.declarations, growable: true))
..fileOffset = statement.fileOffset;
} else if (statement is VariableDeclaration) {
- return new BlockJudgment(<Statement>[statement])
+ return new Block(<Statement>[statement])
..fileOffset = statement.fileOffset;
} else {
return statement;
@@ -594,7 +574,7 @@
/// [whileKeyword] and consisting of the given [condition] and [body].
Statement createWhileStatement(
Token whileKeyword, Expression condition, Statement body) {
- return new WhileJudgment(condition, body)
+ return new WhileStatement(condition, body)
..fileOffset = whileKeyword.charOffset;
}
@@ -603,7 +583,7 @@
/// when no star was included in the source code.
Statement createYieldStatement(
Token yieldKeyword, Token star, Expression expression, Token semicolon) {
- return new YieldJudgment(star != null, expression)
+ return new YieldStatement(expression, isYieldStar: star != null)
..fileOffset = yieldKeyword.charOffset;
}
@@ -658,7 +638,7 @@
bool isFieldFormal: false,
bool isCovariant: false,
bool isLocalFunction: false}) {
- return new VariableDeclarationJudgment(name, functionNestingLevel,
+ return new VariableDeclarationImpl(name, functionNestingLevel,
type: type,
initializer: initializer,
isFinal: isFinal,
@@ -671,7 +651,7 @@
VariableDeclaration createVariableDeclarationForValue(
int fileOffset, Expression initializer,
{DartType type = const DynamicType()}) {
- return new VariableDeclarationJudgment.forValue(initializer)
+ return new VariableDeclarationImpl.forValue(initializer)
..type = type
..fileOffset = fileOffset ?? TreeNode.noOffset;
}
@@ -688,7 +668,7 @@
DartType returnType: const DynamicType(),
AsyncMarker asyncMarker: AsyncMarker.Sync,
AsyncMarker dartAsyncMarker}) {
- return new FunctionNodeJudgment(body,
+ return new FunctionNode(body,
typeParameters: typeParameters,
positionalParameters: positionalParameters,
namedParameters: namedParameters,
@@ -714,10 +694,19 @@
MethodInvocation createFunctionInvocation(
int fileOffset, Expression expression, Arguments arguments) {
- return new MethodInvocationJudgment(expression, callName, arguments)
+ return new MethodInvocationImpl(expression, callName, arguments)
..fileOffset = fileOffset ?? TreeNode.noOffset;
}
+ MethodInvocation createMethodInvocation(
+ int fileOffset, Expression expression, Name name, Arguments arguments,
+ {bool isImplicitCall: false, Member interfaceTarget}) {
+ return new MethodInvocationImpl(expression, name, arguments,
+ isImplicitCall: isImplicitCall)
+ ..fileOffset = fileOffset ?? TreeNode.noOffset
+ ..interfaceTarget = interfaceTarget;
+ }
+
NamedExpression createNamedExpression(String name, Expression expression) {
return new NamedExpression(name, expression);
}
diff --git a/pkg/front_end/lib/src/fasta/kernel/inference_visitor.dart b/pkg/front_end/lib/src/fasta/kernel/inference_visitor.dart
index 0f0236a..cdfc0b1 100644
--- a/pkg/front_end/lib/src/fasta/kernel/inference_visitor.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/inference_visitor.dart
@@ -5,7 +5,10 @@
part of "kernel_shadow_ast.dart";
class InferenceVisitor
- extends BodyVisitor1<ExpressionInferenceResult, DartType> {
+ implements
+ ExpressionVisitor1<ExpressionInferenceResult, DartType>,
+ StatementVisitor<void>,
+ InitializerVisitor<void> {
final ShadowTypeInferrer inferrer;
Class mapEntryClass;
@@ -24,8 +27,7 @@
InferenceVisitor(this.inferrer);
- @override
- ExpressionInferenceResult defaultExpression(
+ ExpressionInferenceResult _unhandledExpression(
Expression node, DartType typeContext) {
unhandled("${node.runtimeType}", "InferenceVisitor", node.fileOffset,
inferrer.helper.uri);
@@ -33,26 +35,166 @@
}
@override
- ExpressionInferenceResult defaultStatement(Statement node, _) {
+ ExpressionInferenceResult defaultExpression(
+ Expression node, DartType typeContext) {
+ if (node is InternalExpression) {
+ switch (node.kind) {
+ case InternalExpressionKind.Cascade:
+ return visitCascade(node, typeContext);
+ case InternalExpressionKind.CompoundIndexSet:
+ return visitCompoundIndexSet(node, typeContext);
+ case InternalExpressionKind.CompoundPropertySet:
+ return visitCompoundPropertySet(node, typeContext);
+ case InternalExpressionKind.DeferredCheck:
+ return visitDeferredCheck(node, typeContext);
+ case InternalExpressionKind.IfNullIndexSet:
+ return visitIfNullIndexSet(node, typeContext);
+ case InternalExpressionKind.IfNullPropertySet:
+ return visitIfNullPropertySet(node, typeContext);
+ case InternalExpressionKind.IfNullSet:
+ return visitIfNullSet(node, typeContext);
+ case InternalExpressionKind.IndexSet:
+ return visitIndexSet(node, typeContext);
+ case InternalExpressionKind.LoadLibraryTearOff:
+ return visitLoadLibraryTearOff(node, typeContext);
+ case InternalExpressionKind.LocalPostIncDec:
+ return visitLocalPostIncDec(node, typeContext);
+ case InternalExpressionKind.NullAwareMethodInvocation:
+ return visitNullAwareMethodInvocation(node, typeContext);
+ case InternalExpressionKind.NullAwarePropertyGet:
+ return visitNullAwarePropertyGet(node, typeContext);
+ case InternalExpressionKind.NullAwarePropertySet:
+ return visitNullAwarePropertySet(node, typeContext);
+ case InternalExpressionKind.PropertyPostIncDec:
+ return visitPropertyPostIncDec(node, typeContext);
+ case InternalExpressionKind.StaticPostIncDec:
+ return visitStaticPostIncDec(node, typeContext);
+ case InternalExpressionKind.SuperPostIncDec:
+ return visitSuperPostIncDec(node, typeContext);
+ }
+ }
+ return _unhandledExpression(node, typeContext);
+ }
+
+ @override
+ ExpressionInferenceResult defaultBasicLiteral(
+ BasicLiteral node, DartType typeContext) {
+ return _unhandledExpression(node, typeContext);
+ }
+
+ @override
+ ExpressionInferenceResult visitBlockExpression(
+ BlockExpression node, DartType typeContext) {
+ return _unhandledExpression(node, typeContext);
+ }
+
+ @override
+ ExpressionInferenceResult visitConstantExpression(
+ ConstantExpression node, DartType typeContext) {
+ return _unhandledExpression(node, typeContext);
+ }
+
+ @override
+ ExpressionInferenceResult visitDirectMethodInvocation(
+ DirectMethodInvocation node, DartType typeContext) {
+ return _unhandledExpression(node, typeContext);
+ }
+
+ @override
+ ExpressionInferenceResult visitDirectPropertyGet(
+ DirectPropertyGet node, DartType typeContext) {
+ return _unhandledExpression(node, typeContext);
+ }
+
+ @override
+ ExpressionInferenceResult visitDirectPropertySet(
+ DirectPropertySet node, DartType typeContext) {
+ return _unhandledExpression(node, typeContext);
+ }
+
+ @override
+ ExpressionInferenceResult visitFileUriExpression(
+ FileUriExpression node, DartType typeContext) {
+ return _unhandledExpression(node, typeContext);
+ }
+
+ @override
+ ExpressionInferenceResult visitInstanceCreation(
+ InstanceCreation node, DartType typeContext) {
+ return _unhandledExpression(node, typeContext);
+ }
+
+ @override
+ ExpressionInferenceResult visitInstantiation(
+ Instantiation node, DartType typeContext) {
+ return _unhandledExpression(node, typeContext);
+ }
+
+ @override
+ ExpressionInferenceResult visitListConcatenation(
+ ListConcatenation node, DartType typeContext) {
+ return _unhandledExpression(node, typeContext);
+ }
+
+ @override
+ ExpressionInferenceResult visitMapConcatenation(
+ MapConcatenation node, DartType typeContext) {
+ return _unhandledExpression(node, typeContext);
+ }
+
+ @override
+ ExpressionInferenceResult visitSetConcatenation(
+ SetConcatenation node, DartType typeContext) {
+ return _unhandledExpression(node, typeContext);
+ }
+
+ void _unhandledStatement(Statement node) {
unhandled("${node.runtimeType}", "InferenceVisitor", node.fileOffset,
inferrer.helper.uri);
- return const ExpressionInferenceResult(const InvalidType());
+ }
+
+ @override
+ void defaultStatement(Statement node) {
+ _unhandledStatement(node);
+ }
+
+ @override
+ void visitAssertBlock(AssertBlock node) {
+ _unhandledStatement(node);
+ }
+
+ void _unhandledInitializer(Initializer node) {
+ unhandled("${node.runtimeType}", "InferenceVisitor", node.fileOffset,
+ node.location.file);
+ }
+
+ @override
+ void defaultInitializer(Initializer node) {
+ _unhandledInitializer(node);
+ }
+
+ @override
+ void visitInvalidInitializer(Initializer node) {
+ _unhandledInitializer(node);
+ }
+
+ @override
+ void visitLocalInitializer(LocalInitializer node) {
+ _unhandledInitializer(node);
}
@override
ExpressionInferenceResult visitInvalidExpression(
- InvalidExpression node, DartType typeContext) =>
- const ExpressionInferenceResult(const BottomType());
+ InvalidExpression node, DartType typeContext) {
+ return const ExpressionInferenceResult(const BottomType());
+ }
@override
ExpressionInferenceResult visitIntLiteral(
- IntLiteral node, DartType typeContext) =>
- new ExpressionInferenceResult(inferrer.coreTypes.intClass.rawType);
-
- @override
- ExpressionInferenceResult visitDoubleLiteral(
- DoubleLiteral node, DartType typeContext) =>
- new ExpressionInferenceResult(inferrer.coreTypes.doubleClass.rawType);
+ IntLiteral node, DartType typeContext) {
+ return new ExpressionInferenceResult(
+ inferrer.coreTypes.intRawType(inferrer.library.nonNullable));
+ }
@override
ExpressionInferenceResult visitAsExpression(
@@ -63,24 +205,23 @@
return new ExpressionInferenceResult(node.type);
}
- void visitAssertInitializerJudgment(AssertInitializerJudgment node) {
- inferrer.inferStatement(node.judgment);
+ @override
+ void visitAssertInitializer(AssertInitializer node) {
+ inferrer.inferStatement(node.statement);
}
- void visitAssertStatementJudgment(AssertStatementJudgment node) {
- Expression conditionJudgment = node.conditionJudgment;
- Expression messageJudgment = node.messageJudgment;
- InterfaceType expectedType = inferrer.coreTypes.boolClass.rawType;
- inferrer.inferExpression(
- conditionJudgment, expectedType, !inferrer.isTopLevel);
+ @override
+ void visitAssertStatement(AssertStatement node) {
+ InterfaceType expectedType =
+ inferrer.coreTypes.boolRawType(inferrer.library.nonNullable);
+ DartType conditionType = inferrer
+ .inferExpression(node.condition, expectedType, !inferrer.isTopLevel)
+ .inferredType;
inferrer.ensureAssignable(
- expectedType,
- getInferredType(conditionJudgment, inferrer),
- conditionJudgment,
- conditionJudgment.fileOffset);
- if (messageJudgment != null) {
+ expectedType, conditionType, node.condition, node.condition.fileOffset);
+ if (node.message != null) {
inferrer.inferExpression(
- messageJudgment, const UnknownType(), !inferrer.isTopLevel);
+ node.message, const UnknownType(), !inferrer.isTopLevel);
}
}
@@ -90,62 +231,64 @@
if (!inferrer.typeSchemaEnvironment.isEmptyContext(typeContext)) {
typeContext = inferrer.wrapFutureOrType(typeContext);
}
- Expression operand = node.operand;
- inferrer.inferExpression(operand, typeContext, true, isVoidAllowed: true);
- DartType inferredType = inferrer.typeSchemaEnvironment
- .unfutureType(getInferredType(operand, inferrer));
- inferrer.storeInferredType(node, inferredType);
+ DartType operandType = inferrer
+ .inferExpression(node.operand, typeContext, true, isVoidAllowed: true)
+ .inferredType;
+ DartType inferredType =
+ inferrer.typeSchemaEnvironment.unfutureType(operandType);
return new ExpressionInferenceResult(inferredType);
}
- void visitBlockJudgment(BlockJudgment node) {
- for (Statement judgment in node.judgments) {
- inferrer.inferStatement(judgment);
+ @override
+ void visitBlock(Block node) {
+ for (Statement statement in node.statements) {
+ inferrer.inferStatement(statement);
}
}
@override
ExpressionInferenceResult visitBoolLiteral(
- BoolLiteral node, DartType typeContext) =>
- new ExpressionInferenceResult(inferrer.coreTypes.boolClass.rawType);
+ BoolLiteral node, DartType typeContext) {
+ return new ExpressionInferenceResult(
+ inferrer.coreTypes.boolRawType(inferrer.library.nonNullable));
+ }
@override
- Null visitBreakStatement(BreakStatement node, _) {
+ void visitBreakStatement(BreakStatement node) {
// No inference needs to be done.
}
- ExpressionInferenceResult visitCascadeJudgment(
- CascadeJudgment node, DartType typeContext) {
+ ExpressionInferenceResult visitCascade(Cascade node, DartType typeContext) {
ExpressionInferenceResult result =
- inferrer.inferExpression(node.targetJudgment, typeContext, true);
- node.inferredType = result.inferredType;
- node.variable.type = getInferredType(node, inferrer);
- for (Expression judgment in node.cascadeJudgments) {
+ inferrer.inferExpression(node.expression, typeContext, true);
+ node.variable.type = result.inferredType;
+ for (Expression judgment in node.cascades) {
inferrer.inferExpression(
judgment, const UnknownType(), !inferrer.isTopLevel,
isVoidAllowed: true);
}
- return new ExpressionInferenceResult(node.inferredType);
+ Expression replacement = node.replace();
+ return new ExpressionInferenceResult(result.inferredType, replacement);
}
@override
ExpressionInferenceResult visitConditionalExpression(
ConditionalExpression node, DartType typeContext) {
- Expression condition = node.condition;
- Expression then = node.then;
- Expression otherwise = node.otherwise;
- InterfaceType expectedType = inferrer.coreTypes.boolClass.rawType;
- inferrer.inferExpression(condition, expectedType, !inferrer.isTopLevel);
+ InterfaceType expectedType =
+ inferrer.coreTypes.boolRawType(inferrer.library.nonNullable);
+ DartType conditionType = inferrer
+ .inferExpression(node.condition, expectedType, !inferrer.isTopLevel)
+ .inferredType;
inferrer.ensureAssignable(
- expectedType,
- getInferredType(condition, inferrer),
- node.condition,
- node.condition.fileOffset);
- inferrer.inferExpression(then, typeContext, true, isVoidAllowed: true);
- inferrer.inferExpression(otherwise, typeContext, true, isVoidAllowed: true);
+ expectedType, conditionType, node.condition, node.condition.fileOffset);
+ DartType thenType = inferrer
+ .inferExpression(node.then, typeContext, true, isVoidAllowed: true)
+ .inferredType;
+ DartType otherwiseType = inferrer
+ .inferExpression(node.otherwise, typeContext, true, isVoidAllowed: true)
+ .inferredType;
DartType inferredType = inferrer.typeSchemaEnvironment
- .getStandardUpperBound(getInferredType(then, inferrer),
- getInferredType(otherwise, inferrer));
+ .getStandardUpperBound(thenType, otherwiseType);
node.staticType = inferredType;
return new ExpressionInferenceResult(inferredType);
}
@@ -196,11 +339,10 @@
DartType inferredType = inferrer.inferInvocation(
typeContext,
node.fileOffset,
- node.target.function.functionType,
+ node.target.function.thisFunctionType,
computeConstructorReturnType(node.target),
node.arguments,
isConst: node.isConst);
- inferrer.storeInferredType(node, inferredType);
if (!inferrer.isTopLevel) {
SourceLibraryBuilder library = inferrer.library;
if (!hasExplicitTypeArguments) {
@@ -212,46 +354,49 @@
return new ExpressionInferenceResult(inferredType);
}
- void visitContinueSwitchJudgment(ContinueSwitchJudgment node) {
+ @override
+ void visitContinueSwitchStatement(ContinueSwitchStatement node) {
// No inference needs to be done.
}
- ExpressionInferenceResult visitDeferredCheckJudgment(
- DeferredCheckJudgment node, DartType typeContext) {
+ ExpressionInferenceResult visitDeferredCheck(
+ DeferredCheck node, DartType typeContext) {
// Since the variable is not used in the body we don't need to type infer
// it. We can just type infer the body.
ExpressionInferenceResult result = inferrer.inferExpression(
node.expression, typeContext, true,
isVoidAllowed: true);
- node.inferredType = result.inferredType;
- return new ExpressionInferenceResult(result.inferredType);
+ Expression replacement = node.replace();
+ return new ExpressionInferenceResult(result.inferredType, replacement);
}
- void visitDoJudgment(DoJudgment node) {
- Expression conditionJudgment = node.conditionJudgment;
+ @override
+ void visitDoStatement(DoStatement node) {
inferrer.inferStatement(node.body);
- InterfaceType boolType = inferrer.coreTypes.boolClass.rawType;
- inferrer.inferExpression(conditionJudgment, boolType, !inferrer.isTopLevel);
+ InterfaceType boolType =
+ inferrer.coreTypes.boolRawType(inferrer.library.nonNullable);
+ DartType conditionType = inferrer
+ .inferExpression(node.condition, boolType, !inferrer.isTopLevel)
+ .inferredType;
inferrer.ensureAssignable(
- boolType,
- getInferredType(conditionJudgment, inferrer),
- node.condition,
- node.condition.fileOffset);
+ boolType, conditionType, node.condition, node.condition.fileOffset);
}
- ExpressionInferenceResult visitDoubleJudgment(
- DoubleJudgment node, DartType typeContext) {
+ ExpressionInferenceResult visitDoubleLiteral(
+ DoubleLiteral node, DartType typeContext) {
return new ExpressionInferenceResult(
- node.inferredType = inferrer.coreTypes.doubleClass.rawType);
+ inferrer.coreTypes.doubleRawType(inferrer.library.nonNullable));
}
- void visitEmptyStatementJudgment(EmptyStatementJudgment node) {
+ @override
+ void visitEmptyStatement(EmptyStatement node) {
// No inference needs to be done.
}
- void visitExpressionStatementJudgment(ExpressionStatementJudgment node) {
+ @override
+ void visitExpressionStatement(ExpressionStatement node) {
inferrer.inferExpression(
- node.judgment, const UnknownType(), !inferrer.isTopLevel,
+ node.expression, const UnknownType(), !inferrer.isTopLevel,
isVoidAllowed: true);
}
@@ -262,11 +407,11 @@
DartType inferredType = inferrer.inferInvocation(
typeContext,
node.fileOffset,
- node.target.function.functionType,
+ node.target.function.thisFunctionType,
computeConstructorReturnType(node.target),
- node.argumentJudgments,
+ node.arguments,
isConst: node.isConst);
- node.inferredType = inferredType;
+ node.hasBeenInferred = true;
if (!inferrer.isTopLevel) {
SourceLibraryBuilder library = inferrer.library;
if (!hadExplicitTypeArguments) {
@@ -278,7 +423,8 @@
return new ExpressionInferenceResult(inferredType);
}
- void visitShadowFieldInitializer(ShadowFieldInitializer node) {
+ @override
+ void visitFieldInitializer(FieldInitializer node) {
ExpressionInferenceResult initializerResult =
inferrer.inferExpression(node.value, node.field.type, true);
DartType initializerType = initializerResult.inferredType;
@@ -292,7 +438,7 @@
DartType elementType;
bool typeNeeded = false;
bool typeChecksNeeded = !inferrer.isTopLevel;
- if (VariableDeclarationJudgment.isImplicitlyTyped(variable)) {
+ if (VariableDeclarationImpl.isImplicitlyTyped(variable)) {
typeNeeded = true;
elementType = const UnknownType();
} else {
@@ -343,9 +489,14 @@
? inferrer.coreTypes.streamClass
: inferrer.coreTypes.iterableClass;
DartType context = inferrer.wrapType(elementType, iterableClass);
- inferrer.inferExpression(iterable, context, typeNeeded);
+ ExpressionInferenceResult iterableResult =
+ inferrer.inferExpression(iterable, context, typeNeeded);
+ DartType iterableType = iterableResult.inferredType;
+ if (iterableResult.replacement != null) {
+ iterable = iterableResult.replacement;
+ }
DartType inferredExpressionType =
- inferrer.resolveTypeParameter(getInferredType(iterable, inferrer));
+ inferrer.resolveTypeParameter(iterableType);
inferrer.ensureAssignable(
inferrer.wrapType(const DynamicType(), iterableClass),
inferredExpressionType,
@@ -374,13 +525,22 @@
DartType syntheticWriteType;
Expression syntheticAssignment;
Expression rhs;
- ExpressionStatement statement =
+ // If `true`, the synthetic statement should not be visited.
+ bool skipStatement = false;
+ ExpressionStatement syntheticStatement =
body is Block ? body.statements.first : body;
- SyntheticExpressionJudgment judgment = statement.expression;
- syntheticAssignment = judgment.desugared;
+ Expression statementExpression = syntheticStatement.expression;
+ if (statementExpression is SyntheticExpressionJudgment) {
+ syntheticAssignment = statementExpression.desugared;
+ } else {
+ syntheticAssignment = statementExpression;
+ }
if (syntheticAssignment is VariableSet) {
syntheticWriteType = elementType = syntheticAssignment.variable.type;
rhs = syntheticAssignment.value;
+ // This expression is fully handled in this method so we should not
+ // visit the synthetic statement.
+ skipStatement = true;
} else if (syntheticAssignment is PropertySet ||
syntheticAssignment is SuperPropertySet) {
DartType receiverType = inferrer.thisType;
@@ -413,7 +573,17 @@
variable.type = inferredType;
}
- inferrer.inferStatement(body);
+ if (body is Block) {
+ for (Statement statement in body.statements) {
+ if (!skipStatement || statement != syntheticStatement) {
+ inferrer.inferStatement(statement);
+ }
+ }
+ } else {
+ if (!skipStatement) {
+ inferrer.inferStatement(body);
+ }
+ }
if (syntheticWriteType != null) {
inferrer.ensureAssignable(
@@ -427,7 +597,7 @@
}
@override
- Null visitForInStatement(ForInStatement node, _) {
+ void visitForInStatement(ForInStatement node) {
if (node.variable.name == null) {
handleForInWithoutVariable(node.variable, node.iterable, node.body,
isAsync: node.isAsync);
@@ -437,14 +607,13 @@
}
}
- void visitForJudgment(ForJudgment node) {
- Expression conditionJudgment = node.conditionJudgment;
+ @override
+ void visitForStatement(ForStatement node) {
for (VariableDeclaration variable in node.variables) {
if (variable.name == null) {
- Expression initializer = variable.initializer;
- if (initializer != null) {
+ if (variable.initializer != null) {
ExpressionInferenceResult result = inferrer.inferExpression(
- initializer, const UnknownType(), true,
+ variable.initializer, const UnknownType(), true,
isVoidAllowed: true);
variable.type = result.inferredType;
}
@@ -452,17 +621,16 @@
inferrer.inferStatement(variable);
}
}
- if (conditionJudgment != null) {
- InterfaceType expectedType = inferrer.coreTypes.boolClass.rawType;
- inferrer.inferExpression(
- conditionJudgment, expectedType, !inferrer.isTopLevel);
- inferrer.ensureAssignable(
- expectedType,
- getInferredType(conditionJudgment, inferrer),
- node.condition,
+ if (node.condition != null) {
+ InterfaceType expectedType =
+ inferrer.coreTypes.boolRawType(inferrer.library.nonNullable);
+ DartType conditionType = inferrer
+ .inferExpression(node.condition, expectedType, !inferrer.isTopLevel)
+ .inferredType;
+ inferrer.ensureAssignable(expectedType, conditionType, node.condition,
node.condition.fileOffset);
}
- for (Expression update in node.updateJudgments) {
+ for (Expression update in node.updates) {
inferrer.inferExpression(
update, const UnknownType(), !inferrer.isTopLevel,
isVoidAllowed: true);
@@ -470,30 +638,27 @@
inferrer.inferStatement(node.body);
}
- DartType visitFunctionNodeJudgment(
- FunctionNodeJudgment node,
- DartType typeContext,
- DartType returnContext,
- int returnTypeInstrumentationOffset) {
+ DartType visitFunctionNode(FunctionNode node, DartType typeContext,
+ DartType returnContext, int returnTypeInstrumentationOffset) {
return inferrer.inferLocalFunction(
node, typeContext, returnTypeInstrumentationOffset, returnContext);
}
- void visitFunctionDeclarationJudgment(FunctionDeclarationJudgment node) {
+ @override
+ void visitFunctionDeclaration(covariant FunctionDeclarationImpl node) {
inferrer.inferMetadataKeepingHelper(node.variable.annotations);
DartType returnContext =
node._hasImplicitReturnType ? null : node.function.returnType;
- DartType inferredType = visitFunctionNodeJudgment(
- node.functionJudgment, null, returnContext, node.fileOffset);
+ DartType inferredType =
+ visitFunctionNode(node.function, null, returnContext, node.fileOffset);
node.variable.type = inferredType;
}
@override
ExpressionInferenceResult visitFunctionExpression(
FunctionExpression node, DartType typeContext) {
- DartType inferredType = visitFunctionNodeJudgment(
- node.function, typeContext, null, node.fileOffset);
- inferrer.storeInferredType(node, inferredType);
+ DartType inferredType =
+ visitFunctionNode(node.function, typeContext, null, node.fileOffset);
return new ExpressionInferenceResult(inferredType);
}
@@ -506,7 +671,7 @@
null,
node.fileOffset,
substitution.substituteType(
- node.target.function.functionType.withoutTypeParameters),
+ node.target.function.thisFunctionType.withoutTypeParameters),
inferrer.thisType,
node.argumentsJudgment,
skipTypeArgumentInference: true);
@@ -514,42 +679,41 @@
ExpressionInferenceResult visitIfNullJudgment(
IfNullJudgment node, DartType typeContext) {
- Expression leftJudgment = node.leftJudgment;
- Expression rightJudgment = node.rightJudgment;
// To infer `e0 ?? e1` in context K:
// - Infer e0 in context K to get T0
- inferrer.inferExpression(leftJudgment, typeContext, true);
- DartType lhsType = getInferredType(leftJudgment, inferrer);
+ DartType lhsType =
+ inferrer.inferExpression(node.left, typeContext, true).inferredType;
node.variable.type = lhsType;
// - Let J = T0 if K is `?` else K.
// - Infer e1 in context J to get T1
+ DartType rhsType;
if (typeContext is UnknownType) {
- inferrer.inferExpression(rightJudgment, lhsType, true,
- isVoidAllowed: true);
+ rhsType = inferrer
+ .inferExpression(node.right, lhsType, true, isVoidAllowed: true)
+ .inferredType;
} else {
- inferrer.inferExpression(rightJudgment, typeContext, true,
- isVoidAllowed: true);
+ rhsType = inferrer
+ .inferExpression(node.right, typeContext, true, isVoidAllowed: true)
+ .inferredType;
}
- DartType rhsType = getInferredType(rightJudgment, inferrer);
// - Let T = greatest closure of K with respect to `?` if K is not `_`, else
// UP(t0, t1)
// - Then the inferred type is T.
- node.inferredType =
+ DartType inferredType =
inferrer.typeSchemaEnvironment.getStandardUpperBound(lhsType, rhsType);
- node.body.staticType = getInferredType(node, inferrer);
- return new ExpressionInferenceResult(node.inferredType);
+ node.body.staticType = inferredType;
+ return new ExpressionInferenceResult(inferredType);
}
- void visitIfJudgment(IfJudgment node) {
- Expression conditionJudgment = node.conditionJudgment;
- InterfaceType expectedType = inferrer.coreTypes.boolClass.rawType;
- inferrer.inferExpression(
- conditionJudgment, expectedType, !inferrer.isTopLevel);
+ @override
+ void visitIfStatement(IfStatement node) {
+ InterfaceType expectedType =
+ inferrer.coreTypes.boolRawType(inferrer.library.nonNullable);
+ DartType conditionType = inferrer
+ .inferExpression(node.condition, expectedType, !inferrer.isTopLevel)
+ .inferredType;
inferrer.ensureAssignable(
- expectedType,
- getInferredType(conditionJudgment, inferrer),
- node.condition,
- node.condition.fileOffset);
+ expectedType, conditionType, node.condition, node.condition.fileOffset);
inferrer.inferStatement(node.then);
if (node.otherwise != null) {
inferrer.inferStatement(node.otherwise);
@@ -565,7 +729,6 @@
inferrer.inferExpression(
node.rhs, const UnknownType(), !inferrer.isTopLevel);
node._replaceWithDesugared();
- node.inferredType = const DynamicType();
return const ExpressionInferenceResult(const DynamicType());
}
@@ -579,7 +742,7 @@
// when doing compound assignment?
DartType indexContext = const UnknownType();
DartType expectedIndexTypeForWrite =
- inferrer.getIndexSetKeyType(writeTarget, receiverType);
+ inferrer.getIndexKeyType(writeTarget, receiverType);
DartType writeContext =
inferrer.getIndexSetValueType(writeTarget, receiverType);
ExpressionInferenceResult indexResult =
@@ -618,8 +781,8 @@
MethodInvocation desugaredInvocation =
read is MethodInvocation ? read : null;
MethodContravarianceCheckKind checkKind =
- inferrer.preCheckInvocationContravariance(node.receiver, receiverType,
- readMember, desugaredInvocation, read.arguments, read);
+ inferrer.preCheckInvocationContravariance(receiverType, readMember,
+ isThisReceiver: node.receiver is ThisExpression);
Expression replacedRead = inferrer.handleInvocationContravariance(
checkKind,
desugaredInvocation,
@@ -643,19 +806,21 @@
if (doubleValue != null) {
node.parent.replaceChild(
node, new DoubleLiteral(doubleValue)..fileOffset = node.fileOffset);
- node.inferredType = inferrer.coreTypes.doubleClass.rawType;
- return new ExpressionInferenceResult(node.inferredType);
+ DartType inferredType =
+ inferrer.coreTypes.doubleRawType(inferrer.library.nonNullable);
+ return new ExpressionInferenceResult(inferredType);
}
}
Expression error = checkWebIntLiteralsErrorIfUnexact(
inferrer, node.value, node.literal, node.fileOffset);
+
if (error != null) {
node.parent.replaceChild(node, error);
- node.inferredType = const BottomType();
return const ExpressionInferenceResult(const BottomType());
}
- node.inferredType = inferrer.coreTypes.intClass.rawType;
- return new ExpressionInferenceResult(node.inferredType);
+ DartType inferredType =
+ inferrer.coreTypes.intRawType(inferrer.library.nonNullable);
+ return new ExpressionInferenceResult(inferredType);
}
ExpressionInferenceResult visitShadowLargeIntLiteral(
@@ -665,8 +830,9 @@
if (doubleValue != null) {
node.parent.replaceChild(
node, new DoubleLiteral(doubleValue)..fileOffset = node.fileOffset);
- node.inferredType = inferrer.coreTypes.doubleClass.rawType;
- return new ExpressionInferenceResult(node.inferredType);
+ DartType inferredType =
+ inferrer.coreTypes.doubleRawType(inferrer.library.nonNullable);
+ return new ExpressionInferenceResult(inferredType);
}
}
@@ -678,20 +844,19 @@
node.fileOffset,
node.literal.length));
node.parent.replaceChild(node, replacement);
- node.inferredType = const BottomType();
return const ExpressionInferenceResult(const BottomType());
}
Expression error = checkWebIntLiteralsErrorIfUnexact(
inferrer, intValue, node.literal, node.fileOffset);
if (error != null) {
node.parent.replaceChild(node, error);
- node.inferredType = const BottomType();
return const ExpressionInferenceResult(const BottomType());
}
node.parent.replaceChild(
node, new IntLiteral(intValue)..fileOffset = node.fileOffset);
- node.inferredType = inferrer.coreTypes.intClass.rawType;
- return new ExpressionInferenceResult(node.inferredType);
+ DartType inferredType =
+ inferrer.coreTypes.intRawType(inferrer.library.nonNullable);
+ return new ExpressionInferenceResult(inferredType);
}
void visitShadowInvalidInitializer(ShadowInvalidInitializer node) {
@@ -708,11 +873,12 @@
IsExpression node, DartType typeContext) {
inferrer.inferExpression(
node.operand, const UnknownType(), !inferrer.isTopLevel);
- return new ExpressionInferenceResult(inferrer.coreTypes.boolClass.rawType);
+ return new ExpressionInferenceResult(
+ inferrer.coreTypes.boolRawType(inferrer.library.nonNullable));
}
@override
- Null visitLabeledStatement(LabeledStatement node, _) {
+ void visitLabeledStatement(LabeledStatement node) {
inferrer.inferStatement(node.body);
}
@@ -735,6 +901,7 @@
TreeNode parent,
DartType inferredTypeArgument,
Map<TreeNode, DartType> inferredSpreadTypes,
+ Map<Expression, DartType> inferredConditionTypes,
bool inferenceNeeded,
bool typeChecksNeeded) {
if (element is SpreadElement) {
@@ -785,7 +952,8 @@
getSpreadElementType(spreadType, element.isNullAware) ??
const DynamicType();
} else if (element is IfElement) {
- DartType boolType = inferrer.coreTypes.boolClass.rawType;
+ DartType boolType =
+ inferrer.coreTypes.boolRawType(inferrer.library.nonNullable);
ExpressionInferenceResult conditionResult = inferrer.inferExpression(
element.condition, boolType, typeChecksNeeded,
isVoidAllowed: false);
@@ -797,6 +965,7 @@
element,
inferredTypeArgument,
inferredSpreadTypes,
+ inferredConditionTypes,
inferenceNeeded,
typeChecksNeeded);
DartType otherwiseType;
@@ -806,6 +975,7 @@
element,
inferredTypeArgument,
inferredSpreadTypes,
+ inferredConditionTypes,
inferenceNeeded,
typeChecksNeeded);
}
@@ -828,19 +998,27 @@
}
}
if (element.condition != null) {
- inferrer.inferExpression(
- element.condition,
- inferrer.coreTypes.boolClass.rawType,
- inferenceNeeded || typeChecksNeeded,
- isVoidAllowed: false);
+ inferredConditionTypes[element.condition] = inferrer
+ .inferExpression(
+ element.condition,
+ inferrer.coreTypes.boolRawType(inferrer.library.nonNullable),
+ inferenceNeeded || typeChecksNeeded,
+ isVoidAllowed: false)
+ .inferredType;
}
for (Expression expression in element.updates) {
inferrer.inferExpression(expression, const UnknownType(),
inferenceNeeded || typeChecksNeeded,
isVoidAllowed: true);
}
- return inferElement(element.body, element, inferredTypeArgument,
- inferredSpreadTypes, inferenceNeeded, typeChecksNeeded);
+ return inferElement(
+ element.body,
+ element,
+ inferredTypeArgument,
+ inferredSpreadTypes,
+ inferredConditionTypes,
+ inferenceNeeded,
+ typeChecksNeeded);
} else if (element is ForInElement) {
if (element.variable.name == null) {
handleForInWithoutVariable(
@@ -856,12 +1034,21 @@
inferenceNeeded || typeChecksNeeded,
isVoidAllowed: true);
}
- return inferElement(element.body, element, inferredTypeArgument,
- inferredSpreadTypes, inferenceNeeded, typeChecksNeeded);
+ return inferElement(
+ element.body,
+ element,
+ inferredTypeArgument,
+ inferredSpreadTypes,
+ inferredConditionTypes,
+ inferenceNeeded,
+ typeChecksNeeded);
} else {
ExpressionInferenceResult result = inferrer.inferExpression(
element, inferredTypeArgument, inferenceNeeded || typeChecksNeeded,
isVoidAllowed: true);
+ if (result.replacement != null) {
+ element = result.replacement;
+ }
DartType inferredType = result.inferredType;
if (inferredTypeArgument is! UnknownType) {
inferrer.ensureAssignable(
@@ -872,35 +1059,51 @@
}
}
- void checkElement(Expression item, Expression parent, DartType typeArgument,
- Map<TreeNode, DartType> inferredSpreadTypes) {
+ void checkElement(
+ Expression item,
+ Expression parent,
+ DartType typeArgument,
+ Map<TreeNode, DartType> inferredSpreadTypes,
+ Map<Expression, DartType> inferredConditionTypes) {
if (item is SpreadElement) {
DartType spreadType = inferredSpreadTypes[item.expression];
if (spreadType is DynamicType) {
- inferrer.ensureAssignable(inferrer.coreTypes.iterableClass.rawType,
- spreadType, item.expression, item.expression.fileOffset);
+ inferrer.ensureAssignable(
+ inferrer.coreTypes.iterableRawType(
+ inferrer.library.nullableIfTrue(item.isNullAware)),
+ spreadType,
+ item.expression,
+ item.expression.fileOffset);
}
} else if (item is IfElement) {
- checkElement(item.then, item, typeArgument, inferredSpreadTypes);
+ checkElement(item.then, item, typeArgument, inferredSpreadTypes,
+ inferredConditionTypes);
if (item.otherwise != null) {
- checkElement(item.otherwise, item, typeArgument, inferredSpreadTypes);
+ checkElement(item.otherwise, item, typeArgument, inferredSpreadTypes,
+ inferredConditionTypes);
}
} else if (item is ForElement) {
if (item.condition != null) {
- DartType conditionType = getInferredType(item.condition, inferrer);
- inferrer.ensureAssignable(inferrer.coreTypes.boolClass.rawType,
- conditionType, item.condition, item.condition.fileOffset);
+ DartType conditionType = inferredConditionTypes[item.condition];
+ inferrer.ensureAssignable(
+ inferrer.coreTypes.boolRawType(inferrer.library.nonNullable),
+ conditionType,
+ item.condition,
+ item.condition.fileOffset);
}
- checkElement(item.body, item, typeArgument, inferredSpreadTypes);
+ checkElement(item.body, item, typeArgument, inferredSpreadTypes,
+ inferredConditionTypes);
} else if (item is ForInElement) {
- checkElement(item.body, item, typeArgument, inferredSpreadTypes);
+ checkElement(item.body, item, typeArgument, inferredSpreadTypes,
+ inferredConditionTypes);
} else {
// Do nothing. Assignability checks are done during type inference.
}
}
- ExpressionInferenceResult visitListLiteralJudgment(
- ListLiteralJudgment node, DartType typeContext) {
+ @override
+ ExpressionInferenceResult visitListLiteral(
+ ListLiteral node, DartType typeContext) {
Class listClass = inferrer.coreTypes.listClass;
InterfaceType listType = listClass.thisType;
List<DartType> inferredTypes;
@@ -910,10 +1113,12 @@
bool inferenceNeeded = node.typeArgument is ImplicitTypeArgument;
bool typeChecksNeeded = !inferrer.isTopLevel;
Map<TreeNode, DartType> inferredSpreadTypes;
+ Map<Expression, DartType> inferredConditionTypes;
if (inferenceNeeded || typeChecksNeeded) {
formalTypes = [];
actualTypes = [];
inferredSpreadTypes = new Map<TreeNode, DartType>.identity();
+ inferredConditionTypes = new Map<Expression, DartType>.identity();
}
if (inferenceNeeded) {
inferredTypes = [const UnknownType()];
@@ -931,6 +1136,7 @@
node,
inferredTypeArgument,
inferredSpreadTypes,
+ inferredConditionTypes,
inferenceNeeded,
typeChecksNeeded);
actualTypes.add(type);
@@ -957,11 +1163,12 @@
}
if (typeChecksNeeded) {
for (int i = 0; i < node.expressions.length; i++) {
- checkElement(
- node.expressions[i], node, node.typeArgument, inferredSpreadTypes);
+ checkElement(node.expressions[i], node, node.typeArgument,
+ inferredSpreadTypes, inferredConditionTypes);
}
}
- node.inferredType = new InterfaceType(listClass, [inferredTypeArgument]);
+ DartType inferredType =
+ new InterfaceType(listClass, [inferredTypeArgument]);
if (!inferrer.isTopLevel) {
SourceLibraryBuilder library = inferrer.library;
if (inferenceNeeded) {
@@ -971,21 +1178,24 @@
}
}
- return new ExpressionInferenceResult(node.inferredType);
+ return new ExpressionInferenceResult(inferredType);
}
@override
ExpressionInferenceResult visitLogicalExpression(
LogicalExpression node, DartType typeContext) {
- InterfaceType boolType = inferrer.coreTypes.boolClass.rawType;
- Expression left = node.left;
- Expression right = node.right;
- inferrer.inferExpression(left, boolType, !inferrer.isTopLevel);
- inferrer.inferExpression(right, boolType, !inferrer.isTopLevel);
- inferrer.ensureAssignable(boolType, getInferredType(left, inferrer),
- node.left, node.left.fileOffset);
- inferrer.ensureAssignable(boolType, getInferredType(right, inferrer),
- node.right, node.right.fileOffset);
+ InterfaceType boolType =
+ inferrer.coreTypes.boolRawType(inferrer.library.nonNullable);
+ DartType leftType = inferrer
+ .inferExpression(node.left, boolType, !inferrer.isTopLevel)
+ .inferredType;
+ DartType rightType = inferrer
+ .inferExpression(node.right, boolType, !inferrer.isTopLevel)
+ .inferredType;
+ inferrer.ensureAssignable(
+ boolType, leftType, node.left, node.left.fileOffset);
+ inferrer.ensureAssignable(
+ boolType, rightType, node.right, node.right.fileOffset);
return new ExpressionInferenceResult(boolType);
}
@@ -1025,6 +1235,7 @@
List<DartType> actualTypes,
List<DartType> actualTypesForSet,
Map<TreeNode, DartType> inferredSpreadTypes,
+ Map<Expression, DartType> inferredConditionTypes,
bool inferenceNeeded,
bool typeChecksNeeded) {
if (entry is SpreadMapEntry) {
@@ -1118,10 +1329,10 @@
entry.entryType = new InterfaceType(
mapEntryClass, <DartType>[actualKeyType, actualValueType]);
- bool isMap = inferrer.typeSchemaEnvironment
- .isSubtypeOf(spreadType, inferrer.coreTypes.mapClass.rawType);
- bool isIterable = inferrer.typeSchemaEnvironment
- .isSubtypeOf(spreadType, inferrer.coreTypes.iterableClass.rawType);
+ bool isMap = inferrer.typeSchemaEnvironment.isSubtypeOf(
+ spreadType, inferrer.coreTypes.mapRawType(inferrer.library.nullable));
+ bool isIterable = inferrer.typeSchemaEnvironment.isSubtypeOf(spreadType,
+ inferrer.coreTypes.iterableRawType(inferrer.library.nullable));
if (isMap && !isIterable) {
mapSpreadOffset = entry.fileOffset;
}
@@ -1131,7 +1342,8 @@
return;
} else if (entry is IfMapEntry) {
- DartType boolType = inferrer.coreTypes.boolClass.rawType;
+ DartType boolType =
+ inferrer.coreTypes.boolRawType(inferrer.library.nonNullable);
ExpressionInferenceResult conditionResult = inferrer.inferExpression(
entry.condition, boolType, typeChecksNeeded,
isVoidAllowed: false);
@@ -1150,6 +1362,7 @@
actualTypes,
actualTypesForSet,
inferredSpreadTypes,
+ inferredConditionTypes,
inferenceNeeded,
typeChecksNeeded);
if (entry.otherwise != null) {
@@ -1167,6 +1380,7 @@
actualTypes,
actualTypesForSet,
inferredSpreadTypes,
+ inferredConditionTypes,
inferenceNeeded,
typeChecksNeeded);
int length = actualTypes.length;
@@ -1196,11 +1410,13 @@
}
}
if (entry.condition != null) {
- inferrer.inferExpression(
- entry.condition,
- inferrer.coreTypes.boolClass.rawType,
- inferenceNeeded || typeChecksNeeded,
- isVoidAllowed: false);
+ inferredConditionTypes[entry.condition] = inferrer
+ .inferExpression(
+ entry.condition,
+ inferrer.coreTypes.boolRawType(inferrer.library.nonNullable),
+ inferenceNeeded || typeChecksNeeded,
+ isVoidAllowed: false)
+ .inferredType;
}
for (Expression expression in entry.updates) {
inferrer.inferExpression(expression, const UnknownType(),
@@ -1217,6 +1433,7 @@
actualTypes,
actualTypesForSet,
inferredSpreadTypes,
+ inferredConditionTypes,
inferenceNeeded,
typeChecksNeeded);
} else if (entry is ForInMapEntry) {
@@ -1244,6 +1461,7 @@
actualTypes,
actualTypesForSet,
inferredSpreadTypes,
+ inferredConditionTypes,
inferenceNeeded,
typeChecksNeeded);
} else {
@@ -1277,7 +1495,8 @@
Expression cachedValue,
DartType keyType,
DartType valueType,
- Map<TreeNode, DartType> inferredSpreadTypes) {
+ Map<TreeNode, DartType> inferredSpreadTypes,
+ Map<Expression, DartType> inferredConditionTypes) {
// It's disambiguated as a map literal.
if (iterableSpreadOffset != null) {
parent.replaceChild(
@@ -1294,34 +1513,42 @@
if (entry is SpreadMapEntry) {
DartType spreadType = inferredSpreadTypes[entry.expression];
if (spreadType is DynamicType) {
- inferrer.ensureAssignable(inferrer.coreTypes.mapClass.rawType,
- spreadType, entry.expression, entry.expression.fileOffset);
+ inferrer.ensureAssignable(
+ inferrer.coreTypes
+ .mapRawType(inferrer.library.nullableIfTrue(entry.isNullAware)),
+ spreadType,
+ entry.expression,
+ entry.expression.fileOffset);
}
} else if (entry is IfMapEntry) {
checkMapEntry(entry.then, entry, cachedKey, cachedValue, keyType,
- valueType, inferredSpreadTypes);
+ valueType, inferredSpreadTypes, inferredConditionTypes);
if (entry.otherwise != null) {
checkMapEntry(entry.otherwise, entry, cachedKey, cachedValue, keyType,
- valueType, inferredSpreadTypes);
+ valueType, inferredSpreadTypes, inferredConditionTypes);
}
} else if (entry is ForMapEntry) {
if (entry.condition != null) {
- DartType conditionType = getInferredType(entry.condition, inferrer);
- inferrer.ensureAssignable(inferrer.coreTypes.boolClass.rawType,
- conditionType, entry.condition, entry.condition.fileOffset);
+ DartType conditionType = inferredConditionTypes[entry.condition];
+ inferrer.ensureAssignable(
+ inferrer.coreTypes.boolRawType(inferrer.library.nonNullable),
+ conditionType,
+ entry.condition,
+ entry.condition.fileOffset);
}
checkMapEntry(entry.body, entry, cachedKey, cachedValue, keyType,
- valueType, inferredSpreadTypes);
+ valueType, inferredSpreadTypes, inferredConditionTypes);
} else if (entry is ForInMapEntry) {
checkMapEntry(entry.body, entry, cachedKey, cachedValue, keyType,
- valueType, inferredSpreadTypes);
+ valueType, inferredSpreadTypes, inferredConditionTypes);
} else {
// Do nothing. Assignability checks are done during type inference.
}
}
- ExpressionInferenceResult visitMapLiteralJudgment(
- MapLiteralJudgment node, DartType typeContext) {
+ @override
+ ExpressionInferenceResult visitMapLiteral(
+ MapLiteral node, DartType typeContext) {
Class mapClass = inferrer.coreTypes.mapClass;
InterfaceType mapType = mapClass.thisType;
List<DartType> inferredTypes;
@@ -1350,23 +1577,26 @@
typeContextIsIterable &&
!typeContextIsMap) {
// Set literal
- SetLiteralJudgment setLiteral = new SetLiteralJudgment([],
+ SetLiteral setLiteral = new SetLiteral([],
typeArgument: const ImplicitTypeArgument(), isConst: node.isConst)
..fileOffset = node.fileOffset;
node.parent.replaceChild(node, setLiteral);
- visitSetLiteralJudgment(setLiteral, typeContext);
- node.inferredType = setLiteral.inferredType;
- return new ExpressionInferenceResult(node.inferredType);
+ ExpressionInferenceResult setLiteralResult =
+ visitSetLiteral(setLiteral, typeContext);
+ DartType inferredType = setLiteralResult.inferredType;
+ return new ExpressionInferenceResult(inferredType);
}
}
}
bool typeChecksNeeded = !inferrer.isTopLevel;
Map<TreeNode, DartType> inferredSpreadTypes;
+ Map<Expression, DartType> inferredConditionTypes;
if (inferenceNeeded || typeChecksNeeded) {
formalTypes = [];
actualTypes = [];
actualTypesForSet = [];
inferredSpreadTypes = new Map<TreeNode, DartType>.identity();
+ inferredConditionTypes = new Map<Expression, DartType>.identity();
}
if (inferenceNeeded) {
inferredTypes = [const UnknownType(), const UnknownType()];
@@ -1415,6 +1645,7 @@
actualTypes,
actualTypesForSet,
inferredSpreadTypes,
+ inferredConditionTypes,
inferenceNeeded,
typeChecksNeeded);
if (inferenceNeeded) {
@@ -1461,20 +1692,24 @@
'typeArgs',
new InstrumentationValueForTypeArgs([inferredTypeArgument]));
- SetLiteralJudgment setLiteral = new SetLiteralJudgment(setElements,
+ SetLiteral setLiteral = new SetLiteral(setElements,
typeArgument: inferredTypeArgument, isConst: node.isConst)
..fileOffset = node.fileOffset;
node.parent.replaceChild(node, setLiteral);
if (typeChecksNeeded) {
for (int i = 0; i < setLiteral.expressions.length; i++) {
- checkElement(setLiteral.expressions[i], setLiteral,
- setLiteral.typeArgument, inferredSpreadTypes);
+ checkElement(
+ setLiteral.expressions[i],
+ setLiteral,
+ setLiteral.typeArgument,
+ inferredSpreadTypes,
+ inferredConditionTypes);
}
}
- node.inferredType = setLiteral.inferredType =
+ DartType inferredType =
new InterfaceType(inferrer.coreTypes.setClass, inferredTypesForSet);
- return new ExpressionInferenceResult(node.inferredType);
+ return new ExpressionInferenceResult(inferredType);
}
if (canBeSet && canBeMap && node.entries.isNotEmpty) {
node.parent.replaceChild(
@@ -1482,7 +1717,6 @@
inferrer.helper.desugarSyntheticExpression(inferrer.helper
.buildProblem(messageCantDisambiguateNotEnoughInformation,
node.fileOffset, 1)));
- node.inferredType = const BottomType();
return const ExpressionInferenceResult(const BottomType());
}
if (!canBeSet && !canBeMap) {
@@ -1493,7 +1727,6 @@
.buildProblem(messageCantDisambiguateAmbiguousInformation,
node.fileOffset, 1)));
}
- node.inferredType = const BottomType();
return const ExpressionInferenceResult(const BottomType());
}
inferrer.typeSchemaEnvironment.inferGenericFunctionOrType(
@@ -1516,11 +1749,18 @@
}
if (typeChecksNeeded) {
for (int i = 0; i < node.entries.length; ++i) {
- checkMapEntry(node.entries[i], node, cachedKeys[i], cachedValues[i],
- node.keyType, node.valueType, inferredSpreadTypes);
+ checkMapEntry(
+ node.entries[i],
+ node,
+ cachedKeys[i],
+ cachedValues[i],
+ node.keyType,
+ node.valueType,
+ inferredSpreadTypes,
+ inferredConditionTypes);
}
}
- node.inferredType =
+ DartType inferredType =
new InterfaceType(mapClass, [inferredKeyType, inferredValueType]);
if (!inferrer.isTopLevel) {
SourceLibraryBuilder library = inferrer.library;
@@ -1532,11 +1772,12 @@
inferred: true);
}
}
- return new ExpressionInferenceResult(node.inferredType);
+ return new ExpressionInferenceResult(inferredType);
}
- ExpressionInferenceResult visitMethodInvocationJudgment(
- MethodInvocationJudgment node, DartType typeContext) {
+ @override
+ ExpressionInferenceResult visitMethodInvocation(
+ covariant MethodInvocationImpl node, DartType typeContext) {
if (node.name.name == 'unary-' &&
node.arguments.types.isEmpty &&
node.arguments.positional.isEmpty &&
@@ -1557,15 +1798,15 @@
if (doubleValue != null) {
node.parent.replaceChild(node,
new DoubleLiteral(doubleValue)..fileOffset = node.fileOffset);
- node.inferredType = inferrer.coreTypes.doubleClass.rawType;
- return new ExpressionInferenceResult(node.inferredType);
+ DartType inferredType =
+ inferrer.coreTypes.doubleRawType(inferrer.library.nonNullable);
+ return new ExpressionInferenceResult(inferredType);
}
}
Expression error = checkWebIntLiteralsErrorIfUnexact(
inferrer, receiver.value, receiver.literal, receiver.fileOffset);
if (error != null) {
node.parent.replaceChild(node, error);
- node.inferredType = const BottomType();
return const ExpressionInferenceResult(const BottomType());
}
} else if (node.receiver is ShadowLargeIntLiteral) {
@@ -1576,8 +1817,9 @@
if (doubleValue != null) {
node.parent.replaceChild(node,
new DoubleLiteral(doubleValue)..fileOffset = node.fileOffset);
- node.inferredType = inferrer.coreTypes.doubleClass.rawType;
- return new ExpressionInferenceResult(node.inferredType);
+ DartType inferredType = inferrer.coreTypes
+ .doubleRawType(inferrer.library.nonNullable);
+ return new ExpressionInferenceResult(inferredType);
}
}
int intValue = receiver.asInt64(negated: true);
@@ -1589,7 +1831,6 @@
receiver.fileOffset,
receiver.literal.length));
node.parent.replaceChild(node, error);
- node.inferredType = const BottomType();
return const ExpressionInferenceResult(const BottomType());
}
if (intValue != null) {
@@ -1597,7 +1838,6 @@
inferrer, intValue, receiver.literal, receiver.fileOffset);
if (error != null) {
node.parent.replaceChild(node, error);
- node.inferredType = const BottomType();
return const ExpressionInferenceResult(const BottomType());
}
node.receiver = new IntLiteral(-intValue)
@@ -1607,57 +1847,786 @@
}
}
}
- ExpressionInferenceResult result = inferrer.inferMethodInvocation(
- node, node.receiver, node.fileOffset, node._isImplicitCall, typeContext,
- desugaredInvocation: node);
- node.inferredType = result.inferredType;
+ ExpressionInferenceResult result =
+ inferrer.inferMethodInvocation(node, typeContext);
return new ExpressionInferenceResult(
result.inferredType, result.replacement);
}
ExpressionInferenceResult visitNamedFunctionExpressionJudgment(
NamedFunctionExpressionJudgment node, DartType typeContext) {
- Expression initializer = node.variableJudgment.initializer;
- inferrer.inferExpression(initializer, typeContext, true);
- node.inferredType = getInferredType(initializer, inferrer);
- node.variable.type = node.inferredType;
- return new ExpressionInferenceResult(node.inferredType);
+ DartType inferredType = inferrer
+ .inferExpression(node.variable.initializer, typeContext, true)
+ .inferredType;
+ node.variable.type = inferredType;
+ return new ExpressionInferenceResult(inferredType);
}
@override
ExpressionInferenceResult visitNot(Not node, DartType typeContext) {
- Expression operand = node.operand;
- InterfaceType boolType = inferrer.coreTypes.boolClass.rawType;
- inferrer.inferExpression(operand, boolType, !inferrer.isTopLevel);
- inferrer.ensureAssignable(boolType, getInferredType(operand, inferrer),
- node.operand, node.fileOffset);
+ InterfaceType boolType =
+ inferrer.coreTypes.boolRawType(inferrer.library.nonNullable);
+ DartType inferredType = inferrer
+ .inferExpression(node.operand, boolType, !inferrer.isTopLevel)
+ .inferredType;
+ inferrer.ensureAssignable(
+ boolType, inferredType, node.operand, node.fileOffset);
return new ExpressionInferenceResult(boolType);
}
- ExpressionInferenceResult visitNullAwareMethodInvocationJudgment(
- NullAwareMethodInvocationJudgment node, DartType typeContext) {
- ExpressionInferenceResult result = inferrer.inferMethodInvocation(
- node, node.variable.initializer, node.fileOffset, false, typeContext,
- receiverVariable: node.variable,
- desugaredInvocation: node._desugaredInvocation);
- node.inferredType = result.inferredType;
- node.body.staticType = node.inferredType;
- return new ExpressionInferenceResult(result.inferredType);
+ ExpressionInferenceResult visitNullAwareMethodInvocation(
+ NullAwareMethodInvocation node, DartType typeContext) {
+ inferrer.inferStatement(node.variable);
+ ExpressionInferenceResult readResult = inferrer.inferExpression(
+ node.invocation, typeContext, true,
+ isVoidAllowed: true);
+ Member equalsMember = inferrer
+ .findInterfaceMember(
+ node.variable.type, new Name('=='), node.fileOffset)
+ .member;
+
+ DartType inferredType = readResult.inferredType;
+
+ Expression replacement;
+ MethodInvocation equalsNull = createEqualsNull(
+ node.fileOffset,
+ new VariableGet(node.variable)..fileOffset = node.fileOffset,
+ equalsMember);
+ ConditionalExpression condition = new ConditionalExpression(
+ equalsNull,
+ new NullLiteral()..fileOffset = node.fileOffset,
+ node.invocation,
+ inferredType);
+ node.replaceWith(replacement = new Let(node.variable, condition)
+ ..fileOffset = node.fileOffset);
+ return new ExpressionInferenceResult(inferredType, replacement);
}
- ExpressionInferenceResult visitNullAwarePropertyGetJudgment(
- NullAwarePropertyGetJudgment node, DartType typeContext) {
- ExpressionInferenceResult result = inferrer.inferPropertyGet(
- node, node.receiverJudgment, node.fileOffset, typeContext,
- receiverVariable: node.variable, desugaredGet: node._desugaredGet);
- node.body.staticType = result.inferredType;
- return new ExpressionInferenceResult(result.inferredType);
+ ExpressionInferenceResult visitNullAwarePropertyGet(
+ NullAwarePropertyGet node, DartType typeContext) {
+ inferrer.inferStatement(node.variable);
+ ExpressionInferenceResult readResult =
+ inferrer.inferExpression(node.read, const UnknownType(), true);
+ Member equalsMember = inferrer
+ .findInterfaceMember(
+ node.variable.type, new Name('=='), node.fileOffset)
+ .member;
+
+ DartType inferredType = readResult.inferredType;
+
+ Expression replacement;
+ MethodInvocation equalsNull = createEqualsNull(
+ node.fileOffset,
+ new VariableGet(node.variable)..fileOffset = node.fileOffset,
+ equalsMember);
+ ConditionalExpression condition = new ConditionalExpression(
+ equalsNull,
+ new NullLiteral()..fileOffset = node.fileOffset,
+ node.read,
+ inferredType);
+ node.replaceWith(replacement = new Let(node.variable, condition)
+ ..fileOffset = node.fileOffset);
+ return new ExpressionInferenceResult(inferredType, replacement);
+ }
+
+ ExpressionInferenceResult visitNullAwarePropertySet(
+ NullAwarePropertySet node, DartType typeContext) {
+ inferrer.inferStatement(node.variable);
+ ExpressionInferenceResult writeResult =
+ inferrer.inferExpression(node.write, typeContext, true);
+ Member equalsMember = inferrer
+ .findInterfaceMember(
+ node.variable.type, new Name('=='), node.fileOffset)
+ .member;
+
+ DartType inferredType = writeResult.inferredType;
+
+ Expression replacement;
+ MethodInvocation equalsNull = createEqualsNull(
+ node.fileOffset,
+ new VariableGet(node.variable)..fileOffset = node.fileOffset,
+ equalsMember);
+ ConditionalExpression condition = new ConditionalExpression(
+ equalsNull,
+ new NullLiteral()..fileOffset = node.fileOffset,
+ node.write,
+ inferredType);
+ node.replaceWith(replacement = new Let(node.variable, condition)
+ ..fileOffset = node.fileOffset);
+ return new ExpressionInferenceResult(inferredType, replacement);
+ }
+
+ ExpressionInferenceResult visitStaticPostIncDec(
+ StaticPostIncDec node, DartType typeContext) {
+ inferrer.inferStatement(node.read);
+ inferrer.inferStatement(node.write);
+ DartType inferredType = node.read.type;
+ Expression replacement = node.replace();
+ return new ExpressionInferenceResult(inferredType, replacement);
+ }
+
+ ExpressionInferenceResult visitSuperPostIncDec(
+ SuperPostIncDec node, DartType typeContext) {
+ inferrer.inferStatement(node.read);
+ inferrer.inferStatement(node.write);
+ DartType inferredType = node.read.type;
+ Expression replacement = node.replace();
+ return new ExpressionInferenceResult(inferredType, replacement);
+ }
+
+ ExpressionInferenceResult visitLocalPostIncDec(
+ LocalPostIncDec node, DartType typeContext) {
+ inferrer.inferStatement(node.read);
+ inferrer.inferStatement(node.write);
+ DartType inferredType = node.read.type;
+ Expression replacement = node.replace();
+ return new ExpressionInferenceResult(inferredType, replacement);
+ }
+
+ ExpressionInferenceResult visitPropertyPostIncDec(
+ PropertyPostIncDec node, DartType typeContext) {
+ inferrer.inferStatement(node.variable);
+ inferrer.inferStatement(node.read);
+ inferrer.inferStatement(node.write);
+ DartType inferredType = node.read.type;
+ Expression replacement = node.replace();
+ return new ExpressionInferenceResult(inferredType, replacement);
+ }
+
+ ExpressionInferenceResult visitCompoundPropertySet(
+ CompoundPropertySet node, DartType typeContext) {
+ inferrer.inferStatement(node.variable);
+ ExpressionInferenceResult writeResult =
+ inferrer.inferExpression(node.write, typeContext, true);
+ Expression replacement = node.replace();
+ return new ExpressionInferenceResult(writeResult.inferredType, replacement);
+ }
+
+ ExpressionInferenceResult visitIfNullPropertySet(
+ IfNullPropertySet node, DartType typeContext) {
+ inferrer.inferStatement(node.variable);
+ ExpressionInferenceResult readResult =
+ inferrer.inferExpression(node.read, const UnknownType(), true);
+ ExpressionInferenceResult writeResult =
+ inferrer.inferExpression(node.write, typeContext, true);
+ Member equalsMember = inferrer
+ .findInterfaceMember(
+ readResult.inferredType, new Name('=='), node.fileOffset)
+ .member;
+
+ DartType inferredType = inferrer.typeSchemaEnvironment
+ .getStandardUpperBound(
+ readResult.inferredType, writeResult.inferredType);
+
+ Expression replacement;
+ if (node.forEffect) {
+ // Encode `o.a ??= b` as:
+ //
+ // let v1 = o in v1.a == null ? v1.a = b : null
+ //
+ MethodInvocation equalsNull =
+ createEqualsNull(node.fileOffset, node.read, equalsMember);
+ ConditionalExpression conditional = new ConditionalExpression(
+ equalsNull,
+ node.write,
+ new NullLiteral()..fileOffset = node.fileOffset,
+ inferredType)
+ ..fileOffset = node.fileOffset;
+ node.replaceWith(replacement =
+ new Let(node.variable, conditional..fileOffset = node.fileOffset));
+ } else {
+ // Encode `o.a ??= b` as:
+ //
+ // let v1 = o in let v2 = v1.a in v2 == null ? v1.a = b : v2
+ //
+ VariableDeclaration readVariable =
+ createVariable(node.read, readResult.inferredType);
+ MethodInvocation equalsNull = createEqualsNull(
+ node.fileOffset, createVariableGet(readVariable), equalsMember);
+ ConditionalExpression conditional = new ConditionalExpression(
+ equalsNull, node.write, createVariableGet(readVariable), inferredType)
+ ..fileOffset = node.fileOffset;
+ node.replaceWith(replacement =
+ new Let(node.variable, createLet(readVariable, conditional))
+ ..fileOffset = node.fileOffset);
+ }
+
+ return new ExpressionInferenceResult(inferredType, replacement);
+ }
+
+ ExpressionInferenceResult visitIfNullSet(
+ IfNullSet node, DartType typeContext) {
+ ExpressionInferenceResult readResult =
+ inferrer.inferExpression(node.read, const UnknownType(), true);
+ ExpressionInferenceResult writeResult =
+ inferrer.inferExpression(node.write, typeContext, true);
+ Member equalsMember = inferrer
+ .findInterfaceMember(
+ readResult.inferredType, new Name('=='), node.fileOffset)
+ .member;
+
+ DartType inferredType = inferrer.typeSchemaEnvironment
+ .getStandardUpperBound(
+ readResult.inferredType, writeResult.inferredType);
+
+ Expression replacement;
+ if (node.forEffect) {
+ // Encode `a ??= b` as:
+ //
+ // a == null ? a = b : null
+ //
+ MethodInvocation equalsNull =
+ createEqualsNull(node.fileOffset, node.read, equalsMember);
+ node.replaceWith(replacement = new ConditionalExpression(
+ equalsNull,
+ node.write,
+ new NullLiteral()..fileOffset = node.fileOffset,
+ inferredType)
+ ..fileOffset = node.fileOffset);
+ } else {
+ // Encode `a ??= b` as:
+ //
+ // let v1 = a in v1 == null ? a = b : v1
+ //
+ VariableDeclaration readVariable =
+ createVariable(node.read, readResult.inferredType);
+ MethodInvocation equalsNull = createEqualsNull(
+ node.fileOffset, createVariableGet(readVariable), equalsMember);
+ ConditionalExpression conditional = new ConditionalExpression(
+ equalsNull, node.write, createVariableGet(readVariable), inferredType)
+ ..fileOffset = node.fileOffset;
+ node.replaceWith(replacement = new Let(readVariable, conditional)
+ ..fileOffset = node.fileOffset);
+ }
+ return new ExpressionInferenceResult(inferredType, replacement);
+ }
+
+ ExpressionInferenceResult visitIndexSet(IndexSet node, DartType typeContext) {
+ ExpressionInferenceResult receiverResult = inferrer.inferExpression(
+ node.receiver, const UnknownType(), true,
+ isVoidAllowed: true);
+ DartType receiverType = receiverResult.inferredType;
+ VariableDeclaration receiverVariable =
+ createVariable(node.receiver, receiverType);
+
+ ObjectAccessTarget indexSetTarget = inferrer.findInterfaceMember(
+ receiverType, new Name('[]='), node.fileOffset,
+ includeExtensionMethods: true);
+
+ DartType indexType = inferrer.getIndexKeyType(indexSetTarget, receiverType);
+ DartType valueType =
+ inferrer.getIndexSetValueType(indexSetTarget, receiverType);
+
+ ExpressionInferenceResult indexResult = inferrer
+ .inferExpression(node.index, indexType, true, isVoidAllowed: true);
+
+ inferrer.ensureAssignable(
+ indexType, indexResult.inferredType, node.index, node.index.fileOffset);
+
+ VariableDeclaration indexVariable =
+ createVariable(node.index, indexResult.inferredType);
+
+ ExpressionInferenceResult valueResult = inferrer
+ .inferExpression(node.value, valueType, true, isVoidAllowed: true);
+ inferrer.ensureAssignable(
+ valueType, valueResult.inferredType, node.value, node.value.fileOffset);
+ VariableDeclaration valueVariable =
+ createVariable(node.value, valueResult.inferredType);
+
+ // The inferred type is that inferred type of the value expression and not
+ // the type of the value parameter.
+ DartType inferredType = valueResult.inferredType;
+
+ Expression replacement;
+ Expression assignment;
+ if (indexSetTarget.isMissing) {
+ assignment = inferrer.helper.buildProblem(
+ templateUndefinedMethod.withArguments('[]=', receiverType),
+ node.fileOffset,
+ '[]='.length,
+ wrapInSyntheticExpression: false);
+ } else if (indexSetTarget.isExtensionMember) {
+ assignment = new StaticInvocation(
+ indexSetTarget.member,
+ new Arguments(<Expression>[
+ createVariableGet(receiverVariable),
+ createVariableGet(indexVariable),
+ createVariableGet(valueVariable)
+ ], types: indexSetTarget.inferredExtensionTypeArguments)
+ ..fileOffset = node.fileOffset)
+ ..fileOffset = node.fileOffset;
+ } else {
+ assignment = new MethodInvocation(
+ createVariableGet(receiverVariable),
+ new Name('[]='),
+ new Arguments(<Expression>[
+ createVariableGet(indexVariable),
+ createVariableGet(valueVariable)
+ ])
+ ..fileOffset = node.fileOffset,
+ indexSetTarget.member)
+ ..fileOffset = node.fileOffset;
+ }
+ VariableDeclaration assignmentVariable =
+ createVariable(assignment, const VoidType());
+ node.replaceWith(replacement = new Let(
+ receiverVariable,
+ createLet(
+ indexVariable,
+ createLet(
+ valueVariable,
+ createLet(
+ assignmentVariable, createVariableGet(valueVariable))))
+ ..fileOffset = node.fileOffset));
+ return new ExpressionInferenceResult(inferredType, replacement);
+ }
+
+ ExpressionInferenceResult visitIfNullIndexSet(
+ IfNullIndexSet node, DartType typeContext) {
+ ExpressionInferenceResult receiverResult = inferrer.inferExpression(
+ node.receiver, const UnknownType(), true,
+ isVoidAllowed: true);
+ DartType receiverType = receiverResult.inferredType;
+ VariableDeclaration receiverVariable =
+ createVariable(node.receiver, receiverType);
+
+ ObjectAccessTarget readTarget = inferrer.findInterfaceMember(
+ receiverType, new Name('[]'), node.readOffset,
+ includeExtensionMethods: true);
+
+ MethodContravarianceCheckKind checkKind =
+ inferrer.preCheckInvocationContravariance(receiverType, readTarget,
+ isThisReceiver: node.receiver is ThisExpression);
+
+ DartType readType = inferrer.getReturnType(readTarget, receiverType);
+ DartType readIndexType = inferrer.getIndexKeyType(readTarget, receiverType);
+
+ Member equalsMember = inferrer
+ .findInterfaceMember(readType, new Name('=='), node.fileOffset)
+ .member;
+
+ ObjectAccessTarget writeTarget = inferrer.findInterfaceMember(
+ receiverType, new Name('[]='), node.fileOffset,
+ includeExtensionMethods: true);
+
+ DartType writeIndexType =
+ inferrer.getIndexKeyType(writeTarget, receiverType);
+ DartType valueType =
+ inferrer.getIndexSetValueType(writeTarget, receiverType);
+
+ ExpressionInferenceResult indexResult = inferrer
+ .inferExpression(node.index, readIndexType, true, isVoidAllowed: true);
+
+ VariableDeclaration indexVariable =
+ createVariable(node.index, indexResult.inferredType);
+
+ Expression readIndex = createVariableGet(indexVariable);
+ readIndex = inferrer.ensureAssignable(readIndexType,
+ indexResult.inferredType, readIndex, readIndex.fileOffset) ??
+ readIndex;
+
+ Expression writeIndex = createVariableGet(indexVariable);
+ writeIndex = inferrer.ensureAssignable(writeIndexType,
+ indexResult.inferredType, writeIndex, writeIndex.fileOffset) ??
+ writeIndex;
+
+ ExpressionInferenceResult valueResult = inferrer
+ .inferExpression(node.value, valueType, true, isVoidAllowed: true);
+ inferrer.ensureAssignable(
+ valueType, valueResult.inferredType, node.value, node.value.fileOffset);
+
+ DartType inferredType = inferrer.typeSchemaEnvironment
+ .getStandardUpperBound(readType, valueResult.inferredType);
+
+ Expression read;
+
+ if (readTarget.isMissing) {
+ read = inferrer.helper.buildProblem(
+ templateUndefinedMethod.withArguments('[]', receiverType),
+ node.readOffset,
+ '[]'.length,
+ wrapInSyntheticExpression: false);
+ } else if (readTarget.isExtensionMember) {
+ read = new StaticInvocation(
+ readTarget.member,
+ new Arguments(<Expression>[
+ createVariableGet(receiverVariable),
+ readIndex,
+ ], types: readTarget.inferredExtensionTypeArguments)
+ ..fileOffset = node.readOffset)
+ ..fileOffset = node.readOffset;
+ } else {
+ read = new MethodInvocation(
+ createVariableGet(receiverVariable),
+ new Name('[]'),
+ new Arguments(<Expression>[
+ readIndex,
+ ])
+ ..fileOffset = node.readOffset,
+ readTarget.member)
+ ..fileOffset = node.readOffset;
+
+ if (checkKind == MethodContravarianceCheckKind.checkMethodReturn) {
+ if (inferrer.instrumentation != null) {
+ inferrer.instrumentation.record(inferrer.uri, node.readOffset,
+ 'checkReturn', new InstrumentationValueForType(readType));
+ }
+ read = new AsExpression(read, readType)
+ ..isTypeError = true
+ ..fileOffset = node.readOffset;
+ }
+ }
+
+ VariableDeclaration valueVariable;
+ Expression valueExpression;
+ if (node.forEffect) {
+ valueExpression = node.value;
+ } else {
+ valueVariable = createVariable(node.value, valueResult.inferredType);
+ valueExpression = createVariableGet(valueVariable);
+ }
+
+ Expression write;
+
+ if (writeTarget.isMissing) {
+ write = inferrer.helper.buildProblem(
+ templateUndefinedMethod.withArguments('[]=', receiverType),
+ node.fileOffset,
+ '[]='.length,
+ wrapInSyntheticExpression: false);
+ } else if (writeTarget.isExtensionMember) {
+ write = new StaticInvocation(
+ writeTarget.member,
+ new Arguments(<Expression>[
+ createVariableGet(receiverVariable),
+ writeIndex,
+ valueExpression
+ ], types: writeTarget.inferredExtensionTypeArguments)
+ ..fileOffset = node.fileOffset)
+ ..fileOffset = node.fileOffset;
+ } else {
+ write = new MethodInvocation(
+ createVariableGet(receiverVariable),
+ new Name('[]='),
+ new Arguments(<Expression>[writeIndex, valueExpression])
+ ..fileOffset = node.fileOffset,
+ writeTarget.member)
+ ..fileOffset = node.fileOffset;
+ }
+
+ Expression replacement;
+ if (node.forEffect) {
+ // Encode `o[a] ??= b` as:
+ //
+ // let v1 = o in
+ // let v2 = a in
+ // let v3 = v1[v2] in
+ // v3 == null ? v1.[]=(v2, b) : null
+ //
+ MethodInvocation equalsNull =
+ createEqualsNull(node.fileOffset, read, equalsMember);
+ ConditionalExpression conditional = new ConditionalExpression(equalsNull,
+ write, new NullLiteral()..fileOffset = node.fileOffset, inferredType)
+ ..fileOffset = node.fileOffset;
+ node.replaceWith(replacement =
+ new Let(receiverVariable, createLet(indexVariable, conditional))
+ ..fileOffset = node.fileOffset);
+ } else {
+ // Encode `o[a] ??= b` as:
+ //
+ // let v1 = o in
+ // let v2 = a in
+ // let v3 = v1[v2] in
+ // v3 == null
+ // ? (let v4 = b in
+ // let _ = v1.[]=(v2, v4) in
+ // v4)
+ // : v3
+ //
+ assert(valueVariable != null);
+
+ VariableDeclaration readVariable = createVariable(read, readType);
+ MethodInvocation equalsNull = createEqualsNull(
+ node.fileOffset, createVariableGet(readVariable), equalsMember);
+ VariableDeclaration writeVariable =
+ createVariable(write, const VoidType());
+ ConditionalExpression conditional = new ConditionalExpression(
+ equalsNull,
+ createLet(valueVariable,
+ createLet(writeVariable, createVariableGet(valueVariable))),
+ createVariableGet(readVariable),
+ inferredType)
+ ..fileOffset = node.fileOffset;
+ node.replaceWith(replacement = new Let(receiverVariable,
+ createLet(indexVariable, createLet(readVariable, conditional)))
+ ..fileOffset = node.fileOffset);
+ }
+ return new ExpressionInferenceResult(inferredType, replacement);
+ }
+
+ ExpressionInferenceResult visitCompoundIndexSet(
+ CompoundIndexSet node, DartType typeContext) {
+ ExpressionInferenceResult receiverResult = inferrer.inferExpression(
+ node.receiver, const UnknownType(), true,
+ isVoidAllowed: true);
+ DartType receiverType = receiverResult.inferredType;
+ VariableDeclaration receiverVariable =
+ createVariable(node.receiver, receiverType);
+
+ ObjectAccessTarget readTarget = inferrer.findInterfaceMember(
+ receiverType, new Name('[]'), node.readOffset,
+ includeExtensionMethods: true);
+
+ MethodContravarianceCheckKind readCheckKind =
+ inferrer.preCheckInvocationContravariance(receiverType, readTarget,
+ isThisReceiver: node.receiver is ThisExpression);
+
+ DartType readType = inferrer.getReturnType(readTarget, receiverType);
+ DartType readIndexType = inferrer.getPositionalParameterTypeForTarget(
+ readTarget, receiverType, 0);
+
+ ExpressionInferenceResult indexResult = inferrer
+ .inferExpression(node.index, readIndexType, true, isVoidAllowed: true);
+ VariableDeclaration indexVariable =
+ createVariable(node.index, indexResult.inferredType);
+
+ Expression readIndex = createVariableGet(indexVariable);
+ Expression readIndexReplacement = inferrer.ensureAssignable(readIndexType,
+ indexResult.inferredType, readIndex, readIndex.fileOffset);
+ if (readIndexReplacement != null) {
+ readIndex = readIndexReplacement;
+ }
+
+ Expression read;
+ if (readTarget.isMissing) {
+ read = inferrer.helper.buildProblem(
+ templateUndefinedMethod.withArguments('[]', receiverType),
+ node.readOffset,
+ '[]'.length,
+ wrapInSyntheticExpression: false);
+ } else if (readTarget.isExtensionMember) {
+ read = new StaticInvocation(
+ readTarget.member,
+ new Arguments(<Expression>[
+ createVariableGet(receiverVariable),
+ readIndex,
+ ], types: readTarget.inferredExtensionTypeArguments)
+ ..fileOffset = node.readOffset)
+ ..fileOffset = node.readOffset;
+ } else {
+ read = new MethodInvocation(
+ createVariableGet(receiverVariable),
+ new Name('[]'),
+ new Arguments(<Expression>[
+ readIndex,
+ ])
+ ..fileOffset = node.readOffset,
+ readTarget.member)
+ ..fileOffset = node.readOffset;
+ if (readCheckKind == MethodContravarianceCheckKind.checkMethodReturn) {
+ if (inferrer.instrumentation != null) {
+ inferrer.instrumentation.record(inferrer.uri, node.readOffset,
+ 'checkReturn', new InstrumentationValueForType(readType));
+ }
+ read = new AsExpression(read, readType)
+ ..isTypeError = true
+ ..fileOffset = node.readOffset;
+ }
+ }
+
+ VariableDeclaration leftVariable;
+ Expression left;
+ if (node.forEffect) {
+ left = read;
+ } else if (node.forPostIncDec) {
+ leftVariable = createVariable(read, readType);
+ left = createVariableGet(leftVariable);
+ } else {
+ left = read;
+ }
+
+ ObjectAccessTarget binaryTarget = inferrer.findInterfaceMember(
+ readType, node.binaryName, node.binaryOffset,
+ includeExtensionMethods: true);
+
+ MethodContravarianceCheckKind binaryCheckKind =
+ inferrer.preCheckInvocationContravariance(readType, binaryTarget,
+ isThisReceiver: false);
+
+ DartType binaryType = inferrer.getReturnType(binaryTarget, readType);
+ DartType rhsType =
+ inferrer.getPositionalParameterTypeForTarget(binaryTarget, readType, 0);
+
+ ExpressionInferenceResult rhsResult =
+ inferrer.inferExpression(node.rhs, rhsType, true, isVoidAllowed: true);
+ inferrer.ensureAssignable(
+ rhsType, rhsResult.inferredType, node.rhs, node.rhs.fileOffset);
+
+ if (inferrer.isOverloadedArithmeticOperatorAndType(
+ binaryTarget, readType)) {
+ binaryType = inferrer.typeSchemaEnvironment
+ .getTypeOfOverloadedArithmetic(readType, rhsResult.inferredType);
+ }
+
+ Expression binary;
+ if (binaryTarget.isMissing) {
+ binary = inferrer.helper.buildProblem(
+ templateUndefinedMethod.withArguments(
+ node.binaryName.name, receiverType),
+ node.binaryOffset,
+ node.binaryName.name.length,
+ wrapInSyntheticExpression: false);
+ } else if (binaryTarget.isExtensionMember) {
+ binary = new StaticInvocation(
+ binaryTarget.member,
+ new Arguments(<Expression>[
+ left,
+ node.rhs,
+ ], types: binaryTarget.inferredExtensionTypeArguments)
+ ..fileOffset = node.binaryOffset)
+ ..fileOffset = node.binaryOffset;
+ } else {
+ binary = new MethodInvocation(
+ left,
+ node.binaryName,
+ new Arguments(<Expression>[
+ node.rhs,
+ ])
+ ..fileOffset = node.binaryOffset,
+ binaryTarget.member)
+ ..fileOffset = node.binaryOffset;
+
+ if (binaryCheckKind == MethodContravarianceCheckKind.checkMethodReturn) {
+ if (inferrer.instrumentation != null) {
+ inferrer.instrumentation.record(inferrer.uri, node.binaryOffset,
+ 'checkReturn', new InstrumentationValueForType(readType));
+ }
+ binary = new AsExpression(binary, binaryType)
+ ..isTypeError = true
+ ..fileOffset = node.binaryOffset;
+ }
+ }
+
+ ObjectAccessTarget writeTarget = inferrer.findInterfaceMember(
+ receiverType, new Name('[]='), node.writeOffset,
+ includeExtensionMethods: true);
+
+ DartType writeIndexType = inferrer.getPositionalParameterTypeForTarget(
+ writeTarget, receiverType, 0);
+ Expression writeIndex = createVariableGet(indexVariable);
+ Expression writeIndexReplacement = inferrer.ensureAssignable(writeIndexType,
+ indexResult.inferredType, writeIndex, writeIndex.fileOffset);
+ if (writeIndexReplacement != null) {
+ writeIndex = writeIndexReplacement;
+ }
+
+ DartType valueType =
+ inferrer.getIndexSetValueType(writeTarget, receiverType);
+ Expression binaryReplacement = inferrer.ensureAssignable(
+ valueType, binaryType, binary, node.fileOffset);
+ if (binaryReplacement != null) {
+ binary = binaryReplacement;
+ }
+
+ Expression replacement;
+
+ VariableDeclaration valueVariable;
+ Expression valueExpression;
+ if (node.forEffect || node.forPostIncDec) {
+ valueExpression = binary;
+ } else {
+ valueVariable = createVariable(binary, binaryType);
+ valueExpression = createVariableGet(valueVariable);
+ }
+
+ Expression write;
+
+ if (writeTarget.isMissing) {
+ write = inferrer.helper.buildProblem(
+ templateUndefinedMethod.withArguments('[]=', receiverType),
+ node.writeOffset,
+ '[]='.length,
+ wrapInSyntheticExpression: false);
+ } else if (writeTarget.isExtensionMember) {
+ write = new StaticInvocation(
+ writeTarget.member,
+ new Arguments(<Expression>[
+ createVariableGet(receiverVariable),
+ writeIndex,
+ valueExpression
+ ], types: writeTarget.inferredExtensionTypeArguments)
+ ..fileOffset = node.writeOffset)
+ ..fileOffset = node.writeOffset;
+ } else {
+ write = new MethodInvocation(
+ createVariableGet(receiverVariable),
+ new Name('[]='),
+ new Arguments(<Expression>[writeIndex, valueExpression])
+ ..fileOffset = node.writeOffset,
+ writeTarget.member)
+ ..fileOffset = node.writeOffset;
+ }
+
+ if (node.forEffect) {
+ assert(leftVariable == null);
+ assert(valueVariable == null);
+ // Encode `o[a] += b` as:
+ //
+ // let v1 = o in let v2 = a in v1.[]=(v2, v1.[](v2) + b)
+ //
+ node.replaceWith(replacement =
+ new Let(receiverVariable, createLet(indexVariable, write))
+ ..fileOffset = node.fileOffset);
+ } else if (node.forPostIncDec) {
+ // Encode `o[a]++` as:
+ //
+ // let v1 = o in
+ // let v2 = a in
+ // let v3 = v1.[](v2)
+ // let v4 = v1.[]=(v2, c3 + b) in v3
+ //
+ assert(leftVariable != null);
+ assert(valueVariable == null);
+
+ VariableDeclaration writeVariable =
+ createVariable(write, const VoidType());
+ node.replaceWith(replacement = new Let(
+ receiverVariable,
+ createLet(
+ indexVariable,
+ createLet(leftVariable,
+ createLet(writeVariable, createVariableGet(leftVariable)))))
+ ..fileOffset = node.fileOffset);
+ } else {
+ // Encode `o[a] += b` as:
+ //
+ // let v1 = o in
+ // let v2 = a in
+ // let v3 = v1.[](v2) + b
+ // let v4 = v1.[]=(v2, c3) in v3
+ //
+ assert(leftVariable == null);
+ assert(valueVariable != null);
+
+ VariableDeclaration writeVariable =
+ createVariable(write, const VoidType());
+ node.replaceWith(replacement = new Let(
+ receiverVariable,
+ createLet(
+ indexVariable,
+ createLet(valueVariable,
+ createLet(writeVariable, createVariableGet(valueVariable)))))
+ ..fileOffset = node.fileOffset);
+ }
+ return new ExpressionInferenceResult(
+ node.forPostIncDec ? readType : binaryType, replacement);
}
@override
ExpressionInferenceResult visitNullLiteral(
- NullLiteral node, DartType typeContext) =>
- new ExpressionInferenceResult(inferrer.coreTypes.nullClass.rawType);
+ NullLiteral node, DartType typeContext) {
+ return new ExpressionInferenceResult(inferrer.coreTypes.nullType);
+ }
@override
ExpressionInferenceResult visitLet(Let node, DartType typeContext) {
@@ -1665,18 +2634,53 @@
if (variableType == const DynamicType()) {
return defaultExpression(node, typeContext);
}
- Expression initializer = node.variable.initializer;
- inferrer.inferExpression(initializer, variableType, true,
+ inferrer.inferExpression(node.variable.initializer, variableType, true,
isVoidAllowed: true);
- Expression body = node.body;
- ExpressionInferenceResult result =
- inferrer.inferExpression(body, typeContext, true, isVoidAllowed: true);
+ ExpressionInferenceResult result = inferrer
+ .inferExpression(node.body, typeContext, true, isVoidAllowed: true);
DartType inferredType = result.inferredType;
- // TODO(ahe): This shouldn't be needed. See InferredTypeVisitor.visitLet.
- inferrer.storeInferredType(node, inferredType);
return new ExpressionInferenceResult(inferredType);
}
+ @override
+ ExpressionInferenceResult visitPropertySet(
+ PropertySet node, DartType typeContext) {
+ DartType receiverType;
+ if (node.receiver != null) {
+ receiverType = inferrer
+ .inferExpression(node.receiver, const UnknownType(), true)
+ .inferredType;
+ } else {
+ receiverType = inferrer.thisType;
+ }
+ ObjectAccessTarget target =
+ inferrer.findPropertySetMember(receiverType, node);
+ DartType writeContext = inferrer.getSetterType(target, receiverType);
+ ExpressionInferenceResult rhsResult = inferrer.inferExpression(
+ node.value, writeContext ?? const UnknownType(), true,
+ isVoidAllowed: true);
+ DartType rhsType = rhsResult.inferredType;
+ inferrer.ensureAssignable(
+ writeContext, rhsType, node.value, node.fileOffset,
+ isVoidAllowed: writeContext is VoidType);
+ Expression replacement;
+ if (target.isExtensionMember) {
+ node.parent.replaceChild(
+ node,
+ replacement = inferrer.helper.forest.createStaticInvocation(
+ node.fileOffset,
+ target.member,
+ inferrer.helper.forest.createArgumentsForExtensionMethod(
+ node.fileOffset,
+ target.inferredExtensionTypeArguments.length,
+ 0,
+ node.receiver,
+ extensionTypeArguments: target.inferredExtensionTypeArguments,
+ positionalArguments: [node.value])));
+ }
+ return new ExpressionInferenceResult(rhsType, replacement);
+ }
+
ExpressionInferenceResult visitPropertyAssignmentJudgment(
PropertyAssignmentJudgment node, DartType typeContext) {
DartType receiverType = node._inferReceiver(inferrer);
@@ -1705,7 +2709,7 @@
DartType writeContext = inferrer.getSetterType(writeTarget, receiverType);
DartType inferredType =
node._inferRhs(inferrer, readType, writeContext).inferredType;
- node.nullAwareGuard?.staticType = node.inferredType;
+ node.nullAwareGuard?.staticType = inferredType;
Expression replacement;
if (writeTarget.isExtensionMember) {
node.parent.replaceChild(
@@ -1721,7 +2725,6 @@
extensionTypeArguments:
writeTarget.inferredExtensionTypeArguments,
positionalArguments: [node.rhs])));
- inferrer.storeInferredType(replacement, inferredType);
} else {
node._replaceWithDesugared();
}
@@ -1733,12 +2736,11 @@
ExpressionInferenceResult visitPropertyGet(
PropertyGet node, DartType typeContext) {
return inferrer.inferPropertyGet(
- node, node.receiver, node.fileOffset, typeContext,
- desugaredGet: node, allowExtensionMethods: true);
+ node, node.receiver, node.fileOffset, typeContext, node);
}
- void visitRedirectingInitializerJudgment(
- RedirectingInitializerJudgment node) {
+ @override
+ void visitRedirectingInitializer(RedirectingInitializer node) {
List<TypeParameter> classTypeParameters =
node.target.enclosingClass.typeParameters;
List<DartType> typeArguments =
@@ -1746,41 +2748,43 @@
for (int i = 0; i < typeArguments.length; i++) {
typeArguments[i] = new TypeParameterType(classTypeParameters[i]);
}
- ArgumentsJudgment.setNonInferrableArgumentTypes(
- node.arguments, typeArguments);
+ ArgumentsImpl.setNonInferrableArgumentTypes(node.arguments, typeArguments);
inferrer.inferInvocation(
null,
node.fileOffset,
- node.target.function.functionType,
+ node.target.function.thisFunctionType,
node.target.enclosingClass.thisType,
- node.argumentJudgments,
+ node.arguments,
skipTypeArgumentInference: true);
- ArgumentsJudgment.removeNonInferrableArgumentTypes(node.arguments);
+ ArgumentsImpl.removeNonInferrableArgumentTypes(node.arguments);
}
@override
- ExpressionInferenceResult visitRethrow(Rethrow node, DartType typeContext) =>
- const ExpressionInferenceResult(const BottomType());
+ ExpressionInferenceResult visitRethrow(Rethrow node, DartType typeContext) {
+ return const ExpressionInferenceResult(const BottomType());
+ }
- void visitReturnJudgment(ReturnJudgment node) {
- Expression judgment = node.judgment;
+ @override
+ void visitReturnStatement(covariant ReturnStatementImpl node) {
ClosureContext closureContext = inferrer.closureContext;
DartType typeContext = !closureContext.isGenerator
? closureContext.returnOrYieldContext
: const UnknownType();
DartType inferredType;
if (node.expression != null) {
- inferrer.inferExpression(judgment, typeContext, true,
- isVoidAllowed: true);
- inferredType = getInferredType(judgment, inferrer);
+ inferredType = inferrer
+ .inferExpression(node.expression, typeContext, true,
+ isVoidAllowed: true)
+ .inferredType;
} else {
- inferredType = inferrer.coreTypes.nullClass.rawType;
+ inferredType = inferrer.coreTypes.nullType;
}
closureContext.handleReturn(inferrer, node, inferredType, node.isArrow);
}
- ExpressionInferenceResult visitSetLiteralJudgment(
- SetLiteralJudgment node, DartType typeContext) {
+ @override
+ ExpressionInferenceResult visitSetLiteral(
+ SetLiteral node, DartType typeContext) {
Class setClass = inferrer.coreTypes.setClass;
InterfaceType setType = setClass.thisType;
List<DartType> inferredTypes;
@@ -1790,10 +2794,12 @@
bool inferenceNeeded = node.typeArgument is ImplicitTypeArgument;
bool typeChecksNeeded = !inferrer.isTopLevel;
Map<TreeNode, DartType> inferredSpreadTypes;
+ Map<Expression, DartType> inferredConditionTypes;
if (inferenceNeeded || typeChecksNeeded) {
formalTypes = [];
actualTypes = [];
inferredSpreadTypes = new Map<TreeNode, DartType>.identity();
+ inferredConditionTypes = new Map<Expression, DartType>.identity();
}
if (inferenceNeeded) {
inferredTypes = [const UnknownType()];
@@ -1811,6 +2817,7 @@
node,
inferredTypeArgument,
inferredSpreadTypes,
+ inferredConditionTypes,
inferenceNeeded,
typeChecksNeeded);
actualTypes.add(type);
@@ -1837,11 +2844,11 @@
}
if (typeChecksNeeded) {
for (int i = 0; i < node.expressions.length; i++) {
- checkElement(
- node.expressions[i], node, node.typeArgument, inferredSpreadTypes);
+ checkElement(node.expressions[i], node, node.typeArgument,
+ inferredSpreadTypes, inferredConditionTypes);
}
}
- node.inferredType = new InterfaceType(setClass, [inferredTypeArgument]);
+ DartType inferredType = new InterfaceType(setClass, [inferredTypeArgument]);
if (!inferrer.isTopLevel) {
SourceLibraryBuilder library = inferrer.library;
if (inferenceNeeded) {
@@ -1854,7 +2861,23 @@
inferrer.helper.transformSetLiterals = true;
}
}
- return new ExpressionInferenceResult(node.inferredType);
+ return new ExpressionInferenceResult(inferredType);
+ }
+
+ @override
+ ExpressionInferenceResult visitStaticSet(
+ StaticSet node, DartType typeContext) {
+ Member writeMember = node.target;
+ DartType writeContext = writeMember.setterType;
+ TypeInferenceEngine.resolveInferenceNode(writeMember);
+ ExpressionInferenceResult rhsResult = inferrer.inferExpression(
+ node.value, writeContext ?? const UnknownType(), true,
+ isVoidAllowed: true);
+ DartType rhsType = rhsResult.inferredType;
+ inferrer.ensureAssignable(
+ writeContext, rhsType, node.value, node.fileOffset,
+ isVoidAllowed: writeContext is VoidType);
+ return new ExpressionInferenceResult(rhsType);
}
ExpressionInferenceResult visitStaticAssignmentJudgment(
@@ -1888,7 +2911,6 @@
if (target is Procedure && target.kind == ProcedureKind.Method) {
type = inferrer.instantiateTearOff(type, typeContext, node);
}
- inferrer.storeInferredType(node, type);
return new ExpressionInferenceResult(type);
}
@@ -1902,7 +2924,6 @@
getExplicitTypeArguments(node.arguments) != null;
DartType inferredType = inferrer.inferInvocation(typeContext,
node.fileOffset, calleeType, calleeType.returnType, node.arguments);
- inferrer.storeInferredType(node, inferredType);
if (!inferrer.isTopLevel &&
!hadExplicitTypeArguments &&
node.target != null) {
@@ -1923,15 +2944,18 @@
}
}
return new ExpressionInferenceResult(
- inferrer.coreTypes.stringClass.rawType);
+ inferrer.coreTypes.stringRawType(inferrer.library.nonNullable));
}
@override
ExpressionInferenceResult visitStringLiteral(
- StringLiteral node, DartType typeContext) =>
- new ExpressionInferenceResult(inferrer.coreTypes.stringClass.rawType);
+ StringLiteral node, DartType typeContext) {
+ return new ExpressionInferenceResult(
+ inferrer.coreTypes.stringRawType(inferrer.library.nonNullable));
+ }
- void visitSuperInitializerJudgment(SuperInitializerJudgment node) {
+ @override
+ void visitSuperInitializer(SuperInitializer node) {
Substitution substitution = Substitution.fromSupertype(
inferrer.classHierarchy.getClassAsInstanceOf(
inferrer.thisType.classNode, node.target.enclosingClass));
@@ -1939,51 +2963,80 @@
null,
node.fileOffset,
substitution.substituteType(
- node.target.function.functionType.withoutTypeParameters),
+ node.target.function.thisFunctionType.withoutTypeParameters),
inferrer.thisType,
- node.argumentJudgments,
+ node.arguments,
skipTypeArgumentInference: true);
}
- ExpressionInferenceResult visitSuperMethodInvocationJudgment(
- SuperMethodInvocationJudgment node, DartType typeContext) {
+ @override
+ ExpressionInferenceResult visitSuperMethodInvocation(
+ SuperMethodInvocation node, DartType typeContext) {
if (node.interfaceTarget != null) {
inferrer.instrumentation?.record(inferrer.uri, node.fileOffset, 'target',
new InstrumentationValueForMember(node.interfaceTarget));
}
- ExpressionInferenceResult result = inferrer.inferMethodInvocation(
- node, null, node.fileOffset, false, typeContext,
- target: node.interfaceTarget != null
+ ExpressionInferenceResult result = inferrer.inferSuperMethodInvocation(
+ node,
+ typeContext,
+ node.interfaceTarget != null
? new ObjectAccessTarget.interfaceMember(node.interfaceTarget)
- : const ObjectAccessTarget.unresolved(),
- methodName: node.name,
- arguments: node.arguments);
- node.inferredType = result.inferredType;
+ : const ObjectAccessTarget.unresolved());
return new ExpressionInferenceResult(result.inferredType);
}
- ExpressionInferenceResult visitSuperPropertyGetJudgment(
- SuperPropertyGetJudgment node, DartType typeContext) {
+ @override
+ ExpressionInferenceResult visitSuperPropertyGet(
+ SuperPropertyGet node, DartType typeContext) {
if (node.interfaceTarget != null) {
inferrer.instrumentation?.record(inferrer.uri, node.fileOffset, 'target',
new InstrumentationValueForMember(node.interfaceTarget));
}
- return inferrer.inferPropertyGet(node, null, node.fileOffset, typeContext,
- readTarget: node.interfaceTarget != null
+ return inferrer.inferSuperPropertyGet(
+ node,
+ typeContext,
+ node.interfaceTarget != null
? new ObjectAccessTarget.interfaceMember(node.interfaceTarget)
- : const ObjectAccessTarget.unresolved(),
- propertyName: node.name);
+ : const ObjectAccessTarget.unresolved());
}
- void visitSwitchStatementJudgment(SwitchStatementJudgment node) {
- Expression expressionJudgment = node.expressionJudgment;
- inferrer.inferExpression(expressionJudgment, const UnknownType(), true);
- DartType expressionType = getInferredType(expressionJudgment, inferrer);
+ @override
+ ExpressionInferenceResult visitSuperPropertySet(
+ SuperPropertySet node, DartType typeContext) {
+ DartType receiverType = inferrer.classHierarchy.getTypeAsInstanceOf(
+ inferrer.thisType, inferrer.thisType.classNode.supertype.classNode);
- for (SwitchCaseJudgment switchCase in node.caseJudgments) {
- for (Expression caseExpression in switchCase.expressionJudgments) {
+ ObjectAccessTarget writeTarget = inferrer.findInterfaceMember(
+ receiverType, node.name, node.fileOffset,
+ setter: true, instrumented: true);
+ if (writeTarget.isInstanceMember) {
+ node.interfaceTarget = writeTarget.member;
+ }
+ DartType writeContext = inferrer.getSetterType(writeTarget, receiverType);
+ ExpressionInferenceResult rhsResult = inferrer.inferExpression(
+ node.value, writeContext ?? const UnknownType(), true,
+ isVoidAllowed: true);
+ DartType rhsType = rhsResult.inferredType;
+ inferrer.ensureAssignable(
+ writeContext, rhsType, node.value, node.fileOffset,
+ isVoidAllowed: writeContext is VoidType);
+
+ return new ExpressionInferenceResult(rhsType);
+ }
+
+ @override
+ void visitSwitchStatement(SwitchStatement node) {
+ DartType expressionType = inferrer
+ .inferExpression(node.expression, const UnknownType(), true)
+ .inferredType;
+
+ for (SwitchCase switchCase in node.cases) {
+ for (Expression caseExpression in switchCase.expressions) {
ExpressionInferenceResult caseExpressionResult =
inferrer.inferExpression(caseExpression, expressionType, true);
+ if (caseExpressionResult.replacement != null) {
+ caseExpression = caseExpressionResult.replacement;
+ }
DartType caseExpressionType = caseExpressionResult.inferredType;
// Check whether the expression type is assignable to the case
@@ -1996,7 +3049,7 @@
noLength,
context: [
messageSwitchExpressionNotAssignableCause.withLocation(
- inferrer.uri, expressionJudgment.fileOffset, noLength)
+ inferrer.uri, node.expression.fileOffset, noLength)
]);
}
}
@@ -2004,10 +3057,12 @@
}
}
- ExpressionInferenceResult visitSymbolLiteralJudgment(
- SymbolLiteralJudgment node, DartType typeContext) {
- node.inferredType = inferrer.coreTypes.symbolClass.rawType;
- return new ExpressionInferenceResult(node.inferredType);
+ @override
+ ExpressionInferenceResult visitSymbolLiteral(
+ SymbolLiteral node, DartType typeContext) {
+ DartType inferredType =
+ inferrer.coreTypes.symbolRawType(inferrer.library.nonNullable);
+ return new ExpressionInferenceResult(inferredType);
}
ExpressionInferenceResult visitInvalidConstructorInvocationJudgment(
@@ -2015,16 +3070,16 @@
FunctionType calleeType;
DartType returnType;
if (node.constructor != null) {
- calleeType = node.constructor.function.functionType;
+ calleeType = node.constructor.function.thisFunctionType;
returnType = computeConstructorReturnType(node.constructor);
} else {
calleeType = new FunctionType([], const DynamicType());
returnType = const DynamicType();
}
- DartType inferredType = inferrer.inferInvocation(typeContext,
- node.fileOffset, calleeType, returnType, node.argumentJudgments);
- node.inferredType = inferredType;
- return visitSyntheticExpressionJudgment(node, typeContext);
+ DartType inferredType = inferrer.inferInvocation(
+ typeContext, node.fileOffset, calleeType, returnType, node.arguments);
+ node._replaceWithDesugared();
+ return new ExpressionInferenceResult(inferredType);
}
ExpressionInferenceResult visitInvalidWriteJudgment(
@@ -2042,13 +3097,13 @@
ExpressionInferenceResult visitSyntheticExpressionJudgment(
SyntheticExpressionJudgment node, DartType typeContext) {
node._replaceWithDesugared();
- node.inferredType = const DynamicType();
return const ExpressionInferenceResult(const DynamicType());
}
ExpressionInferenceResult visitThisExpression(
- ThisExpression node, DartType typeContext) =>
- new ExpressionInferenceResult(inferrer.thisType);
+ ThisExpression node, DartType typeContext) {
+ return new ExpressionInferenceResult(inferrer.thisType);
+ }
@override
ExpressionInferenceResult visitThrow(Throw node, DartType typeContext) {
@@ -2057,26 +3112,44 @@
return const ExpressionInferenceResult(const BottomType());
}
- void visitCatchJudgment(CatchJudgment node) {
+ void visitCatch(Catch node) {
inferrer.inferStatement(node.body);
}
- void visitTryCatchJudgment(TryCatchJudgment node) {
+ @override
+ void visitTryCatch(TryCatch node) {
inferrer.inferStatement(node.body);
- for (CatchJudgment catch_ in node.catchJudgments) {
- visitCatchJudgment(catch_);
+ for (Catch catch_ in node.catches) {
+ visitCatch(catch_);
}
}
- void visitTryFinallyJudgment(TryFinallyJudgment node) {
+ @override
+ void visitTryFinally(TryFinally node) {
inferrer.inferStatement(node.body);
inferrer.inferStatement(node.finalizer);
}
- ExpressionInferenceResult visitTypeLiteralJudgment(
- TypeLiteralJudgment node, DartType typeContext) {
- node.inferredType = inferrer.coreTypes.typeClass.rawType;
- return new ExpressionInferenceResult(node.inferredType);
+ @override
+ ExpressionInferenceResult visitTypeLiteral(
+ TypeLiteral node, DartType typeContext) {
+ DartType inferredType =
+ inferrer.coreTypes.typeRawType(inferrer.library.nonNullable);
+ return new ExpressionInferenceResult(inferredType);
+ }
+
+ @override
+ ExpressionInferenceResult visitVariableSet(
+ VariableSet node, DartType typeContext) {
+ DartType writeContext = node.variable.type;
+ ExpressionInferenceResult rhsResult = inferrer.inferExpression(
+ node.value, writeContext ?? const UnknownType(), true,
+ isVoidAllowed: true);
+ DartType rhsType = rhsResult.inferredType;
+ inferrer.ensureAssignable(
+ writeContext, rhsType, node.value, node.fileOffset,
+ isVoidAllowed: writeContext is VoidType);
+ return new ExpressionInferenceResult(rhsType);
}
ExpressionInferenceResult visitVariableAssignmentJudgment(
@@ -2100,15 +3173,15 @@
return new ExpressionInferenceResult(inferredType);
}
- void visitVariableDeclarationJudgment(VariableDeclarationJudgment node) {
- Expression initializerJudgment = node.initializerJudgment;
+ @override
+ void visitVariableDeclaration(covariant VariableDeclarationImpl node) {
DartType declaredType =
node._implicitlyTyped ? const UnknownType() : node.type;
DartType inferredType;
DartType initializerType;
- if (initializerJudgment != null) {
+ if (node.initializer != null) {
ExpressionInferenceResult initializerResult = inferrer.inferExpression(
- initializerJudgment,
+ node.initializer,
declaredType,
!inferrer.isTopLevel || node._implicitlyTyped,
isVoidAllowed: true);
@@ -2155,16 +3228,18 @@
ExpressionInferenceResult visitUnresolvedVariableAssignmentJudgment(
UnresolvedVariableAssignmentJudgment node, DartType typeContext) {
- inferrer.inferExpression(node.rhs, const UnknownType(), true);
- node.inferredType = node.isCompound
- ? const DynamicType()
- : getInferredType(node.rhs, inferrer);
- return visitSyntheticExpressionJudgment(node, typeContext);
+ DartType rhsType = inferrer
+ .inferExpression(node.rhs, const UnknownType(), true)
+ .inferredType;
+ DartType inferredType = node.isCompound ? const DynamicType() : rhsType;
+ node._replaceWithDesugared();
+ return new ExpressionInferenceResult(inferredType);
}
- ExpressionInferenceResult visitVariableGetJudgment(
- VariableGetJudgment node, DartType typeContext) {
- VariableDeclarationJudgment variable = node.variable;
+ @override
+ ExpressionInferenceResult visitVariableGet(
+ covariant VariableGetImpl node, DartType typeContext) {
+ VariableDeclarationImpl variable = node.variable;
bool mutatedInClosure = variable._mutatedInClosure;
DartType declaredOrInferredType = variable.type;
@@ -2179,26 +3254,25 @@
if (variable._isLocalFunction) {
type = inferrer.instantiateTearOff(type, typeContext, node);
}
- node.inferredType = type;
return new ExpressionInferenceResult(type);
}
- void visitWhileJudgment(WhileJudgment node) {
- Expression conditionJudgment = node.conditionJudgment;
- InterfaceType expectedType = inferrer.coreTypes.boolClass.rawType;
- inferrer.inferExpression(
- conditionJudgment, expectedType, !inferrer.isTopLevel);
+ @override
+ void visitWhileStatement(WhileStatement node) {
+ InterfaceType expectedType =
+ inferrer.coreTypes.boolRawType(inferrer.library.nonNullable);
+ DartType conditionType = inferrer
+ .inferExpression(node.condition, expectedType, !inferrer.isTopLevel)
+ .inferredType;
inferrer.ensureAssignable(
- expectedType,
- getInferredType(conditionJudgment, inferrer),
- node.condition,
- node.condition.fileOffset);
+ expectedType, conditionType, node.condition, node.condition.fileOffset);
inferrer.inferStatement(node.body);
}
- void visitYieldJudgment(YieldJudgment node) {
- Expression judgment = node.judgment;
+ @override
+ void visitYieldStatement(YieldStatement node) {
ClosureContext closureContext = inferrer.closureContext;
+ DartType inferredType;
if (closureContext.isGenerator) {
DartType typeContext = closureContext.returnOrYieldContext;
if (node.isYieldStar && typeContext != null) {
@@ -2208,35 +3282,44 @@
? inferrer.coreTypes.streamClass
: inferrer.coreTypes.iterableClass);
}
- inferrer.inferExpression(judgment, typeContext, true);
+ inferredType = inferrer
+ .inferExpression(node.expression, typeContext, true)
+ .inferredType;
} else {
- inferrer.inferExpression(judgment, const UnknownType(), true);
+ inferredType = inferrer
+ .inferExpression(node.expression, const UnknownType(), true)
+ .inferredType;
}
- closureContext.handleYield(inferrer, node.isYieldStar,
- getInferredType(judgment, inferrer), node.expression, node.fileOffset);
+ closureContext.handleYield(inferrer, node.isYieldStar, inferredType,
+ node.expression, node.fileOffset);
}
- ExpressionInferenceResult visitLoadLibraryJudgment(
- LoadLibraryJudgment node, DartType typeContext) {
- node.inferredType =
+ @override
+ ExpressionInferenceResult visitLoadLibrary(
+ covariant LoadLibraryImpl node, DartType typeContext) {
+ DartType inferredType =
inferrer.typeSchemaEnvironment.futureType(const DynamicType());
if (node.arguments != null) {
- FunctionType calleeType = new FunctionType([], node.inferredType);
+ FunctionType calleeType = new FunctionType([], inferredType);
inferrer.inferInvocation(typeContext, node.fileOffset, calleeType,
- calleeType.returnType, node.argumentJudgments);
+ calleeType.returnType, node.arguments);
}
- return new ExpressionInferenceResult(node.inferredType);
+ return new ExpressionInferenceResult(inferredType);
}
- ExpressionInferenceResult visitLoadLibraryTearOffJudgment(
- LoadLibraryTearOffJudgment node, DartType typeContext) {
- node.inferredType = new FunctionType(
+ ExpressionInferenceResult visitLoadLibraryTearOff(
+ LoadLibraryTearOff node, DartType typeContext) {
+ DartType inferredType = new FunctionType(
[], inferrer.typeSchemaEnvironment.futureType(const DynamicType()));
- return new ExpressionInferenceResult(node.inferredType);
+ Expression replacement = node.replace();
+ return new ExpressionInferenceResult(inferredType, replacement);
}
@override
ExpressionInferenceResult visitCheckLibraryIsLoaded(
- CheckLibraryIsLoaded node, DartType typeContext) =>
- new ExpressionInferenceResult(inferrer.coreTypes.objectClass.rawType);
+ CheckLibraryIsLoaded node, DartType typeContext) {
+ // TODO(dmitryas): Figure out the suitable nullability for that.
+ return new ExpressionInferenceResult(
+ inferrer.coreTypes.objectRawType(inferrer.library.nullable));
+ }
}
diff --git a/pkg/front_end/lib/src/fasta/kernel/inferred_type_visitor.dart b/pkg/front_end/lib/src/fasta/kernel/inferred_type_visitor.dart
deleted file mode 100644
index 05513ad..0000000
--- a/pkg/front_end/lib/src/fasta/kernel/inferred_type_visitor.dart
+++ /dev/null
@@ -1,162 +0,0 @@
-// Copyright (c) 2018, 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.
-
-part of "kernel_shadow_ast.dart";
-
-DartType getInferredType(Expression expression, TypeInferrerImpl inferrer) {
- if (expression is ExpressionJudgment) {
- return expression.inferredType;
- } else {
- return expression.accept1(const InferredTypeVisitor(), inferrer);
- }
-}
-
-DartType invalidToBottom(DartType type) {
- // TODO(ahe): This should really return [BottomType], but that requires more
- // work to the Kernel type system and implementation.
- return (type == null || type is InvalidType) ? const DynamicType() : type;
-}
-
-DartType invalidToTop(DartType type) {
- return (type == null || type is InvalidType) ? const DynamicType() : type;
-}
-
-class InferredTypeVisitor
- extends ExpressionVisitor1<DartType, TypeInferrerImpl> {
- const InferredTypeVisitor();
-
- @override
- DartType defaultExpression(Expression node, TypeInferrerImpl inferrer) {
- unhandled("${node.runtimeType}", "getInferredType", node.fileOffset,
- inferrer.uri);
- return const InvalidType();
- }
-
- @override
- DartType visitIntLiteral(IntLiteral node, TypeInferrerImpl inferrer) {
- return inferrer.coreTypes.intClass.rawType;
- }
-
- @override
- DartType visitDoubleLiteral(DoubleLiteral node, TypeInferrerImpl inferrer) {
- return inferrer.coreTypes.doubleClass.rawType;
- }
-
- @override
- DartType visitInvalidExpression(
- InvalidExpression node, TypeInferrerImpl inferrer) {
- return const BottomType();
- }
-
- @override
- DartType visitAsExpression(AsExpression node, TypeInferrerImpl inferrer) {
- return invalidToBottom(node.type);
- }
-
- @override
- DartType visitAwaitExpression(
- AwaitExpression node, TypeInferrerImpl inferrer) {
- return inferrer.readInferredType(node);
- }
-
- @override
- DartType visitThisExpression(ThisExpression node, TypeInferrerImpl inferrer) {
- return invalidToBottom(inferrer.thisType);
- }
-
- @override
- DartType visitBoolLiteral(BoolLiteral node, TypeInferrerImpl inferrer) {
- return inferrer.coreTypes.boolClass.rawType;
- }
-
- @override
- DartType visitConditionalExpression(
- ConditionalExpression node, TypeInferrerImpl inferrer) {
- return node.staticType;
- }
-
- @override
- DartType visitConstructorInvocation(
- ConstructorInvocation node, TypeInferrerImpl inferrer) {
- return inferrer.readInferredType(node);
- }
-
- @override
- DartType visitIsExpression(IsExpression node, TypeInferrerImpl inferrer) {
- return inferrer.coreTypes.boolClass.rawType;
- }
-
- @override
- DartType visitFunctionExpression(
- FunctionExpression node, TypeInferrerImpl inferrer) {
- return inferrer.readInferredType(node);
- }
-
- @override
- DartType visitLogicalExpression(
- LogicalExpression node, TypeInferrerImpl inferrer) {
- return inferrer.coreTypes.boolClass.rawType;
- }
-
- @override
- DartType visitNot(Not node, TypeInferrerImpl inferrer) {
- return inferrer.coreTypes.boolClass.rawType;
- }
-
- @override
- DartType visitNullLiteral(NullLiteral node, TypeInferrerImpl inferrer) {
- return inferrer.coreTypes.nullClass.rawType;
- }
-
- @override
- DartType visitPropertyGet(PropertyGet node, TypeInferrerImpl inferrer) {
- return inferrer.readInferredType(node);
- }
-
- @override
- DartType visitRethrow(Rethrow node, TypeInferrerImpl inferrer) {
- return const BottomType();
- }
-
- @override
- DartType visitStringConcatenation(
- StringConcatenation node, TypeInferrerImpl inferrer) {
- return inferrer.coreTypes.stringClass.rawType;
- }
-
- @override
- DartType visitStringLiteral(StringLiteral node, TypeInferrerImpl inferrer) {
- return inferrer.coreTypes.stringClass.rawType;
- }
-
- @override
- DartType visitLet(Let node, TypeInferrerImpl inferrer) {
- // TODO(ahe): We should be able to return the inferred type of
- // node.body. However, that type may be lost, for example, in
- // VariableAssignmentJudgment._replaceWithDesugared.
- return inferrer.readInferredType(node);
- }
-
- @override
- DartType visitStaticGet(StaticGet node, TypeInferrerImpl inferrer) {
- return inferrer.readInferredType(node);
- }
-
- @override
- DartType visitStaticInvocation(
- StaticInvocation node, TypeInferrerImpl inferrer) {
- return inferrer.readInferredType(node);
- }
-
- @override
- DartType visitThrow(Throw node, TypeInferrerImpl inferrer) {
- return const BottomType();
- }
-
- @override
- DartType visitCheckLibraryIsLoaded(
- CheckLibraryIsLoaded node, TypeInferrerImpl inferrer) {
- return inferrer.coreTypes.objectClass.rawType;
- }
-}
diff --git a/pkg/front_end/lib/src/fasta/kernel/kernel_ast_api.dart b/pkg/front_end/lib/src/fasta/kernel/kernel_ast_api.dart
index bca9db5..65f8ccf 100644
--- a/pkg/front_end/lib/src/fasta/kernel/kernel_ast_api.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/kernel_ast_api.dart
@@ -84,37 +84,22 @@
export 'kernel_shadow_ast.dart'
show
- ArgumentsJudgment,
- AssertInitializerJudgment,
- AssertStatementJudgment,
- BlockJudgment,
- CascadeJudgment,
+ ArgumentsImpl,
+ Cascade,
ComplexAssignmentJudgment,
- ContinueSwitchJudgment,
- DeferredCheckJudgment,
- ExpressionStatementJudgment,
+ DeferredCheck,
FactoryConstructorInvocationJudgment,
- FunctionDeclarationJudgment,
- FunctionNodeJudgment,
- IfJudgment,
+ FunctionDeclarationImpl,
IfNullJudgment,
InvalidSuperInitializerJudgment,
- LoadLibraryTearOffJudgment,
- MethodInvocationJudgment,
+ LoadLibraryTearOff,
+ MethodInvocationImpl,
NamedFunctionExpressionJudgment,
- NullAwareMethodInvocationJudgment,
- NullAwarePropertyGetJudgment,
- RedirectingInitializerJudgment,
- ReturnJudgment,
- ShadowFieldInitializer,
+ NullAwareMethodInvocation,
+ NullAwarePropertyGet,
+ ReturnStatementImpl,
ShadowInvalidFieldInitializer,
ShadowInvalidInitializer,
ShadowLargeIntLiteral,
- SuperInitializerJudgment,
- SuperMethodInvocationJudgment,
- SuperPropertyGetJudgment,
- SwitchCaseJudgment,
- SwitchStatementJudgment,
- VariableDeclarationJudgment,
- VariableGetJudgment,
- YieldJudgment;
+ VariableDeclarationImpl,
+ VariableGetImpl;
diff --git a/pkg/front_end/lib/src/fasta/kernel/kernel_shadow_ast.dart b/pkg/front_end/lib/src/fasta/kernel/kernel_shadow_ast.dart
index 36e77d4..99d2714 100644
--- a/pkg/front_end/lib/src/fasta/kernel/kernel_shadow_ast.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/kernel_shadow_ast.dart
@@ -20,8 +20,6 @@
import 'dart:core' hide MapEntry;
-import 'package:kernel/ast.dart' as kernel show Expression, Initializer;
-
import 'package:kernel/ast.dart';
import 'package:kernel/type_algebra.dart' show Substitution;
@@ -53,6 +51,7 @@
templateSpreadMapEntryTypeMismatch,
templateSpreadTypeMismatch,
templateSwitchExpressionNotAssignable,
+ templateUndefinedMethod,
templateWebLiteralCannotBeRepresentedExactly;
import '../problems.dart' show getFileUri, unhandled, unsupported;
@@ -98,7 +97,6 @@
import 'implicit_type_argument.dart' show ImplicitTypeArgument;
part "inference_visitor.dart";
-part "inferred_type_visitor.dart";
/// Computes the return type of a (possibly factory) constructor.
InterfaceType computeConstructorReturnType(Member constructor) {
@@ -110,7 +108,7 @@
}
int getExtensionTypeParameterCount(Arguments arguments) {
- if (arguments is ArgumentsJudgment) {
+ if (arguments is ArgumentsImpl) {
return arguments._extensionTypeParameterCount;
} else {
// TODO(johnniwinther): Remove this path or assert why it is accepted.
@@ -119,7 +117,7 @@
}
int getExtensionTypeArgumentCount(Arguments arguments) {
- if (arguments is ArgumentsJudgment) {
+ if (arguments is ArgumentsImpl) {
return arguments._extensionTypeArgumentCount;
} else {
// TODO(johnniwinther): Remove this path or assert why it is accepted.
@@ -128,7 +126,7 @@
}
List<DartType> getExplicitExtensionTypeArguments(Arguments arguments) {
- if (arguments is ArgumentsJudgment) {
+ if (arguments is ArgumentsImpl) {
if (arguments._extensionTypeArgumentCount == 0) {
return null;
} else {
@@ -143,7 +141,7 @@
}
List<DartType> getExplicitTypeArguments(Arguments arguments) {
- if (arguments is ArgumentsJudgment) {
+ if (arguments is ArgumentsImpl) {
if (arguments._explicitTypeArgumentCount == 0) {
return null;
} else if (arguments._extensionTypeParameterCount == 0) {
@@ -179,8 +177,52 @@
ClassInferenceInfo(this.builder);
}
-/// Concrete shadow object representing a set of invocation arguments.
-class ArgumentsJudgment extends Arguments {
+enum InternalExpressionKind {
+ Cascade,
+ CompoundIndexSet,
+ CompoundPropertySet,
+ DeferredCheck,
+ IfNullIndexSet,
+ IfNullPropertySet,
+ IfNullSet,
+ IndexSet,
+ LoadLibraryTearOff,
+ LocalPostIncDec,
+ NullAwareMethodInvocation,
+ NullAwarePropertyGet,
+ NullAwarePropertySet,
+ PropertyPostIncDec,
+ StaticPostIncDec,
+ SuperPostIncDec,
+}
+
+/// Common base class for internal expressions.
+abstract class InternalExpression extends Expression {
+ InternalExpressionKind get kind;
+
+ /// Replaces this [InternalExpression] with a semantically equivalent
+ /// [Expression] and returns the replacing [Expression].
+ ///
+ /// This method most be called after inference has been performed to ensure
+ /// that [InternalExpression] nodes do not leak.
+ Expression replace() {
+ throw new UnsupportedError('$runtimeType.replace()');
+ }
+
+ @override
+ R accept<R>(ExpressionVisitor<R> visitor) => visitor.defaultExpression(this);
+
+ @override
+ R accept1<R, A>(ExpressionVisitor1<R, A> visitor, A arg) =>
+ visitor.defaultExpression(this, arg);
+
+ @override
+ DartType getStaticType(types) =>
+ unsupported("${runtimeType}.getStaticType", -1, null);
+}
+
+/// Front end specific implementation of [Argument].
+class ArgumentsImpl extends Arguments {
// TODO(johnniwinther): Move this to the static invocation instead.
final int _extensionTypeParameterCount;
@@ -188,16 +230,14 @@
int _explicitTypeArgumentCount;
- List<Expression> get positionalJudgments => positional.cast();
-
- ArgumentsJudgment(List<Expression> positional,
+ ArgumentsImpl(List<Expression> positional,
{List<DartType> types, List<NamedExpression> named})
: _explicitTypeArgumentCount = types?.length ?? 0,
_extensionTypeParameterCount = 0,
_extensionTypeArgumentCount = 0,
super(positional, types: types, named: named);
- ArgumentsJudgment.forExtensionMethod(int extensionTypeParameterCount,
+ ArgumentsImpl.forExtensionMethod(int extensionTypeParameterCount,
int typeParameterCount, Expression receiver,
{List<DartType> extensionTypeArguments = const <DartType>[],
List<DartType> typeArguments = const <DartType>[],
@@ -227,64 +267,19 @@
}
static void setNonInferrableArgumentTypes(
- ArgumentsJudgment arguments, List<DartType> types) {
+ ArgumentsImpl arguments, List<DartType> types) {
arguments.types.clear();
arguments.types.addAll(types);
arguments._explicitTypeArgumentCount = types.length;
}
- static void removeNonInferrableArgumentTypes(ArgumentsJudgment arguments) {
+ static void removeNonInferrableArgumentTypes(ArgumentsImpl arguments) {
arguments.types.clear();
arguments._explicitTypeArgumentCount = 0;
}
}
-/// Concrete shadow object representing an assert initializer in kernel form.
-class AssertInitializerJudgment extends AssertInitializer
- implements InitializerJudgment {
- AssertInitializerJudgment(AssertStatement statement) : super(statement);
-
- AssertStatementJudgment get judgment => statement;
-
- @override
- void acceptInference(InferenceVisitor visitor) {
- return visitor.visitAssertInitializerJudgment(this);
- }
-}
-
-/// Concrete shadow object representing an assertion statement in kernel form.
-class AssertStatementJudgment extends AssertStatement
- implements StatementJudgment {
- AssertStatementJudgment(Expression condition,
- {Expression message, int conditionStartOffset, int conditionEndOffset})
- : super(condition,
- message: message,
- conditionStartOffset: conditionStartOffset,
- conditionEndOffset: conditionEndOffset);
-
- Expression get conditionJudgment => condition;
-
- Expression get messageJudgment => message;
-
- @override
- void acceptInference(InferenceVisitor visitor) {
- return visitor.visitAssertStatementJudgment(this);
- }
-}
-
-/// Concrete shadow object representing a statement block in kernel form.
-class BlockJudgment extends Block implements StatementJudgment {
- BlockJudgment(List<Statement> statements) : super(statements);
-
- List<Statement> get judgments => statements;
-
- @override
- void acceptInference(InferenceVisitor visitor) {
- return visitor.visitBlockJudgment(this);
- }
-}
-
-/// Concrete shadow object representing a cascade expression.
+/// Internal expression representing a cascade expression.
///
/// A cascade expression of the form `a..b()..c()` is represented as the kernel
/// expression:
@@ -298,32 +293,45 @@
/// variable"--this is the variable that remembers the value of the expression
/// preceding the first `..` while the cascades are being evaluated.
///
-/// After constructing a [CascadeJudgment], the caller should
+/// After constructing a [Cascade], the caller should
/// call [finalize] with an expression representing the expression after the
/// `..`. If a further `..` follows that expression, the caller should call
/// [extend] followed by [finalize] for each subsequent cascade.
-class CascadeJudgment extends Let implements ExpressionJudgment {
- DartType inferredType;
+// TODO(johnniwinther): Change the representation to be direct and perform
+// the [Let] encoding in [replace].
+class Cascade extends InternalExpression {
+ VariableDeclaration variable;
- /// Pointer to the last "let" expression in the cascade.
- Let nextCascade;
+ /// Pointer to the first "let" expression in the cascade, i.e. `e1` in
+ /// `e..e1..e2..e3`;
+ Let _firstCascade;
- /// Creates a [CascadeJudgment] using [variable] as the cascade
+ /// Pointer to the last "let" expression in the cascade, i.e. `e3` in
+ // /// `e..e1..e2..e3`;
+ Let _lastCascade;
+
+ /// Creates a [Cascade] using [variable] as the cascade
/// variable. Caller is responsible for ensuring that [variable]'s
/// initializer is the expression preceding the first `..` of the cascade
/// expression.
- CascadeJudgment(VariableDeclarationJudgment variable)
- : super(
- variable,
- makeLet(new VariableDeclaration.forValue(new _UnfinishedCascade()),
- new VariableGet(variable))) {
- nextCascade = body;
+ Cascade(this.variable) {
+ _lastCascade = _firstCascade = makeLet(
+ new VariableDeclaration.forValue(new _UnfinishedCascade()),
+ new VariableGet(variable));
+ variable?.parent = this;
+ _firstCascade.parent = this;
}
- Expression get targetJudgment => variable.initializer;
+ @override
+ InternalExpressionKind get kind => InternalExpressionKind.Cascade;
- Iterable<Expression> get cascadeJudgments sync* {
- Let section = body;
+ /// The initial expression of the cascade, i.e. `e` in `e..e1..e2..e3`.
+ Expression get expression => variable.initializer;
+
+ /// Returns the cascade expressions of the cascade, i.e. `e1`, `e2`, and `e3`
+ /// in `e..e1..e2..e3`.
+ Iterable<Expression> get cascades sync* {
+ Let section = _firstCascade;
while (true) {
yield section.variable.initializer;
if (section.body is! Let) break;
@@ -334,26 +342,48 @@
/// Adds a new unfinalized section to the end of the cascade. Should be
/// called after the previous cascade section has been finalized.
void extend() {
- assert(nextCascade.variable.initializer is! _UnfinishedCascade);
+ assert(_lastCascade.variable.initializer is! _UnfinishedCascade);
Let newCascade = makeLet(
new VariableDeclaration.forValue(new _UnfinishedCascade()),
- nextCascade.body);
- nextCascade.body = newCascade;
- newCascade.parent = nextCascade;
- nextCascade = newCascade;
+ _lastCascade.body);
+ _lastCascade.body = newCascade;
+ newCascade.parent = _lastCascade;
+ _lastCascade = newCascade;
}
/// Finalizes the last cascade section with the given [expression].
void finalize(Expression expression) {
- assert(nextCascade.variable.initializer is _UnfinishedCascade);
- nextCascade.variable.initializer = expression;
- expression.parent = nextCascade.variable;
+ assert(_lastCascade.variable.initializer is _UnfinishedCascade);
+ _lastCascade.variable.initializer = expression;
+ expression.parent = _lastCascade.variable;
}
@override
- ExpressionInferenceResult acceptInference(
- InferenceVisitor visitor, DartType typeContext) {
- return visitor.visitCascadeJudgment(this, typeContext);
+ Expression replace() {
+ Expression replacement;
+ parent.replaceChild(
+ this,
+ replacement = new Let(variable, _firstCascade)
+ ..fileOffset = fileOffset);
+ return replacement;
+ }
+
+ @override
+ void visitChildren(Visitor<dynamic> v) {
+ variable?.accept(v);
+ _firstCascade?.accept(v);
+ }
+
+ @override
+ void transformChildren(Transformer v) {
+ if (variable != null) {
+ variable = variable.accept<TreeNode>(v);
+ variable?.parent = this;
+ }
+ if (_firstCascade != null) {
+ _firstCascade = _firstCascade.accept<TreeNode>(v);
+ _firstCascade?.parent = this;
+ }
}
}
@@ -447,7 +477,7 @@
FunctionType combinerType =
inferrer.getFunctionType(combinerTarget, readType, false);
if (isPreIncDec || isPostIncDec) {
- rhsType = inferrer.coreTypes.intClass.rawType;
+ rhsType = inferrer.coreTypes.intRawType(inferrer.library.nonNullable);
} else {
// It's not necessary to call _storeLetType for [rhs] because the RHS
// is always passed directly to the combiner; it's never stored in a
@@ -474,8 +504,8 @@
combinedType = combinerType.returnType;
}
MethodContravarianceCheckKind checkKind =
- inferrer.preCheckInvocationContravariance(read, readType,
- combinerTarget, combiner, combiner.arguments, combiner);
+ inferrer.preCheckInvocationContravariance(readType, combinerTarget,
+ isThisReceiver: read is ThisExpression);
Expression replacedCombiner = inferrer.handleInvocationContravariance(
checkKind,
combiner,
@@ -522,7 +552,7 @@
} else {
_storeLetType(inferrer, write, combinedType);
}
- inferredType =
+ DartType inferredType =
isPostIncDec ? (readType ?? const DynamicType()) : combinedType;
return new _ComplexAssignmentInferenceResult(
combinerTarget.member, inferredType);
@@ -553,8 +583,9 @@
DartType _inferReceiver(ShadowTypeInferrer inferrer) {
if (receiver != null) {
- inferrer.inferExpression(receiver, const UnknownType(), true);
- DartType receiverType = getInferredType(receiver, inferrer);
+ DartType receiverType = inferrer
+ .inferExpression(receiver, const UnknownType(), true)
+ .inferredType;
_storeLetType(inferrer, receiver, receiverType);
return receiverType;
} else if (isSuper) {
@@ -566,109 +597,67 @@
}
}
-/// Concrete shadow object representing a continue statement from a switch
-/// statement, in kernel form.
-class ContinueSwitchJudgment extends ContinueSwitchStatement
- implements StatementJudgment {
- ContinueSwitchJudgment(SwitchCase target) : super(target);
+/// Internal expression representing a deferred check.
+// TODO(johnniwinther): Change the representation to be direct and perform
+// the [Let] encoding in [replace].
+class DeferredCheck extends InternalExpression {
+ VariableDeclaration _variable;
+ Expression expression;
- SwitchCaseJudgment get targetJudgment => target;
-
- @override
- void acceptInference(InferenceVisitor visitor) {
- return visitor.visitContinueSwitchJudgment(this);
+ DeferredCheck(this._variable, this.expression) {
+ _variable?.parent = this;
+ expression?.parent = this;
}
-}
-/// Shadow object representing a deferred check in kernel form.
-class DeferredCheckJudgment extends Let implements ExpressionJudgment {
- DartType inferredType;
-
- DeferredCheckJudgment(VariableDeclaration variable, Expression body)
- : super(variable, body);
-
- Expression get expression => body;
+ InternalExpressionKind get kind => InternalExpressionKind.DeferredCheck;
@override
- ExpressionInferenceResult acceptInference(
- InferenceVisitor visitor, DartType typeContext) {
- return visitor.visitDeferredCheckJudgment(this, typeContext);
+ Expression replace() {
+ Expression replacement;
+ parent.replaceChild(this,
+ replacement = new Let(_variable, expression)..fileOffset = fileOffset);
+ return replacement;
}
-}
-
-/// Concrete shadow object representing a do loop in kernel form.
-class DoJudgment extends DoStatement implements StatementJudgment {
- DoJudgment(Statement body, Expression condition) : super(body, condition);
-
- Expression get conditionJudgment => condition;
@override
- void acceptInference(InferenceVisitor visitor) {
- return visitor.visitDoJudgment(this);
+ void visitChildren(Visitor<dynamic> v) {
+ _variable?.accept(v);
+ expression?.accept(v);
}
-}
-
-/// Concrete shadow object representing a double literal in kernel form.
-class DoubleJudgment extends DoubleLiteral implements ExpressionJudgment {
- DartType inferredType;
-
- DoubleJudgment(double value) : super(value);
@override
- ExpressionInferenceResult acceptInference(
- InferenceVisitor visitor, DartType typeContext) {
- return visitor.visitDoubleJudgment(this, typeContext);
+ void transformChildren(Transformer v) {
+ if (_variable != null) {
+ _variable = _variable.accept<TreeNode>(v);
+ _variable?.parent = this;
+ }
+ if (expression != null) {
+ expression = expression.accept<TreeNode>(v);
+ expression?.parent = this;
+ }
}
}
/// Common base class for shadow objects representing expressions in kernel
/// form.
abstract class ExpressionJudgment extends Expression {
- DartType inferredType;
-
/// Calls back to [inferrer] to perform type inference for whatever concrete
/// type of [Expression] this is.
ExpressionInferenceResult acceptInference(
InferenceVisitor visitor, DartType typeContext);
}
-/// Concrete shadow object representing an empty statement in kernel form.
-class EmptyStatementJudgment extends EmptyStatement
- implements StatementJudgment {
- EmptyStatementJudgment();
-
- @override
- void acceptInference(InferenceVisitor visitor) {
- return visitor.visitEmptyStatementJudgment(this);
- }
-}
-
-/// Concrete shadow object representing an expression statement in kernel form.
-class ExpressionStatementJudgment extends ExpressionStatement
- implements StatementJudgment {
- ExpressionStatementJudgment(Expression expression) : super(expression);
-
- Expression get judgment => expression;
-
- @override
- void acceptInference(InferenceVisitor visitor) {
- return visitor.visitExpressionStatementJudgment(this);
- }
-}
-
/// Shadow object for [StaticInvocation] when the procedure being invoked is a
/// factory constructor.
class FactoryConstructorInvocationJudgment extends StaticInvocation
implements ExpressionJudgment {
- DartType inferredType;
+ bool hasBeenInferred = false;
FactoryConstructorInvocationJudgment(
- Procedure target, ArgumentsJudgment arguments,
+ Procedure target, ArgumentsImpl arguments,
{bool isConst: false})
: super(target, arguments, isConst: isConst);
- ArgumentsJudgment get argumentJudgments => arguments;
-
@override
ExpressionInferenceResult acceptInference(
InferenceVisitor visitor, DartType typeContext) {
@@ -676,74 +665,16 @@
}
}
-/// Concrete shadow object representing a field initializer in kernel form.
-class ShadowFieldInitializer extends FieldInitializer
- implements InitializerJudgment {
- ShadowFieldInitializer(Field field, Expression value) : super(field, value);
-
- @override
- void acceptInference(InferenceVisitor visitor) {
- return visitor.visitShadowFieldInitializer(this);
- }
-}
-
-/// Concrete shadow object representing a classic for loop in kernel form.
-class ForJudgment extends ForStatement implements StatementJudgment {
- ForJudgment(List<VariableDeclaration> variables, Expression condition,
- List<Expression> updates, Statement body)
- : super(variables ?? [], condition, updates, body);
-
- Expression get conditionJudgment => condition;
-
- List<Expression> get updateJudgments => updates.cast();
-
- @override
- void acceptInference(InferenceVisitor visitor) {
- return visitor.visitForJudgment(this);
- }
-}
-
-/// Concrete shadow object representing a function expression in kernel form.
-class FunctionNodeJudgment extends FunctionNode {
- FunctionNodeJudgment(Statement body,
- {List<TypeParameter> typeParameters,
- List<VariableDeclaration> positionalParameters,
- List<VariableDeclaration> namedParameters,
- int requiredParameterCount,
- DartType returnType: const DynamicType(),
- AsyncMarker asyncMarker: AsyncMarker.Sync,
- AsyncMarker dartAsyncMarker})
- : super(body,
- typeParameters: typeParameters,
- positionalParameters: positionalParameters,
- namedParameters: namedParameters,
- requiredParameterCount: requiredParameterCount,
- returnType: returnType,
- asyncMarker: asyncMarker,
- dartAsyncMarker: dartAsyncMarker);
-}
-
-/// Concrete shadow object representing a local function declaration in kernel
-/// form.
-class FunctionDeclarationJudgment extends FunctionDeclaration
- implements StatementJudgment {
+/// Front end specific implementation of [FunctionDeclaration].
+class FunctionDeclarationImpl extends FunctionDeclaration {
bool _hasImplicitReturnType = false;
- FunctionDeclarationJudgment(
- VariableDeclarationJudgment variable, FunctionNodeJudgment function)
+ FunctionDeclarationImpl(
+ VariableDeclarationImpl variable, FunctionNode function)
: super(variable, function);
- VariableDeclarationJudgment get variableJudgment => variable;
-
- FunctionNodeJudgment get functionJudgment => function;
-
- @override
- void acceptInference(InferenceVisitor visitor) {
- return visitor.visitFunctionDeclarationJudgment(this);
- }
-
static void setHasImplicitReturnType(
- FunctionDeclarationJudgment declaration, bool hasImplicitReturnType) {
+ FunctionDeclarationImpl declaration, bool hasImplicitReturnType) {
declaration._hasImplicitReturnType = hasImplicitReturnType;
}
}
@@ -752,7 +683,7 @@
class InvalidSuperInitializerJudgment extends LocalInitializer
implements InitializerJudgment {
final Constructor target;
- final ArgumentsJudgment argumentsJudgment;
+ final ArgumentsImpl argumentsJudgment;
InvalidSuperInitializerJudgment(
this.target, this.argumentsJudgment, VariableDeclaration variable)
@@ -771,8 +702,6 @@
///
/// let v = a in v == null ? b : v
class IfNullJudgment extends Let implements ExpressionJudgment {
- DartType inferredType;
-
IfNullJudgment(VariableDeclaration variable, Expression body)
: super(variable, body);
@@ -780,10 +709,10 @@
ConditionalExpression get body => super.body;
/// Returns the expression to the left of `??`.
- Expression get leftJudgment => variable.initializer;
+ Expression get left => variable.initializer;
/// Returns the expression to the right of `??`.
- Expression get rightJudgment => body.then;
+ Expression get right => body.then;
@override
ExpressionInferenceResult acceptInference(
@@ -792,19 +721,6 @@
}
}
-/// Concrete shadow object representing an if statement in kernel form.
-class IfJudgment extends IfStatement implements StatementJudgment {
- IfJudgment(Expression condition, Statement then, Statement otherwise)
- : super(condition, then, otherwise);
-
- Expression get conditionJudgment => condition;
-
- @override
- void acceptInference(InferenceVisitor visitor) {
- return visitor.visitIfJudgment(this);
- }
-}
-
/// Concrete shadow object representing an assignment to a target for which
/// assignment is not allowed.
class IllegalAssignmentJudgment extends ComplexAssignmentJudgment {
@@ -892,7 +808,6 @@
/// Concrete shadow object representing an integer literal in kernel form.
class IntJudgment extends IntLiteral implements ExpressionJudgment {
- DartType inferredType;
final String literal;
IntJudgment(int value, this.literal) : super(value);
@@ -916,8 +831,6 @@
final int fileOffset;
bool isParenthesized = false;
- DartType inferredType;
-
ShadowLargeIntLiteral(this.literal, this.fileOffset) : super(0);
double asDouble({bool negated: false}) {
@@ -965,86 +878,21 @@
value?.parent = this;
}
- Expression get judgment => value;
-
@override
void acceptInference(InferenceVisitor visitor) {
return visitor.visitShadowInvalidFieldInitializer(this);
}
}
-/// Type inference derivation for [ListLiteral].
-class ListLiteralJudgment extends ListLiteral implements ExpressionJudgment {
- DartType inferredType;
-
- ListLiteralJudgment(List<Expression> expressions,
- {DartType typeArgument, bool isConst: false})
- : assert(typeArgument != null),
- super(expressions, typeArgument: typeArgument, isConst: isConst);
-
- @override
- ExpressionInferenceResult acceptInference(
- InferenceVisitor visitor, DartType typeContext) {
- return visitor.visitListLiteralJudgment(this, typeContext);
- }
-}
-
-/// Type inference derivation for [SetLiteral].
-class SetLiteralJudgment extends SetLiteral implements ExpressionJudgment {
- DartType inferredType;
-
- SetLiteralJudgment(List<Expression> expressions,
- {DartType typeArgument, bool isConst: false})
- : assert(typeArgument != null),
- super(expressions, typeArgument: typeArgument, isConst: isConst);
-
- @override
- ExpressionInferenceResult acceptInference(
- InferenceVisitor visitor, DartType typeContext) {
- return visitor.visitSetLiteralJudgment(this, typeContext);
- }
-}
-
-/// Type inference derivation for [MapLiteral].
-class MapLiteralJudgment extends MapLiteral implements ExpressionJudgment {
- DartType inferredType;
-
- MapLiteralJudgment(List<MapEntry> judgments,
- {DartType keyType, DartType valueType, bool isConst: false})
- : assert(keyType != null),
- assert(valueType != null),
- super(judgments,
- keyType: keyType, valueType: valueType, isConst: isConst);
-
- @override
- ExpressionInferenceResult acceptInference(
- InferenceVisitor visitor, DartType typeContext) {
- return visitor.visitMapLiteralJudgment(this, typeContext);
- }
-}
-
-/// Shadow object for [MethodInvocation].
-class MethodInvocationJudgment extends MethodInvocation
- implements ExpressionJudgment {
- DartType inferredType;
-
+/// Front end specific implementation of [MethodInvocation].
+class MethodInvocationImpl extends MethodInvocation {
/// Indicates whether this method invocation is a call to a `call` method
/// resulting from the invocation of a function expression.
- final bool _isImplicitCall;
+ final bool isImplicitCall;
- MethodInvocationJudgment(
- Expression receiver, Name name, ArgumentsJudgment arguments,
- {bool isImplicitCall: false, Member interfaceTarget})
- : _isImplicitCall = isImplicitCall,
- super(receiver, name, arguments, interfaceTarget);
-
- ArgumentsJudgment get argumentJudgments => arguments;
-
- @override
- ExpressionInferenceResult acceptInference(
- InferenceVisitor visitor, DartType typeContext) {
- return visitor.visitMethodInvocationJudgment(this, typeContext);
- }
+ MethodInvocationImpl(Expression receiver, Name name, ArgumentsImpl arguments,
+ {this.isImplicitCall: false, Member interfaceTarget})
+ : super(receiver, name, arguments, interfaceTarget);
}
/// Concrete shadow object representing a named function expression.
@@ -1058,13 +906,9 @@
/// let f = () { ... } in f
class NamedFunctionExpressionJudgment extends Let
implements ExpressionJudgment {
- DartType inferredType;
-
- NamedFunctionExpressionJudgment(VariableDeclarationJudgment variable)
+ NamedFunctionExpressionJudgment(VariableDeclarationImpl variable)
: super(variable, new VariableGet(variable));
- VariableDeclarationJudgment get variableJudgment => variable;
-
@override
ExpressionInferenceResult acceptInference(
InferenceVisitor visitor, DartType typeContext) {
@@ -1072,56 +916,126 @@
}
}
-/// Concrete shadow object representing a null-aware method invocation.
+/// Internal expression representing a null-aware method invocation.
///
-/// A null-aware method invocation of the form `a?.b(...)` is represented as the
-/// expression:
+/// A null-aware method invocation of the form `a?.b(...)` is encoded as:
///
/// let v = a in v == null ? null : v.b(...)
-class NullAwareMethodInvocationJudgment extends Let
- implements ExpressionJudgment {
- DartType inferredType;
+///
+class NullAwareMethodInvocation extends InternalExpression {
+ /// The synthetic variable whose initializer hold the receiver.
+ VariableDeclaration variable;
- NullAwareMethodInvocationJudgment(
- VariableDeclaration variable, Expression body)
- : super(variable, body);
+ /// The expression that invokes the method on [variable].
+ Expression invocation;
+
+ NullAwareMethodInvocation(this.variable, this.invocation) {
+ variable?.parent = this;
+ invocation?.parent = this;
+ }
@override
- ConditionalExpression get body => super.body;
-
- MethodInvocation get _desugaredInvocation => body.otherwise;
+ InternalExpressionKind get kind =>
+ InternalExpressionKind.NullAwareMethodInvocation;
@override
- ExpressionInferenceResult acceptInference(
- InferenceVisitor visitor, DartType typeContext) {
- return visitor.visitNullAwareMethodInvocationJudgment(this, typeContext);
+ void visitChildren(Visitor<dynamic> v) {
+ variable?.accept(v);
+ invocation?.accept(v);
+ }
+
+ @override
+ transformChildren(Transformer v) {
+ if (variable != null) {
+ variable = variable.accept<TreeNode>(v);
+ variable?.parent = this;
+ }
+ if (invocation != null) {
+ invocation = invocation.accept<TreeNode>(v);
+ invocation?.parent = this;
+ }
}
}
-/// Concrete shadow object representing a null-aware read from a property.
+/// Internal expression representing a null-aware read from a property.
///
-/// A null-aware property get of the form `a?.b` is represented as the kernel
-/// expression:
+/// A null-aware property get of the form `a?.b` is encoded as:
///
/// let v = a in v == null ? null : v.b
-class NullAwarePropertyGetJudgment extends Let implements ExpressionJudgment {
- DartType inferredType;
+///
+class NullAwarePropertyGet extends InternalExpression {
+ /// The synthetic variable whose initializer hold the receiver.
+ VariableDeclaration variable;
- NullAwarePropertyGetJudgment(
- VariableDeclaration variable, ConditionalExpression body)
- : super(variable, body);
+ /// The expression that reads the property from [variable].
+ Expression read;
+
+ NullAwarePropertyGet(this.variable, this.read) {
+ variable?.parent = this;
+ read?.parent = this;
+ }
@override
- ConditionalExpression get body => super.body;
-
- PropertyGet get _desugaredGet => body.otherwise;
-
- Expression get receiverJudgment => variable.initializer;
+ InternalExpressionKind get kind =>
+ InternalExpressionKind.NullAwarePropertyGet;
@override
- ExpressionInferenceResult acceptInference(
- InferenceVisitor visitor, DartType typeContext) {
- return visitor.visitNullAwarePropertyGetJudgment(this, typeContext);
+ void visitChildren(Visitor<dynamic> v) {
+ variable?.accept(v);
+ read?.accept(v);
+ }
+
+ @override
+ transformChildren(Transformer v) {
+ if (variable != null) {
+ variable = variable.accept<TreeNode>(v);
+ variable?.parent = this;
+ }
+ if (read != null) {
+ read = read.accept<TreeNode>(v);
+ read?.parent = this;
+ }
+ }
+}
+
+/// Internal expression representing a null-aware read from a property.
+///
+/// A null-aware property get of the form `a?.b = c` is encoded as:
+///
+/// let v = a in v == null ? null : v.b = c
+///
+class NullAwarePropertySet extends InternalExpression {
+ /// The synthetic variable whose initializer hold the receiver.
+ VariableDeclaration variable;
+
+ /// The expression that writes the value to the property in [variable].
+ Expression write;
+
+ NullAwarePropertySet(this.variable, this.write) {
+ variable?.parent = this;
+ write?.parent = this;
+ }
+
+ @override
+ InternalExpressionKind get kind =>
+ InternalExpressionKind.NullAwarePropertySet;
+
+ @override
+ void visitChildren(Visitor<dynamic> v) {
+ variable?.accept(v);
+ write?.accept(v);
+ }
+
+ @override
+ transformChildren(Transformer v) {
+ if (variable != null) {
+ variable = variable.accept<TreeNode>(v);
+ variable?.parent = this;
+ }
+ if (write != null) {
+ write = write.accept<TreeNode>(v);
+ write?.parent = this;
+ }
}
}
@@ -1154,42 +1068,12 @@
}
}
-/// Concrete shadow object representing a redirecting initializer in kernel
-/// form.
-class RedirectingInitializerJudgment extends RedirectingInitializer
- implements InitializerJudgment {
- RedirectingInitializerJudgment(
- Constructor target, ArgumentsJudgment arguments)
- : super(target, arguments);
-
- ArgumentsJudgment get argumentJudgments => arguments;
-
- @override
- void acceptInference(InferenceVisitor visitor) {
- return visitor.visitRedirectingInitializerJudgment(this);
- }
-}
-
-/// Concrete shadow object representing a return statement in kernel form.
-class ReturnJudgment extends ReturnStatement implements StatementJudgment {
+/// Front end specific implementation of [ReturnStatement].
+class ReturnStatementImpl extends ReturnStatement {
final bool isArrow;
- ReturnJudgment(this.isArrow, [Expression expression]) : super(expression);
-
- Expression get judgment => expression;
-
- @override
- void acceptInference(InferenceVisitor visitor) {
- return visitor.visitReturnJudgment(this);
- }
-}
-
-/// Common base class for shadow objects representing statements in kernel
-/// form.
-abstract class StatementJudgment extends Statement {
- /// Calls back to [inferrer] to perform type inference for whatever concrete
- /// type of [StatementJudgment] this is.
- void acceptInference(InferenceVisitor visitor);
+ ReturnStatementImpl(this.isArrow, [Expression expression])
+ : super(expression);
}
/// Concrete shadow object representing an assignment to a static variable.
@@ -1203,97 +1087,6 @@
}
}
-/// Concrete shadow object representing a super initializer in kernel form.
-class SuperInitializerJudgment extends SuperInitializer
- implements InitializerJudgment {
- SuperInitializerJudgment(Constructor target, ArgumentsJudgment arguments)
- : super(target, arguments);
-
- ArgumentsJudgment get argumentJudgments => arguments;
-
- @override
- void acceptInference(InferenceVisitor visitor) {
- return visitor.visitSuperInitializerJudgment(this);
- }
-}
-
-/// Shadow object for [SuperMethodInvocation].
-class SuperMethodInvocationJudgment extends SuperMethodInvocation
- implements ExpressionJudgment {
- DartType inferredType;
-
- SuperMethodInvocationJudgment(Name name, ArgumentsJudgment arguments,
- {Procedure interfaceTarget})
- : super(name, arguments, interfaceTarget);
-
- ArgumentsJudgment get argumentJudgments => arguments;
-
- @override
- ExpressionInferenceResult acceptInference(
- InferenceVisitor visitor, DartType typeContext) {
- return visitor.visitSuperMethodInvocationJudgment(this, typeContext);
- }
-}
-
-/// Shadow object for [SuperPropertyGet].
-class SuperPropertyGetJudgment extends SuperPropertyGet
- implements ExpressionJudgment {
- DartType inferredType;
-
- SuperPropertyGetJudgment(Name name, {Member interfaceTarget})
- : super(name, interfaceTarget);
-
- @override
- ExpressionInferenceResult acceptInference(
- InferenceVisitor visitor, DartType typeContext) {
- return visitor.visitSuperPropertyGetJudgment(this, typeContext);
- }
-}
-
-/// Concrete shadow object representing a switch case.
-class SwitchCaseJudgment extends SwitchCase {
- SwitchCaseJudgment(
- List<Expression> expressions, List<int> expressionOffsets, Statement body,
- {bool isDefault: false})
- : super(expressions, expressionOffsets, body, isDefault: isDefault);
-
- SwitchCaseJudgment.defaultCase(Statement body) : super.defaultCase(body);
-
- SwitchCaseJudgment.empty() : super.empty();
-
- List<Expression> get expressionJudgments => expressions.cast();
-}
-
-/// Concrete shadow object representing a switch statement in kernel form.
-class SwitchStatementJudgment extends SwitchStatement
- implements StatementJudgment {
- SwitchStatementJudgment(Expression expression, List<SwitchCase> cases)
- : super(expression, cases);
-
- Expression get expressionJudgment => expression;
-
- List<SwitchCaseJudgment> get caseJudgments => cases.cast();
-
- @override
- void acceptInference(InferenceVisitor visitor) {
- return visitor.visitSwitchStatementJudgment(this);
- }
-}
-
-/// Shadow object for [SymbolLiteral].
-class SymbolLiteralJudgment extends SymbolLiteral
- implements ExpressionJudgment {
- DartType inferredType;
-
- SymbolLiteralJudgment(String value) : super(value);
-
- @override
- ExpressionInferenceResult acceptInference(
- InferenceVisitor visitor, DartType typeContext) {
- return visitor.visitSymbolLiteralJudgment(this, typeContext);
- }
-}
-
/// Synthetic judgment class representing an attempt to invoke an unresolved
/// constructor, or a constructor that cannot be invoked, or a resolved
/// constructor with wrong number of arguments.
@@ -1303,11 +1096,9 @@
final Arguments arguments;
InvalidConstructorInvocationJudgment._(
- kernel.Expression desugared, this.constructor, this.arguments)
+ Expression desugared, this.constructor, this.arguments)
: super._(desugared);
- ArgumentsJudgment get argumentJudgments => arguments;
-
@override
ExpressionInferenceResult acceptInference(
InferenceVisitor visitor, DartType typeContext) {
@@ -1320,7 +1111,7 @@
class InvalidWriteJudgment extends SyntheticExpressionJudgment {
final Expression expression;
- InvalidWriteJudgment._(kernel.Expression desugared, this.expression)
+ InvalidWriteJudgment._(Expression desugared, this.expression)
: super._(desugared);
@override
@@ -1336,8 +1127,6 @@
/// These expressions are removed by type inference and replaced with their
/// desugared equivalents.
class SyntheticExpressionJudgment extends Let implements ExpressionJudgment {
- DartType inferredType;
-
SyntheticExpressionJudgment._(Expression desugared)
: super(new VariableDeclaration('_', initializer: new NullLiteral()),
desugared);
@@ -1359,9 +1148,16 @@
/// Removes this expression from the expression tree, replacing it with
/// [desugared].
Expression _replaceWithDesugared() {
- parent.replaceChild(this, desugared);
+ Expression replacement = desugared;
+ if (replacement is InternalExpression) {
+ // This is needed because some (StaticAssignmentJudgment at least) do
+ // not visit their desugared expression during inference.
+ InternalExpression internalExpression = replacement;
+ replacement = internalExpression.replace();
+ }
+ parent.replaceChild(this, replacement);
parent = null;
- return desugared;
+ return replacement;
}
/// Updates any [Let] nodes in the desugared expression to account for the
@@ -1400,51 +1196,17 @@
// lead to exceptions during transformations, but we have to accept a
// [Transformer] as this is used to implement `replaceChild`.
if (v is Transformer) return super.accept(v);
- throw unsupported("accept", fileOffset, getFileUri(this));
+ throw unsupported("${runtimeType}.accept", fileOffset, getFileUri(this));
}
@override
R accept1<R, A>(ExpressionVisitor1<R, A> v, A arg) {
- throw unsupported("accept1", fileOffset, getFileUri(this));
+ throw unsupported("${runtimeType}.accept1", fileOffset, getFileUri(this));
}
@override
visitChildren(Visitor<dynamic> v) {
- unsupported("visitChildren", fileOffset, getFileUri(this));
- }
-}
-
-/// Concrete shadow object representing a catch clause.
-class CatchJudgment extends Catch {
- CatchJudgment(VariableDeclaration exception, Statement body,
- {DartType guard: const DynamicType(), VariableDeclaration stackTrace})
- : super(exception, body, guard: guard, stackTrace: stackTrace);
-
- VariableDeclarationJudgment get exceptionJudgment => exception;
-
- VariableDeclarationJudgment get stackTraceJudgment => stackTrace;
-}
-
-/// Concrete shadow object representing a try-catch block in kernel form.
-class TryCatchJudgment extends TryCatch implements StatementJudgment {
- TryCatchJudgment(Statement body, List<Catch> catches) : super(body, catches);
-
- List<CatchJudgment> get catchJudgments => catches.cast();
-
- @override
- void acceptInference(InferenceVisitor visitor) {
- return visitor.visitTryCatchJudgment(this);
- }
-}
-
-/// Concrete shadow object representing a try-finally block in kernel form.
-class TryFinallyJudgment extends TryFinally implements StatementJudgment {
- TryFinallyJudgment(Statement body, Statement finalizer)
- : super(body, finalizer);
-
- @override
- void acceptInference(InferenceVisitor visitor) {
- return visitor.visitTryFinallyJudgment(this);
+ unsupported("${runtimeType}.visitChildren", fileOffset, getFileUri(this));
}
}
@@ -1485,7 +1247,7 @@
@override
ExpressionInferenceResult inferExpression(
- kernel.Expression expression, DartType typeContext, bool typeNeeded,
+ Expression expression, DartType typeContext, bool typeNeeded,
{bool isVoidAllowed: false}) {
// `null` should never be used as the type context. An instance of
// `UnknownType` should be used instead.
@@ -1515,7 +1277,7 @@
DartType inferredType = result.inferredType;
assert(inferredType != null, "No type inferred for $expression.");
if (inferredType is VoidType && !isVoidAllowed) {
- if (expression.parent is! ArgumentsJudgment) {
+ if (expression.parent is! ArgumentsImpl) {
helper?.addProblem(
messageVoidExpression, expression.fileOffset, noLength);
}
@@ -1524,17 +1286,18 @@
}
@override
- void inferInitializer(
- InferenceHelper helper, kernel.Initializer initializer) {
- assert(initializer is InitializerJudgment);
+ void inferInitializer(InferenceHelper helper, Initializer initializer) {
this.helper = helper;
// Use polymorphic dispatch on [KernelInitializer] to perform whatever
// kind of type inference is correct for this kind of initializer.
// TODO(paulberry): experiment to see if dynamic dispatch would be better,
// so that the type hierarchy will be simpler (which may speed up "is"
// checks).
- InitializerJudgment kernelInitializer = initializer;
- kernelInitializer.acceptInference(new InferenceVisitor(this));
+ if (initializer is InitializerJudgment) {
+ initializer.acceptInference(new InferenceVisitor(this));
+ } else {
+ initializer.accept(new InferenceVisitor(this));
+ }
this.helper = null;
}
@@ -1543,41 +1306,12 @@
// For full (non-top level) inference, we need access to the
// ExpressionGeneratorHelper so that we can perform error recovery.
if (!isTopLevel) assert(helper != null);
-
- if (statement is StatementJudgment) {
- // Use polymorphic dispatch on [KernelStatement] to perform whatever kind
- // of type inference is correct for this kind of statement.
- // TODO(paulberry): experiment to see if dynamic dispatch would be better,
- // so that the type hierarchy will be simpler (which may speed up "is"
- // checks).
- return statement.acceptInference(new InferenceVisitor(this));
- } else if (statement is ForInStatement) {
- return statement.accept1(new InferenceVisitor(this), null);
- } else if (statement is LabeledStatement) {
- return statement.accept1(new InferenceVisitor(this), null);
- } else if (statement is BreakStatement) {
- return statement.accept1(new InferenceVisitor(this), null);
- } else {
- // Encountered a statement type for which type inference is not yet
- // implemented, so just skip it for now.
- // TODO(paulberry): once the BodyBuilder uses shadow classes for
- // everything, this case should no longer be needed.
+ if (statement != null) {
+ statement.accept(new InferenceVisitor(this));
}
}
}
-class TypeLiteralJudgment extends TypeLiteral implements ExpressionJudgment {
- DartType inferredType;
-
- TypeLiteralJudgment(DartType type) : super(type);
-
- @override
- ExpressionInferenceResult acceptInference(
- InferenceVisitor visitor, DartType typeContext) {
- return visitor.visitTypeLiteralJudgment(this, typeContext);
- }
-}
-
/// Concrete implementation of [TypePromoter] specialized to work with kernel
/// objects.
class ShadowTypePromoter extends TypePromoterImpl {
@@ -1586,7 +1320,7 @@
@override
int getVariableFunctionNestingLevel(VariableDeclaration variable) {
- if (variable is VariableDeclarationJudgment) {
+ if (variable is VariableDeclarationImpl) {
return variable._functionNestingLevel;
} else {
// Hack to deal with the fact that BodyBuilder still creates raw
@@ -1599,8 +1333,8 @@
@override
bool isPromotionCandidate(VariableDeclaration variable) {
- assert(variable is VariableDeclarationJudgment);
- VariableDeclarationJudgment kernelVariableDeclaration = variable;
+ assert(variable is VariableDeclarationImpl);
+ VariableDeclarationImpl kernelVariableDeclaration = variable;
return !kernelVariableDeclaration._isLocalFunction;
}
@@ -1611,7 +1345,7 @@
@override
void setVariableMutatedAnywhere(VariableDeclaration variable) {
- if (variable is VariableDeclarationJudgment) {
+ if (variable is VariableDeclarationImpl) {
variable._mutatedAnywhere = true;
} else {
// Hack to deal with the fact that BodyBuilder still creates raw
@@ -1623,7 +1357,7 @@
@override
void setVariableMutatedInClosure(VariableDeclaration variable) {
- if (variable is VariableDeclarationJudgment) {
+ if (variable is VariableDeclarationImpl) {
variable._mutatedInClosure = true;
} else {
// Hack to deal with the fact that BodyBuilder still creates raw
@@ -1635,7 +1369,7 @@
@override
bool wasVariableMutatedAnywhere(VariableDeclaration variable) {
- if (variable is VariableDeclarationJudgment) {
+ if (variable is VariableDeclarationImpl) {
return variable._mutatedAnywhere;
} else {
// Hack to deal with the fact that BodyBuilder still creates raw
@@ -1657,9 +1391,8 @@
}
}
-/// Concrete shadow object representing a variable declaration in kernel form.
-class VariableDeclarationJudgment extends VariableDeclaration
- implements StatementJudgment {
+/// Front end specific implementation of [VariableDeclaration].
+class VariableDeclarationImpl extends VariableDeclaration {
final bool forSyntheticToken;
final bool _implicitlyTyped;
@@ -1680,7 +1413,7 @@
// TODO(ahe): Investigate if this can be removed.
final bool _isLocalFunction;
- VariableDeclarationJudgment(String name, this._functionNestingLevel,
+ VariableDeclarationImpl(String name, this._functionNestingLevel,
{this.forSyntheticToken: false,
Expression initializer,
DartType type,
@@ -1703,51 +1436,44 @@
isLate: isLate,
isRequired: isRequired);
- VariableDeclarationJudgment.forEffect(
- Expression initializer, this._functionNestingLevel)
+ VariableDeclarationImpl.forEffect(Expression initializer)
: forSyntheticToken = false,
+ _functionNestingLevel = 0,
_implicitlyTyped = false,
_isLocalFunction = false,
super.forValue(initializer);
- VariableDeclarationJudgment.forValue(Expression initializer)
+ VariableDeclarationImpl.forValue(Expression initializer)
: forSyntheticToken = false,
_functionNestingLevel = 0,
_implicitlyTyped = true,
_isLocalFunction = false,
super.forValue(initializer);
- Expression get initializerJudgment => initializer;
-
- @override
- void acceptInference(InferenceVisitor visitor) {
- return visitor.visitVariableDeclarationJudgment(this);
- }
-
- /// Determine whether the given [VariableDeclarationJudgment] had an implicit
+ /// Determine whether the given [VariableDeclarationImpl] had an implicit
/// type.
///
/// This is static to avoid introducing a method that would be visible to
/// the kernel.
- static bool isImplicitlyTyped(VariableDeclarationJudgment variable) =>
+ static bool isImplicitlyTyped(VariableDeclarationImpl variable) =>
variable._implicitlyTyped;
- /// Determines whether the given [VariableDeclarationJudgment] represents a
+ /// Determines whether the given [VariableDeclarationImpl] represents a
/// local function.
///
/// This is static to avoid introducing a method that would be visible to the
/// kernel.
- static bool isLocalFunction(VariableDeclarationJudgment variable) =>
+ static bool isLocalFunction(VariableDeclarationImpl variable) =>
variable._isLocalFunction;
}
/// Synthetic judgment class representing an attempt to invoke an unresolved
/// target.
class UnresolvedTargetInvocationJudgment extends SyntheticExpressionJudgment {
- final ArgumentsJudgment argumentsJudgment;
+ final ArgumentsImpl argumentsJudgment;
UnresolvedTargetInvocationJudgment._(
- kernel.Expression desugared, this.argumentsJudgment)
+ Expression desugared, this.argumentsJudgment)
: super._(desugared);
@override
@@ -1764,7 +1490,7 @@
final Expression rhs;
UnresolvedVariableAssignmentJudgment._(
- kernel.Expression desugared, this.isCompound, this.rhs)
+ Expression desugared, this.isCompound, this.rhs)
: super._(desugared);
@override
@@ -1774,79 +1500,55 @@
}
}
-/// Concrete shadow object representing a read from a variable in kernel form.
-class VariableGetJudgment extends VariableGet implements ExpressionJudgment {
- DartType inferredType;
-
+/// Front end specific implementation of [VariableGet].
+class VariableGetImpl extends VariableGet {
final TypePromotionFact _fact;
final TypePromotionScope _scope;
- VariableGetJudgment(VariableDeclaration variable, this._fact, this._scope)
+ VariableGetImpl(VariableDeclaration variable, this._fact, this._scope)
: super(variable);
-
- @override
- ExpressionInferenceResult acceptInference(
- InferenceVisitor visitor, DartType typeContext) {
- return visitor.visitVariableGetJudgment(this, typeContext);
- }
}
-/// Concrete shadow object representing a while loop in kernel form.
-class WhileJudgment extends WhileStatement implements StatementJudgment {
- WhileJudgment(Expression condition, Statement body) : super(condition, body);
-
- Expression get conditionJudgment => condition;
-
- @override
- void acceptInference(InferenceVisitor visitor) {
- return visitor.visitWhileJudgment(this);
- }
-}
-
-/// Concrete shadow object representing a yield statement in kernel form.
-class YieldJudgment extends YieldStatement implements StatementJudgment {
- YieldJudgment(bool isYieldStar, Expression expression)
- : super(expression, isYieldStar: isYieldStar);
-
- Expression get judgment => expression;
-
- @override
- void acceptInference(InferenceVisitor visitor) {
- return visitor.visitYieldJudgment(this);
- }
-}
-
-/// Concrete shadow object representing a deferred load library call.
-class LoadLibraryJudgment extends LoadLibrary implements ExpressionJudgment {
+/// Front end specific implementation of [LoadLibrary].
+class LoadLibraryImpl extends LoadLibrary {
final Arguments arguments;
- DartType inferredType;
-
- LoadLibraryJudgment(LibraryDependency import, this.arguments) : super(import);
-
- ArgumentsJudgment get argumentJudgments => arguments;
-
- @override
- ExpressionInferenceResult acceptInference(
- InferenceVisitor visitor, DartType typeContext) {
- return visitor.visitLoadLibraryJudgment(this, typeContext);
- }
+ LoadLibraryImpl(LibraryDependency import, this.arguments) : super(import);
}
-/// Concrete shadow object representing a tear-off of a `loadLibrary` function.
-class LoadLibraryTearOffJudgment extends StaticGet
- implements ExpressionJudgment {
- final LibraryDependency import;
+/// Internal expression representing a tear-off of a `loadLibrary` function.
+class LoadLibraryTearOff extends InternalExpression {
+ LibraryDependency import;
+ Procedure target;
- DartType inferredType;
-
- LoadLibraryTearOffJudgment(this.import, Procedure target) : super(target);
+ LoadLibraryTearOff(this.import, this.target);
@override
- ExpressionInferenceResult acceptInference(
- InferenceVisitor visitor, DartType typeContext) {
- return visitor.visitLoadLibraryTearOffJudgment(this, typeContext);
+ InternalExpressionKind get kind => InternalExpressionKind.LoadLibraryTearOff;
+
+ @override
+ Expression replace() {
+ Expression replacement;
+ parent.replaceChild(
+ this, replacement = new StaticGet(target)..fileOffset = fileOffset);
+ return replacement;
+ }
+
+ @override
+ void visitChildren(Visitor<dynamic> v) {
+ import?.accept(v);
+ target?.accept(v);
+ }
+
+ @override
+ void transformChildren(Transformer v) {
+ if (import != null) {
+ import = import.accept<TreeNode>(v);
+ }
+ if (target != null) {
+ target = target.accept<TreeNode>(v);
+ }
}
}
@@ -1867,11 +1569,11 @@
R accept1<R, A>(v, arg) => unsupported("accept1", -1, null);
- getStaticType(types) => unsupported("getStaticType", -1, null);
+ DartType getStaticType(types) => unsupported("getStaticType", -1, null);
- transformChildren(v) => unsupported("transformChildren", -1, null);
+ void transformChildren(v) => unsupported("transformChildren", -1, null);
- visitChildren(v) => unsupported("visitChildren", -1, null);
+ void visitChildren(v) => unsupported("visitChildren", -1, null);
}
class SyntheticWrapper {
@@ -1890,7 +1592,7 @@
}
static Expression wrapInvalidConstructorInvocation(
- kernel.Expression desugared, Member constructor, Arguments arguments) {
+ Expression desugared, Member constructor, Arguments arguments) {
return new InvalidConstructorInvocationJudgment._(
desugared, constructor, arguments)
..fileOffset = desugared.fileOffset;
@@ -1934,3 +1636,620 @@
return new VariableAssignmentJudgment._(rhs)..fileOffset = rhs.fileOffset;
}
}
+
+/// Internal expression representing an if-null property set.
+///
+/// An if-null property set of the form `o.a ??= b` is, if used for value,
+/// encoded as the expression:
+///
+/// let v1 = o in let v2 = v1.a in v2 == null ? v1.a = b : v2
+///
+/// and, if used for effect, encoded as the expression:
+///
+/// let v1 = o in v1.a == null ? v1.a = b : null
+///
+class IfNullPropertySet extends InternalExpression {
+ /// The synthetic variable whose initializer hold the receiver.
+ VariableDeclaration variable;
+
+ /// The expression that reads the property from [variable].
+ Expression read;
+
+ /// The expression that writes the value to the property on [variable].
+ Expression write;
+
+ /// If `true`, the expression is only need for effect and not for its value.
+ final bool forEffect;
+
+ IfNullPropertySet(this.variable, this.read, this.write, {this.forEffect})
+ : assert(forEffect != null) {
+ variable?.parent = this;
+ read?.parent = this;
+ write?.parent = this;
+ }
+
+ @override
+ InternalExpressionKind get kind => InternalExpressionKind.IfNullPropertySet;
+
+ @override
+ void visitChildren(Visitor<dynamic> v) {
+ variable?.accept(v);
+ read?.accept(v);
+ write?.accept(v);
+ }
+
+ @override
+ void transformChildren(Transformer v) {
+ if (variable != null) {
+ variable = variable.accept<TreeNode>(v);
+ variable?.parent = this;
+ }
+ if (read != null) {
+ read = read.accept<TreeNode>(v);
+ read?.parent = this;
+ }
+ if (write != null) {
+ write = write.accept<TreeNode>(v);
+ write?.parent = this;
+ }
+ }
+}
+
+/// Internal expression representing an if-null assignment.
+///
+/// An if-null assignment of the form `a ??= b` is, if used for value,
+/// encoded as the expression:
+///
+/// let v1 = a in v1 == null ? a = b : v1
+///
+/// and, if used for effect, encoded as the expression:
+///
+/// a == null ? a = b : null
+///
+class IfNullSet extends InternalExpression {
+ /// The expression that reads the property from [variable].
+ Expression read;
+
+ /// The expression that writes the value to the property on [variable].
+ Expression write;
+
+ /// If `true`, the expression is only need for effect and not for its value.
+ final bool forEffect;
+
+ IfNullSet(this.read, this.write, {this.forEffect})
+ : assert(forEffect != null) {
+ read?.parent = this;
+ write?.parent = this;
+ }
+
+ @override
+ InternalExpressionKind get kind => InternalExpressionKind.IfNullSet;
+
+ @override
+ void visitChildren(Visitor<dynamic> v) {
+ read?.accept(v);
+ write?.accept(v);
+ }
+
+ @override
+ void transformChildren(Transformer v) {
+ if (read != null) {
+ read = read.accept<TreeNode>(v);
+ read?.parent = this;
+ }
+ if (write != null) {
+ write = write.accept<TreeNode>(v);
+ write?.parent = this;
+ }
+ }
+}
+
+/// Internal expression representing an compound property assignment.
+///
+/// An compound property assignment of the form `o.a += b` is encoded as the
+/// expression:
+///
+/// let v1 = o in v1.a = v1.a + b
+///
+class CompoundPropertySet extends InternalExpression {
+ /// The synthetic variable whose initializer hold the receiver.
+ VariableDeclaration variable;
+
+ /// The expression that writes the result of the binary operation to the
+ /// property on [variable].
+ Expression write;
+
+ CompoundPropertySet(this.variable, this.write) {
+ variable?.parent = this;
+ write?.parent = this;
+ }
+
+ @override
+ InternalExpressionKind get kind => InternalExpressionKind.CompoundPropertySet;
+
+ @override
+ Expression replace() {
+ Expression replacement;
+ replaceWith(
+ replacement = new Let(variable, write)..fileOffset = fileOffset);
+ return replacement;
+ }
+
+ @override
+ void visitChildren(Visitor<dynamic> v) {
+ variable?.accept(v);
+ write?.accept(v);
+ }
+
+ @override
+ void transformChildren(Transformer v) {
+ if (variable != null) {
+ variable = variable.accept<TreeNode>(v);
+ variable?.parent = this;
+ }
+ if (write != null) {
+ write = write.accept<TreeNode>(v);
+ write?.parent = this;
+ }
+ }
+}
+
+/// Internal expression representing an compound property assignment.
+///
+/// An compound property assignment of the form `o.a++` is encoded as the
+/// expression:
+///
+/// let v1 = o in let v2 = v1.a in let v3 = v1.a = v2 + 1 in v2
+///
+class PropertyPostIncDec extends InternalExpression {
+ /// The synthetic variable whose initializer hold the receiver.
+ VariableDeclaration variable;
+
+ /// The expression that reads the property on [variable].
+ VariableDeclaration read;
+
+ /// The expression that writes the result of the binary operation to the
+ /// property on [variable].
+ VariableDeclaration write;
+
+ PropertyPostIncDec(this.variable, this.read, this.write) {
+ variable?.parent = this;
+ read?.parent = this;
+ write?.parent = this;
+ }
+
+ @override
+ InternalExpressionKind get kind => InternalExpressionKind.PropertyPostIncDec;
+
+ @override
+ Expression replace() {
+ Expression replacement;
+ replaceWith(replacement = new Let(
+ variable, createLet(read, createLet(write, createVariableGet(read))))
+ ..fileOffset = fileOffset);
+ return replacement;
+ }
+
+ @override
+ void visitChildren(Visitor<dynamic> v) {
+ variable?.accept(v);
+ read?.accept(v);
+ write?.accept(v);
+ }
+
+ @override
+ void transformChildren(Transformer v) {
+ if (variable != null) {
+ variable = variable.accept<TreeNode>(v);
+ variable?.parent = this;
+ }
+ if (write != null) {
+ write = write.accept<TreeNode>(v);
+ write?.parent = this;
+ }
+ }
+}
+
+/// Internal expression representing an local variable post inc/dec expression.
+///
+/// An local variable post inc/dec expression of the form `a++` is encoded as
+/// the expression:
+///
+/// let v1 = a in let v2 = a = v1 + 1 in v1
+///
+class LocalPostIncDec extends InternalExpression {
+ /// The expression that reads the local variable.
+ VariableDeclaration read;
+
+ /// The expression that writes the result of the binary operation to the
+ /// local variable.
+ VariableDeclaration write;
+
+ LocalPostIncDec(this.read, this.write) {
+ read?.parent = this;
+ write?.parent = this;
+ }
+
+ @override
+ InternalExpressionKind get kind => InternalExpressionKind.LocalPostIncDec;
+
+ @override
+ Expression replace() {
+ Expression replacement;
+ replaceWith(
+ replacement = new Let(read, createLet(write, createVariableGet(read)))
+ ..fileOffset = fileOffset);
+ return replacement;
+ }
+
+ @override
+ void visitChildren(Visitor<dynamic> v) {
+ read?.accept(v);
+ write?.accept(v);
+ }
+
+ @override
+ void transformChildren(Transformer v) {
+ if (read != null) {
+ read = read.accept<TreeNode>(v);
+ read?.parent = this;
+ }
+ if (write != null) {
+ write = write.accept<TreeNode>(v);
+ write?.parent = this;
+ }
+ }
+}
+
+/// Internal expression representing an static member post inc/dec expression.
+///
+/// An local variable post inc/dec expression of the form `a++` is encoded as
+/// the expression:
+///
+/// let v1 = a in let v2 = a = v1 + 1 in v1
+///
+class StaticPostIncDec extends InternalExpression {
+ /// The expression that reads the static member.
+ VariableDeclaration read;
+
+ /// The expression that writes the result of the binary operation to the
+ /// static member.
+ VariableDeclaration write;
+
+ StaticPostIncDec(this.read, this.write) {
+ read?.parent = this;
+ write?.parent = this;
+ }
+
+ @override
+ InternalExpressionKind get kind => InternalExpressionKind.StaticPostIncDec;
+
+ @override
+ Expression replace() {
+ Expression replacement;
+ replaceWith(
+ replacement = new Let(read, createLet(write, createVariableGet(read)))
+ ..fileOffset = fileOffset);
+ return replacement;
+ }
+
+ @override
+ void visitChildren(Visitor<dynamic> v) {
+ read?.accept(v);
+ write?.accept(v);
+ }
+
+ @override
+ void transformChildren(Transformer v) {
+ if (read != null) {
+ read = read.accept<TreeNode>(v);
+ read?.parent = this;
+ }
+ if (write != null) {
+ write = write.accept<TreeNode>(v);
+ write?.parent = this;
+ }
+ }
+}
+
+/// Internal expression representing an static member post inc/dec expression.
+///
+/// An local variable post inc/dec expression of the form `super.a++` is encoded
+/// as the expression:
+///
+/// let v1 = super.a in let v2 = super.a = v1 + 1 in v1
+///
+class SuperPostIncDec extends InternalExpression {
+ /// The expression that reads the static member.
+ VariableDeclaration read;
+
+ /// The expression that writes the result of the binary operation to the
+ /// static member.
+ VariableDeclaration write;
+
+ SuperPostIncDec(this.read, this.write) {
+ read?.parent = this;
+ write?.parent = this;
+ }
+
+ @override
+ InternalExpressionKind get kind => InternalExpressionKind.SuperPostIncDec;
+
+ @override
+ Expression replace() {
+ Expression replacement;
+ replaceWith(
+ replacement = new Let(read, createLet(write, createVariableGet(read)))
+ ..fileOffset = fileOffset);
+ return replacement;
+ }
+
+ @override
+ void visitChildren(Visitor<dynamic> v) {
+ read?.accept(v);
+ write?.accept(v);
+ }
+
+ @override
+ void transformChildren(Transformer v) {
+ if (read != null) {
+ read = read.accept<TreeNode>(v);
+ read?.parent = this;
+ }
+ if (write != null) {
+ write = write.accept<TreeNode>(v);
+ write?.parent = this;
+ }
+ }
+}
+
+/// Internal expression representing an index set expression.
+///
+/// An index set expression of the form `o[a] = b` used for value is encoded as
+/// the expression:
+///
+/// let v1 = o in let v2 = a in let v3 = b in let _ = o.[]=(v2, v3) in v3
+///
+/// An index set expression used for effect is encoded as
+///
+/// o.[]=(a, b)
+///
+/// using [MethodInvocationImpl].
+///
+class IndexSet extends InternalExpression {
+ /// The receiver on which the index set operation is performed.
+ Expression receiver;
+
+ /// The index expression of the operation.
+ Expression index;
+
+ /// The value expression of the operation.
+ Expression value;
+
+ IndexSet(this.receiver, this.index, this.value) {
+ receiver?.parent = this;
+ index?.parent = this;
+ value?.parent = this;
+ }
+
+ @override
+ InternalExpressionKind get kind => InternalExpressionKind.IndexSet;
+
+ @override
+ void visitChildren(Visitor<dynamic> v) {
+ receiver?.accept(v);
+ index?.accept(v);
+ value?.accept(v);
+ }
+
+ @override
+ void transformChildren(Transformer v) {
+ if (receiver != null) {
+ receiver = receiver.accept<TreeNode>(v);
+ receiver?.parent = this;
+ }
+ if (index != null) {
+ index = index.accept<TreeNode>(v);
+ index?.parent = this;
+ }
+ if (value != null) {
+ value = value.accept<TreeNode>(v);
+ value?.parent = this;
+ }
+ }
+}
+
+/// Internal expression representing an if-null index assignment.
+///
+/// An if-null index assignment of the form `o[a] ??= b` is, if used for value,
+/// encoded as the expression:
+///
+/// let v1 = o in
+/// let v2 = a in
+/// let v3 = v1[v2] in
+/// v3 == null
+/// ? (let v4 = b in
+/// let _ = v1.[]=(v2, v4) in
+/// v4)
+/// : v3
+///
+/// and, if used for effect, encoded as the expression:
+///
+/// let v1 = o in
+/// let v2 = a in
+/// let v3 = v1[v2] in
+/// v3 == null ? v1.[]=(v2, b) : null
+///
+class IfNullIndexSet extends InternalExpression {
+ /// The receiver on which the index set operation is performed.
+ Expression receiver;
+
+ /// The index expression of the operation.
+ Expression index;
+
+ /// The value expression of the operation.
+ Expression value;
+
+ /// The file offset for the [] operation.
+ final int readOffset;
+
+ /// If `true`, the expression is only need for effect and not for its value.
+ final bool forEffect;
+
+ IfNullIndexSet(this.receiver, this.index, this.value, this.readOffset,
+ {this.forEffect})
+ : assert(forEffect != null) {
+ receiver?.parent = this;
+ index?.parent = this;
+ value?.parent = this;
+ }
+
+ @override
+ InternalExpressionKind get kind => InternalExpressionKind.IfNullIndexSet;
+
+ @override
+ void visitChildren(Visitor<dynamic> v) {
+ receiver?.accept(v);
+ index?.accept(v);
+ value?.accept(v);
+ }
+
+ @override
+ void transformChildren(Transformer v) {
+ if (receiver != null) {
+ receiver = receiver.accept<TreeNode>(v);
+ receiver?.parent = this;
+ }
+ if (index != null) {
+ index = index.accept<TreeNode>(v);
+ index?.parent = this;
+ }
+ if (value != null) {
+ value = value.accept<TreeNode>(v);
+ value?.parent = this;
+ }
+ }
+}
+
+/// Internal expression representing an if-null index assignment.
+///
+/// An if-null index assignment of the form `o[a] += b` is, if used for value,
+/// encoded as the expression:
+///
+/// let v1 = o in
+/// let v2 = a in
+/// let v3 = v1.[](v2) + b
+/// let v4 = v1.[]=(v2, c3) in v3
+///
+/// and, if used for effect, encoded as the expression:
+///
+/// let v1 = o in let v2 = a in v1.[]=(v2, v1.[](v2) + b)
+///
+class CompoundIndexSet extends InternalExpression {
+ /// The receiver on which the index set operation is performed.
+ Expression receiver;
+
+ /// The index expression of the operation.
+ Expression index;
+
+ /// The name of the binary operation.
+ Name binaryName;
+
+ /// The right-hand side of the binary expression.
+ Expression rhs;
+
+ /// The file offset for the [] operation.
+ final int readOffset;
+
+ /// The file offset for the []= operation.
+ final int writeOffset;
+
+ /// The file offset for the binary operation.
+ final int binaryOffset;
+
+ /// If `true`, the expression is only need for effect and not for its value.
+ final bool forEffect;
+
+ /// If `true`, the expression is a post-fix inc/dec expression.
+ final bool forPostIncDec;
+
+ CompoundIndexSet(this.receiver, this.index, this.binaryName, this.rhs,
+ {this.readOffset,
+ this.binaryOffset,
+ this.writeOffset,
+ this.forEffect,
+ this.forPostIncDec})
+ : assert(forEffect != null) {
+ receiver?.parent = this;
+ index?.parent = this;
+ rhs?.parent = this;
+ fileOffset = binaryOffset;
+ }
+
+ @override
+ InternalExpressionKind get kind => InternalExpressionKind.CompoundIndexSet;
+
+ @override
+ void visitChildren(Visitor<dynamic> v) {
+ receiver?.accept(v);
+ index?.accept(v);
+ rhs?.accept(v);
+ }
+
+ @override
+ void transformChildren(Transformer v) {
+ if (receiver != null) {
+ receiver = receiver.accept<TreeNode>(v);
+ receiver?.parent = this;
+ }
+ if (index != null) {
+ index = index.accept<TreeNode>(v);
+ index?.parent = this;
+ }
+ if (rhs != null) {
+ rhs = rhs.accept<TreeNode>(v);
+ rhs?.parent = this;
+ }
+ }
+}
+
+/// Creates a [Let] of [variable] with the given [body] using
+/// `variable.fileOffset` as the file offset for the let.
+///
+/// This is useful for create let expressions in replacement code.
+Let createLet(VariableDeclaration variable, Expression body) {
+ return new Let(variable, body)..fileOffset = variable.fileOffset;
+}
+
+/// Creates a [VariableDeclaration] for [expression] with the static [type]
+/// using `expression.fileOffset` as the file offset for the declaration.
+///
+/// This is useful for creating let variables for expressions in replacement
+/// code.
+VariableDeclaration createVariable(Expression expression, DartType type) {
+ return new VariableDeclaration.forValue(expression, type: type)
+ ..fileOffset = expression.fileOffset;
+}
+
+/// Creates a [VariableGet] of [variable] using `variable.fileOffset` as the
+/// file offset for the expression.
+///
+/// This is useful for referencing let variables for expressions in replacement
+/// code.
+VariableGet createVariableGet(VariableDeclaration variable) {
+ return new VariableGet(variable)..fileOffset = variable.fileOffset;
+}
+
+/// Creates a `e == null` test for the expression [left] using the [fileOffset]
+/// as file offset for the created nodes and [equalsMember] as the interface
+/// target of the created method invocation.
+MethodInvocation createEqualsNull(
+ int fileOffset, Expression left, Member equalsMember) {
+ return new MethodInvocation(
+ left,
+ new Name('=='),
+ new Arguments(<Expression>[new NullLiteral()..fileOffset = fileOffset])
+ ..fileOffset = fileOffset)
+ ..fileOffset = fileOffset
+ ..interfaceTarget = equalsMember;
+}
diff --git a/pkg/front_end/lib/src/fasta/kernel/kernel_target.dart b/pkg/front_end/lib/src/fasta/kernel/kernel_target.dart
index 8755030..1c4a783 100644
--- a/pkg/front_end/lib/src/fasta/kernel/kernel_target.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/kernel_target.dart
@@ -132,8 +132,6 @@
final TypeBuilder bottomType =
new NamedTypeBuilder("Null", const NullabilityBuilder.nullable(), null);
- bool get legacyMode => backendTarget.legacyMode;
-
final bool excludeSource = !CompilerContext.current.options.embedSourceText;
final Map<String, String> environmentDefines =
@@ -268,7 +266,6 @@
loader.checkSemantics(objectClassBuilder);
loader.finishTypeVariables(objectClassBuilder, dynamicType);
loader.buildComponent();
- loader.finalizeInitializingFormals();
installDefaultSupertypes();
installSyntheticConstructors(myClasses);
loader.resolveConstructors();
diff --git a/pkg/front_end/lib/src/fasta/kernel/redirecting_factory_body.dart b/pkg/front_end/lib/src/fasta/kernel/redirecting_factory_body.dart
index 4af23ec..ff2b557 100644
--- a/pkg/front_end/lib/src/fasta/kernel/redirecting_factory_body.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/redirecting_factory_body.dart
@@ -7,7 +7,6 @@
import 'package:kernel/ast.dart'
show
DartType,
- DynamicType,
Expression,
ExpressionStatement,
FunctionNode,
@@ -132,8 +131,7 @@
RedirectionTarget(this.target, this.typeArguments);
}
-RedirectionTarget getRedirectionTarget(Procedure member, EnsureLoaded helper,
- {bool legacyMode}) {
+RedirectionTarget getRedirectionTarget(Procedure member, EnsureLoaded helper) {
List<DartType> typeArguments = <DartType>[]..length =
member.function.typeParameters.length;
for (int i = 0; i < typeArguments.length; i++) {
@@ -155,27 +153,15 @@
Member nextTortoise = tortoiseBody.target;
helper.ensureLoaded(nextTortoise);
List<DartType> nextTypeArguments = tortoiseBody.typeArguments;
- if (!legacyMode && nextTypeArguments == null) {
+ if (nextTypeArguments == null) {
nextTypeArguments = <DartType>[];
}
- if (!legacyMode || nextTypeArguments != null) {
- Substitution sub = Substitution.fromPairs(
- tortoise.function.typeParameters, typeArguments);
- typeArguments = <DartType>[]..length = nextTypeArguments.length;
- for (int i = 0; i < typeArguments.length; i++) {
- typeArguments[i] = sub.substituteType(nextTypeArguments[i]);
- }
- } else {
- // In Dart 1, we need to throw away the extra type arguments and use
- // `dynamic` in place of the missing ones.
- int typeArgumentCount = typeArguments.length;
- int nextTypeArgumentCount =
- nextTortoise.enclosingClass.typeParameters.length;
- typeArguments.length = nextTypeArgumentCount;
- for (int i = typeArgumentCount; i < nextTypeArgumentCount; i++) {
- typeArguments[i] = const DynamicType();
- }
+ Substitution sub =
+ Substitution.fromPairs(tortoise.function.typeParameters, typeArguments);
+ typeArguments = <DartType>[]..length = nextTypeArguments.length;
+ for (int i = 0; i < typeArguments.length; i++) {
+ typeArguments[i] = sub.substituteType(nextTypeArguments[i]);
}
tortoise = nextTortoise;
diff --git a/pkg/front_end/lib/src/fasta/kernel/transform_collections.dart b/pkg/front_end/lib/src/fasta/kernel/transform_collections.dart
index e7d57d6..6e519f9 100644
--- a/pkg/front_end/lib/src/fasta/kernel/transform_collections.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/transform_collections.dart
@@ -429,7 +429,7 @@
VariableDeclaration temp;
if (entry.isNullAware) {
temp = new VariableDeclaration.forValue(value,
- type: coreTypes.mapClass.rawType);
+ type: coreTypes.mapLegacyRawType);
body.add(temp);
value = new VariableGet(temp);
}
diff --git a/pkg/front_end/lib/src/fasta/kernel/type_algorithms.dart b/pkg/front_end/lib/src/fasta/kernel/type_algorithms.dart
index e176829..010f327 100644
--- a/pkg/front_end/lib/src/fasta/kernel/type_algorithms.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/type_algorithms.dart
@@ -209,7 +209,8 @@
}
if (changed) {
- return new FunctionTypeBuilder(returnType, variables, formals);
+ return new FunctionTypeBuilder(
+ returnType, variables, formals, type.nullabilityBuilder);
}
return type;
diff --git a/pkg/front_end/lib/src/fasta/kernel/type_builder_computer.dart b/pkg/front_end/lib/src/fasta/kernel/type_builder_computer.dart
index 5f6dfb0..1c060a6 100644
--- a/pkg/front_end/lib/src/fasta/kernel/type_builder_computer.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/type_builder_computer.dart
@@ -114,8 +114,8 @@
new FormalParameterBuilder(null, 0, type, parameter.name, null, -1)
..kind = FormalParameterKind.optionalNamed;
}
-
- return new FunctionTypeBuilder(returnType, typeVariables, formals);
+ return new FunctionTypeBuilder(returnType, typeVariables, formals,
+ new NullabilityBuilder.fromNullability(node.nullability));
}
TypeBuilder visitTypeParameterType(TypeParameterType node) {
@@ -123,10 +123,8 @@
Class kernelClass = parameter.parent;
Library kernelLibrary = kernelClass.enclosingLibrary;
LibraryBuilder library = loader.builders[kernelLibrary.importUri];
- // TODO(dmitryas): Compute the nullabilityBuilder field for the result from
- // the nullability field of 'node'.
- return new NamedTypeBuilder(
- parameter.name, const NullabilityBuilder.pendingImplementation(), null)
+ return new NamedTypeBuilder(parameter.name,
+ new NullabilityBuilder.fromNullability(node.nullability), null)
..bind(new TypeVariableBuilder.fromKernel(parameter, library));
}
diff --git a/pkg/front_end/lib/src/fasta/kernel/verifier.dart b/pkg/front_end/lib/src/fasta/kernel/verifier.dart
index ac24a09..4f0387f 100644
--- a/pkg/front_end/lib/src/fasta/kernel/verifier.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/verifier.dart
@@ -12,6 +12,7 @@
DartType,
ExpressionStatement,
Field,
+ FunctionType,
Let,
Library,
Member,
@@ -20,7 +21,8 @@
SuperMethodInvocation,
SuperPropertyGet,
SuperPropertySet,
- TreeNode;
+ TreeNode,
+ TypeParameter;
import 'package:kernel/transformations/flags.dart' show TransformerFlag;
@@ -183,6 +185,20 @@
}
@override
+ visitFunctionType(FunctionType node) {
+ if (node.typeParameters.isNotEmpty) {
+ for (TypeParameter typeParameter in node.typeParameters) {
+ if (typeParameter.parent != null) {
+ problem(
+ null,
+ "Type parameters of function types shouldn't have parents: "
+ "$node.");
+ }
+ }
+ }
+ }
+
+ @override
visitSuperMethodInvocation(SuperMethodInvocation node) {
checkSuperInvocation(node);
super.visitSuperMethodInvocation(node);
diff --git a/pkg/front_end/lib/src/fasta/parser/parser.dart b/pkg/front_end/lib/src/fasta/parser/parser.dart
index 9ad4e92..c185f92 100644
--- a/pkg/front_end/lib/src/fasta/parser/parser.dart
+++ b/pkg/front_end/lib/src/fasta/parser/parser.dart
@@ -3428,6 +3428,10 @@
//
// method
//
+ if (varFinalOrConst != null) {
+ assert(optional('const', varFinalOrConst));
+ reportRecoverableError(varFinalOrConst, fasta.messageConstMethod);
+ }
switch (kind) {
case DeclarationKind.Class:
// TODO(danrubel): Remove beginInitializers token from method events
@@ -4178,12 +4182,17 @@
int tokenLevel = _computePrecedence(next);
for (int level = tokenLevel; level >= precedence; --level) {
int lastBinaryExpressionLevel = -1;
+ Token lastCascade;
while (identical(tokenLevel, level)) {
Token operator = next;
if (identical(tokenLevel, CASCADE_PRECEDENCE)) {
if (!allowCascades) {
return token;
+ } else if (lastCascade != null && optional('?..', next)) {
+ reportRecoverableError(
+ next, fasta.messageNullAwareCascadeOutOfOrder);
}
+ lastCascade = next;
token = parseCascadeExpression(token);
} else if (identical(tokenLevel, ASSIGNMENT_PRECEDENCE)) {
// Right associative, so we recurse at the same precedence
diff --git a/pkg/front_end/lib/src/fasta/scanner/abstract_scanner.dart b/pkg/front_end/lib/src/fasta/scanner/abstract_scanner.dart
index e34362d..cae857c 100644
--- a/pkg/front_end/lib/src/fasta/scanner/abstract_scanner.dart
+++ b/pkg/front_end/lib/src/fasta/scanner/abstract_scanner.dart
@@ -73,6 +73,10 @@
/// and https://github.com/dart-lang/language/issues/60
bool _enableTripleShift = false;
+ /// Experimental flag for enabling variance.
+ /// See https://github.com/dart-lang/language/issues/524
+ bool _enableVariance = false;
+
/**
* The string offset for the next token that will be created.
*
@@ -139,6 +143,7 @@
_enableExtensionMethods = config.enableExtensionMethods;
_enableNonNullable = config.enableNonNullable;
_enableTripleShift = config.enableTripleShift;
+ _enableVariance = config.enableVariance;
}
}
@@ -1483,6 +1488,10 @@
(state.keyword == Keyword.LATE || state.keyword == Keyword.REQUIRED)) {
return tokenizeIdentifier(next, start, allowDollar);
}
+ if (!_enableVariance &&
+ (state.keyword == Keyword.OUT || state.keyword == Keyword.INOUT)) {
+ return tokenizeIdentifier(next, start, allowDollar);
+ }
if (($A <= next && next <= $Z) ||
($0 <= next && next <= $9) ||
identical(next, $_) ||
@@ -1907,13 +1916,19 @@
/// and https://github.com/dart-lang/language/issues/60
final bool enableTripleShift;
+ /// Experimental flag for enabling variance.
+ /// See https://github.com/dart-lang/language/issues/524
+ final bool enableVariance;
+
const ScannerConfiguration({
bool enableExtensionMethods,
bool enableNonNullable,
bool enableTripleShift,
+ bool enableVariance,
}) : this.enableExtensionMethods = enableExtensionMethods ?? false,
this.enableNonNullable = enableNonNullable ?? false,
- this.enableTripleShift = enableTripleShift ?? false;
+ this.enableTripleShift = enableTripleShift ?? false,
+ this.enableVariance = enableVariance ?? false;
}
bool _isIdentifierChar(int next, bool allowDollar) {
diff --git a/pkg/front_end/lib/src/fasta/severity.dart b/pkg/front_end/lib/src/fasta/severity.dart
index d3eb763..71f1cd6 100644
--- a/pkg/front_end/lib/src/fasta/severity.dart
+++ b/pkg/front_end/lib/src/fasta/severity.dart
@@ -7,6 +7,7 @@
enum Severity {
context,
error,
+ // TODO(johnniwinther): Remove legacy warning.
errorLegacyWarning,
ignored,
internalProblem,
diff --git a/pkg/front_end/lib/src/fasta/source/outline_builder.dart b/pkg/front_end/lib/src/fasta/source/outline_builder.dart
index 13ee5bc..d2272da 100644
--- a/pkg/front_end/lib/src/fasta/source/outline_builder.dart
+++ b/pkg/front_end/lib/src/fasta/source/outline_builder.dart
@@ -19,7 +19,6 @@
Message,
messageConstConstructorWithBody,
messageConstInstanceField,
- messageConstMethod,
messageConstructorWithReturnType,
messageConstructorWithTypeParameters,
messageExpectedBlockToSkip,
@@ -1031,7 +1030,8 @@
beginInitializers: beginInitializers);
} else {
if (isConst) {
- addProblem(messageConstMethod, varFinalOrConstOffset, 5);
+ // TODO(danrubel): consider removing this
+ // because it is an error to have a const method.
modifiers &= ~constMask;
}
final int startCharOffset =
@@ -1388,7 +1388,11 @@
TypeBuilder returnType = pop();
List<TypeVariableBuilder> typeVariables = pop();
push(library.addFunctionType(
- returnType, typeVariables, formals, functionToken.charOffset));
+ returnType,
+ typeVariables,
+ formals,
+ library.computeNullabilityFromToken(questionMark != null),
+ functionToken.charOffset));
}
@override
@@ -1401,8 +1405,8 @@
if (!library.loader.target.enableNonNullable) {
reportErrorIfNullableType(question);
}
- push(library.addFunctionType(
- returnType, typeVariables, formals, formalsOffset));
+ push(library.addFunctionType(returnType, typeVariables, formals,
+ library.computeNullabilityFromToken(question != null), formalsOffset));
}
@override
@@ -1432,8 +1436,9 @@
library.beginNestedDeclaration(
TypeParameterScopeKind.functionType, "#function_type",
hasMembers: false);
- functionType =
- library.addFunctionType(returnType, null, formals, charOffset);
+ // TODO(dmitryas): Make sure that RHS of typedefs can't have '?'.
+ functionType = library.addFunctionType(returnType, null, formals,
+ const NullabilityBuilder.omitted(), charOffset);
} else {
Object type = pop();
typeVariables = pop();
diff --git a/pkg/front_end/lib/src/fasta/source/source_library_builder.dart b/pkg/front_end/lib/src/fasta/source/source_library_builder.dart
index 308acca..3ef57cb 100644
--- a/pkg/front_end/lib/src/fasta/source/source_library_builder.dart
+++ b/pkg/front_end/lib/src/fasta/source/source_library_builder.dart
@@ -255,8 +255,6 @@
final List<Object> accessors = <Object>[];
- final bool legacyMode;
-
String documentationComment;
String name;
@@ -317,8 +315,6 @@
/// the error message is the corresponding value in the map.
Map<String, String> unserializableExports;
- List<FormalParameterBuilder> untypedInitializingFormals;
-
List<FieldBuilder> implicitlyTypedFields;
bool languageVersionExplicitlySet = false;
@@ -346,7 +342,6 @@
this.library,
this._nameOrigin)
: currentTypeParameterScopeBuilder = libraryDeclaration,
- legacyMode = loader.target.legacyMode,
super(
fileUri, libraryDeclaration.toScope(importScope), new Scope.top());
@@ -623,8 +618,7 @@
bool isFinal = modifiers & finalMask != 0;
bool potentiallyNeedInitializerInOutline = isConst || isFinal;
Token startToken;
- if (potentiallyNeedInitializerInOutline ||
- (type == null && !legacyMode)) {
+ if (potentiallyNeedInitializerInOutline || type == null) {
startToken = info.initializerToken;
}
if (startToken != null) {
@@ -1096,11 +1090,7 @@
int typeCount = types.length;
for (UnresolvedType t in types) {
t.resolveIn(scope, this);
- if (!loader.target.legacyMode) {
- t.checkType(this);
- } else {
- t.normalizeType();
- }
+ t.checkType(this);
}
types.clear();
return typeCount;
@@ -1767,7 +1757,7 @@
metadata, type, name, modifiers, this, charOffset, charEndOffset);
fieldBuilder.constInitializerToken = constInitializerToken;
addBuilder(name, fieldBuilder, charOffset);
- if (!legacyMode && type == null && initializerToken != null) {
+ if (type == null && initializerToken != null) {
fieldBuilder.field.type =
new ImplicitFieldType(fieldBuilder, initializerToken);
(implicitlyTypedFields ??= <FieldBuilder>[]).add(fieldBuilder);
@@ -2001,9 +1991,10 @@
TypeBuilder returnType,
List<TypeVariableBuilder> typeVariables,
List<FormalParameterBuilder> formals,
+ NullabilityBuilder nullabilityBuilder,
int charOffset) {
- FunctionTypeBuilder builder =
- new FunctionTypeBuilder(returnType, typeVariables, formals);
+ FunctionTypeBuilder builder = new FunctionTypeBuilder(
+ returnType, typeVariables, formals, nullabilityBuilder);
checkTypeVariables(typeVariables, null);
// Nested declaration began in `OutlineBuilder.beginFunctionType` or
// `OutlineBuilder.beginFunctionTypedFormalParameter`.
@@ -2026,9 +2017,6 @@
FormalParameterBuilder formal = new FormalParameterBuilder(
metadata, modifiers, type, name, this, charOffset);
formal.initializerToken = initializerToken;
- if (legacyMode && hasThis && type == null) {
- (untypedInitializingFormals ??= <FormalParameterBuilder>[]).add(formal);
- }
return formal;
}
@@ -2383,12 +2371,12 @@
ClassBuilder objectClass) {
int count = 0;
- int computeDefaultTypesForVariables(
- List<TypeVariableBuilder> variables, bool legacyMode) {
+ int computeDefaultTypesForVariables(List<TypeVariableBuilder> variables,
+ {bool inErrorRecovery}) {
if (variables == null) return 0;
bool haveErroneousBounds = false;
- if (!legacyMode) {
+ if (!inErrorRecovery) {
for (int i = 0; i < variables.length; ++i) {
TypeVariableBuilder variable = variables[i];
List<TypeBuilder> genericFunctionTypes = <TypeBuilder>[];
@@ -2410,8 +2398,8 @@
}
}
- if (legacyMode || haveErroneousBounds) {
- // In Dart 1, put `dynamic` everywhere.
+ if (inErrorRecovery || haveErroneousBounds) {
+ // Use dynamic in case of errors.
for (int i = 0; i < variables.length; ++i) {
variables[i].defaultType = dynamicType;
}
@@ -2432,47 +2420,37 @@
}
}
- bool legacyMode = loader.target.legacyMode;
for (Builder declaration in libraryDeclaration.members.values) {
if (declaration is ClassBuilder) {
{
- List<Object> issues = legacyMode
- ? const <Object>[]
- : getNonSimplicityIssuesForDeclaration(declaration,
- performErrorRecovery: true);
+ List<Object> issues = getNonSimplicityIssuesForDeclaration(
+ declaration,
+ performErrorRecovery: true);
reportIssues(issues);
- // In case of issues, use legacy mode for error recovery.
- count += computeDefaultTypesForVariables(
- declaration.typeVariables, legacyMode || issues.isNotEmpty);
+ count += computeDefaultTypesForVariables(declaration.typeVariables,
+ inErrorRecovery: issues.isNotEmpty);
}
declaration.forEach((String name, Builder member) {
if (member is ProcedureBuilder) {
- List<Object> issues = legacyMode
- ? const <Object>[]
- : getNonSimplicityIssuesForTypeVariables(member.typeVariables);
+ List<Object> issues =
+ getNonSimplicityIssuesForTypeVariables(member.typeVariables);
reportIssues(issues);
- // In case of issues, use legacy mode for error recovery.
- count += computeDefaultTypesForVariables(
- member.typeVariables, legacyMode || issues.isNotEmpty);
+ count += computeDefaultTypesForVariables(member.typeVariables,
+ inErrorRecovery: issues.isNotEmpty);
}
});
} else if (declaration is TypeAliasBuilder) {
- List<Object> issues = legacyMode
- ? const <Object>[]
- : getNonSimplicityIssuesForDeclaration(declaration,
- performErrorRecovery: true);
+ List<Object> issues = getNonSimplicityIssuesForDeclaration(declaration,
+ performErrorRecovery: true);
reportIssues(issues);
- // In case of issues, use legacy mode for error recovery.
- count += computeDefaultTypesForVariables(
- declaration.typeVariables, legacyMode || issues.isNotEmpty);
+ count += computeDefaultTypesForVariables(declaration.typeVariables,
+ inErrorRecovery: issues.isNotEmpty);
} else if (declaration is FunctionBuilder) {
- List<Object> issues = legacyMode
- ? const <Object>[]
- : getNonSimplicityIssuesForTypeVariables(declaration.typeVariables);
+ List<Object> issues =
+ getNonSimplicityIssuesForTypeVariables(declaration.typeVariables);
reportIssues(issues);
- // In case of issues, use legacy mode for error recovery.
- count += computeDefaultTypesForVariables(
- declaration.typeVariables, legacyMode || issues.isNotEmpty);
+ count += computeDefaultTypesForVariables(declaration.typeVariables,
+ inErrorRecovery: issues.isNotEmpty);
}
}
@@ -2637,7 +2615,6 @@
}
void checkBoundsInField(Field field, TypeEnvironment typeEnvironment) {
- if (loader.target.legacyMode) return;
checkBoundsInType(
field.type, typeEnvironment, field.fileUri, field.fileOffset,
allowSuperBounded: true);
@@ -2649,7 +2626,6 @@
List<VariableDeclaration> positionalParameters,
List<VariableDeclaration> namedParameters,
DartType returnType}) {
- if (loader.target.legacyMode) return;
if (typeParameters != null) {
for (TypeParameter parameter in typeParameters) {
checkBoundsInType(
@@ -2704,7 +2680,6 @@
void checkBoundsInFunctionNode(
FunctionNode function, TypeEnvironment typeEnvironment, Uri fileUri) {
- if (loader.target.legacyMode) return;
checkBoundsInFunctionNodeParts(
typeEnvironment, fileUri, function.fileOffset,
typeParameters: function.typeParameters,
@@ -2716,7 +2691,6 @@
void checkBoundsInListLiteral(
ListLiteral node, TypeEnvironment typeEnvironment, Uri fileUri,
{bool inferred = false}) {
- if (loader.target.legacyMode) return;
checkBoundsInType(
node.typeArgument, typeEnvironment, fileUri, node.fileOffset,
inferred: inferred, allowSuperBounded: true);
@@ -2725,7 +2699,6 @@
void checkBoundsInSetLiteral(
SetLiteral node, TypeEnvironment typeEnvironment, Uri fileUri,
{bool inferred = false}) {
- if (loader.target.legacyMode) return;
checkBoundsInType(
node.typeArgument, typeEnvironment, fileUri, node.fileOffset,
inferred: inferred, allowSuperBounded: true);
@@ -2734,7 +2707,6 @@
void checkBoundsInMapLiteral(
MapLiteral node, TypeEnvironment typeEnvironment, Uri fileUri,
{bool inferred = false}) {
- if (loader.target.legacyMode) return;
checkBoundsInType(node.keyType, typeEnvironment, fileUri, node.fileOffset,
inferred: inferred, allowSuperBounded: true);
checkBoundsInType(node.valueType, typeEnvironment, fileUri, node.fileOffset,
@@ -2744,7 +2716,6 @@
void checkBoundsInType(
DartType type, TypeEnvironment typeEnvironment, Uri fileUri, int offset,
{bool inferred, bool allowSuperBounded = true}) {
- if (loader.target.legacyMode) return;
List<TypeArgumentIssue> issues = findTypeArgumentIssues(
type, typeEnvironment,
allowSuperBounded: allowSuperBounded);
@@ -2756,7 +2727,6 @@
void checkBoundsInVariableDeclaration(
VariableDeclaration node, TypeEnvironment typeEnvironment, Uri fileUri,
{bool inferred = false}) {
- if (loader.target.legacyMode) return;
if (node.type == null) return;
checkBoundsInType(node.type, typeEnvironment, fileUri, node.fileOffset,
inferred: inferred, allowSuperBounded: true);
@@ -2765,7 +2735,6 @@
void checkBoundsInConstructorInvocation(
ConstructorInvocation node, TypeEnvironment typeEnvironment, Uri fileUri,
{bool inferred = false}) {
- if (loader.target.legacyMode) return;
if (node.arguments.types.isEmpty) return;
Constructor constructor = node.target;
Class klass = constructor.enclosingClass;
@@ -2778,7 +2747,6 @@
void checkBoundsInFactoryInvocation(
StaticInvocation node, TypeEnvironment typeEnvironment, Uri fileUri,
{bool inferred = false}) {
- if (loader.target.legacyMode) return;
if (node.arguments.types.isEmpty) return;
Procedure factory = node.target;
assert(factory.isFactory);
@@ -2792,7 +2760,6 @@
void checkBoundsInStaticInvocation(
StaticInvocation node, TypeEnvironment typeEnvironment, Uri fileUri,
{bool inferred = false}) {
- if (loader.target.legacyMode) return;
if (node.arguments.types.isEmpty) return;
Class klass = node.target.enclosingClass;
List<TypeParameter> parameters = node.target.function.typeParameters;
@@ -2825,7 +2792,6 @@
Uri fileUri,
int offset,
{bool inferred = false}) {
- if (loader.target.legacyMode) return;
if (arguments.types.isEmpty) return;
Class klass;
List<DartType> receiverTypeArguments;
@@ -2876,7 +2842,6 @@
}
void checkBoundsInOutline(TypeEnvironment typeEnvironment) {
- if (loader.target.legacyMode) return;
Iterator<Builder> iterator = this.iterator;
while (iterator.moveNext()) {
Builder declaration = iterator.current;
@@ -2892,16 +2857,6 @@
inferredTypes.clear();
}
- int finalizeInitializingFormals() {
- if (!legacyMode || untypedInitializingFormals == null) return 0;
- for (int i = 0; i < untypedInitializingFormals.length; i++) {
- untypedInitializingFormals[i].finalizeInitializingFormal();
- }
- int count = untypedInitializingFormals.length;
- untypedInitializingFormals = null;
- return count;
- }
-
@override
List<FieldBuilder> takeImplicitlyTypedFields() {
List<FieldBuilder> result = implicitlyTypedFields;
diff --git a/pkg/front_end/lib/src/fasta/source/source_loader.dart b/pkg/front_end/lib/src/fasta/source/source_loader.dart
index f9a2a91..eeb0bac 100644
--- a/pkg/front_end/lib/src/fasta/source/source_loader.dart
+++ b/pkg/front_end/lib/src/fasta/source/source_loader.dart
@@ -474,17 +474,6 @@
ticker.logMs("Resolved $typeCount types");
}
- void finalizeInitializingFormals() {
- int formalCount = 0;
- builders.forEach((Uri uri, LibraryBuilder library) {
- if (library.loader == this) {
- SourceLibraryBuilder sourceLibrary = library;
- formalCount += sourceLibrary.finalizeInitializingFormals();
- }
- });
- ticker.logMs("Finalized $formalCount initializing formals");
- }
-
void finishDeferredLoadTearoffs() {
int count = 0;
builders.forEach((Uri uri, LibraryBuilder library) {
@@ -890,8 +879,6 @@
}
void checkBounds() {
- if (target.legacyMode) return;
-
builders.forEach((Uri uri, LibraryBuilder library) {
if (library is SourceLibraryBuilder) {
if (library.loader == this) {
@@ -935,7 +922,6 @@
void checkRedirectingFactories(List<SourceClassBuilder> sourceClasses) {
// TODO(ahe): Move this to [ClassHierarchyBuilder].
- if (target.legacyMode) return;
for (SourceClassBuilder builder in sourceClasses) {
if (builder.library.loader == this && !builder.isPatch) {
builder.checkRedirectingFactories(
@@ -999,13 +985,10 @@
}
void createTypeInferenceEngine() {
- if (target.legacyMode) return;
typeInferenceEngine = new ShadowTypeInferenceEngine(instrumentation);
}
void performTopLevelInference(List<SourceClassBuilder> sourceClasses) {
- if (target.legacyMode) return;
-
/// The first phase of top level initializer inference, which consists of
/// creating kernel objects for all fields and top level variables that
/// might be subject to type inference, and records dependencies between
diff --git a/pkg/front_end/lib/src/fasta/target_implementation.dart b/pkg/front_end/lib/src/fasta/target_implementation.dart
index e6ada23..4aa0538 100644
--- a/pkg/front_end/lib/src/fasta/target_implementation.dart
+++ b/pkg/front_end/lib/src/fasta/target_implementation.dart
@@ -154,7 +154,7 @@
Severity fixSeverity(Severity severity, Message message, Uri fileUri) {
severity ??= message.code.severity;
if (severity == Severity.errorLegacyWarning) {
- severity = backendTarget.legacyMode ? Severity.warning : Severity.error;
+ severity = Severity.error;
}
return rewriteSeverity(severity, message.code, fileUri);
}
diff --git a/pkg/front_end/lib/src/fasta/type_inference/inference_helper.dart b/pkg/front_end/lib/src/fasta/type_inference/inference_helper.dart
index d08f492..f01923c 100644
--- a/pkg/front_end/lib/src/fasta/type_inference/inference_helper.dart
+++ b/pkg/front_end/lib/src/fasta/type_inference/inference_helper.dart
@@ -22,7 +22,9 @@
set transformSetLiterals(bool value);
Expression buildProblem(Message message, int charOffset, int length,
- {List<LocatedMessage> context, bool suppressMessage});
+ {List<LocatedMessage> context,
+ bool suppressMessage,
+ bool wrapInSyntheticExpression: true});
LocatedMessage checkArgumentsForType(
FunctionType function, Arguments arguments, int offset);
diff --git a/pkg/front_end/lib/src/fasta/type_inference/standard_bounds.dart b/pkg/front_end/lib/src/fasta/type_inference/standard_bounds.dart
index 982987c..0fb91de 100644
--- a/pkg/front_end/lib/src/fasta/type_inference/standard_bounds.dart
+++ b/pkg/front_end/lib/src/fasta/type_inference/standard_bounds.dart
@@ -14,6 +14,7 @@
InterfaceType,
InvalidType,
NamedType,
+ Nullability,
TypeParameterType,
VoidType;
@@ -337,7 +338,8 @@
// TODO(paulberry): We could do better here, e.g.:
// SUB(([int]) -> void, (int) -> void) = (int) -> void
if (f.requiredParameterCount != g.requiredParameterCount) {
- return functionClass.rawType;
+ return new InterfaceType(
+ functionClass, const <DynamicType>[], Nullability.legacy);
}
int requiredParameterCount = f.requiredParameterCount;
diff --git a/pkg/front_end/lib/src/fasta/type_inference/type_constraint_gatherer.dart b/pkg/front_end/lib/src/fasta/type_inference/type_constraint_gatherer.dart
index 3912f27..930810e 100644
--- a/pkg/front_end/lib/src/fasta/type_inference/type_constraint_gatherer.dart
+++ b/pkg/front_end/lib/src/fasta/type_inference/type_constraint_gatherer.dart
@@ -298,17 +298,10 @@
DartType supertypeArg = supertype.typeArguments[0];
DartType supertypeFuture = futureType(supertypeArg);
- // The outcome of both trySubtypeMatch and _isSubtypeMatch is includes the
- // returned boolean value and the added constraints to _protoConstraints.
- // Here we need to match 'subtype' against both possibilities of the
- // FutureOr<X> which is 'supertype,' that is, we need to match 'subtype'
- // against Future<X> and X. However, if the first matching against
- // Future<X> finds any new constraints and adds them to _protoConstraints,
- // we should prefer them over the constraints possibly found while
- // matching against X. Note that if matching against Future<X> returned
- // true, but didn't find any new constraints, then matching against X
- // should still be done and the new constraints should still be added to
- // _protoConstraints.
+ // The match against FutureOr<X> succeeds if the match against either
+ // Future<X> or X succeeds. If they both succeed, the one adding new
+ // constraints should be preferred. If both matches against Future<X> and
+ // X add new constraints, the former should be preferred over the latter.
int oldProtoConstraintsLength = _protoConstraints.length;
bool matchesFuture = trySubtypeMatch(subtype, supertypeFuture);
bool matchesArg = oldProtoConstraintsLength != _protoConstraints.length
diff --git a/pkg/front_end/lib/src/fasta/type_inference/type_inferrer.dart b/pkg/front_end/lib/src/fasta/type_inference/type_inferrer.dart
index f01431a..9bb90d0 100644
--- a/pkg/front_end/lib/src/fasta/type_inference/type_inferrer.dart
+++ b/pkg/front_end/lib/src/fasta/type_inference/type_inferrer.dart
@@ -2,58 +2,11 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE.md file.
-import 'package:front_end/src/fasta/kernel/kernel_shadow_ast.dart';
-import 'package:kernel/ast.dart' as kernel;
+import 'dart:core' hide MapEntry;
-import 'package:kernel/ast.dart'
- show
- Arguments,
- AsExpression,
- AsyncMarker,
- BottomType,
- Class,
- ConditionalExpression,
- ConstructorInvocation,
- DartType,
- DynamicType,
- Expression,
- Extension,
- Field,
- FunctionExpression,
- FunctionNode,
- FunctionType,
- Instantiation,
- InterfaceType,
- InvalidType,
- InvocationExpression,
- Let,
- ListLiteral,
- MapLiteral,
- Member,
- MethodInvocation,
- Name,
- NullLiteral,
- Procedure,
- ProcedureKind,
- PropertyGet,
- PropertySet,
- ReturnStatement,
- SetLiteral,
- Statement,
- StaticGet,
- StaticInvocation,
- SuperMethodInvocation,
- SuperPropertyGet,
- SuperPropertySet,
- Supertype,
- ThisExpression,
- TreeNode,
- TypeParameter,
- TypeParameterType,
- VariableDeclaration,
- VariableGet,
- VoidType,
- setParents;
+import 'package:front_end/src/fasta/kernel/kernel_shadow_ast.dart';
+
+import 'package:kernel/ast.dart';
import 'package:kernel/class_hierarchy.dart' show ClassHierarchy;
@@ -86,8 +39,6 @@
templateArgumentTypeNotAssignable,
templateDuplicatedNamedArgument,
templateImplicitCallOfNonMethod,
- templateInternalProblemNoInferredTypeStored,
- templateInternalProblemStoringMultipleInferredTypes,
templateInvalidAssignment,
templateInvalidCastFunctionExpr,
templateInvalidCastLiteralList,
@@ -107,10 +58,9 @@
import '../kernel/kernel_shadow_ast.dart'
show
- ExpressionJudgment,
ShadowTypeInferenceEngine,
ShadowTypeInferrer,
- VariableDeclarationJudgment,
+ VariableDeclarationImpl,
getExplicitTypeArguments,
getExtensionTypeParameterCount;
@@ -118,7 +68,7 @@
import '../names.dart' show callName, unaryMinusName;
-import '../problems.dart' show internalProblem, unexpected, unhandled;
+import '../problems.dart' show unexpected, unhandled;
import '../source/source_library_builder.dart' show SourceLibraryBuilder;
@@ -262,7 +212,7 @@
// Null.
if (flattenedReturnType is VoidType ||
flattenedReturnType is DynamicType ||
- flattenedReturnType == inferrer.coreTypes.nullClass.rawType) {
+ flattenedReturnType == inferrer.coreTypes.nullType) {
return true;
}
statement.expression = inferrer.helper.wrapInProblem(
@@ -287,7 +237,7 @@
if (returnType is VoidType &&
flattenedExpressionType is! VoidType &&
flattenedExpressionType is! DynamicType &&
- flattenedExpressionType != inferrer.coreTypes.nullClass.rawType) {
+ flattenedExpressionType != inferrer.coreTypes.nullType) {
statement.expression = inferrer.helper.wrapInProblem(
statement.expression, messageReturnFromVoidFunction, noLength)
..parent = statement;
@@ -300,7 +250,7 @@
if (flattenedExpressionType is VoidType &&
flattenedReturnType is! VoidType &&
flattenedReturnType is! DynamicType &&
- flattenedReturnType != inferrer.coreTypes.nullClass.rawType) {
+ flattenedReturnType != inferrer.coreTypes.nullType) {
statement.expression = inferrer.helper
.wrapInProblem(statement.expression, messageVoidExpression, noLength)
..parent = statement;
@@ -475,28 +425,27 @@
Uri get uri;
/// Performs full type inference on the given field initializer.
- void inferFieldInitializer(InferenceHelper helper, DartType declaredType,
- kernel.Expression initializer);
+ void inferFieldInitializer(
+ InferenceHelper helper, DartType declaredType, Expression initializer);
/// Performs type inference on the given function body.
void inferFunctionBody(InferenceHelper helper, DartType returnType,
AsyncMarker asyncMarker, Statement body);
/// Performs type inference on the given constructor initializer.
- void inferInitializer(InferenceHelper helper, kernel.Initializer initializer);
+ void inferInitializer(InferenceHelper helper, Initializer initializer);
/// Performs type inference on the given metadata annotations.
- void inferMetadata(
- InferenceHelper helper, List<kernel.Expression> annotations);
+ void inferMetadata(InferenceHelper helper, List<Expression> annotations);
/// Performs type inference on the given metadata annotations keeping the
/// existing helper if possible.
- void inferMetadataKeepingHelper(List<kernel.Expression> annotations);
+ void inferMetadataKeepingHelper(List<Expression> annotations);
/// Performs type inference on the given function parameter initializer
/// expression.
- void inferParameterInitializer(InferenceHelper helper,
- kernel.Expression initializer, DartType declaredType);
+ void inferParameterInitializer(
+ InferenceHelper helper, Expression initializer, DartType declaredType);
}
/// Derived class containing generic implementations of [TypeInferrer].
@@ -531,8 +480,6 @@
@override
final SourceLibraryBuilder library;
- final Map<TreeNode, DartType> inferredTypesMap = <TreeNode, DartType>{};
-
InferenceHelper helper;
/// Context information for the current closure, or `null` if we are not
@@ -556,32 +503,6 @@
isTopLevel = topLevel,
super.private(engine.coreTypes);
- DartType storeInferredType(TreeNode node, DartType type) {
- if (node is ExpressionJudgment) {
- return node.inferredType = type;
- } else {
- if (inferredTypesMap.containsKey(node)) {
- internalProblem(
- templateInternalProblemStoringMultipleInferredTypes.withArguments(
- inferredTypesMap[node], "${node.runtimeType}"),
- node.fileOffset,
- uri);
- }
- return inferredTypesMap[node] = type;
- }
- }
-
- DartType readInferredType(TreeNode node) {
- if (!inferredTypesMap.containsKey(node) && !isTopLevel) {
- internalProblem(
- templateInternalProblemNoInferredTypeStored
- .withArguments("${node.runtimeType}"),
- node.fileOffset,
- uri);
- }
- return inferredTypesMap[node];
- }
-
/// Gets the type promoter that should be used to promote types during
/// inference.
TypePromoter get typePromoter;
@@ -599,7 +520,8 @@
InterfaceType type = typeContext;
typeContext = type.typeArguments.first;
}
- return typeContext == coreTypes.doubleClass.rawType;
+ return typeContext is InterfaceType &&
+ typeContext.classNode == coreTypes.doubleClass;
}
bool isAssignable(DartType expectedType, DartType actualType) {
@@ -758,10 +680,7 @@
/// be targeted due to, e.g., an incorrect argument count).
ObjectAccessTarget findInterfaceMember(
DartType receiverType, Name name, int fileOffset,
- {Template<Message Function(String, DartType)> errorTemplate,
- Expression expression,
- Expression receiver,
- bool setter: false,
+ {bool setter: false,
bool instrumented: true,
bool includeExtensionMethods: false}) {
assert(receiverType != null && isKnown(receiverType));
@@ -777,9 +696,19 @@
: coreTypes.objectClass;
Member interfaceMember =
_getInterfaceMember(classNode, name, setter, fileOffset);
- ObjectAccessTarget target = interfaceMember != null
- ? new ObjectAccessTarget.interfaceMember(interfaceMember)
- : const ObjectAccessTarget.unresolved();
+ ObjectAccessTarget target;
+ if (interfaceMember != null) {
+ target = new ObjectAccessTarget.interfaceMember(interfaceMember);
+ } else if (receiverType is DynamicType) {
+ target = const ObjectAccessTarget.dynamic();
+ } else if (receiverType is InvalidType) {
+ target = const ObjectAccessTarget.invalid();
+ } else if (receiverType == coreTypes.functionLegacyRawType &&
+ name.name == 'call') {
+ target = const ObjectAccessTarget.callFunction();
+ } else {
+ target = const ObjectAccessTarget.missing();
+ }
if (instrumented &&
receiverType != const DynamicType() &&
target.isInstanceMember) {
@@ -881,14 +810,41 @@
// one potential targets were found.
}
}
+ return target;
+ }
- if (!isTopLevel &&
- target.isUnresolved &&
- receiverType is! DynamicType &&
- receiverType is! InvalidType &&
- !(receiverType == coreTypes.functionClass.rawType &&
- name.name == 'call') &&
- errorTemplate != null) {
+ /// Finds a member of [receiverType] called [name], and if it is found,
+ /// reports it through instrumentation using [fileOffset].
+ ///
+ /// For the case where [receiverType] is a [FunctionType], and the name
+ /// is `call`, the string 'call' is returned as a sentinel object.
+ ///
+ /// For the case where [receiverType] is `dynamic`, and the name is declared
+ /// in Object, the member from Object is returned though the call may not end
+ /// up targeting it if the arguments do not match (the basic principle is that
+ /// the Object member is used for inferring types only if noSuchMethod cannot
+ /// be targeted due to, e.g., an incorrect argument count).
+ ///
+ /// If no target is found on a non-dynamic receiver an error is reported
+ /// using [errorTemplate] and [expression] is replaced by an invalid
+ /// expression.
+ ObjectAccessTarget findInterfaceMemberOrReport(
+ DartType receiverType,
+ Name name,
+ int fileOffset,
+ Template<Message Function(String, DartType)> errorTemplate,
+ Expression expression,
+ {bool setter: false,
+ bool instrumented: true,
+ bool includeExtensionMethods: false}) {
+ ObjectAccessTarget target = findInterfaceMember(
+ receiverType, name, fileOffset,
+ setter: setter,
+ instrumented: instrumented,
+ includeExtensionMethods: includeExtensionMethods);
+
+ assert(receiverType != null && isKnown(receiverType));
+ if (!isTopLevel && target.isMissing && errorTemplate != null) {
int length = name.name.length;
if (identical(name.name, callName.name) ||
identical(name.name, unaryMinusName.name)) {
@@ -897,7 +853,8 @@
expression.parent.replaceChild(
expression,
helper.desugarSyntheticExpression(helper.buildProblem(
- errorTemplate.withArguments(name.name, receiverType),
+ errorTemplate.withArguments(
+ name.name, resolveTypeParameter(receiverType)),
fileOffset,
length)));
}
@@ -912,11 +869,12 @@
// TODO(paulberry): could we add getters to InvocationExpression to make
// these is-checks unnecessary?
if (methodInvocation is MethodInvocation) {
- ObjectAccessTarget interfaceTarget = findInterfaceMember(
- receiverType, methodInvocation.name, methodInvocation.fileOffset,
- errorTemplate: templateUndefinedMethod,
- expression: methodInvocation,
- receiver: methodInvocation.receiver,
+ ObjectAccessTarget interfaceTarget = findInterfaceMemberOrReport(
+ receiverType,
+ methodInvocation.name,
+ methodInvocation.fileOffset,
+ templateUndefinedMethod,
+ methodInvocation,
instrumented: instrumented,
includeExtensionMethods: true);
if (interfaceTarget.isInstanceMember) {
@@ -930,7 +888,7 @@
signature.positionalParameters.length) {
return const ObjectAccessTarget.unresolved();
}
- for (kernel.NamedExpression argument in arguments.named) {
+ for (NamedExpression argument in arguments.named) {
if (!signature.namedParameters
.any((declaration) => declaration.name == argument.name)) {
return const ObjectAccessTarget.unresolved();
@@ -967,11 +925,12 @@
// TODO(paulberry): could we add a common base class to PropertyGet and
// SuperPropertyGet to make these is-checks unnecessary?
if (propertyGet is PropertyGet) {
- ObjectAccessTarget readTarget = findInterfaceMember(
- receiverType, propertyGet.name, propertyGet.fileOffset,
- errorTemplate: templateUndefinedGetter,
- expression: propertyGet,
- receiver: propertyGet.receiver,
+ ObjectAccessTarget readTarget = findInterfaceMemberOrReport(
+ receiverType,
+ propertyGet.name,
+ propertyGet.fileOffset,
+ templateUndefinedGetter,
+ propertyGet,
instrumented: instrumented);
if (readTarget.isInstanceMember) {
if (instrumented &&
@@ -1004,11 +963,12 @@
DartType receiverType, Expression propertySet,
{bool instrumented: true}) {
if (propertySet is PropertySet) {
- ObjectAccessTarget writeTarget = findInterfaceMember(
- receiverType, propertySet.name, propertySet.fileOffset,
- errorTemplate: templateUndefinedSetter,
- expression: propertySet,
- receiver: propertySet.receiver,
+ ObjectAccessTarget writeTarget = findInterfaceMemberOrReport(
+ receiverType,
+ propertySet.name,
+ propertySet.fileOffset,
+ templateUndefinedSetter,
+ propertySet,
setter: true,
instrumented: instrumented,
includeExtensionMethods: true);
@@ -1055,6 +1015,9 @@
case ObjectAccessTargetKind.callFunction:
return receiverType;
case ObjectAccessTargetKind.unresolved:
+ case ObjectAccessTargetKind.dynamic:
+ case ObjectAccessTargetKind.invalid:
+ case ObjectAccessTargetKind.missing:
return const DynamicType();
case ObjectAccessTargetKind.instanceMember:
return getGetterTypeForMemberTarget(target.member, receiverType);
@@ -1111,8 +1074,7 @@
DartType getGetterTypeForMemberTarget(
Member interfaceMember, DartType receiverType) {
Class memberClass = interfaceMember.enclosingClass;
- assert(
- interfaceMember is kernel.Field || interfaceMember is kernel.Procedure,
+ assert(interfaceMember is Field || interfaceMember is Procedure,
"Unexpected interface member $interfaceMember.");
DartType calleeType = interfaceMember.getterType;
if (memberClass.typeParameters.isNotEmpty) {
@@ -1151,6 +1113,9 @@
case ObjectAccessTargetKind.callFunction:
return _getFunctionType(receiverType, followCall);
case ObjectAccessTargetKind.unresolved:
+ case ObjectAccessTargetKind.dynamic:
+ case ObjectAccessTargetKind.invalid:
+ case ObjectAccessTargetKind.missing:
return unknownFunction;
case ObjectAccessTargetKind.instanceMember:
return _getFunctionType(
@@ -1172,23 +1137,95 @@
throw unhandled('$target', 'getFunctionType', null, null);
}
- /// Returns the type of the 'key' parameter in an []= implementation.
+ /// Returns the return type of the invocation of [target] on [receiverType].
+ // TODO(johnniwinther): Cleanup [getFunctionType], [getReturnType],
+ // [getIndexKeyType] and [getIndexSetValueType]. We shouldn't need that many.
+ DartType getReturnType(ObjectAccessTarget target, DartType receiverType) {
+ switch (target.kind) {
+ case ObjectAccessTargetKind.instanceMember:
+ FunctionType functionType = _getFunctionType(
+ getGetterTypeForMemberTarget(target.member, receiverType), false);
+ return functionType.returnType;
+ break;
+ case ObjectAccessTargetKind.extensionMember:
+ switch (target.extensionMethodKind) {
+ case ProcedureKind.Operator:
+ FunctionType functionType = target.member.function.functionType;
+ DartType returnType = functionType.returnType;
+ if (functionType.typeParameters.isNotEmpty) {
+ Substitution substitution = Substitution.fromPairs(
+ functionType.typeParameters,
+ target.inferredExtensionTypeArguments);
+ return substitution.substituteType(returnType);
+ }
+ return returnType;
+ default:
+ throw unhandled('$target', 'getFunctionType', null, null);
+ }
+ break;
+ case ObjectAccessTargetKind.callFunction:
+ case ObjectAccessTargetKind.unresolved:
+ case ObjectAccessTargetKind.dynamic:
+ case ObjectAccessTargetKind.invalid:
+ case ObjectAccessTargetKind.missing:
+ break;
+ }
+ return const DynamicType();
+ }
+
+ DartType getPositionalParameterTypeForTarget(
+ ObjectAccessTarget target, DartType receiverType, int index) {
+ switch (target.kind) {
+ case ObjectAccessTargetKind.instanceMember:
+ FunctionType functionType = _getFunctionType(
+ getGetterTypeForMemberTarget(target.member, receiverType), false);
+ if (functionType.positionalParameters.length > index) {
+ return functionType.positionalParameters[index];
+ }
+ break;
+ case ObjectAccessTargetKind.extensionMember:
+ FunctionType functionType = target.member.function.functionType;
+ if (functionType.positionalParameters.length > index + 1) {
+ DartType keyType = functionType.positionalParameters[index + 1];
+ if (functionType.typeParameters.isNotEmpty) {
+ Substitution substitution = Substitution.fromPairs(
+ functionType.typeParameters,
+ target.inferredExtensionTypeArguments);
+ return substitution.substituteType(keyType);
+ }
+ return keyType;
+ }
+ break;
+ case ObjectAccessTargetKind.callFunction:
+ case ObjectAccessTargetKind.unresolved:
+ case ObjectAccessTargetKind.dynamic:
+ case ObjectAccessTargetKind.invalid:
+ case ObjectAccessTargetKind.missing:
+ break;
+ }
+ return const DynamicType();
+ }
+
+ /// Returns the type of the 'key' parameter in an [] or []= implementation.
///
/// For instance
///
/// class Class<K, V> {
+ /// V operator [](K key) => null;
/// void operator []=(K key, V value) {}
/// }
///
/// extension Extension<K, V> on Class<K, V> {
+ /// V operator [](K key) => null;
/// void operator []=(K key, V value) {}
/// }
///
+ /// new Class<int, String>()[0]; // The key type is `int`.
/// new Class<int, String>()[0] = 'foo'; // The key type is `int`.
+ /// Extension<int, String>(null)[0]; // The key type is `int`.
/// Extension<int, String>(null)[0] = 'foo'; // The key type is `int`.
///
- DartType getIndexSetKeyType(
- ObjectAccessTarget target, DartType receiverType) {
+ DartType getIndexKeyType(ObjectAccessTarget target, DartType receiverType) {
switch (target.kind) {
case ObjectAccessTargetKind.instanceMember:
FunctionType functionType = _getFunctionType(
@@ -1202,14 +1239,14 @@
case ProcedureKind.Operator:
FunctionType functionType = target.member.function.functionType;
if (functionType.positionalParameters.length >= 2) {
- DartType indexType = functionType.positionalParameters[1];
+ DartType keyType = functionType.positionalParameters[1];
if (functionType.typeParameters.isNotEmpty) {
Substitution substitution = Substitution.fromPairs(
functionType.typeParameters,
target.inferredExtensionTypeArguments);
- return substitution.substituteType(indexType);
+ return substitution.substituteType(keyType);
}
- return indexType;
+ return keyType;
}
break;
default:
@@ -1218,9 +1255,12 @@
break;
case ObjectAccessTargetKind.callFunction:
case ObjectAccessTargetKind.unresolved:
+ case ObjectAccessTargetKind.dynamic:
+ case ObjectAccessTargetKind.invalid:
+ case ObjectAccessTargetKind.missing:
break;
}
- return const UnknownType();
+ return const DynamicType();
}
/// Returns the type of the 'value' parameter in an []= implementation.
@@ -1269,9 +1309,12 @@
break;
case ObjectAccessTargetKind.callFunction:
case ObjectAccessTargetKind.unresolved:
+ case ObjectAccessTargetKind.dynamic:
+ case ObjectAccessTargetKind.invalid:
+ case ObjectAccessTargetKind.missing:
break;
}
- return const UnknownType();
+ return const DynamicType();
}
FunctionType _getFunctionType(DartType calleeType, bool followCall) {
@@ -1317,6 +1360,9 @@
DartType getSetterType(ObjectAccessTarget target, DartType receiverType) {
switch (target.kind) {
case ObjectAccessTargetKind.unresolved:
+ case ObjectAccessTargetKind.dynamic:
+ case ObjectAccessTargetKind.invalid:
+ case ObjectAccessTargetKind.missing:
return const DynamicType();
case ObjectAccessTargetKind.instanceMember:
Member interfaceMember = target.member;
@@ -1366,6 +1412,7 @@
// TODO(johnniwinther): Compute the right setter type.
return const DynamicType();
case ObjectAccessTargetKind.callFunction:
+ break;
}
throw unhandled(target.runtimeType.toString(), 'getSetterType', null, null);
}
@@ -1498,20 +1545,23 @@
/// Derived classes should override this method with logic that dispatches on
/// the expression type and calls the appropriate specialized "infer" method.
ExpressionInferenceResult inferExpression(
- kernel.Expression expression, DartType typeContext, bool typeNeeded,
+ Expression expression, DartType typeContext, bool typeNeeded,
{bool isVoidAllowed});
@override
void inferFieldInitializer(
InferenceHelper helper,
DartType context,
- kernel.Expression initializer,
+ Expression initializer,
) {
assert(closureContext == null);
assert(!isTopLevel);
this.helper = helper;
ExpressionInferenceResult result =
inferExpression(initializer, context, true, isVoidAllowed: true);
+ if (result.replacement != null) {
+ initializer = result.replacement;
+ }
ensureAssignable(
context, result.inferredType, initializer, initializer.fileOffset,
isVoidAllowed: context is VoidType);
@@ -1624,6 +1674,7 @@
DartType _inferInvocation(DartType typeContext, int offset,
FunctionType calleeType, DartType returnType, Arguments arguments,
{bool isOverloadedArithmeticOperator: false,
+ bool isBinaryOperator: false,
DartType receiverType,
bool skipTypeArgumentInference: false,
bool isConst: false,
@@ -1717,7 +1768,7 @@
});
// Check for and remove duplicated named arguments.
- List<kernel.NamedExpression> named = arguments.named;
+ List<NamedExpression> named = arguments.named;
if (named.length == 2) {
if (named[0].name == named[1].name) {
String name = named[1].name;
@@ -1726,21 +1777,20 @@
templateDuplicatedNamedArgument.withArguments(name),
named[1].fileOffset,
name.length));
- arguments.named = [new kernel.NamedExpression(named[1].name, error)];
+ arguments.named = [new NamedExpression(named[1].name, error)];
formalTypes.removeLast();
actualTypes.removeLast();
}
} else if (named.length > 2) {
- Map<String, kernel.NamedExpression> seenNames =
- <String, kernel.NamedExpression>{};
+ Map<String, NamedExpression> seenNames = <String, NamedExpression>{};
bool hasProblem = false;
int namedTypeIndex = arguments.positional.length;
- List<kernel.NamedExpression> uniqueNamed = <kernel.NamedExpression>[];
- for (kernel.NamedExpression expression in named) {
+ List<NamedExpression> uniqueNamed = <NamedExpression>[];
+ for (NamedExpression expression in named) {
String name = expression.name;
if (seenNames.containsKey(name)) {
hasProblem = true;
- kernel.NamedExpression prevNamedExpression = seenNames[name];
+ NamedExpression prevNamedExpression = seenNames[name];
prevNamedExpression.value = helper.desugarSyntheticExpression(
helper.buildProblem(
templateDuplicatedNamedArgument.withArguments(name),
@@ -1796,6 +1846,8 @@
ensureAssignable(
expectedType, actualType, expression, expression.fileOffset,
isVoidAllowed: expectedType is VoidType,
+ // TODO(johnniwinther): Specialize message for operator
+ // invocations.
template: templateArgumentTypeNotAssignable);
}
}
@@ -1891,11 +1943,11 @@
// Otherwise, if `Qi` is not `_`, let `Ri` be the greatest closure of
// `Qi[T/S]` with respect to `?`. Otherwise, let `Ri` be `dynamic`.
for (int i = 0; i < formals.length; i++) {
- VariableDeclarationJudgment formal = formals[i];
- if (VariableDeclarationJudgment.isImplicitlyTyped(formal)) {
+ VariableDeclarationImpl formal = formals[i];
+ if (VariableDeclarationImpl.isImplicitlyTyped(formal)) {
DartType inferredType;
- if (formalTypesFromContext[i] == coreTypes.nullClass.rawType) {
- inferredType = coreTypes.objectClass.rawType;
+ if (formalTypesFromContext[i] == coreTypes.nullType) {
+ inferredType = coreTypes.objectRawType(library.nullable);
} else if (formalTypesFromContext[i] != null) {
inferredType = greatestClosure(coreTypes,
substitution.substituteType(formalTypesFromContext[i]));
@@ -1947,8 +1999,7 @@
}
@override
- void inferMetadata(
- InferenceHelper helper, List<kernel.Expression> annotations) {
+ void inferMetadata(InferenceHelper helper, List<Expression> annotations) {
if (annotations != null) {
this.helper = helper;
inferMetadataKeepingHelper(annotations);
@@ -1957,7 +2008,7 @@
}
@override
- void inferMetadataKeepingHelper(List<kernel.Expression> annotations) {
+ void inferMetadataKeepingHelper(List<Expression> annotations) {
if (annotations != null) {
// Place annotations in a temporary list literal so that they will have a
// parent. This is necessary in case any of the annotations need to get
@@ -1999,90 +2050,75 @@
/// Performs the core type inference algorithm for method invocations (this
/// handles both null-aware and non-null-aware method invocations).
ExpressionInferenceResult inferMethodInvocation(
- kernel.Expression expression,
- kernel.Expression receiver,
- int fileOffset,
- bool isImplicitCall,
- DartType typeContext,
- {VariableDeclaration receiverVariable,
- MethodInvocation desugaredInvocation,
- ObjectAccessTarget target,
- Name methodName,
- Arguments arguments}) {
- assert(desugaredInvocation == null || target == null);
- assert(desugaredInvocation != null || target != null);
+ MethodInvocationImpl node, DartType typeContext) {
// First infer the receiver so we can look up the method that was invoked.
- DartType receiverType;
- if (receiver == null) {
- receiverType = thisType;
- } else {
- ExpressionInferenceResult result =
- inferExpression(receiver, const UnknownType(), true);
- receiverType = result.inferredType;
- }
- receiverVariable?.type = receiverType;
- if (desugaredInvocation != null) {
- target = findMethodInvocationMember(receiverType, desugaredInvocation);
- methodName = desugaredInvocation.name;
- arguments = desugaredInvocation.arguments;
- }
- assert(
- target != null,
- "No target for ${expression} with desugared "
- "invocation ${desugaredInvocation}.");
- bool isOverloadedArithmeticOperator = target.isInstanceMember &&
- target.member is Procedure &&
- typeSchemaEnvironment.isOverloadedArithmeticOperatorAndType(
- target.member, receiverType);
+ ExpressionInferenceResult result =
+ inferExpression(node.receiver, const UnknownType(), true);
+ DartType receiverType = result.inferredType;
+ ObjectAccessTarget target = findMethodInvocationMember(receiverType, node);
+ Name methodName = node.name;
+ Arguments arguments = node.arguments;
+ assert(target != null, "No target for ${node}.");
+ bool isOverloadedArithmeticOperator =
+ isOverloadedArithmeticOperatorAndType(target, receiverType);
DartType calleeType = getGetterType(target, receiverType);
FunctionType functionType =
- getFunctionType(target, receiverType, !isImplicitCall);
+ getFunctionType(target, receiverType, !node.isImplicitCall);
if (!target.isUnresolved &&
calleeType is! DynamicType &&
- calleeType != coreTypes.functionClass.rawType &&
+ !(calleeType is InterfaceType &&
+ calleeType.classNode == coreTypes.functionClass) &&
identical(functionType, unknownFunction)) {
- TreeNode parent = expression.parent;
- kernel.Expression error = helper.wrapInProblem(expression,
+ TreeNode parent = node.parent;
+ Expression error = helper.wrapInProblem(node,
templateInvokeNonFunction.withArguments(methodName.name), noLength);
- parent?.replaceChild(expression, error);
+ parent?.replaceChild(node, error);
return const ExpressionInferenceResult(const DynamicType());
}
MethodContravarianceCheckKind checkKind = preCheckInvocationContravariance(
- receiver,
- receiverType,
- target,
- desugaredInvocation,
- arguments,
- expression);
+ receiverType, target,
+ isThisReceiver: node.receiver is ThisExpression);
StaticInvocation replacement;
if (target.isExtensionMember) {
replacement = transformExtensionMethodInvocation(
- target, expression, receiver, arguments);
+ target, node, node.receiver, arguments);
arguments = replacement.arguments;
}
- DartType inferredType = inferInvocation(typeContext, fileOffset,
+ DartType inferredType = inferInvocation(typeContext, node.fileOffset,
functionType, functionType.returnType, arguments,
isOverloadedArithmeticOperator: isOverloadedArithmeticOperator,
receiverType: receiverType,
isImplicitExtensionMember: target.isExtensionMember);
if (methodName.name == '==') {
- inferredType = coreTypes.boolClass.rawType;
+ inferredType = coreTypes.boolRawType(library.nonNullable);
}
- handleInvocationContravariance(checkKind, desugaredInvocation, arguments,
- expression, inferredType, functionType, fileOffset);
- if (isImplicitCall && target.isInstanceMember) {
+ handleInvocationContravariance(checkKind, node, arguments, node,
+ inferredType, functionType, node.fileOffset);
+ if (node.isImplicitCall && target.isInstanceMember) {
Member member = target.member;
if (!(member is Procedure && member.kind == ProcedureKind.Method)) {
- TreeNode parent = expression.parent;
+ TreeNode parent = node.parent;
Expression errorNode = helper.wrapInProblem(
- expression,
+ node,
templateImplicitCallOfNonMethod.withArguments(receiverType),
noLength);
- parent?.replaceChild(expression, errorNode);
+ parent?.replaceChild(node, errorNode);
}
}
+ _checkBoundsInMethodInvocation(target, receiverType, calleeType, methodName,
+ arguments, node.fileOffset);
+ return new ExpressionInferenceResult(inferredType, replacement);
+ }
+
+ void _checkBoundsInMethodInvocation(
+ ObjectAccessTarget target,
+ DartType receiverType,
+ DartType calleeType,
+ Name methodName,
+ Arguments arguments,
+ int fileOffset) {
// If [arguments] were inferred, check them.
// TODO(dmitryas): Figure out why [library] is sometimes null? Answer:
// because top level inference never got a library. This has changed so
@@ -2119,18 +2155,66 @@
fileOffset,
inferred: getExplicitTypeArguments(arguments) == null);
}
+ }
- return new ExpressionInferenceResult(inferredType, replacement);
+ bool isOverloadedArithmeticOperatorAndType(
+ ObjectAccessTarget target, DartType receiverType) {
+ return target.isInstanceMember &&
+ target.member is Procedure &&
+ typeSchemaEnvironment.isOverloadedArithmeticOperatorAndType(
+ target.member, receiverType);
+ }
+
+ /// Performs the core type inference algorithm for super method invocations.
+ ExpressionInferenceResult inferSuperMethodInvocation(
+ SuperMethodInvocation expression,
+ DartType typeContext,
+ ObjectAccessTarget target) {
+ int fileOffset = expression.fileOffset;
+ Name methodName = expression.name;
+ Arguments arguments = expression.arguments;
+ DartType receiverType = thisType;
+ bool isOverloadedArithmeticOperator =
+ isOverloadedArithmeticOperatorAndType(target, receiverType);
+ DartType calleeType = getGetterType(target, receiverType);
+ FunctionType functionType = getFunctionType(target, receiverType, true);
+
+ if (!target.isUnresolved &&
+ calleeType is! DynamicType &&
+ !(calleeType is InterfaceType &&
+ calleeType.classNode == coreTypes.functionClass) &&
+ identical(functionType, unknownFunction)) {
+ TreeNode parent = expression.parent;
+ Expression error = helper.wrapInProblem(expression,
+ templateInvokeNonFunction.withArguments(methodName.name), noLength);
+ parent?.replaceChild(expression, error);
+ return const ExpressionInferenceResult(const DynamicType());
+ }
+ DartType inferredType = inferInvocation(typeContext, fileOffset,
+ functionType, functionType.returnType, arguments,
+ isOverloadedArithmeticOperator: isOverloadedArithmeticOperator,
+ receiverType: receiverType,
+ isImplicitExtensionMember: target.isExtensionMember);
+ if (methodName.name == '==') {
+ inferredType = coreTypes.boolRawType(library.nonNullable);
+ }
+ _checkBoundsInMethodInvocation(
+ target, receiverType, calleeType, methodName, arguments, fileOffset);
+
+ return new ExpressionInferenceResult(inferredType);
}
@override
- void inferParameterInitializer(InferenceHelper helper,
- kernel.Expression initializer, DartType declaredType) {
+ void inferParameterInitializer(
+ InferenceHelper helper, Expression initializer, DartType declaredType) {
assert(closureContext == null);
this.helper = helper;
assert(declaredType != null);
ExpressionInferenceResult result =
inferExpression(initializer, declaredType, true);
+ if (result.replacement != null) {
+ initializer = result.replacement;
+ }
ensureAssignable(
declaredType, result.inferredType, initializer, initializer.fileOffset);
this.helper = null;
@@ -2138,13 +2222,13 @@
/// Performs the core type inference algorithm for property gets (this handles
/// both null-aware and non-null-aware property gets).
- ExpressionInferenceResult inferPropertyGet(Expression expression,
- Expression receiver, int fileOffset, DartType typeContext,
- {VariableDeclaration receiverVariable,
- PropertyGet desugaredGet,
- ObjectAccessTarget readTarget,
- Name propertyName,
- bool allowExtensionMethods: false}) {
+ ExpressionInferenceResult inferPropertyGet(
+ Expression expression,
+ Expression receiver,
+ int fileOffset,
+ DartType typeContext,
+ PropertyGet propertyGet,
+ {VariableDeclaration nullAwareReceiverVariable}) {
// First infer the receiver so we can look up the getter that was invoked.
DartType receiverType;
if (receiver == null) {
@@ -2152,27 +2236,26 @@
} else {
ExpressionInferenceResult result =
inferExpression(receiver, const UnknownType(), true);
+ if (result.replacement != null) {
+ receiver = result.replacement;
+ }
receiverType = result.inferredType;
}
- receiverVariable?.type = receiverType;
- propertyName ??= desugaredGet.name;
- if (desugaredGet != null) {
- readTarget = findInterfaceMember(receiverType, propertyName, fileOffset,
- errorTemplate: templateUndefinedGetter,
- expression: expression,
- receiver: receiver,
- includeExtensionMethods: allowExtensionMethods);
- if (readTarget.isInstanceMember) {
- if (instrumentation != null && receiverType == const DynamicType()) {
- instrumentation.record(uri, desugaredGet.fileOffset, 'target',
- new InstrumentationValueForMember(readTarget.member));
- }
- desugaredGet.interfaceTarget = readTarget.member;
+ nullAwareReceiverVariable?.type = receiverType;
+ Name propertyName = propertyGet.name;
+ ObjectAccessTarget readTarget = findInterfaceMemberOrReport(receiverType,
+ propertyName, fileOffset, templateUndefinedGetter, expression,
+ includeExtensionMethods: true);
+ if (readTarget.isInstanceMember) {
+ if (instrumentation != null && receiverType == const DynamicType()) {
+ instrumentation.record(uri, propertyGet.fileOffset, 'target',
+ new InstrumentationValueForMember(readTarget.member));
}
+ propertyGet.interfaceTarget = readTarget.member;
}
DartType inferredType = getGetterType(readTarget, receiverType);
Expression replacedExpression = handlePropertyGetContravariance(receiver,
- readTarget, desugaredGet, expression, inferredType, fileOffset);
+ readTarget, propertyGet, expression, inferredType, fileOffset);
Expression replacement;
if (readTarget.isInstanceMember) {
Member member = readTarget.member;
@@ -2183,7 +2266,7 @@
} else if (readTarget.isExtensionMember) {
int fileOffset = expression.fileOffset;
switch (readTarget.extensionMethodKind) {
- case kernel.ProcedureKind.Getter:
+ case ProcedureKind.Getter:
expression.parent.replaceChild(
expression,
replacement = expression = helper.forest.createStaticInvocation(
@@ -2197,7 +2280,7 @@
extensionTypeArguments:
readTarget.inferredExtensionTypeArguments)));
break;
- case kernel.ProcedureKind.Method:
+ case ProcedureKind.Method:
expression.parent.replaceChild(
expression,
replacement = expression = helper.forest.createStaticInvocation(
@@ -2211,14 +2294,29 @@
extensionTypeArguments:
readTarget.inferredExtensionTypeArguments)));
break;
- case kernel.ProcedureKind.Setter:
- case kernel.ProcedureKind.Factory:
- case kernel.ProcedureKind.Operator:
+ case ProcedureKind.Setter:
+ case ProcedureKind.Factory:
+ case ProcedureKind.Operator:
unhandled('$readTarget', "inferPropertyGet", fileOffset, uri);
break;
}
}
- storeInferredType(expression, inferredType);
+ return new ExpressionInferenceResult(inferredType, replacement);
+ }
+
+ /// Performs the core type inference algorithm for super property get.
+ ExpressionInferenceResult inferSuperPropertyGet(SuperPropertyGet expression,
+ DartType typeContext, ObjectAccessTarget readTarget) {
+ DartType receiverType = thisType;
+ DartType inferredType = getGetterType(readTarget, receiverType);
+ Expression replacement;
+ if (readTarget.isInstanceMember) {
+ Member member = readTarget.member;
+ if (member is Procedure && member.kind == ProcedureKind.Method) {
+ inferredType =
+ instantiateTearOff(inferredType, typeContext, expression);
+ }
+ }
return new ExpressionInferenceResult(inferredType, replacement);
}
@@ -2290,12 +2388,9 @@
/// boolean indicating whether an "as" check will need to be added due to
/// contravariance.
MethodContravarianceCheckKind preCheckInvocationContravariance(
- Expression receiver,
- DartType receiverType,
- ObjectAccessTarget target,
- MethodInvocation desugaredInvocation,
- Arguments arguments,
- Expression expression) {
+ DartType receiverType, ObjectAccessTarget target,
+ {bool isThisReceiver}) {
+ assert(isThisReceiver != null);
if (target.isInstanceMember) {
Member interfaceMember = target.member;
if (interfaceMember is Field ||
@@ -2305,7 +2400,7 @@
if (getType is DynamicType) {
return MethodContravarianceCheckKind.none;
}
- if (receiver != null && receiver is! ThisExpression) {
+ if (!isThisReceiver) {
if ((interfaceMember is Field &&
returnedTypeParametersOccurNonCovariantly(
interfaceMember.enclosingClass, interfaceMember.type)) ||
@@ -2316,8 +2411,7 @@
return MethodContravarianceCheckKind.checkGetterReturn;
}
}
- } else if (receiver != null &&
- receiver is! ThisExpression &&
+ } else if (!isThisReceiver &&
interfaceMember is Procedure &&
returnedTypeParametersOccurNonCovariantly(
interfaceMember.enclosingClass,
@@ -2389,7 +2483,7 @@
for (Expression expression in arguments.positional) {
callback(null, expression);
}
- for (kernel.NamedExpression namedExpression in arguments.named) {
+ for (NamedExpression namedExpression in arguments.named) {
callback(namedExpression.name, namedExpression.value);
}
}
@@ -2441,8 +2535,8 @@
}
if (expression is VariableGet) {
VariableDeclaration variable = expression.variable;
- if (variable is VariableDeclarationJudgment &&
- VariableDeclarationJudgment.isLocalFunction(variable)) {
+ if (variable is VariableDeclarationImpl &&
+ VariableDeclarationImpl.isLocalFunction(variable)) {
return templateInvalidCastLocalFunction;
}
}
@@ -2621,8 +2715,12 @@
enum ObjectAccessTargetKind {
instanceMember,
callFunction,
- unresolved,
extensionMember,
+ dynamic,
+ invalid,
+ missing,
+ // TODO(johnniwinther): Remove this.
+ unresolved,
}
/// Result for performing an access on an object, like `o.foo`, `o.foo()` and
@@ -2652,13 +2750,26 @@
const ObjectAccessTarget.callFunction()
: this.internal(ObjectAccessTargetKind.callFunction, null);
- /// Creates an access with no target.
- ///
- /// Done depending on context this may or may not be an error. For instance
- /// if the receiver has type `dynamic` this is not an error.
+ /// Creates an access with no known target.
const ObjectAccessTarget.unresolved()
: this.internal(ObjectAccessTargetKind.unresolved, null);
+ /// Creates an access on a dynamic receiver type with no known target.
+ const ObjectAccessTarget.dynamic()
+ : this.internal(ObjectAccessTargetKind.dynamic, null);
+
+ /// Creates an access with no target due to an invalid receiver type.
+ ///
+ /// This is not in itself an error but a consequence of another error.
+ const ObjectAccessTarget.invalid()
+ : this.internal(ObjectAccessTargetKind.invalid, null);
+
+ /// Creates an access with no target.
+ ///
+ /// This is an error case.
+ const ObjectAccessTarget.missing()
+ : this.internal(ObjectAccessTargetKind.missing, null);
+
/// Returns `true` if this is an access to an instance member.
bool get isInstanceMember => kind == ObjectAccessTargetKind.instanceMember;
@@ -2669,7 +2780,20 @@
bool get isCallFunction => kind == ObjectAccessTargetKind.callFunction;
/// Returns `true` if this is an access without a known target.
- bool get isUnresolved => kind == ObjectAccessTargetKind.unresolved;
+ bool get isUnresolved =>
+ kind == ObjectAccessTargetKind.unresolved ||
+ isDynamic ||
+ isInvalid ||
+ isMissing;
+
+ /// Returns `true` if this is an access on a dynamic receiver type.
+ bool get isDynamic => kind == ObjectAccessTargetKind.dynamic;
+
+ /// Returns `true` if this is an access on an invalid receiver type.
+ bool get isInvalid => kind == ObjectAccessTargetKind.invalid;
+
+ /// Returns `true` if this is an access with no target.
+ bool get isMissing => kind == ObjectAccessTargetKind.missing;
/// Returns the original procedure kind, if this is an extension method
/// target.
@@ -2709,7 +2833,8 @@
@override
String toString() =>
- 'ExtensionAccessTarget($kind,$member,$extensionMethodKind)';
+ 'ExtensionAccessTarget($kind,$member,$extensionMethodKind,'
+ '$inferredExtensionTypeArguments)';
}
class ExtensionAccessCandidate {
diff --git a/pkg/front_end/lib/src/fasta/type_inference/type_schema_elimination.dart b/pkg/front_end/lib/src/fasta/type_inference/type_schema_elimination.dart
index 1b8cd24..e7fc374 100644
--- a/pkg/front_end/lib/src/fasta/type_inference/type_schema_elimination.dart
+++ b/pkg/front_end/lib/src/fasta/type_inference/type_schema_elimination.dart
@@ -58,7 +58,7 @@
bool isLeastClosure;
_TypeSchemaEliminationVisitor(CoreTypes coreTypes, this.isLeastClosure)
- : nullType = coreTypes.nullClass.rawType;
+ : nullType = coreTypes.nullType;
@override
DartType visitFunctionType(FunctionType node) {
diff --git a/pkg/front_end/lib/src/fasta/type_inference/type_schema_environment.dart b/pkg/front_end/lib/src/fasta/type_inference/type_schema_environment.dart
index cf1097f..ad77c76 100644
--- a/pkg/front_end/lib/src/fasta/type_inference/type_schema_environment.dart
+++ b/pkg/front_end/lib/src/fasta/type_inference/type_schema_environment.dart
@@ -102,7 +102,7 @@
InterfaceType getLegacyLeastUpperBound(
InterfaceType type1, InterfaceType type2) {
- return hierarchy.getLegacyLeastUpperBound(type1, type2);
+ return hierarchy.getLegacyLeastUpperBound(type1, type2, this.coreTypes);
}
/// Modify the given [constraint]'s lower bound to include [lower].
@@ -405,12 +405,12 @@
class TypeVariableEliminator extends Substitution {
final CoreTypes _coreTypes;
+ // TODO(dmitryas): Instead of a CoreTypes object pass null and an Object type
+ // explicitly, with the suitable nullability on the latter.
TypeVariableEliminator(this._coreTypes);
@override
DartType getSubstitute(TypeParameter parameter, bool upperBound) {
- return upperBound
- ? _coreTypes.nullClass.rawType
- : _coreTypes.objectClass.rawType;
+ return upperBound ? _coreTypes.nullType : _coreTypes.objectLegacyRawType;
}
}
diff --git a/pkg/front_end/lib/src/scanner/token.dart b/pkg/front_end/lib/src/scanner/token.dart
index d16d2d4..37a8a52 100644
--- a/pkg/front_end/lib/src/scanner/token.dart
+++ b/pkg/front_end/lib/src/scanner/token.dart
@@ -209,6 +209,8 @@
static const Keyword IN = const Keyword("in", "IN");
+ static const Keyword INOUT = const Keyword("inout", "INOUT", isPseudo: true);
+
static const Keyword INTERFACE =
const Keyword("interface", "INTERFACE", isBuiltIn: true);
@@ -237,6 +239,8 @@
static const Keyword OPERATOR =
const Keyword("operator", "OPERATOR", isBuiltIn: true);
+ static const Keyword OUT = const Keyword("out", "OUT", isPseudo: true);
+
static const Keyword PART =
const Keyword("part", "PART", isBuiltIn: true, isTopLevelKeyword: true);
@@ -321,6 +325,7 @@
IMPLEMENTS,
IMPORT,
IN,
+ INOUT,
INTERFACE,
IS,
LATE,
@@ -332,6 +337,7 @@
OF,
ON,
OPERATOR,
+ OUT,
PART,
PATCH,
REQUIRED,
diff --git a/pkg/front_end/lib/src/testing/id.dart b/pkg/front_end/lib/src/testing/id.dart
index f0b323e..16fdce5 100644
--- a/pkg/front_end/lib/src/testing/id.dart
+++ b/pkg/front_end/lib/src/testing/id.dart
@@ -350,22 +350,34 @@
/// Checks for duplicate data for [id].
void registerValue(Uri uri, int offset, Id id, T value, Object object) {
if (value != null) {
+ ActualData<T> newData = new ActualData<T>(id, value, uri, offset, object);
if (actualMap.containsKey(id)) {
- // TODO(johnniwinther): Maybe let the test supply a way to merge
- // multiple data on the same id?
ActualData<T> existingData = actualMap[id];
- report(uri, offset, "Duplicate id ${id}, value=$value, object=$object");
- report(
- uri,
- offset,
- "Duplicate id ${id}, value=${existingData.value}, "
- "object=${existingData.object}");
- fail("Duplicate id $id.");
+ ActualData<T> mergedData = mergeData(existingData, newData);
+ if (mergedData != null) {
+ actualMap[id] = mergedData;
+ } else {
+ report(
+ uri,
+ offset,
+ "Duplicate id ${id}, value=$value, object=$object "
+ "(${object.runtimeType})");
+ report(
+ uri,
+ offset,
+ "Duplicate id ${id}, value=${existingData.value}, "
+ "object=${existingData.object} "
+ "(${existingData.object.runtimeType})");
+ fail("Duplicate id $id.");
+ }
+ } else {
+ actualMap[id] = newData;
}
- actualMap[id] = new ActualData<T>(id, value, uri, offset, object);
}
}
+ ActualData<T> mergeData(ActualData<T> value1, ActualData<T> value2) => null;
+
/// Called to report duplicate errors.
void report(Uri uri, int offset, String message);
diff --git a/pkg/front_end/messages.status b/pkg/front_end/messages.status
index 8d11e08..5c99198 100644
--- a/pkg/front_end/messages.status
+++ b/pkg/front_end/messages.status
@@ -406,6 +406,7 @@
NotAnLvalue/example: Fail
NotBinaryOperator/analyzerCode: Fail
NotConstantExpression/example: Fail
+NullAwareCascadeOutOfOrder/example: Fail
OperatorMinusParameterMismatch/example: Fail
OperatorParameterMismatch0/analyzerCode: Fail
OperatorParameterMismatch0/example: Fail
diff --git a/pkg/front_end/messages.yaml b/pkg/front_end/messages.yaml
index a1b889c..0436850 100644
--- a/pkg/front_end/messages.yaml
+++ b/pkg/front_end/messages.yaml
@@ -195,6 +195,16 @@
template: "Not a constant expression."
analyzerCode: NOT_CONSTANT_EXPRESSION
+MissingExplicitConst:
+ template: "Constant expression expected."
+ tip: "Try inserting 'const'."
+ analyzerCode: NOT_CONSTANT_EXPRESSION
+ script: >
+ class A {
+ final x;
+ const A(): x = [];
+ }
+
NonAsciiIdentifier:
template: "The non-ASCII character '#character' (#unicode) can't be used in identifiers, only in strings and comments."
tip: "Try using an US-ASCII letter, a digit, '_' (an underscore), or '$' (a dollar sign)."
@@ -1249,6 +1259,12 @@
tip: "Try replacing '?.' with '.'"
analyzerCode: ParserErrorCode.INVALID_OPERATOR_QUESTIONMARK_PERIOD_FOR_SUPER
+NullAwareCascadeOutOfOrder:
+ index: 96
+ template: "The '?..' cascade operator must be first in the cascade sequence."
+ tip: "Try moving the '?..' operator to be the first cascade operator in the sequence."
+ analyzerCode: ParserErrorCode.NULL_AWARE_CASCADE_OUT_OF_ORDER
+
ConstFieldWithoutInitializer:
template: "The const variable '#name' must be initialized."
tip: "Try adding an initializer ('= <expression>') to the declaration."
@@ -1680,14 +1696,6 @@
template: "Compilation aborted due to fatal '#name' at:\n#string"
severity: INTERNAL_PROBLEM
-InternalProblemNoInferredTypeStored:
- template: "There's no inferred type for '#name'."
- severity: INTERNAL_PROBLEM
-
-InternalProblemStoringMultipleInferredTypes:
- template: "There's already an inferred type, '#type', for '#name'."
- severity: INTERNAL_PROBLEM
-
InternalProblemLabelUsageInVariablesDeclaration:
template: "Unexpected usage of label inside declaration of variables."
severity: INTERNAL_PROBLEM
diff --git a/pkg/front_end/pubspec.yaml b/pkg/front_end/pubspec.yaml
index ea3f3bf..e39bb2e 100644
--- a/pkg/front_end/pubspec.yaml
+++ b/pkg/front_end/pubspec.yaml
@@ -1,17 +1,17 @@
name: front_end
# Currently, front_end API is not stable and users should not
# depend on semver semantics when depending on this package.
-version: 0.1.24
+version: 0.1.25
author: Dart Team <misc@dartlang.org>
description: Front end for compilation of Dart code.
homepage: https://github.com/dart-lang/sdk/tree/master/pkg/front_end
environment:
sdk: '>=2.2.2 <3.0.0'
dependencies:
- kernel: 0.3.24
+ kernel: 0.3.25
package_config: '^1.1.0'
dev_dependencies:
- analyzer: 0.38.2
+ analyzer: 0.38.3
args: '>=0.13.0 <2.0.0'
build_integration:
path: ../build_integration
diff --git a/pkg/front_end/test/dill_round_trip_test.dart b/pkg/front_end/test/dill_round_trip_test.dart
new file mode 100644
index 0000000..424a3b1
--- /dev/null
+++ b/pkg/front_end/test/dill_round_trip_test.dart
@@ -0,0 +1,59 @@
+// Copyright (c) 2019, 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.
+
+import 'package:front_end/src/fasta/kernel/utils.dart' show serializeComponent;
+
+import 'package:kernel/ast.dart' show Component;
+
+import 'package:kernel/binary/ast_from_binary.dart' show BinaryBuilder;
+
+import 'package:kernel/target/targets.dart' show NoneTarget, TargetFlags;
+
+import 'incremental_load_from_dill_test.dart'
+ show checkIsEqual, getOptions, normalCompilePlain;
+
+main() async {
+ final Uri dart2jsUrl = Uri.base.resolve("pkg/compiler/bin/dart2js.dart");
+ Stopwatch stopwatch = new Stopwatch()..start();
+ Component compiledComponent = await normalCompilePlain(dart2jsUrl,
+ options: getOptions()
+ ..target = new NoneTarget(new TargetFlags())
+ ..omitPlatform = false);
+ print("Compiled dart2js in ${stopwatch.elapsedMilliseconds} ms");
+ stopwatch.reset();
+
+ List<int> bytes = serializeComponent(compiledComponent);
+ print("Serialized dart2js in ${stopwatch.elapsedMilliseconds} ms");
+ print("Output is ${bytes.length} bytes long.");
+ print("");
+ stopwatch.reset();
+
+ print("Round-tripping with lazy disabled");
+ roundTrip(
+ new BinaryBuilder(bytes,
+ disableLazyReading: true, disableLazyClassReading: true),
+ bytes);
+
+ print("Round-tripping with lazy enabled");
+ roundTrip(
+ new BinaryBuilder(bytes,
+ disableLazyReading: false, disableLazyClassReading: false),
+ bytes);
+
+ print("OK");
+}
+
+void roundTrip(BinaryBuilder binaryBuilder, List<int> bytes) {
+ Stopwatch stopwatch = new Stopwatch()..start();
+ Component c = new Component();
+ binaryBuilder.readComponent(c);
+ List<int> bytesRoundTripped = serializeComponent(c);
+ print("Loaded and serialized in ${stopwatch.elapsedMilliseconds} ms");
+ stopwatch.reset();
+
+ checkIsEqual(bytes, bytesRoundTripped);
+ print("Checked equal in ${stopwatch.elapsedMilliseconds} ms");
+ stopwatch.reset();
+ print("");
+}
diff --git a/pkg/front_end/test/fasta/flow_analysis/flow_analysis_test.dart b/pkg/front_end/test/fasta/flow_analysis/flow_analysis_test.dart
index 26fa4ca..b93bf2e 100644
--- a/pkg/front_end/test/fasta/flow_analysis/flow_analysis_test.dart
+++ b/pkg/front_end/test/fasta/flow_analysis/flow_analysis_test.dart
@@ -331,18 +331,31 @@
h.declare(x, initialized: true);
h.promote(x, 'int');
expect(flow.promotedType(x).type, 'int');
- flow.forEach_bodyBegin({x});
+ flow.forEach_bodyBegin({x}, null);
expect(flow.promotedType(x), isNull);
flow.forEach_end();
});
});
+ test('forEach_bodyBegin() writes to loop variable', () {
+ var h = _Harness();
+ var x = h.addVar('x', 'int?');
+ h.run((flow) {
+ h.declare(x, initialized: false);
+ expect(flow.isAssigned(x), false);
+ flow.forEach_bodyBegin({x}, x);
+ expect(flow.isAssigned(x), true);
+ flow.forEach_end();
+ expect(flow.isAssigned(x), false);
+ });
+ });
+
test('forEach_end() restores state before loop', () {
var h = _Harness();
var x = h.addVar('x', 'int?');
h.run((flow) {
h.declare(x, initialized: true);
- flow.forEach_bodyBegin({});
+ flow.forEach_bodyBegin({}, null);
h.promote(x, 'int');
expect(flow.promotedType(x).type, 'int');
flow.forEach_end();
diff --git a/pkg/front_end/test/fasta/generator_to_string_test.dart b/pkg/front_end/test/fasta/generator_to_string_test.dart
index 30206f6..273a013 100644
--- a/pkg/front_end/test/fasta/generator_to_string_test.dart
+++ b/pkg/front_end/test/fasta/generator_to_string_test.dart
@@ -73,8 +73,7 @@
new KernelTarget(
null,
false,
- new DillTarget(null, null,
- new NoneTarget(new TargetFlags(legacyMode: true))),
+ new DillTarget(null, null, new NoneTarget(new TargetFlags())),
null)
.loader,
null);
diff --git a/pkg/front_end/test/fasta/incremental_hello_test.dart b/pkg/front_end/test/fasta/incremental_hello_test.dart
index ccafee3..f7435f6 100644
--- a/pkg/front_end/test/fasta/incremental_hello_test.dart
+++ b/pkg/front_end/test/fasta/incremental_hello_test.dart
@@ -35,8 +35,7 @@
test({bool sdkFromSource}) async {
final CompilerOptions optionBuilder = new CompilerOptions()
..packagesFileUri = Uri.base.resolve(".packages")
- ..target = new VmTarget(new TargetFlags(legacyMode: true))
- ..legacyMode = true
+ ..target = new VmTarget(new TargetFlags())
..omitPlatform = true
..onDiagnostic = diagnosticMessageHandler
..environmentDefines = const {};
diff --git a/pkg/front_end/test/fasta/incremental_test.dart b/pkg/front_end/test/fasta/incremental_test.dart
index 59c2e1d..3b22af2 100644
--- a/pkg/front_end/test/fasta/incremental_test.dart
+++ b/pkg/front_end/test/fasta/incremental_test.dart
@@ -225,7 +225,6 @@
final List<DiagnosticMessage> errors = <DiagnosticMessage>[];
final CompilerOptions optionBuilder = new CompilerOptions()
- ..legacyMode = true
..verbose = true
..fileSystem = fs
..sdkSummary = sdkSummary
diff --git a/pkg/front_end/test/fasta/testing/suite.dart b/pkg/front_end/test/fasta/testing/suite.dart
index 4170490..3837eea 100644
--- a/pkg/front_end/test/fasta/testing/suite.dart
+++ b/pkg/front_end/test/fasta/testing/suite.dart
@@ -131,10 +131,6 @@
final Expectation runtimeError = ExpectationSet.Default["RuntimeError"];
-String generateExpectationName(bool legacyMode) {
- return legacyMode ? "legacy" : "strong";
-}
-
const String experimentalFlagOptions = '--enable-experiment=';
class TestOptions {
diff --git a/pkg/front_end/test/fasta/type_inference/type_constraint_gatherer_test.dart b/pkg/front_end/test/fasta/type_inference/type_constraint_gatherer_test.dart
index 262886f..8da59a4 100644
--- a/pkg/front_end/test/fasta/type_inference/type_constraint_gatherer_test.dart
+++ b/pkg/front_end/test/fasta/type_inference/type_constraint_gatherer_test.dart
@@ -53,7 +53,7 @@
Class get functionClass => coreTypes.functionClass;
- InterfaceType get functionType => functionClass.rawType;
+ InterfaceType get functionType => coreTypes.functionLegacyRawType;
Class get iterableClass => coreTypes.iterableClass;
@@ -61,15 +61,15 @@
Class get mapClass => coreTypes.mapClass;
- InterfaceType get nullType => coreTypes.nullClass.rawType;
+ InterfaceType get nullType => coreTypes.nullType;
Class get objectClass => coreTypes.objectClass;
- InterfaceType get objectType => objectClass.rawType;
+ InterfaceType get objectType => coreTypes.objectLegacyRawType;
- InterfaceType get P => classP.rawType;
+ InterfaceType get P => coreTypes.legacyRawType(classP);
- InterfaceType get Q => classQ.rawType;
+ InterfaceType get Q => coreTypes.legacyRawType(classQ);
void test_any_subtype_parameter() {
_checkConstraints(Q, T1, ['lib::Q* <: T1']);
@@ -180,7 +180,7 @@
}
void test_null_subtype_any() {
- _checkConstraints(nullType, T1, ['dart.core::Null* <: T1']);
+ _checkConstraints(nullType, T1, ['dart.core::Null? <: T1']);
_checkConstraints(nullType, Q, []);
}
diff --git a/pkg/front_end/test/fasta/type_inference/type_schema_elimination_test.dart b/pkg/front_end/test/fasta/type_inference/type_schema_elimination_test.dart
index bd78483..b6d152f 100644
--- a/pkg/front_end/test/fasta/type_inference/type_schema_elimination_test.dart
+++ b/pkg/front_end/test/fasta/type_inference/type_schema_elimination_test.dart
@@ -24,9 +24,9 @@
DartType get dynamicType => const DynamicType();
- DartType get nullType => coreTypes.nullClass.rawType;
+ DartType get nullType => coreTypes.nullType;
- DartType get objectType => coreTypes.objectClass.rawType;
+ DartType get objectType => coreTypes.objectLegacyRawType;
DartType greatestClosure(DartType schema) =>
typeSchemaElimination.greatestClosure(coreTypes, schema);
@@ -38,11 +38,11 @@
expect(
greatestClosure(new FunctionType([unknownType], dynamicType))
.toString(),
- '(dart.core::Null*) →* dynamic');
+ '(dart.core::Null?) →* dynamic');
expect(
greatestClosure(new FunctionType([], dynamicType,
namedParameters: [new NamedType('foo', unknownType)])).toString(),
- '({foo: dart.core::Null*}) →* dynamic');
+ '({foo: dart.core::Null?}) →* dynamic');
}
void test_greatestClosure_contravariant_contravariant() {
@@ -71,8 +71,8 @@
new NamedType('a', unknownType),
new NamedType('b', unknownType)
])).toString(),
- '(dart.core::Null*, dart.core::Null*, {a: dart.core::Null*, '
- 'b: dart.core::Null*}) →* dynamic');
+ '(dart.core::Null?, dart.core::Null?, {a: dart.core::Null?, '
+ 'b: dart.core::Null?}) →* dynamic');
}
void test_greatestClosure_simple() {
@@ -95,16 +95,16 @@
new FunctionType([unknownType], dynamicType)
], dynamicType))
.toString(),
- '((dart.core::Null*) →* dynamic) →* dynamic');
+ '((dart.core::Null?) →* dynamic) →* dynamic');
}
void test_leastClosure_covariant() {
expect(leastClosure(new FunctionType([], unknownType)).toString(),
- '() →* dart.core::Null*');
+ '() →* dart.core::Null?');
expect(
leastClosure(new InterfaceType(coreTypes.listClass, [unknownType]))
.toString(),
- 'dart.core::List<dart.core::Null*>*');
+ 'dart.core::List<dart.core::Null?>*');
}
void test_leastClosure_function_multipleUnknown() {
@@ -114,11 +114,11 @@
new NamedType('a', unknownType),
new NamedType('b', unknownType)
])).toString(),
- '(dynamic, dynamic, {a: dynamic, b: dynamic}) →* dart.core::Null*');
+ '(dynamic, dynamic, {a: dynamic, b: dynamic}) →* dart.core::Null?');
}
void test_leastClosure_simple() {
- expect(leastClosure(unknownType).toString(), 'dart.core::Null*');
+ expect(leastClosure(unknownType).toString(), 'dart.core::Null?');
}
}
@@ -132,7 +132,12 @@
@override
final Class objectClass = new Class(name: 'Object');
+ @override
+ InterfaceType nullType;
+
_MockCoreTypes() {
+ nullType = new InterfaceType(
+ nullClass, const <DynamicType>[], Nullability.nullable);
new Library(Uri.parse('dart:core'),
name: 'dart.core', classes: [listClass, nullClass, objectClass]);
}
diff --git a/pkg/front_end/test/fasta/type_inference/type_schema_environment_test.dart b/pkg/front_end/test/fasta/type_inference/type_schema_environment_test.dart
index 101fb7f..1908a65 100644
--- a/pkg/front_end/test/fasta/type_inference/type_schema_environment_test.dart
+++ b/pkg/front_end/test/fasta/type_inference/type_schema_environment_test.dart
@@ -39,11 +39,11 @@
coreTypes = new CoreTypes(component);
}
- InterfaceType get doubleType => coreTypes.doubleClass.rawType;
+ InterfaceType get doubleType => coreTypes.doubleLegacyRawType;
- InterfaceType get functionType => coreTypes.functionClass.rawType;
+ InterfaceType get functionType => coreTypes.functionLegacyRawType;
- InterfaceType get intType => coreTypes.intClass.rawType;
+ InterfaceType get intType => coreTypes.intLegacyRawType;
Class get iterableClass => coreTypes.iterableClass;
@@ -51,20 +51,20 @@
Class get mapClass => coreTypes.mapClass;
- InterfaceType get nullType => coreTypes.nullClass.rawType;
+ InterfaceType get nullType => coreTypes.nullType;
- InterfaceType get numType => coreTypes.numClass.rawType;
+ InterfaceType get numType => coreTypes.numLegacyRawType;
Class get objectClass => coreTypes.objectClass;
- InterfaceType get objectType => objectClass.rawType;
+ InterfaceType get objectType => coreTypes.objectLegacyRawType;
void test_addLowerBound() {
- var A = _addClass(_class('A')).rawType;
- var B =
- _addClass(_class('B', supertype: A.classNode.asThisSupertype)).rawType;
- var C =
- _addClass(_class('C', supertype: A.classNode.asThisSupertype)).rawType;
+ var A = coreTypes.legacyRawType(_addClass(_class('A')));
+ var B = coreTypes.legacyRawType(
+ _addClass(_class('B', supertype: A.classNode.asThisSupertype)));
+ var C = coreTypes.legacyRawType(
+ _addClass(_class('C', supertype: A.classNode.asThisSupertype)));
var env = _makeEnv();
var typeConstraint = new TypeConstraint();
expect(typeConstraint.lower, same(unknownType));
@@ -75,11 +75,13 @@
}
void test_addUpperBound() {
- var A = _addClass(_class('A')).rawType;
- var B =
- _addClass(_class('B', supertype: A.classNode.asThisSupertype)).rawType;
- var C =
- _addClass(_class('C', supertype: A.classNode.asThisSupertype)).rawType;
+ var A = coreTypes.rawType(_addClass(_class('A')), Nullability.legacy);
+ var B = coreTypes.rawType(
+ _addClass(_class('B', supertype: A.classNode.asThisSupertype)),
+ Nullability.legacy);
+ var C = coreTypes.rawType(
+ _addClass(_class('C', supertype: A.classNode.asThisSupertype)),
+ Nullability.legacy);
var env = _makeEnv();
var typeConstraint = new TypeConstraint();
expect(typeConstraint.upper, same(unknownType));
@@ -92,16 +94,17 @@
}
void test_glb_bottom() {
- var A = _addClass(_class('A')).rawType;
+ var A = coreTypes.rawType(_addClass(_class('A')), Nullability.legacy);
var env = _makeEnv();
expect(env.getStandardLowerBound(bottomType, A), same(bottomType));
expect(env.getStandardLowerBound(A, bottomType), same(bottomType));
}
void test_glb_function() {
- var A = _addClass(_class('A')).rawType;
- var B =
- _addClass(_class('B', supertype: A.classNode.asThisSupertype)).rawType;
+ var A = coreTypes.rawType(_addClass(_class('A')), Nullability.legacy);
+ var B = coreTypes.rawType(
+ _addClass(_class('B', supertype: A.classNode.asThisSupertype)),
+ Nullability.legacy);
var env = _makeEnv();
// GLB(() -> A, () -> B) = () -> B
expect(
@@ -219,23 +222,24 @@
}
void test_glb_identical() {
- var A = _addClass(_class('A')).rawType;
+ var A = coreTypes.rawType(_addClass(_class('A')), Nullability.legacy);
var env = _makeEnv();
expect(env.getStandardLowerBound(A, A), same(A));
expect(env.getStandardLowerBound(new InterfaceType(A.classNode), A), A);
}
void test_glb_subtype() {
- var A = _addClass(_class('A')).rawType;
- var B =
- _addClass(_class('B', supertype: A.classNode.asThisSupertype)).rawType;
+ var A = coreTypes.rawType(_addClass(_class('A')), Nullability.legacy);
+ var B = coreTypes.rawType(
+ _addClass(_class('B', supertype: A.classNode.asThisSupertype)),
+ Nullability.legacy);
var env = _makeEnv();
expect(env.getStandardLowerBound(A, B), same(B));
expect(env.getStandardLowerBound(B, A), same(B));
}
void test_glb_top() {
- var A = _addClass(_class('A')).rawType;
+ var A = coreTypes.rawType(_addClass(_class('A')), Nullability.legacy);
var env = _makeEnv();
expect(env.getStandardLowerBound(dynamicType, A), same(A));
expect(env.getStandardLowerBound(A, dynamicType), same(A));
@@ -246,15 +250,15 @@
}
void test_glb_unknown() {
- var A = _addClass(_class('A')).rawType;
+ var A = coreTypes.rawType(_addClass(_class('A')), Nullability.legacy);
var env = _makeEnv();
expect(env.getStandardLowerBound(A, unknownType), same(A));
expect(env.getStandardLowerBound(unknownType, A), same(A));
}
void test_glb_unrelated() {
- var A = _addClass(_class('A')).rawType;
- var B = _addClass(_class('B')).rawType;
+ var A = coreTypes.rawType(_addClass(_class('A')), Nullability.legacy);
+ var B = coreTypes.rawType(_addClass(_class('B')), Nullability.legacy);
var env = _makeEnv();
expect(env.getStandardLowerBound(A, B), same(bottomType));
}
@@ -350,19 +354,25 @@
// B C
// |X|
// D E
- var A = _addClass(_class('A')).rawType;
- var B =
- _addClass(_class('B', supertype: A.classNode.asThisSupertype)).rawType;
- var C =
- _addClass(_class('C', supertype: A.classNode.asThisSupertype)).rawType;
- var D = _addClass(_class('D', implementedTypes: [
- B.classNode.asThisSupertype,
- C.classNode.asThisSupertype
- ])).rawType;
- var E = _addClass(_class('E', implementedTypes: [
- B.classNode.asThisSupertype,
- C.classNode.asThisSupertype
- ])).rawType;
+ var A = coreTypes.rawType(_addClass(_class('A')), Nullability.legacy);
+ var B = coreTypes.rawType(
+ _addClass(_class('B', supertype: A.classNode.asThisSupertype)),
+ Nullability.legacy);
+ var C = coreTypes.rawType(
+ _addClass(_class('C', supertype: A.classNode.asThisSupertype)),
+ Nullability.legacy);
+ var D = coreTypes.rawType(
+ _addClass(_class('D', implementedTypes: [
+ B.classNode.asThisSupertype,
+ C.classNode.asThisSupertype
+ ])),
+ Nullability.legacy);
+ var E = coreTypes.rawType(
+ _addClass(_class('E', implementedTypes: [
+ B.classNode.asThisSupertype,
+ C.classNode.asThisSupertype
+ ])),
+ Nullability.legacy);
var env = _makeEnv();
expect(env.getStandardUpperBound(D, E), A);
}
@@ -374,9 +384,10 @@
}
void test_lub_function() {
- var A = _addClass(_class('A')).rawType;
- var B =
- _addClass(_class('B', supertype: A.classNode.asThisSupertype)).rawType;
+ var A = coreTypes.rawType(_addClass(_class('A')), Nullability.legacy);
+ var B = coreTypes.rawType(
+ _addClass(_class('B', supertype: A.classNode.asThisSupertype)),
+ Nullability.legacy);
var env = _makeEnv();
// LUB(() -> A, () -> B) = () -> A
expect(
@@ -490,16 +501,17 @@
}
void test_lub_identical() {
- var A = _addClass(_class('A')).rawType;
+ var A = coreTypes.rawType(_addClass(_class('A')), Nullability.legacy);
var env = _makeEnv();
expect(env.getStandardUpperBound(A, A), same(A));
expect(env.getStandardUpperBound(new InterfaceType(A.classNode), A), A);
}
void test_lub_sameClass() {
- var A = _addClass(_class('A')).rawType;
- var B =
- _addClass(_class('B', supertype: A.classNode.asThisSupertype)).rawType;
+ var A = coreTypes.rawType(_addClass(_class('A')), Nullability.legacy);
+ var B = coreTypes.rawType(
+ _addClass(_class('B', supertype: A.classNode.asThisSupertype)),
+ Nullability.legacy);
var env = _makeEnv();
expect(env.getStandardUpperBound(_map(A, B), _map(B, A)), _map(A, A));
}
@@ -513,7 +525,7 @@
}
void test_lub_top() {
- var A = _addClass(_class('A')).rawType;
+ var A = coreTypes.rawType(_addClass(_class('A')), Nullability.legacy);
var env = _makeEnv();
expect(env.getStandardUpperBound(dynamicType, A), same(dynamicType));
expect(env.getStandardUpperBound(A, dynamicType), same(dynamicType));
@@ -549,16 +561,17 @@
}
void test_lub_unknown() {
- var A = _addClass(_class('A')).rawType;
+ var A = coreTypes.rawType(_addClass(_class('A')), Nullability.legacy);
var env = _makeEnv();
expect(env.getStandardLowerBound(A, unknownType), same(A));
expect(env.getStandardLowerBound(unknownType, A), same(A));
}
void test_solveTypeConstraint() {
- var A = _addClass(_class('A')).rawType;
- var B =
- _addClass(_class('B', supertype: A.classNode.asThisSupertype)).rawType;
+ var A = coreTypes.rawType(_addClass(_class('A')), Nullability.legacy);
+ var B = coreTypes.rawType(
+ _addClass(_class('B', supertype: A.classNode.asThisSupertype)),
+ Nullability.legacy);
var env = _makeEnv();
// Solve(? <: T <: ?) => ?
expect(env.solveTypeConstraint(_makeConstraint()), same(unknownType));
@@ -653,15 +666,19 @@
}
void test_typeSatisfiesConstraint() {
- var A = _addClass(_class('A')).rawType;
- var B =
- _addClass(_class('B', supertype: A.classNode.asThisSupertype)).rawType;
- var C =
- _addClass(_class('C', supertype: B.classNode.asThisSupertype)).rawType;
- var D =
- _addClass(_class('D', supertype: C.classNode.asThisSupertype)).rawType;
- var E =
- _addClass(_class('E', supertype: D.classNode.asThisSupertype)).rawType;
+ var A = coreTypes.rawType(_addClass(_class('A')), Nullability.legacy);
+ var B = coreTypes.rawType(
+ _addClass(_class('B', supertype: A.classNode.asThisSupertype)),
+ Nullability.legacy);
+ var C = coreTypes.rawType(
+ _addClass(_class('C', supertype: B.classNode.asThisSupertype)),
+ Nullability.legacy);
+ var D = coreTypes.rawType(
+ _addClass(_class('D', supertype: C.classNode.asThisSupertype)),
+ Nullability.legacy);
+ var E = coreTypes.rawType(
+ _addClass(_class('E', supertype: D.classNode.asThisSupertype)),
+ Nullability.legacy);
var env = _makeEnv();
var typeConstraint = _makeConstraint(upper: B, lower: D);
expect(env.typeSatisfiesConstraint(A, typeConstraint), isFalse);
@@ -672,13 +689,13 @@
}
void test_unknown_at_bottom() {
- var A = _addClass(_class('A')).rawType;
+ var A = coreTypes.rawType(_addClass(_class('A')), Nullability.legacy);
var env = _makeEnv();
expect(env.isSubtypeOf(unknownType, A), isTrue);
}
void test_unknown_at_top() {
- var A = _addClass(_class('A')).rawType;
+ var A = coreTypes.rawType(_addClass(_class('A')), Nullability.legacy);
var env = _makeEnv();
expect(env.isSubtypeOf(A, unknownType), isTrue);
}
diff --git a/pkg/front_end/test/fasta/types/fasta_legacy_upper_bound_test.dart b/pkg/front_end/test/fasta/types/fasta_legacy_upper_bound_test.dart
index dec96a2..289f047 100644
--- a/pkg/front_end/test/fasta/types/fasta_legacy_upper_bound_test.dart
+++ b/pkg/front_end/test/fasta/types/fasta_legacy_upper_bound_test.dart
@@ -48,12 +48,12 @@
await target.buildOutlines();
ClassBuilder objectClass =
loader.coreLibrary.lookupLocalMember("Object", required: true);
- hierarchy = new ClassHierarchyBuilder(
- objectClass, loader, new CoreTypes(component));
+ hierarchy = new ClassHierarchyBuilder(objectClass, loader, coreTypes);
}
@override
- DartType getLegacyLeastUpperBound(DartType a, DartType b) {
+ DartType getLegacyLeastUpperBound(
+ DartType a, DartType b, CoreTypes coreTypes) {
return hierarchy.getKernelLegacyLeastUpperBound(a, b);
}
}
diff --git a/pkg/front_end/test/fasta/types/kernel_legacy_upper_bound_test.dart b/pkg/front_end/test/fasta/types/kernel_legacy_upper_bound_test.dart
index 9004191..da6a0ad 100644
--- a/pkg/front_end/test/fasta/types/kernel_legacy_upper_bound_test.dart
+++ b/pkg/front_end/test/fasta/types/kernel_legacy_upper_bound_test.dart
@@ -8,6 +8,8 @@
import "package:kernel/class_hierarchy.dart" show ClassHierarchy;
+import "package:kernel/core_types.dart" show CoreTypes;
+
class KernelLegacyUpperBoundTest extends LegacyUpperBoundTest {
ClassHierarchy hierarchy;
@@ -19,8 +21,9 @@
}
@override
- DartType getLegacyLeastUpperBound(DartType a, DartType b) {
- return hierarchy.getLegacyLeastUpperBound(a, b);
+ DartType getLegacyLeastUpperBound(
+ DartType a, DartType b, CoreTypes coreTypes) {
+ return hierarchy.getLegacyLeastUpperBound(a, b, coreTypes);
}
}
diff --git a/pkg/front_end/test/fasta/types/kernel_type_parser.dart b/pkg/front_end/test/fasta/types/kernel_type_parser.dart
index 4d47cf6..4a7f3b8 100644
--- a/pkg/front_end/test/fasta/types/kernel_type_parser.dart
+++ b/pkg/front_end/test/fasta/types/kernel_type_parser.dart
@@ -336,7 +336,7 @@
TypeParameter typeParameter = typeParameters[i];
if (bound == null) {
typeParameter
- ..bound = objectClass.rawType
+ ..bound = new InterfaceType(objectClass)
..defaultType = const DynamicType();
} else {
DartType type =
diff --git a/pkg/front_end/test/fasta/types/legacy_upper_bound_helper.dart b/pkg/front_end/test/fasta/types/legacy_upper_bound_helper.dart
index 1a6c955..7b13fe0 100644
--- a/pkg/front_end/test/fasta/types/legacy_upper_bound_helper.dart
+++ b/pkg/front_end/test/fasta/types/legacy_upper_bound_helper.dart
@@ -8,6 +8,8 @@
import "package:kernel/ast.dart" show Class, Component, DartType, InterfaceType;
+import "package:kernel/core_types.dart";
+
import "package:kernel/library_index.dart" show LibraryIndex;
import "kernel_type_parser.dart" as kernel_type_parser show parseComponent;
@@ -17,20 +19,23 @@
abstract class LegacyUpperBoundTest {
Component component;
+ CoreTypes coreTypes;
+
LibraryIndex index;
- DartType get objectType => getCoreClass("Object").rawType;
+ DartType get objectType => coreTypes.objectLegacyRawType;
- DartType get intType => getCoreClass("int").rawType;
+ DartType get intType => coreTypes.intLegacyRawType;
- DartType get stringType => getCoreClass("String").rawType;
+ DartType get stringType => coreTypes.intLegacyRawType;
- DartType get doubleType => getCoreClass("double").rawType;
+ DartType get doubleType => coreTypes.doubleLegacyRawType;
- DartType get boolType => getCoreClass("bool").rawType;
+ DartType get boolType => coreTypes.boolLegacyRawType;
void parseComponent(String source) {
component = kernel_type_parser.parseComponent(source, libraryUri);
+ coreTypes = new CoreTypes(component);
index = new LibraryIndex.all(component);
}
@@ -42,11 +47,12 @@
return index.getClass("dart:core", name);
}
- DartType getLegacyLeastUpperBound(DartType a, DartType b);
+ DartType getLegacyLeastUpperBound(
+ DartType a, DartType b, CoreTypes coreTypes);
void checkGetLegacyLeastUpperBound(
DartType a, DartType b, DartType expected) {
- DartType actual = getLegacyLeastUpperBound(a, b);
+ DartType actual = getLegacyLeastUpperBound(a, b, coreTypes);
Expect.equals(expected, actual);
}
@@ -125,9 +131,9 @@
new InterfaceType(d, [boolType, doubleType]),
new InterfaceType(c, [doubleType]));
checkGetLegacyLeastUpperBound(new InterfaceType(d, [intType, doubleType]),
- new InterfaceType(d, [boolType, intType]), a.rawType);
- checkGetLegacyLeastUpperBound(
- e.rawType, f.rawType, new InterfaceType(b, [intType]));
+ new InterfaceType(d, [boolType, intType]), coreTypes.legacyRawType(a));
+ checkGetLegacyLeastUpperBound(coreTypes.legacyRawType(e),
+ coreTypes.legacyRawType(f), new InterfaceType(b, [intType]));
}
Future<void> test_getLegacyLeastUpperBound_nonGeneric() async {
@@ -152,13 +158,21 @@
Class h = getClass("H");
Class i = getClass("I");
- checkGetLegacyLeastUpperBound(a.rawType, b.rawType, objectType);
- checkGetLegacyLeastUpperBound(a.rawType, objectType, objectType);
- checkGetLegacyLeastUpperBound(objectType, b.rawType, objectType);
- checkGetLegacyLeastUpperBound(c.rawType, d.rawType, a.rawType);
- checkGetLegacyLeastUpperBound(c.rawType, a.rawType, a.rawType);
- checkGetLegacyLeastUpperBound(a.rawType, d.rawType, a.rawType);
- checkGetLegacyLeastUpperBound(f.rawType, g.rawType, a.rawType);
- checkGetLegacyLeastUpperBound(h.rawType, i.rawType, a.rawType);
+ checkGetLegacyLeastUpperBound(
+ coreTypes.legacyRawType(a), coreTypes.legacyRawType(b), objectType);
+ checkGetLegacyLeastUpperBound(
+ coreTypes.legacyRawType(a), objectType, objectType);
+ checkGetLegacyLeastUpperBound(
+ objectType, coreTypes.legacyRawType(b), objectType);
+ checkGetLegacyLeastUpperBound(coreTypes.legacyRawType(c),
+ coreTypes.legacyRawType(d), coreTypes.legacyRawType(a));
+ checkGetLegacyLeastUpperBound(coreTypes.legacyRawType(c),
+ coreTypes.legacyRawType(a), coreTypes.legacyRawType(a));
+ checkGetLegacyLeastUpperBound(coreTypes.legacyRawType(a),
+ coreTypes.legacyRawType(d), coreTypes.legacyRawType(a));
+ checkGetLegacyLeastUpperBound(coreTypes.legacyRawType(f),
+ coreTypes.legacyRawType(g), coreTypes.legacyRawType(a));
+ checkGetLegacyLeastUpperBound(coreTypes.legacyRawType(h),
+ coreTypes.legacyRawType(i), coreTypes.legacyRawType(a));
}
}
diff --git a/pkg/front_end/test/fasta/unlinked_scope_test.dart b/pkg/front_end/test/fasta/unlinked_scope_test.dart
index 05a25dc..d9eea6f 100644
--- a/pkg/front_end/test/fasta/unlinked_scope_test.dart
+++ b/pkg/front_end/test/fasta/unlinked_scope_test.dart
@@ -51,8 +51,8 @@
new KernelTarget(
null,
false,
- new DillTarget(null, null,
- new NoneTarget(new TargetFlags(legacyMode: true))),
+ new DillTarget(
+ null, null, new NoneTarget(new TargetFlags())),
null)
.loader,
null);
diff --git a/pkg/front_end/test/flow_analysis/definite_assignment/data/for_each.dart b/pkg/front_end/test/flow_analysis/definite_assignment/data/for_each.dart
index 57a41f8..7276903 100644
--- a/pkg/front_end/test/flow_analysis/definite_assignment/data/for_each.dart
+++ b/pkg/front_end/test/flow_analysis/definite_assignment/data/for_each.dart
@@ -33,9 +33,33 @@
/*unassigned*/ v2;
}
+forEach_assigns_to_identifier() {
+ late int i;
+ for (i in [0, 1, 2]) {
+ i;
+ }
+ /*unassigned*/ i;
+}
+
+forEach_assigns_to_declared_var() {
+ for (int i in [0, 1, 2]) {
+ i;
+ }
+}
+
collection_forEach() {
late Object v1, v2;
[for (var _ in (v1 = [0, 1, 2])) (v2 = 0)];
v1;
/*unassigned*/ v2;
}
+
+collection_forEach_assigns_to_identifier() {
+ late int i;
+ [for (i in [0, 1, 2]) i];
+ /*unassigned*/ i;
+}
+
+collection_forEach_assigns_to_declared_var() {
+ [for (int i in [0, 1, 2]) i];
+}
diff --git a/pkg/front_end/test/hot_reload_e2e_test.dart b/pkg/front_end/test/hot_reload_e2e_test.dart
index 2b10afd..cda1f76 100644
--- a/pkg/front_end/test/hot_reload_e2e_test.dart
+++ b/pkg/front_end/test/hot_reload_e2e_test.dart
@@ -301,7 +301,6 @@
var options = new CompilerOptions()
..sdkRoot = sdkRoot
..librariesSpecificationUri = Uri.base.resolve("sdk/lib/libraries.json")
- ..legacyMode = true
..fileSystem = fs;
return new IncrementalKernelGenerator(options, entryUri);
}
diff --git a/pkg/front_end/test/incremental_dart2js_load_from_dill_test.dart b/pkg/front_end/test/incremental_dart2js_load_from_dill_test.dart
index f1469a1..2b16989 100644
--- a/pkg/front_end/test/incremental_dart2js_load_from_dill_test.dart
+++ b/pkg/front_end/test/incremental_dart2js_load_from_dill_test.dart
@@ -84,7 +84,7 @@
bool initializeResult = await initializedCompile(
dart2jsUrl, fullDillFromInitialized, initializeWith, [invalidateUri],
options: getOptions()..target = new NoneTarget(new TargetFlags()));
- Expect.equals(initializeResult, initializeExpect);
+ Expect.equals(initializeExpect, initializeResult);
print("Initialized compile(s) from ${initializeWith.pathSegments.last} "
"took ${stopwatch.elapsedMilliseconds} ms");
diff --git a/pkg/front_end/test/incremental_load_from_dill_test.dart b/pkg/front_end/test/incremental_load_from_dill_test.dart
index d258364..dd6bf04 100644
--- a/pkg/front_end/test/incremental_load_from_dill_test.dart
+++ b/pkg/front_end/test/incremental_load_from_dill_test.dart
@@ -839,14 +839,20 @@
Future<Component> normalCompileToComponent(Uri input,
{CompilerOptions options, IncrementalCompiler compiler}) async {
- options ??= getOptions();
- compiler ??= new TestIncrementalCompiler(options, input);
- Component component = await compiler.computeDelta();
+ Component component =
+ await normalCompilePlain(input, options: options, compiler: compiler);
util.throwOnEmptyMixinBodies(component);
util.throwOnInsufficientUriToSource(component);
return component;
}
+Future<Component> normalCompilePlain(Uri input,
+ {CompilerOptions options, IncrementalCompiler compiler}) async {
+ options ??= getOptions();
+ compiler ??= new TestIncrementalCompiler(options, input);
+ return await compiler.computeDelta();
+}
+
Future<bool> initializedCompile(
Uri input, Uri output, Uri initializeWith, List<Uri> invalidateUris,
{CompilerOptions options}) async {
diff --git a/pkg/front_end/test/lint_test.status b/pkg/front_end/test/lint_test.status
index f7c20bf..f943795 100644
--- a/pkg/front_end/test/lint_test.status
+++ b/pkg/front_end/test/lint_test.status
@@ -9,7 +9,6 @@
src/fasta/incremental_compiler/ImportsTwice: Fail
src/fasta/kernel/body_builder/ImportsTwice: Fail
src/fasta/kernel/expression_generator_helper/ImportsTwice: Fail
-src/fasta/kernel/kernel_shadow_ast/ImportsTwice: Fail
src/fasta/parser/parser/ImportsTwice: Fail
src/fasta/scanner/abstract_scanner/ImportsTwice: Fail
src/fasta/scanner/recover/ImportsTwice: Fail
diff --git a/pkg/front_end/test/scanner_test.dart b/pkg/front_end/test/scanner_test.dart
index bd3ab0a..8f9700e 100644
--- a/pkg/front_end/test/scanner_test.dart
+++ b/pkg/front_end/test/scanner_test.dart
@@ -544,6 +544,16 @@
_assertKeywordToken("in");
}
+ void test_keyword_inout() {
+ _assertKeywordToken("inout",
+ configuration: ScannerConfiguration(enableVariance: true));
+ }
+
+ void test_keyword_inout_old() {
+ _assertNotKeywordToken("inout",
+ configuration: ScannerConfiguration(enableVariance: false));
+ }
+
void test_keyword_is() {
_assertKeywordToken("is");
}
@@ -590,6 +600,16 @@
_assertKeywordToken("operator");
}
+ void test_keyword_out() {
+ _assertKeywordToken("out",
+ configuration: ScannerConfiguration(enableVariance: true));
+ }
+
+ void test_keyword_out_old() {
+ _assertNotKeywordToken("out",
+ configuration: ScannerConfiguration(enableVariance: false));
+ }
+
void test_keyword_part() {
_assertKeywordToken("part");
}
diff --git a/pkg/front_end/test/spell_checking_list_code.txt b/pkg/front_end/test/spell_checking_list_code.txt
index 7a131c6..893e05d 100644
--- a/pkg/front_end/test/spell_checking_list_code.txt
+++ b/pkg/front_end/test/spell_checking_list_code.txt
@@ -102,6 +102,7 @@
bypassing
c
caches
+calculations
callee
caller's
callers
@@ -229,6 +230,8 @@
dijkstra's
directed
directions
+dirtify
+dirtifying
dirty
disallow
disambiguator
@@ -302,6 +305,7 @@
fff
ffff
fffff
+ffffffff
ffi
file's
filenames
@@ -638,6 +642,8 @@
reassigned
rebind
rebuild
+recalculating
+recalculation
recall
received
recompiled
diff --git a/pkg/front_end/test/spell_checking_list_common.txt b/pkg/front_end/test/spell_checking_list_common.txt
index f27e950..00968fa 100644
--- a/pkg/front_end/test/spell_checking_list_common.txt
+++ b/pkg/front_end/test/spell_checking_list_common.txt
@@ -683,6 +683,7 @@
delegates
delegation
delete
+deleted
deliberately
delimited
delimiter
@@ -914,6 +915,7 @@
escaped
escapes
escaping
+especially
essence
essentials
etc
@@ -1353,6 +1355,7 @@
inlining
inner
innermost
+inout
input
inputs
insert
@@ -2147,6 +2150,7 @@
really
reason
reasonable
+reasoning
reasons
receive
receiver
@@ -2307,6 +2311,7 @@
retype
reuse
reused
+reuses
reusing
reverse
reversed
diff --git a/pkg/front_end/test/spell_checking_list_tests.txt b/pkg/front_end/test/spell_checking_list_tests.txt
index 6786412..22cb2ac 100644
--- a/pkg/front_end/test/spell_checking_list_tests.txt
+++ b/pkg/front_end/test/spell_checking_list_tests.txt
@@ -210,6 +210,7 @@
lc
ld
le
+lengths
lightly
likewise
linebreaks
@@ -312,6 +313,7 @@
shipped
shot
signalled
+somehow
spans
spell
spellcheck
@@ -350,6 +352,8 @@
trigger
triggers
trimming
+tripped
+tripping
trivially
truncated
tt
diff --git a/pkg/front_end/test/split_dill_test.dart b/pkg/front_end/test/split_dill_test.dart
new file mode 100644
index 0000000..828dae4
--- /dev/null
+++ b/pkg/front_end/test/split_dill_test.dart
@@ -0,0 +1,99 @@
+// Copyright (c) 2019, 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.
+
+import 'dart:io' show Directory, File, Platform, Process, ProcessResult;
+
+import 'dart:typed_data' show Uint8List;
+
+import 'package:front_end/src/fasta/kernel/utils.dart' show serializeComponent;
+
+import 'package:kernel/ast.dart' show Component, Library;
+
+import 'package:kernel/binary/ast_from_binary.dart' show BinaryBuilder;
+
+import 'package:kernel/target/targets.dart' show TargetFlags;
+
+import "package:vm/target/vm.dart" show VmTarget;
+
+import 'incremental_load_from_dill_test.dart'
+ show getOptions, normalCompileToComponent;
+
+import 'utils/io_utils.dart' show computeRepoDir;
+
+main() async {
+ final Uri dart2jsUrl = Uri.base.resolve("pkg/compiler/bin/dart2js.dart");
+ Stopwatch stopwatch = new Stopwatch()..start();
+ Component component = await normalCompileToComponent(dart2jsUrl,
+ options: getOptions()
+ ..target = new VmTarget(new TargetFlags())
+ ..omitPlatform = false);
+ print("Compiled dart2js in ${stopwatch.elapsedMilliseconds} ms");
+
+ component.computeCanonicalNames();
+
+ stopwatch.reset();
+ List<List<int>> libComponents = new List<List<int>>();
+ for (Library lib in component.libraries) {
+ Component libComponent = new Component(nameRoot: component.root);
+ libComponent.libraries.add(lib);
+ libComponent.uriToSource.addAll(component.uriToSource);
+ libComponent.mainMethod = component.mainMethod;
+ libComponents.add(serializeComponent(libComponent));
+ }
+ print("Serialized ${libComponents.length} separate library components "
+ "in ${stopwatch.elapsedMilliseconds} ms");
+
+ stopwatch.reset();
+ int totalLength = 0;
+ for (List<int> libComponent in libComponents) {
+ totalLength += libComponent.length;
+ }
+ Uint8List combined = new Uint8List(totalLength);
+ int index = 0;
+ for (List<int> libComponent in libComponents) {
+ combined.setRange(index, index + libComponent.length, libComponent);
+ index += libComponent.length;
+ }
+ print("Combined in ${stopwatch.elapsedMilliseconds} ms");
+
+ stopwatch.reset();
+ Component combinedComponent = new Component();
+ new BinaryBuilder(combined).readComponent(combinedComponent);
+ print("Read combined in ${stopwatch.elapsedMilliseconds} ms");
+
+ stopwatch.reset();
+ Uint8List merged = serializeComponent(combinedComponent);
+ print("Serialized combined component in ${stopwatch.elapsedMilliseconds} ms");
+
+ for (Uint8List data in [combined, merged]) {
+ stopwatch.reset();
+ Directory out = Directory.systemTemp.createTempSync("split_dill_test");
+ try {
+ File f = new File.fromUri(out.uri.resolve("out.dill"));
+ f.writeAsBytesSync(data);
+
+ ProcessResult result = await Process.run(
+ dartVm,
+ [
+ "--compile_all",
+ f.path,
+ "-h",
+ ],
+ workingDirectory: out.path);
+ print("stdout: ${result.stdout}");
+ print("stderr: ${result.stderr}");
+ print("Exit code: ${result.exitCode}");
+ if (result.exitCode != 0) {
+ throw "Got exit code ${result.exitCode}";
+ }
+ print("Ran VM on dill in ${stopwatch.elapsedMilliseconds} ms");
+ } finally {
+ out.deleteSync(recursive: true);
+ }
+ }
+}
+
+final String repoDir = computeRepoDir();
+
+String get dartVm => Platform.resolvedExecutable;
diff --git a/pkg/front_end/test/static_types/data/null_aware_for_in.dart b/pkg/front_end/test/static_types/data/null_aware_for_in.dart
new file mode 100644
index 0000000..56ea80b
--- /dev/null
+++ b/pkg/front_end/test/static_types/data/null_aware_for_in.dart
@@ -0,0 +1,12 @@
+// Copyright (c) 2019, 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.
+
+class Class {}
+
+main() {
+ var o;
+ // ignore: unused_local_variable
+ /*as: Class*/ for (Class c
+ in /*as: Iterable<dynamic>*/ /*dynamic*/ o?. /*dynamic*/ iterable) {}
+}
diff --git a/pkg/front_end/test/static_types/static_type_test.dart b/pkg/front_end/test/static_types/static_type_test.dart
index 5a0f1f2..0014368 100644
--- a/pkg/front_end/test/static_types/static_type_test.dart
+++ b/pkg/front_end/test/static_types/static_type_test.dart
@@ -58,4 +58,16 @@
}
return null;
}
+
+ ActualData<String> mergeData(
+ ActualData<String> value1, ActualData<String> value2) {
+ if (value1.object is NullLiteral && value2.object is! NullLiteral) {
+ // Skip `null` literals from null-aware operations.
+ return value2;
+ } else if (value1.object is! NullLiteral && value2.object is NullLiteral) {
+ // Skip `null` literals from null-aware operations.
+ return value1;
+ }
+ return null;
+ }
}
diff --git a/pkg/front_end/test/token_test.dart b/pkg/front_end/test/token_test.dart
index dda8af0..cef530f 100644
--- a/pkg/front_end/test/token_test.dart
+++ b/pkg/front_end/test/token_test.dart
@@ -171,9 +171,11 @@
Keyword.AWAIT,
Keyword.FUNCTION,
Keyword.HIDE,
+ Keyword.INOUT,
Keyword.NATIVE,
Keyword.OF,
Keyword.ON,
+ Keyword.OUT,
Keyword.PATCH,
Keyword.SHOW,
Keyword.SOURCE,
diff --git a/pkg/front_end/test/utils/kernel_chain.dart b/pkg/front_end/test/utils/kernel_chain.dart
index fca8792..7b44127 100644
--- a/pkg/front_end/test/utils/kernel_chain.dart
+++ b/pkg/front_end/test/utils/kernel_chain.dart
@@ -35,8 +35,6 @@
import 'package:kernel/ast.dart' show Component, Library;
-import 'package:kernel/binary/ast_from_binary.dart' show BinaryBuilder;
-
import 'package:kernel/binary/ast_to_binary.dart' show BinaryPrinter;
import 'package:kernel/error_formatter.dart' show ErrorFormatter;
@@ -333,11 +331,7 @@
File generated = new File.fromUri(uri);
IOSink sink = generated.openWrite();
try {
- try {
- new BinaryPrinter(sink).writeComponentFile(component);
- } finally {
- component.unbindCanonicalNames();
- }
+ new BinaryPrinter(sink).writeComponentFile(component);
} catch (e, s) {
return fail(uri, e, s);
} finally {
@@ -363,21 +357,6 @@
}
}
-class Copy extends Step<Component, Component, ChainContext> {
- const Copy();
-
- String get name => "copy component";
-
- Future<Result<Component>> run(Component component, _) async {
- BytesCollector sink = new BytesCollector();
- new BinaryPrinter(sink).writeComponentFile(component);
- component.unbindCanonicalNames();
- Uint8List bytes = sink.collect();
- new BinaryBuilder(bytes).readComponent(component);
- return pass(component);
- }
-}
-
class BytesCollector implements Sink<List<int>> {
final List<List<int>> lists = <List<int>>[];
diff --git a/pkg/front_end/test/utils/validating_instrumentation.dart b/pkg/front_end/test/utils/validating_instrumentation.dart
index afdda22..741876c 100644
--- a/pkg/front_end/test/utils/validating_instrumentation.dart
+++ b/pkg/front_end/test/utils/validating_instrumentation.dart
@@ -194,7 +194,7 @@
_Expectation expectation = expectationsAtOffset[i];
if (expectation.property == property) {
if (!value.matches(expectation.value)) {
- _problemWithStack(
+ _problem(
uri,
offset,
'expected $property=${expectation.value}, got '
@@ -209,7 +209,7 @@
}
// Unexpected property/value pair. See if we should report.
if (_shouldCheck(property, uri, offset)) {
- _problemWithStack(
+ _problem(
uri,
offset,
'expected nothing, got $property=${value.toString()}',
@@ -273,6 +273,7 @@
_fixes.putIfAbsent(uri, () => []).add(fix);
}
+ /// ignore: unused_element
void _problemWithStack(Uri uri, int offset, String desc, _Fix fix) {
_problems.add(_formatProblem(uri, offset, desc, StackTrace.current));
_fixes.putIfAbsent(uri, () => []).add(fix);
diff --git a/pkg/front_end/testcases/dartino/add_static_field.incremental.yaml b/pkg/front_end/testcases/dartino/add_static_field.incremental.yaml
index e552e1a..6dee955 100644
--- a/pkg/front_end/testcases/dartino/add_static_field.incremental.yaml
+++ b/pkg/front_end/testcases/dartino/add_static_field.incremental.yaml
@@ -15,7 +15,7 @@
print("v1");
====
print(C.field);
- field = "value";
+ C.field = "value";
print(C.field);
>>>>
}
diff --git a/pkg/front_end/testcases/dartino/add_static_method.incremental.yaml b/pkg/front_end/testcases/dartino/add_static_method.incremental.yaml
index 4a45a2b..1874341 100644
--- a/pkg/front_end/testcases/dartino/add_static_method.incremental.yaml
+++ b/pkg/front_end/testcases/dartino/add_static_method.incremental.yaml
@@ -6,7 +6,7 @@
// Test that static methods can be added
class C {
- <<<< "threw"
+ <<<< "v1"
==== "v2"
static foo() {
print('v2');
@@ -15,10 +15,9 @@
}
main() {
- new C(); // TODO(ahe): Work around dart2js assertion in World.subclassesOf
- try {
+ <<<<
+ print("v1");
+ ====
C.foo();
- } catch(e) {
- print('threw');
- }
+ >>>>
}
diff --git a/pkg/front_end/testcases/dartino/add_top_level_method.incremental.yaml b/pkg/front_end/testcases/dartino/add_top_level_method.incremental.yaml
index 7d3f08c..4c7b3e8 100644
--- a/pkg/front_end/testcases/dartino/add_top_level_method.incremental.yaml
+++ b/pkg/front_end/testcases/dartino/add_top_level_method.incremental.yaml
@@ -5,16 +5,15 @@
main.dart.patch: |
// Test that top-level functions can be added
- <<<< "threw"
+ <<<< []
==== "v2"
foo() {
print('v2');
}
>>>>
main() {
- try {
+ <<<<
+ ====
foo();
- } catch(e) {
- print('threw');
- }
+ >>>>
}
diff --git a/pkg/front_end/testcases/dartino/bad_diagnostics.incremental.yaml b/pkg/front_end/testcases/dartino/bad_diagnostics.incremental.yaml
index b84bac2..259f494 100644
--- a/pkg/front_end/testcases/dartino/bad_diagnostics.incremental.yaml
+++ b/pkg/front_end/testcases/dartino/bad_diagnostics.incremental.yaml
@@ -6,7 +6,7 @@
// Test that our diagnostics handler doesn't crash
main() {
<<<< []
- ==== []
+ ==== {"messages":[],"hasCompileTimeError":1}
// This is a long comment to guarantee that we have a position beyond the end
// of the first version of this file.
NoSuchClass c = null; // Provoke a warning to exercise the diagnostic handler.
diff --git a/pkg/front_end/testcases/dartino/compile_time_error_006.incremental.yaml b/pkg/front_end/testcases/dartino/compile_time_error_006.incremental.yaml
index eda61f0..c0a306c 100644
--- a/pkg/front_end/testcases/dartino/compile_time_error_006.incremental.yaml
+++ b/pkg/front_end/testcases/dartino/compile_time_error_006.incremental.yaml
@@ -3,16 +3,15 @@
# BSD-style license that can be found in the LICENSE.md file.
main.dart.patch: |
- <<<< "error"
+ <<<< []
==== {"messages":[],"hasCompileTimeError":1}
test({b}) {
if (?b) return b;
}
>>>>
main() {
- try {
- test(b: 2);
- } catch (e) {
- print("error");
- }
+ <<<<
+ ====
+ test(b: 2);
+ >>>>
}
diff --git a/pkg/front_end/testcases/dartino/instance_field_to_static_field.incremental.yaml b/pkg/front_end/testcases/dartino/instance_field_to_static_field.incremental.yaml
index fa6f56b..aeb652c 100644
--- a/pkg/front_end/testcases/dartino/instance_field_to_static_field.incremental.yaml
+++ b/pkg/front_end/testcases/dartino/instance_field_to_static_field.incremental.yaml
@@ -6,14 +6,14 @@
// Test that instance field can be made static
class C {
- <<<< ["[instance] is null","[C.x] threw","v1"]
- int x;
+ <<<< {"messages":[],"hasCompileTimeError":1}
+ String x;
==== ["v2","[instance.x] threw"]
- static int x;
+ static String x;
>>>>
}
- var instance;
+ dynamic instance;
main() {
if (instance == null) {
diff --git a/pkg/front_end/testcases/dartino/remove_class.incremental.yaml b/pkg/front_end/testcases/dartino/remove_class.incremental.yaml
index f0218de..618a7a3 100644
--- a/pkg/front_end/testcases/dartino/remove_class.incremental.yaml
+++ b/pkg/front_end/testcases/dartino/remove_class.incremental.yaml
@@ -8,13 +8,9 @@
<<<< "v1"
class C {
}
- ==== {"messages":["v2"]}
+ ==== {"messages":[],"hasCompileTimeError":1}
>>>>
main() {
- try {
- new C();
- print('v1');
- } catch (e) {
- print('v2');
- }
+ new C();
+ print('v1');
}
diff --git a/pkg/front_end/testcases/dartino/remove_class_with_static_method.incremental.yaml b/pkg/front_end/testcases/dartino/remove_class_with_static_method.incremental.yaml
index 1ed4752..a687de8 100644
--- a/pkg/front_end/testcases/dartino/remove_class_with_static_method.incremental.yaml
+++ b/pkg/front_end/testcases/dartino/remove_class_with_static_method.incremental.yaml
@@ -11,12 +11,9 @@
print('v1');
}
}
- ==== "v2"
+ ==== {"messages":[],"hasCompileTimeError":1}
>>>>
main() {
- try {
- C.m();
- } catch (e) {
- print('v2');
- }
+ C.m();
+ print('v2');
}
diff --git a/pkg/front_end/testcases/dartino/remove_instance_method_stored_in_tearoff.incremental.yaml b/pkg/front_end/testcases/dartino/remove_instance_method_stored_in_tearoff.incremental.yaml
index 39f252c..4db42fd 100644
--- a/pkg/front_end/testcases/dartino/remove_instance_method_stored_in_tearoff.incremental.yaml
+++ b/pkg/front_end/testcases/dartino/remove_instance_method_stored_in_tearoff.incremental.yaml
@@ -10,7 +10,7 @@
m() {
print('v1');
}
- ==== {"messages":["threw", "threw"]}
+ ==== {"messages":[],"hasCompileTimeError":1}
>>>>
}
var closure;
@@ -19,15 +19,5 @@
print('instance is null');
closure = new C().m;
}
- try {
- closure();
- } catch (e) {
- print('threw');
- }
-
- try {
- new C().m;
- } catch (e) {
- print("threw");
- }
+ closure();
}
diff --git a/pkg/front_end/testcases/dartino/remove_instance_method_with_optional_parameters_stored_in_tearoff.incremental.yaml b/pkg/front_end/testcases/dartino/remove_instance_method_with_optional_parameters_stored_in_tearoff.incremental.yaml
index 21c855e..ff69c99 100644
--- a/pkg/front_end/testcases/dartino/remove_instance_method_with_optional_parameters_stored_in_tearoff.incremental.yaml
+++ b/pkg/front_end/testcases/dartino/remove_instance_method_with_optional_parameters_stored_in_tearoff.incremental.yaml
@@ -11,7 +11,7 @@
m([a = "a"]) {
print('v1');
}
- ==== ["threw", "threw"]
+ ==== {"messages":[],"hasCompileTimeError":1}
>>>>
}
var closure;
@@ -20,14 +20,6 @@
print('closure is null');
closure = new C().m;
}
- try {
- closure();
- } catch (e) {
- print('threw');
- }
- try {
- closure("b");
- } catch (e) {
- print('threw');
- }
+ closure();
+ closure("b");
}
diff --git a/pkg/front_end/testcases/dartino/remove_static_method.incremental.yaml b/pkg/front_end/testcases/dartino/remove_static_method.incremental.yaml
index aeb8ca6..f82093b 100644
--- a/pkg/front_end/testcases/dartino/remove_static_method.incremental.yaml
+++ b/pkg/front_end/testcases/dartino/remove_static_method.incremental.yaml
@@ -10,11 +10,11 @@
static staticMethod() {
print('v1');
}
- ==== "threw"
+ ==== {"messages":[],"hasCompileTimeError":1}
>>>>
}
class C {
- m() {
+ m(dynamic o) {
try {
B.staticMethod();
} catch (e) {
@@ -23,7 +23,7 @@
try {
// Ensure that noSuchMethod support is compiled. This test is not about
// adding new classes.
- B.missingMethod();
+ o.missingMethod();
print('bad');
} catch (e) {
}
@@ -31,10 +31,9 @@
}
var instance;
main() {
- new B(); // TODO(ahe): Work around dart2js assertion in World.subclassesOf
if (instance == null) {
print('instance is null');
instance = new C();
}
- instance.m();
+ instance.m(new B());
}
diff --git a/pkg/front_end/testcases/dartino/remove_top_level_method.incremental.yaml b/pkg/front_end/testcases/dartino/remove_top_level_method.incremental.yaml
index 5b10cc6..cc671ce 100644
--- a/pkg/front_end/testcases/dartino/remove_top_level_method.incremental.yaml
+++ b/pkg/front_end/testcases/dartino/remove_top_level_method.incremental.yaml
@@ -9,15 +9,11 @@
toplevel() {
print('v1');
}
- ==== {"messages":["threw"]}
+ ==== {"messages":[],"hasCompileTimeError":1}
>>>>
class C {
m() {
- try {
- toplevel();
- } catch (e) {
- print('threw');
- }
+ toplevel();
}
}
var instance;
diff --git a/pkg/front_end/testcases/dartino/static_field_to_instance_field.incremental.yaml b/pkg/front_end/testcases/dartino/static_field_to_instance_field.incremental.yaml
index 5823153..b75163d 100644
--- a/pkg/front_end/testcases/dartino/static_field_to_instance_field.incremental.yaml
+++ b/pkg/front_end/testcases/dartino/static_field_to_instance_field.incremental.yaml
@@ -7,13 +7,13 @@
class C {
<<<< ["[instance] is null","v1","[instance.x] threw"]
- static int x;
- ==== ["[C.x] threw","v2"]
- int x;
+ static String x;
+ ==== {"messages":[],"hasCompileTimeError":1}
+ String x;
>>>>
}
- var instance;
+ dynamic instance;
main() {
if (instance == null) {
diff --git a/pkg/front_end/testcases/dartino/super_call_signature_change.incremental.yaml b/pkg/front_end/testcases/dartino/super_call_signature_change.incremental.yaml
index 8cee0a9..d750812 100644
--- a/pkg/front_end/testcases/dartino/super_call_signature_change.incremental.yaml
+++ b/pkg/front_end/testcases/dartino/super_call_signature_change.incremental.yaml
@@ -5,11 +5,11 @@
main.dart.patch: |
// Test that super calls are dispatched correctly
class C {
- <<<< ["instance is null", "v1", "super.foo()", "super.foo(42) threw"]
+ <<<< ["instance is null", "v1", "super.foo()"]
foo() {
print('v1');
}
- ==== ["super.foo() threw", "v2", "super.foo(42)"]
+ ==== {"messages":[],"hasCompileTimeError":1}
foo(int i) {
print('v2');
}
@@ -17,8 +17,7 @@
}
class B extends C {
- superFooNoArgs() => super.foo();
- superFooOneArg(x) => super.foo(x);
+ superFoo() => super.foo();
}
var instance;
@@ -28,16 +27,6 @@
print('instance is null');
instance = new B();
}
- try {
- instance.superFooNoArgs();
- print("super.foo()");
- } catch (e) {
- print("super.foo() threw");
- }
- try {
- instance.superFooOneArg(42);
- print("super.foo(42)");
- } catch (e) {
- print("super.foo(42) threw");
- }
+ instance.superFoo();
+ print("super.foo()");
}
diff --git a/pkg/front_end/testcases/dartino/super_is_parameter.incremental.yaml b/pkg/front_end/testcases/dartino/super_is_parameter.incremental.yaml
index fef1a3e..f770d0a 100644
--- a/pkg/front_end/testcases/dartino/super_is_parameter.incremental.yaml
+++ b/pkg/front_end/testcases/dartino/super_is_parameter.incremental.yaml
@@ -5,7 +5,7 @@
main.dart.patch: |
<<<< []
class A<S> {
- ==== []
+ ==== {"messages":[],"hasCompileTimeError":1}
class A<S extends num> {
>>>>
S field;
diff --git a/pkg/front_end/testcases/dartino/two_updates_with_removal.incremental.yaml b/pkg/front_end/testcases/dartino/two_updates_with_removal.incremental.yaml
index 8106a59..4300168 100644
--- a/pkg/front_end/testcases/dartino/two_updates_with_removal.incremental.yaml
+++ b/pkg/front_end/testcases/dartino/two_updates_with_removal.incremental.yaml
@@ -14,13 +14,9 @@
foo() {
print("Hello, Brave New World!");
}
- ==== "threw"
+ ==== {"messages":[],"hasCompileTimeError":1}
>>>>
main() {
- try {
- foo();
- } catch (e) {
- print("threw");
- }
+ foo();
}
diff --git a/pkg/front_end/testcases/expression/class_type_param_reference_arg_inferred.expression.yaml.expect b/pkg/front_end/testcases/expression/class_type_param_reference_arg_inferred.expression.yaml.expect
index ee48a6d..4842362 100644
--- a/pkg/front_end/testcases/expression/class_type_param_reference_arg_inferred.expression.yaml.expect
+++ b/pkg/front_end/testcases/expression/class_type_param_reference_arg_inferred.expression.yaml.expect
@@ -1,6 +1,6 @@
Errors: {
}
method /* from org-dartlang-debug:synthetic_debug_expression */ debugExpr(dynamic x) → dynamic
- return () → dart.core::Null* {
+ return () → dart.core::Null? {
x = main::id<dynamic>(x);
};
diff --git a/pkg/front_end/testcases/expression/class_type_param_reference_ctor_inferred.expression.yaml.expect b/pkg/front_end/testcases/expression/class_type_param_reference_ctor_inferred.expression.yaml.expect
index e41764a..5d5e32a 100644
--- a/pkg/front_end/testcases/expression/class_type_param_reference_ctor_inferred.expression.yaml.expect
+++ b/pkg/front_end/testcases/expression/class_type_param_reference_ctor_inferred.expression.yaml.expect
@@ -1,6 +1,6 @@
Errors: {
}
method /* from org-dartlang-debug:synthetic_debug_expression */ debugExpr(dynamic x) → dynamic
- return () → dart.core::Null* {
+ return () → dart.core::Null? {
x = new main::A::•<dynamic>();
};
diff --git a/pkg/front_end/testcases/expression/lib_ctor.expression.yaml.expect b/pkg/front_end/testcases/expression/lib_ctor.expression.yaml.expect
index 9398271..dc61171 100644
--- a/pkg/front_end/testcases/expression/lib_ctor.expression.yaml.expect
+++ b/pkg/front_end/testcases/expression/lib_ctor.expression.yaml.expect
@@ -1,7 +1,7 @@
Errors: {
}
method /* from org-dartlang-debug:synthetic_debug_expression */ debugExpr() → dynamic
- return () → dart.core::Null* {
+ return () → dart.core::Null? {
new main::A::•<dynamic>();
const main::A::•<dynamic>();
};
diff --git a/pkg/front_end/testcases/expression/lib_external_ctor.expression.yaml.expect b/pkg/front_end/testcases/expression/lib_external_ctor.expression.yaml.expect
index f2dfa42..4bc18c6 100644
--- a/pkg/front_end/testcases/expression/lib_external_ctor.expression.yaml.expect
+++ b/pkg/front_end/testcases/expression/lib_external_ctor.expression.yaml.expect
@@ -4,7 +4,7 @@
^^^^^^^
}
method /* from org-dartlang-debug:synthetic_debug_expression */ debugExpr() → dynamic
- return () → dart.core::Null* {
+ return () → dart.core::Null? {
throw new dart.core::AbstractClassInstantiationError::•("Process");
dart.io::File::fromUri(dart.core::Uri::parse("file://test.dart"));
};
diff --git a/pkg/front_end/testcases/expression/param_capture.expression.yaml.expect b/pkg/front_end/testcases/expression/param_capture.expression.yaml.expect
index 81af55b..36a812e 100644
--- a/pkg/front_end/testcases/expression/param_capture.expression.yaml.expect
+++ b/pkg/front_end/testcases/expression/param_capture.expression.yaml.expect
@@ -1,6 +1,6 @@
Errors: {
}
method /* from org-dartlang-debug:synthetic_debug_expression */ debugExpr(dynamic x, dynamic y) → dynamic
- return () → dart.core::Null* {
+ return () → dart.core::Null? {
x = x.+(y);
};
diff --git a/pkg/front_end/testcases/expression/type_param_shadow_arg_ctor_inferred.expression.yaml.expect b/pkg/front_end/testcases/expression/type_param_shadow_arg_ctor_inferred.expression.yaml.expect
index 82ea2ad..8789584 100644
--- a/pkg/front_end/testcases/expression/type_param_shadow_arg_ctor_inferred.expression.yaml.expect
+++ b/pkg/front_end/testcases/expression/type_param_shadow_arg_ctor_inferred.expression.yaml.expect
@@ -6,6 +6,6 @@
^
}
method /* from org-dartlang-debug:synthetic_debug_expression */ debugExpr<T extends dynamic>() → dynamic
- return () → dart.core::Null* {
+ return () → dart.core::Null? {
main::A::debugExpr::T* k = let final<BottomType> #t1 = invalid-expression "org-dartlang-debug:synthetic_debug_expression:2:13: Error: A value of type 'A<dynamic>' can't be assigned to a variable of type 'T'.\n - 'A' is from 'pkg/front_end/testcases/expression/main.dart'.\nTry changing the type of the left hand side, or casting the right hand side to 'T'.\n T k = new A();\n ^" in new main::A::•<dynamic>() as{TypeError} <BottomType>;
};
diff --git a/pkg/front_end/testcases/expression/type_param_shadow_arg_inferred.expression.yaml.expect b/pkg/front_end/testcases/expression/type_param_shadow_arg_inferred.expression.yaml.expect
index 140cb36..a7a450a 100644
--- a/pkg/front_end/testcases/expression/type_param_shadow_arg_inferred.expression.yaml.expect
+++ b/pkg/front_end/testcases/expression/type_param_shadow_arg_inferred.expression.yaml.expect
@@ -1,7 +1,7 @@
Errors: {
}
method /* from org-dartlang-debug:synthetic_debug_expression */ debugExpr<T extends dynamic>() → dynamic
- return () → dart.core::Null* {
+ return () → dart.core::Null? {
main::A::debugExpr::T* k = null;
k = main::id<main::A::debugExpr::T*>(k);
};
diff --git a/pkg/front_end/testcases/expression/type_param_shadow_var.expression.yaml.expect b/pkg/front_end/testcases/expression/type_param_shadow_var.expression.yaml.expect
index ad817cd..50019f0 100644
--- a/pkg/front_end/testcases/expression/type_param_shadow_var.expression.yaml.expect
+++ b/pkg/front_end/testcases/expression/type_param_shadow_var.expression.yaml.expect
@@ -1,6 +1,6 @@
Errors: {
}
method /* from org-dartlang-debug:synthetic_debug_expression */ debugExpr<T extends dynamic>(dynamic x) → dynamic
- return () → dart.core::Null* {
+ return () → dart.core::Null? {
main::A::debugExpr::T* x = null;
};
diff --git a/pkg/front_end/testcases/extensions/compounds.dart b/pkg/front_end/testcases/extensions/compounds.dart
new file mode 100644
index 0000000..1664612
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/compounds.dart
@@ -0,0 +1,108 @@
+// Copyright (c) 2019, 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.
+
+class Number {
+ final int value;
+
+ Number(this.value);
+
+ int get hashCode => value.hashCode;
+
+ bool operator ==(Object other) => other is Number && value == other.value;
+
+ String toString() => 'Number($value)';
+}
+
+extension NumberExtension on Number {
+ Number operator +(Object other) {
+ if (other is int) {
+ return new Number(value + other);
+ } else if (other is Number) {
+ return new Number(value + other.value);
+ } else {
+ throw new ArgumentError('$other');
+ }
+ }
+ Number operator -(Object other) {
+ if (other is int) {
+ return new Number(value - other);
+ } else if (other is Number) {
+ return new Number(value - other.value);
+ } else {
+ throw new ArgumentError('$other');
+ }
+ }
+}
+
+class Class {
+ Number field;
+
+ Class(this.field);
+}
+
+extension ClassExtension on Class {
+ Number get property => field;
+ void set property(Number value) {
+ field = value;
+ }
+}
+
+main() {
+ testLocals();
+ testProperties();
+}
+
+testLocals() {
+ Number n0 = new Number(0);
+ Number n1 = new Number(1);
+ Number n2 = new Number(2);
+ Number v = n0;
+ expect(n0, v);
+ expect(n1, v += n1);
+ expect(n2, v += n1);
+ expect(n0, v -= n2);
+ expect(n1, v += n1);
+ expect(n0, v -= n1);
+ expect(n1, ++v);
+ expect(n0, --v);
+ expect(n0, v++);
+ expect(n1, v--);
+ expect(n0, v);
+}
+
+testProperties() {
+ Number n0 = new Number(0);
+ Number n1 = new Number(1);
+ Number n2 = new Number(2);
+ Class v = new Class(n0);
+ expect(n0, v.field);
+ expect(n1, v.field += n1);
+ expect(n2, v.field += n1);
+ expect(n0, v.field -= n2);
+ expect(n1, v.field += n1);
+ expect(n0, v.field -= n1);
+ expect(n1, ++v.field);
+ expect(n0, --v.field);
+ expect(n0, v.field++);
+ expect(n1, v.field--);
+ expect(n0, v.field);
+
+ expect(n0, v.property);
+ expect(n1, v.property += n1);
+ expect(n2, v.property += n1);
+ expect(n0, v.property -= n2);
+ expect(n1, v.property += n1);
+ expect(n0, v.property -= n1);
+ expect(n1, ++v.property);
+ expect(n0, --v.property);
+ expect(n0, v.property++);
+ expect(n1, v.property--);
+ expect(n0, v.property);
+}
+
+expect(expected, actual) {
+ if (expected != actual) {
+ throw 'Mismatch: expected=$expected, actual=$actual';
+ }
+}
\ No newline at end of file
diff --git a/pkg/front_end/testcases/extensions/compounds.dart.outline.expect b/pkg/front_end/testcases/extensions/compounds.dart.outline.expect
new file mode 100644
index 0000000..10363aa
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/compounds.dart.outline.expect
@@ -0,0 +1,44 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class Number extends core::Object {
+ final field core::int* value;
+ constructor •(core::int* value) → self::Number*
+ ;
+ get hashCode() → core::int*
+ ;
+ operator ==(core::Object* other) → core::bool*
+ ;
+ method toString() → core::String*
+ ;
+}
+class Class extends core::Object {
+ field self::Number* field;
+ constructor •(self::Number* field) → self::Class*
+ ;
+}
+extension NumberExtension on self::Number* {
+ operator + = self::NumberExtension|+;
+ operator - = self::NumberExtension|-;
+}
+extension ClassExtension on self::Class* {
+ get property = self::ClassExtension|get#property;
+ set property = self::ClassExtension|set#property;
+}
+static method NumberExtension|+(final self::Number* #this, core::Object* other) → self::Number*
+ ;
+static method NumberExtension|-(final self::Number* #this, core::Object* other) → self::Number*
+ ;
+static method ClassExtension|get#property(final self::Class* #this) → self::Number*
+ ;
+static method ClassExtension|set#property(final self::Class* #this, self::Number* value) → void
+ ;
+static method main() → dynamic
+ ;
+static method testLocals() → dynamic
+ ;
+static method testProperties() → dynamic
+ ;
+static method expect(dynamic expected, dynamic actual) → dynamic
+ ;
diff --git a/pkg/front_end/testcases/extensions/compounds.dart.strong.expect b/pkg/front_end/testcases/extensions/compounds.dart.strong.expect
new file mode 100644
index 0000000..1360e1d
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/compounds.dart.strong.expect
@@ -0,0 +1,115 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class Number extends core::Object {
+ final field core::int* value;
+ constructor •(core::int* value) → self::Number*
+ : self::Number::value = value, super core::Object::•()
+ ;
+ get hashCode() → core::int*
+ return this.{self::Number::value}.{core::num::hashCode};
+ operator ==(core::Object* other) → core::bool*
+ return other is self::Number* && this.{self::Number::value}.{core::num::==}(other{self::Number*}.{self::Number::value});
+ method toString() → core::String*
+ return "Number(${this.{self::Number::value}})";
+}
+class Class extends core::Object {
+ field self::Number* field;
+ constructor •(self::Number* field) → self::Class*
+ : self::Class::field = field, super core::Object::•()
+ ;
+}
+extension NumberExtension on self::Number* {
+ operator + = self::NumberExtension|+;
+ operator - = self::NumberExtension|-;
+}
+extension ClassExtension on self::Class* {
+ get property = self::ClassExtension|get#property;
+ set property = self::ClassExtension|set#property;
+}
+static method NumberExtension|+(final self::Number* #this, core::Object* other) → self::Number* {
+ if(other is core::int*) {
+ return new self::Number::•(#this.{self::Number::value}.{core::num::+}(other{core::int*}));
+ }
+ else
+ if(other is self::Number*) {
+ return new self::Number::•(#this.{self::Number::value}.{core::num::+}(other{self::Number*}.{self::Number::value}));
+ }
+ else {
+ throw new core::ArgumentError::•("${other}");
+ }
+}
+static method NumberExtension|-(final self::Number* #this, core::Object* other) → self::Number* {
+ if(other is core::int*) {
+ return new self::Number::•(#this.{self::Number::value}.{core::num::-}(other{core::int*}));
+ }
+ else
+ if(other is self::Number*) {
+ return new self::Number::•(#this.{self::Number::value}.{core::num::-}(other{self::Number*}.{self::Number::value}));
+ }
+ else {
+ throw new core::ArgumentError::•("${other}");
+ }
+}
+static method ClassExtension|get#property(final self::Class* #this) → self::Number*
+ return #this.{self::Class::field};
+static method ClassExtension|set#property(final self::Class* #this, self::Number* value) → self::Number* {
+ final self::Number* #t1 = value;
+ #this.{self::Class::field} = value;
+ return #t1;
+}
+static method main() → dynamic {
+ self::testLocals();
+ self::testProperties();
+}
+static method testLocals() → dynamic {
+ self::Number* n0 = new self::Number::•(0);
+ self::Number* n1 = new self::Number::•(1);
+ self::Number* n2 = new self::Number::•(2);
+ self::Number* v = n0;
+ self::expect(n0, v);
+ self::expect(n1, v = self::NumberExtension|+(v, n1));
+ self::expect(n2, v = self::NumberExtension|+(v, n1));
+ self::expect(n0, v = self::NumberExtension|-(v, n2));
+ self::expect(n1, v = self::NumberExtension|+(v, n1));
+ self::expect(n0, v = self::NumberExtension|-(v, n1));
+ self::expect(n1, v = self::NumberExtension|+(v, 1));
+ self::expect(n0, v = self::NumberExtension|-(v, 1));
+ self::expect(n0, let final self::Number* #t2 = v in let final self::Number* #t3 = v = self::NumberExtension|+(#t2, 1) in #t2);
+ self::expect(n1, let final self::Number* #t4 = v in let final self::Number* #t5 = v = self::NumberExtension|-(#t4, 1) in #t4);
+ self::expect(n0, v);
+}
+static method testProperties() → dynamic {
+ self::Number* n0 = new self::Number::•(0);
+ self::Number* n1 = new self::Number::•(1);
+ self::Number* n2 = new self::Number::•(2);
+ self::Class* v = new self::Class::•(n0);
+ self::expect(n0, v.{self::Class::field});
+ self::expect(n1, let final self::Class* #t6 = v in #t6.{self::Class::field} = self::NumberExtension|+(#t6.{self::Class::field}, n1));
+ self::expect(n2, let final self::Class* #t7 = v in #t7.{self::Class::field} = self::NumberExtension|+(#t7.{self::Class::field}, n1));
+ self::expect(n0, let final self::Class* #t8 = v in #t8.{self::Class::field} = self::NumberExtension|-(#t8.{self::Class::field}, n2));
+ self::expect(n1, let final self::Class* #t9 = v in #t9.{self::Class::field} = self::NumberExtension|+(#t9.{self::Class::field}, n1));
+ self::expect(n0, let final self::Class* #t10 = v in #t10.{self::Class::field} = self::NumberExtension|-(#t10.{self::Class::field}, n1));
+ self::expect(n1, let final self::Class* #t11 = v in #t11.{self::Class::field} = self::NumberExtension|+(#t11.{self::Class::field}, 1));
+ self::expect(n0, let final self::Class* #t12 = v in #t12.{self::Class::field} = self::NumberExtension|-(#t12.{self::Class::field}, 1));
+ self::expect(n0, let final self::Class* #t13 = v in let final self::Number* #t14 = #t13.{self::Class::field} in let final self::Number* #t15 = #t13.{self::Class::field} = self::NumberExtension|+(#t14, 1) in #t14);
+ self::expect(n1, let final self::Class* #t16 = v in let final self::Number* #t17 = #t16.{self::Class::field} in let final self::Number* #t18 = #t16.{self::Class::field} = self::NumberExtension|-(#t17, 1) in #t17);
+ self::expect(n0, v.{self::Class::field});
+ self::expect(n0, self::ClassExtension|get#property(v));
+ self::expect(n1, let final self::Class* #t19 = v in self::ClassExtension|set#property(#t19, self::NumberExtension|+(self::ClassExtension|get#property(#t19), n1)));
+ self::expect(n2, let final self::Class* #t20 = v in self::ClassExtension|set#property(#t20, self::NumberExtension|+(self::ClassExtension|get#property(#t20), n1)));
+ self::expect(n0, let final self::Class* #t21 = v in self::ClassExtension|set#property(#t21, self::NumberExtension|-(self::ClassExtension|get#property(#t21), n2)));
+ self::expect(n1, let final self::Class* #t22 = v in self::ClassExtension|set#property(#t22, self::NumberExtension|+(self::ClassExtension|get#property(#t22), n1)));
+ self::expect(n0, let final self::Class* #t23 = v in self::ClassExtension|set#property(#t23, self::NumberExtension|-(self::ClassExtension|get#property(#t23), n1)));
+ self::expect(n1, let final self::Class* #t24 = v in self::ClassExtension|set#property(#t24, self::NumberExtension|+(self::ClassExtension|get#property(#t24), 1)));
+ self::expect(n0, let final self::Class* #t25 = v in self::ClassExtension|set#property(#t25, self::NumberExtension|-(self::ClassExtension|get#property(#t25), 1)));
+ self::expect(n0, let final self::Class* #t26 = v in let final self::Number* #t27 = self::ClassExtension|get#property(#t26) in let final self::Number* #t28 = self::ClassExtension|set#property(#t26, self::NumberExtension|+(#t27, 1)) in #t27);
+ self::expect(n1, let final self::Class* #t29 = v in let final self::Number* #t30 = self::ClassExtension|get#property(#t29) in let final self::Number* #t31 = self::ClassExtension|set#property(#t29, self::NumberExtension|-(#t30, 1)) in #t30);
+ self::expect(n0, self::ClassExtension|get#property(v));
+}
+static method expect(dynamic expected, dynamic actual) → dynamic {
+ if(!expected.{core::Object::==}(actual)) {
+ throw "Mismatch: expected=${expected}, actual=${actual}";
+ }
+}
diff --git a/pkg/front_end/testcases/extensions/compounds.dart.strong.transformed.expect b/pkg/front_end/testcases/extensions/compounds.dart.strong.transformed.expect
new file mode 100644
index 0000000..1360e1d
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/compounds.dart.strong.transformed.expect
@@ -0,0 +1,115 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class Number extends core::Object {
+ final field core::int* value;
+ constructor •(core::int* value) → self::Number*
+ : self::Number::value = value, super core::Object::•()
+ ;
+ get hashCode() → core::int*
+ return this.{self::Number::value}.{core::num::hashCode};
+ operator ==(core::Object* other) → core::bool*
+ return other is self::Number* && this.{self::Number::value}.{core::num::==}(other{self::Number*}.{self::Number::value});
+ method toString() → core::String*
+ return "Number(${this.{self::Number::value}})";
+}
+class Class extends core::Object {
+ field self::Number* field;
+ constructor •(self::Number* field) → self::Class*
+ : self::Class::field = field, super core::Object::•()
+ ;
+}
+extension NumberExtension on self::Number* {
+ operator + = self::NumberExtension|+;
+ operator - = self::NumberExtension|-;
+}
+extension ClassExtension on self::Class* {
+ get property = self::ClassExtension|get#property;
+ set property = self::ClassExtension|set#property;
+}
+static method NumberExtension|+(final self::Number* #this, core::Object* other) → self::Number* {
+ if(other is core::int*) {
+ return new self::Number::•(#this.{self::Number::value}.{core::num::+}(other{core::int*}));
+ }
+ else
+ if(other is self::Number*) {
+ return new self::Number::•(#this.{self::Number::value}.{core::num::+}(other{self::Number*}.{self::Number::value}));
+ }
+ else {
+ throw new core::ArgumentError::•("${other}");
+ }
+}
+static method NumberExtension|-(final self::Number* #this, core::Object* other) → self::Number* {
+ if(other is core::int*) {
+ return new self::Number::•(#this.{self::Number::value}.{core::num::-}(other{core::int*}));
+ }
+ else
+ if(other is self::Number*) {
+ return new self::Number::•(#this.{self::Number::value}.{core::num::-}(other{self::Number*}.{self::Number::value}));
+ }
+ else {
+ throw new core::ArgumentError::•("${other}");
+ }
+}
+static method ClassExtension|get#property(final self::Class* #this) → self::Number*
+ return #this.{self::Class::field};
+static method ClassExtension|set#property(final self::Class* #this, self::Number* value) → self::Number* {
+ final self::Number* #t1 = value;
+ #this.{self::Class::field} = value;
+ return #t1;
+}
+static method main() → dynamic {
+ self::testLocals();
+ self::testProperties();
+}
+static method testLocals() → dynamic {
+ self::Number* n0 = new self::Number::•(0);
+ self::Number* n1 = new self::Number::•(1);
+ self::Number* n2 = new self::Number::•(2);
+ self::Number* v = n0;
+ self::expect(n0, v);
+ self::expect(n1, v = self::NumberExtension|+(v, n1));
+ self::expect(n2, v = self::NumberExtension|+(v, n1));
+ self::expect(n0, v = self::NumberExtension|-(v, n2));
+ self::expect(n1, v = self::NumberExtension|+(v, n1));
+ self::expect(n0, v = self::NumberExtension|-(v, n1));
+ self::expect(n1, v = self::NumberExtension|+(v, 1));
+ self::expect(n0, v = self::NumberExtension|-(v, 1));
+ self::expect(n0, let final self::Number* #t2 = v in let final self::Number* #t3 = v = self::NumberExtension|+(#t2, 1) in #t2);
+ self::expect(n1, let final self::Number* #t4 = v in let final self::Number* #t5 = v = self::NumberExtension|-(#t4, 1) in #t4);
+ self::expect(n0, v);
+}
+static method testProperties() → dynamic {
+ self::Number* n0 = new self::Number::•(0);
+ self::Number* n1 = new self::Number::•(1);
+ self::Number* n2 = new self::Number::•(2);
+ self::Class* v = new self::Class::•(n0);
+ self::expect(n0, v.{self::Class::field});
+ self::expect(n1, let final self::Class* #t6 = v in #t6.{self::Class::field} = self::NumberExtension|+(#t6.{self::Class::field}, n1));
+ self::expect(n2, let final self::Class* #t7 = v in #t7.{self::Class::field} = self::NumberExtension|+(#t7.{self::Class::field}, n1));
+ self::expect(n0, let final self::Class* #t8 = v in #t8.{self::Class::field} = self::NumberExtension|-(#t8.{self::Class::field}, n2));
+ self::expect(n1, let final self::Class* #t9 = v in #t9.{self::Class::field} = self::NumberExtension|+(#t9.{self::Class::field}, n1));
+ self::expect(n0, let final self::Class* #t10 = v in #t10.{self::Class::field} = self::NumberExtension|-(#t10.{self::Class::field}, n1));
+ self::expect(n1, let final self::Class* #t11 = v in #t11.{self::Class::field} = self::NumberExtension|+(#t11.{self::Class::field}, 1));
+ self::expect(n0, let final self::Class* #t12 = v in #t12.{self::Class::field} = self::NumberExtension|-(#t12.{self::Class::field}, 1));
+ self::expect(n0, let final self::Class* #t13 = v in let final self::Number* #t14 = #t13.{self::Class::field} in let final self::Number* #t15 = #t13.{self::Class::field} = self::NumberExtension|+(#t14, 1) in #t14);
+ self::expect(n1, let final self::Class* #t16 = v in let final self::Number* #t17 = #t16.{self::Class::field} in let final self::Number* #t18 = #t16.{self::Class::field} = self::NumberExtension|-(#t17, 1) in #t17);
+ self::expect(n0, v.{self::Class::field});
+ self::expect(n0, self::ClassExtension|get#property(v));
+ self::expect(n1, let final self::Class* #t19 = v in self::ClassExtension|set#property(#t19, self::NumberExtension|+(self::ClassExtension|get#property(#t19), n1)));
+ self::expect(n2, let final self::Class* #t20 = v in self::ClassExtension|set#property(#t20, self::NumberExtension|+(self::ClassExtension|get#property(#t20), n1)));
+ self::expect(n0, let final self::Class* #t21 = v in self::ClassExtension|set#property(#t21, self::NumberExtension|-(self::ClassExtension|get#property(#t21), n2)));
+ self::expect(n1, let final self::Class* #t22 = v in self::ClassExtension|set#property(#t22, self::NumberExtension|+(self::ClassExtension|get#property(#t22), n1)));
+ self::expect(n0, let final self::Class* #t23 = v in self::ClassExtension|set#property(#t23, self::NumberExtension|-(self::ClassExtension|get#property(#t23), n1)));
+ self::expect(n1, let final self::Class* #t24 = v in self::ClassExtension|set#property(#t24, self::NumberExtension|+(self::ClassExtension|get#property(#t24), 1)));
+ self::expect(n0, let final self::Class* #t25 = v in self::ClassExtension|set#property(#t25, self::NumberExtension|-(self::ClassExtension|get#property(#t25), 1)));
+ self::expect(n0, let final self::Class* #t26 = v in let final self::Number* #t27 = self::ClassExtension|get#property(#t26) in let final self::Number* #t28 = self::ClassExtension|set#property(#t26, self::NumberExtension|+(#t27, 1)) in #t27);
+ self::expect(n1, let final self::Class* #t29 = v in let final self::Number* #t30 = self::ClassExtension|get#property(#t29) in let final self::Number* #t31 = self::ClassExtension|set#property(#t29, self::NumberExtension|-(#t30, 1)) in #t30);
+ self::expect(n0, self::ClassExtension|get#property(v));
+}
+static method expect(dynamic expected, dynamic actual) → dynamic {
+ if(!expected.{core::Object::==}(actual)) {
+ throw "Mismatch: expected=${expected}, actual=${actual}";
+ }
+}
diff --git a/pkg/front_end/testcases/extensions/compounds.dart.type_promotion.expect b/pkg/front_end/testcases/extensions/compounds.dart.type_promotion.expect
new file mode 100644
index 0000000..28a5f00
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/compounds.dart.type_promotion.expect
@@ -0,0 +1,42 @@
+pkg/front_end/testcases/extensions/compounds.dart:12:43: Context: Possible promotion of other@340
+ bool operator ==(Object other) => other is Number && value == other.value;
+ ^^
+pkg/front_end/testcases/extensions/compounds.dart:19:15: Context: Possible promotion of other@501
+ if (other is int) {
+ ^^
+pkg/front_end/testcases/extensions/compounds.dart:21:22: Context: Possible promotion of other@501
+ } else if (other is Number) {
+ ^^
+pkg/front_end/testcases/extensions/compounds.dart:28:15: Context: Possible promotion of other@501
+ if (other is int) {
+ ^^
+pkg/front_end/testcases/extensions/compounds.dart:30:22: Context: Possible promotion of other@501
+ } else if (other is Number) {
+ ^^
+pkg/front_end/testcases/extensions/compounds.dart:62:16: Context: Write to v@1309
+ expect(n1, v += n1);
+ ^^
+pkg/front_end/testcases/extensions/compounds.dart:63:16: Context: Write to v@1309
+ expect(n2, v += n1);
+ ^^
+pkg/front_end/testcases/extensions/compounds.dart:64:16: Context: Write to v@1309
+ expect(n0, v -= n2);
+ ^^
+pkg/front_end/testcases/extensions/compounds.dart:65:16: Context: Write to v@1309
+ expect(n1, v += n1);
+ ^^
+pkg/front_end/testcases/extensions/compounds.dart:66:16: Context: Write to v@1309
+ expect(n0, v -= n1);
+ ^^
+pkg/front_end/testcases/extensions/compounds.dart:67:14: Context: Write to v@1309
+ expect(n1, ++v);
+ ^^
+pkg/front_end/testcases/extensions/compounds.dart:68:14: Context: Write to v@1309
+ expect(n0, --v);
+ ^^
+pkg/front_end/testcases/extensions/compounds.dart:69:15: Context: Write to v@1309
+ expect(n0, v++);
+ ^^
+pkg/front_end/testcases/extensions/compounds.dart:70:15: Context: Write to v@1309
+ expect(n1, v--);
+ ^^
diff --git a/pkg/front_end/testcases/extensions/direct_static_access.dart.strong.expect b/pkg/front_end/testcases/extensions/direct_static_access.dart.strong.expect
index a7051b9..19243a9 100644
--- a/pkg/front_end/testcases/extensions/direct_static_access.dart.strong.expect
+++ b/pkg/front_end/testcases/extensions/direct_static_access.dart.strong.expect
@@ -109,15 +109,15 @@
({value: dynamic}) →* dynamic tearOffNamed = #C5;
tearOffNamed.call();
tearOffNamed.call(value: value);
- <S extends core::Object* = dynamic>(self::Extension|genericWriteSetterRequired::S*) →* dynamic tearOffGenericRequired = #C6;
+ <S extends core::Object* = dynamic>(S*) →* dynamic tearOffGenericRequired = #C6;
tearOffGenericRequired.call<core::int*>(value);
tearOffGenericRequired.call<core::int*>(value);
- <S extends core::Object* = dynamic>([self::Extension|genericWriteSetterOptional::S*]) →* dynamic tearOffGenericOptional = #C7;
+ <S extends core::Object* = dynamic>([S*]) →* dynamic tearOffGenericOptional = #C7;
tearOffGenericOptional.call<dynamic>();
tearOffGenericOptional.call<core::int*>();
tearOffGenericOptional.call<core::int*>(value);
tearOffGenericOptional.call<core::int*>(value);
- <S extends core::Object* = dynamic>({value: self::Extension|genericWriteSetterNamed::S*}) →* dynamic tearOffGenericNamed = #C8;
+ <S extends core::Object* = dynamic>({value: S*}) →* dynamic tearOffGenericNamed = #C8;
tearOffGenericNamed.call<dynamic>();
tearOffGenericNamed.call<core::int*>();
tearOffGenericNamed.call<core::int*>(value: value);
@@ -176,15 +176,15 @@
({value: dynamic}) →* dynamic tearOffNamed = #C5;
tearOffNamed.call();
tearOffNamed.call(value: value);
- <S extends core::Object* = dynamic>(self::Extension|genericWriteSetterRequired::S*) →* dynamic tearOffGenericRequired = #C6;
+ <S extends core::Object* = dynamic>(S*) →* dynamic tearOffGenericRequired = #C6;
tearOffGenericRequired.call<self::Extension|tearOffsFromInstanceContext::T*>(value);
tearOffGenericRequired.call<self::Extension|tearOffsFromInstanceContext::T*>(value);
- <S extends core::Object* = dynamic>([self::Extension|genericWriteSetterOptional::S*]) →* dynamic tearOffGenericOptional = #C7;
+ <S extends core::Object* = dynamic>([S*]) →* dynamic tearOffGenericOptional = #C7;
tearOffGenericOptional.call<dynamic>();
tearOffGenericOptional.call<self::Extension|tearOffsFromInstanceContext::T*>();
tearOffGenericOptional.call<self::Extension|tearOffsFromInstanceContext::T*>(value);
tearOffGenericOptional.call<self::Extension|tearOffsFromInstanceContext::T*>(value);
- <S extends core::Object* = dynamic>({value: self::Extension|genericWriteSetterNamed::S*}) →* dynamic tearOffGenericNamed = #C8;
+ <S extends core::Object* = dynamic>({value: S*}) →* dynamic tearOffGenericNamed = #C8;
tearOffGenericNamed.call<dynamic>();
tearOffGenericNamed.call<self::Extension|tearOffsFromInstanceContext::T*>();
tearOffGenericNamed.call<self::Extension|tearOffsFromInstanceContext::T*>(value: value);
diff --git a/pkg/front_end/testcases/extensions/direct_static_access.dart.strong.transformed.expect b/pkg/front_end/testcases/extensions/direct_static_access.dart.strong.transformed.expect
index a7051b9..19243a9 100644
--- a/pkg/front_end/testcases/extensions/direct_static_access.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/extensions/direct_static_access.dart.strong.transformed.expect
@@ -109,15 +109,15 @@
({value: dynamic}) →* dynamic tearOffNamed = #C5;
tearOffNamed.call();
tearOffNamed.call(value: value);
- <S extends core::Object* = dynamic>(self::Extension|genericWriteSetterRequired::S*) →* dynamic tearOffGenericRequired = #C6;
+ <S extends core::Object* = dynamic>(S*) →* dynamic tearOffGenericRequired = #C6;
tearOffGenericRequired.call<core::int*>(value);
tearOffGenericRequired.call<core::int*>(value);
- <S extends core::Object* = dynamic>([self::Extension|genericWriteSetterOptional::S*]) →* dynamic tearOffGenericOptional = #C7;
+ <S extends core::Object* = dynamic>([S*]) →* dynamic tearOffGenericOptional = #C7;
tearOffGenericOptional.call<dynamic>();
tearOffGenericOptional.call<core::int*>();
tearOffGenericOptional.call<core::int*>(value);
tearOffGenericOptional.call<core::int*>(value);
- <S extends core::Object* = dynamic>({value: self::Extension|genericWriteSetterNamed::S*}) →* dynamic tearOffGenericNamed = #C8;
+ <S extends core::Object* = dynamic>({value: S*}) →* dynamic tearOffGenericNamed = #C8;
tearOffGenericNamed.call<dynamic>();
tearOffGenericNamed.call<core::int*>();
tearOffGenericNamed.call<core::int*>(value: value);
@@ -176,15 +176,15 @@
({value: dynamic}) →* dynamic tearOffNamed = #C5;
tearOffNamed.call();
tearOffNamed.call(value: value);
- <S extends core::Object* = dynamic>(self::Extension|genericWriteSetterRequired::S*) →* dynamic tearOffGenericRequired = #C6;
+ <S extends core::Object* = dynamic>(S*) →* dynamic tearOffGenericRequired = #C6;
tearOffGenericRequired.call<self::Extension|tearOffsFromInstanceContext::T*>(value);
tearOffGenericRequired.call<self::Extension|tearOffsFromInstanceContext::T*>(value);
- <S extends core::Object* = dynamic>([self::Extension|genericWriteSetterOptional::S*]) →* dynamic tearOffGenericOptional = #C7;
+ <S extends core::Object* = dynamic>([S*]) →* dynamic tearOffGenericOptional = #C7;
tearOffGenericOptional.call<dynamic>();
tearOffGenericOptional.call<self::Extension|tearOffsFromInstanceContext::T*>();
tearOffGenericOptional.call<self::Extension|tearOffsFromInstanceContext::T*>(value);
tearOffGenericOptional.call<self::Extension|tearOffsFromInstanceContext::T*>(value);
- <S extends core::Object* = dynamic>({value: self::Extension|genericWriteSetterNamed::S*}) →* dynamic tearOffGenericNamed = #C8;
+ <S extends core::Object* = dynamic>({value: S*}) →* dynamic tearOffGenericNamed = #C8;
tearOffGenericNamed.call<dynamic>();
tearOffGenericNamed.call<self::Extension|tearOffsFromInstanceContext::T*>();
tearOffGenericNamed.call<self::Extension|tearOffsFromInstanceContext::T*>(value: value);
diff --git a/pkg/front_end/testcases/extensions/index.dart b/pkg/front_end/testcases/extensions/index.dart
index f34eac8..582d067 100644
--- a/pkg/front_end/testcases/extensions/index.dart
+++ b/pkg/front_end/testcases/extensions/index.dart
@@ -20,8 +20,28 @@
map1.put(0, '0');
expect('0', map1[0]);
expect(null, map1[1]);
- expect('1', map1[1] = '1');
+ map1[1] = '1';
expect('1', map1[1]);
+ expect('2', map1[1] = '2');
+ expect('2', map1[1]);
+ map1[1] ??= '3';
+ expect('2', map1[1]);
+ expect('2', map1[1] ??= '4');
+ expect('2', map1[1]);
+ map1[2] ??= '2';
+ expect('2', map1[2]);
+ expect('3', map1[3] ??= '3');
+ expect('3', map1[3]);
+
+ MapLike<int, int> map2 = new MapLike();
+ expect(1, map2[0] = 1);
+ expect(3, map2[0] += 2);
+ expect(5, map2[0] += 2);
+ expect(5, map2[0]++);
+ expect(6, map2[0]);
+ expect(5, --map2[0]);
+ expect(5, map2[0]);
+
}
expect(expected, actual) {
diff --git a/pkg/front_end/testcases/extensions/index.dart.strong.expect b/pkg/front_end/testcases/extensions/index.dart.strong.expect
index 70bdb38..4f14d3dc 100644
--- a/pkg/front_end/testcases/extensions/index.dart.strong.expect
+++ b/pkg/front_end/testcases/extensions/index.dart.strong.expect
@@ -26,8 +26,26 @@
map1.{self::MapLike::put}(0, "0");
self::expect("0", self::Extension|[]<core::int*, core::String*>(map1, 0));
self::expect(null, self::Extension|[]<core::int*, core::String*>(map1, 1));
- self::expect("1", let final self::MapLike<core::int*, core::String*>* #t5 = map1 in let final core::int* #t6 = 1 in let final core::String* #t7 = "1" in let final void #t8 = self::Extension|[]=<core::int*, core::String*>(#t5, #t6, #t7) in #t7);
+ self::Extension|[]=<core::int*, core::String*>(map1, 1, "1");
self::expect("1", self::Extension|[]<core::int*, core::String*>(map1, 1));
+ self::expect("2", let final self::MapLike<core::int*, core::String*>* #t5 = map1 in let final core::int* #t6 = 1 in let final core::String* #t7 = "2" in let final void #t8 = self::Extension|[]=<core::int*, core::String*>(#t5, #t6, #t7) in #t7);
+ self::expect("2", self::Extension|[]<core::int*, core::String*>(map1, 1));
+ let final self::MapLike<core::int*, core::String*>* #t9 = map1 in let final core::int* #t10 = 1 in self::Extension|[]<core::int*, core::String*>(#t9, #t10).{core::String::==}(null) ?{core::String*} self::Extension|[]=<core::int*, core::String*>(#t9, #t10, "3") : null;
+ self::expect("2", self::Extension|[]<core::int*, core::String*>(map1, 1));
+ self::expect("2", let final self::MapLike<core::int*, core::String*>* #t11 = map1 in let final core::int* #t12 = 1 in let final core::String* #t13 = self::Extension|[]<core::int*, core::String*>(#t11, #t12) in #t13.{core::String::==}(null) ?{core::String*} let final core::String* #t14 = "4" in let final void #t15 = self::Extension|[]=<core::int*, core::String*>(#t11, #t12, #t14) in #t14 : #t13);
+ self::expect("2", self::Extension|[]<core::int*, core::String*>(map1, 1));
+ let final self::MapLike<core::int*, core::String*>* #t16 = map1 in let final core::int* #t17 = 2 in self::Extension|[]<core::int*, core::String*>(#t16, #t17).{core::String::==}(null) ?{core::String*} self::Extension|[]=<core::int*, core::String*>(#t16, #t17, "2") : null;
+ self::expect("2", self::Extension|[]<core::int*, core::String*>(map1, 2));
+ self::expect("3", let final self::MapLike<core::int*, core::String*>* #t18 = map1 in let final core::int* #t19 = 3 in let final core::String* #t20 = self::Extension|[]<core::int*, core::String*>(#t18, #t19) in #t20.{core::String::==}(null) ?{core::String*} let final core::String* #t21 = "3" in let final void #t22 = self::Extension|[]=<core::int*, core::String*>(#t18, #t19, #t21) in #t21 : #t20);
+ self::expect("3", self::Extension|[]<core::int*, core::String*>(map1, 3));
+ self::MapLike<core::int*, core::int*>* map2 = new self::MapLike::•<core::int*, core::int*>();
+ self::expect(1, let final self::MapLike<core::int*, core::int*>* #t23 = map2 in let final core::int* #t24 = 0 in let final core::int* #t25 = 1 in let final void #t26 = self::Extension|[]=<core::int*, core::int*>(#t23, #t24, #t25) in #t25);
+ self::expect(3, let final self::MapLike<core::int*, core::int*>* #t27 = map2 in let final core::int* #t28 = 0 in let final core::int* #t29 = self::Extension|[]<core::int*, core::int*>(#t27, #t28).{core::num::+}(2) in let final void #t30 = self::Extension|[]=<core::int*, core::int*>(#t27, #t28, #t29) in #t29);
+ self::expect(5, let final self::MapLike<core::int*, core::int*>* #t31 = map2 in let final core::int* #t32 = 0 in let final core::int* #t33 = self::Extension|[]<core::int*, core::int*>(#t31, #t32).{core::num::+}(2) in let final void #t34 = self::Extension|[]=<core::int*, core::int*>(#t31, #t32, #t33) in #t33);
+ self::expect(5, let final self::MapLike<core::int*, core::int*>* #t35 = map2 in let final core::int* #t36 = 0 in let final core::int* #t37 = self::Extension|[]<core::int*, core::int*>(#t35, #t36) in let final void #t38 = self::Extension|[]=<core::int*, core::int*>(#t35, #t36, #t37.{core::num::+}(1)) in #t37);
+ self::expect(6, self::Extension|[]<core::int*, core::int*>(map2, 0));
+ self::expect(5, let final self::MapLike<core::int*, core::int*>* #t39 = map2 in let final core::int* #t40 = 0 in let final core::int* #t41 = self::Extension|[]<core::int*, core::int*>(#t39, #t40).{core::num::-}(1) in let final void #t42 = self::Extension|[]=<core::int*, core::int*>(#t39, #t40, #t41) in #t41);
+ self::expect(5, self::Extension|[]<core::int*, core::int*>(map2, 0));
}
static method expect(dynamic expected, dynamic actual) → dynamic {
if(!expected.{core::Object::==}(actual)) {
diff --git a/pkg/front_end/testcases/extensions/index.dart.strong.transformed.expect b/pkg/front_end/testcases/extensions/index.dart.strong.transformed.expect
index 70bdb38..4f14d3dc 100644
--- a/pkg/front_end/testcases/extensions/index.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/extensions/index.dart.strong.transformed.expect
@@ -26,8 +26,26 @@
map1.{self::MapLike::put}(0, "0");
self::expect("0", self::Extension|[]<core::int*, core::String*>(map1, 0));
self::expect(null, self::Extension|[]<core::int*, core::String*>(map1, 1));
- self::expect("1", let final self::MapLike<core::int*, core::String*>* #t5 = map1 in let final core::int* #t6 = 1 in let final core::String* #t7 = "1" in let final void #t8 = self::Extension|[]=<core::int*, core::String*>(#t5, #t6, #t7) in #t7);
+ self::Extension|[]=<core::int*, core::String*>(map1, 1, "1");
self::expect("1", self::Extension|[]<core::int*, core::String*>(map1, 1));
+ self::expect("2", let final self::MapLike<core::int*, core::String*>* #t5 = map1 in let final core::int* #t6 = 1 in let final core::String* #t7 = "2" in let final void #t8 = self::Extension|[]=<core::int*, core::String*>(#t5, #t6, #t7) in #t7);
+ self::expect("2", self::Extension|[]<core::int*, core::String*>(map1, 1));
+ let final self::MapLike<core::int*, core::String*>* #t9 = map1 in let final core::int* #t10 = 1 in self::Extension|[]<core::int*, core::String*>(#t9, #t10).{core::String::==}(null) ?{core::String*} self::Extension|[]=<core::int*, core::String*>(#t9, #t10, "3") : null;
+ self::expect("2", self::Extension|[]<core::int*, core::String*>(map1, 1));
+ self::expect("2", let final self::MapLike<core::int*, core::String*>* #t11 = map1 in let final core::int* #t12 = 1 in let final core::String* #t13 = self::Extension|[]<core::int*, core::String*>(#t11, #t12) in #t13.{core::String::==}(null) ?{core::String*} let final core::String* #t14 = "4" in let final void #t15 = self::Extension|[]=<core::int*, core::String*>(#t11, #t12, #t14) in #t14 : #t13);
+ self::expect("2", self::Extension|[]<core::int*, core::String*>(map1, 1));
+ let final self::MapLike<core::int*, core::String*>* #t16 = map1 in let final core::int* #t17 = 2 in self::Extension|[]<core::int*, core::String*>(#t16, #t17).{core::String::==}(null) ?{core::String*} self::Extension|[]=<core::int*, core::String*>(#t16, #t17, "2") : null;
+ self::expect("2", self::Extension|[]<core::int*, core::String*>(map1, 2));
+ self::expect("3", let final self::MapLike<core::int*, core::String*>* #t18 = map1 in let final core::int* #t19 = 3 in let final core::String* #t20 = self::Extension|[]<core::int*, core::String*>(#t18, #t19) in #t20.{core::String::==}(null) ?{core::String*} let final core::String* #t21 = "3" in let final void #t22 = self::Extension|[]=<core::int*, core::String*>(#t18, #t19, #t21) in #t21 : #t20);
+ self::expect("3", self::Extension|[]<core::int*, core::String*>(map1, 3));
+ self::MapLike<core::int*, core::int*>* map2 = new self::MapLike::•<core::int*, core::int*>();
+ self::expect(1, let final self::MapLike<core::int*, core::int*>* #t23 = map2 in let final core::int* #t24 = 0 in let final core::int* #t25 = 1 in let final void #t26 = self::Extension|[]=<core::int*, core::int*>(#t23, #t24, #t25) in #t25);
+ self::expect(3, let final self::MapLike<core::int*, core::int*>* #t27 = map2 in let final core::int* #t28 = 0 in let final core::int* #t29 = self::Extension|[]<core::int*, core::int*>(#t27, #t28).{core::num::+}(2) in let final void #t30 = self::Extension|[]=<core::int*, core::int*>(#t27, #t28, #t29) in #t29);
+ self::expect(5, let final self::MapLike<core::int*, core::int*>* #t31 = map2 in let final core::int* #t32 = 0 in let final core::int* #t33 = self::Extension|[]<core::int*, core::int*>(#t31, #t32).{core::num::+}(2) in let final void #t34 = self::Extension|[]=<core::int*, core::int*>(#t31, #t32, #t33) in #t33);
+ self::expect(5, let final self::MapLike<core::int*, core::int*>* #t35 = map2 in let final core::int* #t36 = 0 in let final core::int* #t37 = self::Extension|[]<core::int*, core::int*>(#t35, #t36) in let final void #t38 = self::Extension|[]=<core::int*, core::int*>(#t35, #t36, #t37.{core::num::+}(1)) in #t37);
+ self::expect(6, self::Extension|[]<core::int*, core::int*>(map2, 0));
+ self::expect(5, let final self::MapLike<core::int*, core::int*>* #t39 = map2 in let final core::int* #t40 = 0 in let final core::int* #t41 = self::Extension|[]<core::int*, core::int*>(#t39, #t40).{core::num::-}(1) in let final void #t42 = self::Extension|[]=<core::int*, core::int*>(#t39, #t40, #t41) in #t41);
+ self::expect(5, self::Extension|[]<core::int*, core::int*>(map2, 0));
}
static method expect(dynamic expected, dynamic actual) → dynamic {
if(!expected.{core::Object::==}(actual)) {
diff --git a/pkg/front_end/testcases/extensions/instance_access.dart b/pkg/front_end/testcases/extensions/instance_access.dart
index 249f712..93f74ed 100644
--- a/pkg/front_end/testcases/extensions/instance_access.dart
+++ b/pkg/front_end/testcases/extensions/instance_access.dart
@@ -69,11 +69,13 @@
Class1 c1 = new Class1(1);
expect(0, c0.method());
expect(1, c1.method());
+ expect(1, c1?.method());
expect(42, c0.genericMethod(42));
expect(43, c0.genericMethod<num>(43));
expect(88, c1.genericMethod(87));
expect(89, c1.genericMethod<num>(88));
expect(0, c0.property);
+ expect(0, c0?.property);
expect(42, c0.property = 42);
expect(1, c1.property);
expect(87, c0.property = 87);
@@ -87,12 +89,14 @@
Class2 c0 = new Class2(0);
Class2 c1 = new Class2(1);
expect(3, c0.method());
+ expect(3, c0?.method());
expect(4, c1.method());
expect(46, c0.genericMethod(42));
expect(47, c0.genericMethod<num>(43));
expect(92, c1.genericMethod(87));
expect(93, c1.genericMethod<num>(88));
expect(5, c0.property);
+ expect(5, c0?.property);
expect(42, c0.property = 42);
expect(48, c0.property);
expect(6, c1.property);
diff --git a/pkg/front_end/testcases/extensions/instance_access.dart.strong.expect b/pkg/front_end/testcases/extensions/instance_access.dart.strong.expect
index 1417dd4..9812038 100644
--- a/pkg/front_end/testcases/extensions/instance_access.dart.strong.expect
+++ b/pkg/front_end/testcases/extensions/instance_access.dart.strong.expect
@@ -89,11 +89,13 @@
self::Class1* c1 = new self::Class1::•(1);
self::expect(0, self::Extension1|method(c0));
self::expect(1, self::Extension1|method(c1));
+ self::expect(1, let final self::Class1* #t3 = c1 in #t3.{core::Object::==}(null) ?{core::int*} null : self::Extension1|method(#t3));
self::expect(42, self::Extension1|genericMethod<core::int*>(c0, 42));
self::expect(43, self::Extension1|genericMethod<core::num*>(c0, 43));
self::expect(88, self::Extension1|genericMethod<core::int*>(c1, 87));
self::expect(89, self::Extension1|genericMethod<core::num*>(c1, 88));
self::expect(0, self::Extension1|get#property(c0));
+ self::expect(0, let final self::Class1* #t4 = c0 in #t4.{core::Object::==}(null) ?{core::int*} null : self::Extension1|get#property(#t4));
self::expect(42, self::Extension1|set#property(c0, 42));
self::expect(1, self::Extension1|get#property(c1));
self::expect(87, self::Extension1|set#property(c0, 87));
@@ -106,12 +108,14 @@
self::Class2* c0 = new self::Class2::•(0);
self::Class2* c1 = new self::Class2::•(1);
self::expect(3, self::Extension2|method(c0));
+ self::expect(3, let final self::Class2* #t5 = c0 in #t5.{core::Object::==}(null) ?{core::int*} null : self::Extension2|method(#t5));
self::expect(4, self::Extension2|method(c1));
self::expect(46, self::Extension2|genericMethod<core::int*>(c0, 42));
self::expect(47, self::Extension2|genericMethod<core::num*>(c0, 43));
self::expect(92, self::Extension2|genericMethod<core::int*>(c1, 87));
self::expect(93, self::Extension2|genericMethod<core::num*>(c1, 88));
self::expect(5, self::Extension2|get#property(c0));
+ self::expect(5, let final self::Class2* #t6 = c0 in #t6.{core::Object::==}(null) ?{core::int*} null : self::Extension2|get#property(#t6));
self::expect(42, self::Extension2|set#property(c0, 42));
self::expect(48, self::Extension2|get#property(c0));
self::expect(6, self::Extension2|get#property(c1));
diff --git a/pkg/front_end/testcases/extensions/instance_access.dart.strong.transformed.expect b/pkg/front_end/testcases/extensions/instance_access.dart.strong.transformed.expect
index 1417dd4..9812038 100644
--- a/pkg/front_end/testcases/extensions/instance_access.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/extensions/instance_access.dart.strong.transformed.expect
@@ -89,11 +89,13 @@
self::Class1* c1 = new self::Class1::•(1);
self::expect(0, self::Extension1|method(c0));
self::expect(1, self::Extension1|method(c1));
+ self::expect(1, let final self::Class1* #t3 = c1 in #t3.{core::Object::==}(null) ?{core::int*} null : self::Extension1|method(#t3));
self::expect(42, self::Extension1|genericMethod<core::int*>(c0, 42));
self::expect(43, self::Extension1|genericMethod<core::num*>(c0, 43));
self::expect(88, self::Extension1|genericMethod<core::int*>(c1, 87));
self::expect(89, self::Extension1|genericMethod<core::num*>(c1, 88));
self::expect(0, self::Extension1|get#property(c0));
+ self::expect(0, let final self::Class1* #t4 = c0 in #t4.{core::Object::==}(null) ?{core::int*} null : self::Extension1|get#property(#t4));
self::expect(42, self::Extension1|set#property(c0, 42));
self::expect(1, self::Extension1|get#property(c1));
self::expect(87, self::Extension1|set#property(c0, 87));
@@ -106,12 +108,14 @@
self::Class2* c0 = new self::Class2::•(0);
self::Class2* c1 = new self::Class2::•(1);
self::expect(3, self::Extension2|method(c0));
+ self::expect(3, let final self::Class2* #t5 = c0 in #t5.{core::Object::==}(null) ?{core::int*} null : self::Extension2|method(#t5));
self::expect(4, self::Extension2|method(c1));
self::expect(46, self::Extension2|genericMethod<core::int*>(c0, 42));
self::expect(47, self::Extension2|genericMethod<core::num*>(c0, 43));
self::expect(92, self::Extension2|genericMethod<core::int*>(c1, 87));
self::expect(93, self::Extension2|genericMethod<core::num*>(c1, 88));
self::expect(5, self::Extension2|get#property(c0));
+ self::expect(5, let final self::Class2* #t6 = c0 in #t6.{core::Object::==}(null) ?{core::int*} null : self::Extension2|get#property(#t6));
self::expect(42, self::Extension2|set#property(c0, 42));
self::expect(48, self::Extension2|get#property(c0));
self::expect(6, self::Extension2|get#property(c1));
diff --git a/pkg/front_end/testcases/extensions/instance_tearoff.dart.strong.expect b/pkg/front_end/testcases/extensions/instance_tearoff.dart.strong.expect
index be0799d..4ba1b5e 100644
--- a/pkg/front_end/testcases/extensions/instance_tearoff.dart.strong.expect
+++ b/pkg/front_end/testcases/extensions/instance_tearoff.dart.strong.expect
@@ -69,10 +69,10 @@
self::expect(1, tearOff1.call());
c1 = new self::Class1::•(7.{core::int::unary-}());
self::expect(1, tearOff1.call());
- <T extends core::num* = dynamic>(self::Extension1|genericMethod::T*) →* core::int* genericTearOff0 = self::Extension1|get#genericMethod(c0);
+ <T extends core::num* = dynamic>(T*) →* core::int* genericTearOff0 = self::Extension1|get#genericMethod(c0);
self::expect(38, genericTearOff0.call<core::int*>(42));
self::expect(38, genericTearOff0.call<core::num*>(42));
- <T extends core::num* = dynamic>(self::Extension1|genericMethod::T*) →* core::int* genericTearOff1 = self::Extension1|get#genericMethod(c1);
+ <T extends core::num* = dynamic>(T*) →* core::int* genericTearOff1 = self::Extension1|get#genericMethod(c1);
self::expect(35, genericTearOff1.call<core::int*>(42));
self::expect(35, genericTearOff1.call<core::num*>(42));
}
@@ -87,10 +87,10 @@
self::expect(3, tearOff1.call());
c1 = new self::Class2::•(7.{core::int::unary-}());
self::expect(3, tearOff1.call());
- <T extends core::num* = dynamic>(self::Extension2|genericMethod::T*) →* core::int* genericTearOff0 = self::Extension2|get#genericMethod(c0);
+ <T extends core::num* = dynamic>(T*) →* core::int* genericTearOff0 = self::Extension2|get#genericMethod(c0);
self::expect(41, genericTearOff0.call<core::int*>(42));
self::expect(41, genericTearOff0.call<core::num*>(42));
- <T extends core::num* = dynamic>(self::Extension2|genericMethod::T*) →* core::int* genericTearOff1 = self::Extension2|get#genericMethod(c1);
+ <T extends core::num* = dynamic>(T*) →* core::int* genericTearOff1 = self::Extension2|get#genericMethod(c1);
self::expect(38, genericTearOff1.call<core::int*>(42));
self::expect(38, genericTearOff1.call<core::num*>(42));
}
diff --git a/pkg/front_end/testcases/extensions/instance_tearoff.dart.strong.transformed.expect b/pkg/front_end/testcases/extensions/instance_tearoff.dart.strong.transformed.expect
index be0799d..4ba1b5e 100644
--- a/pkg/front_end/testcases/extensions/instance_tearoff.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/extensions/instance_tearoff.dart.strong.transformed.expect
@@ -69,10 +69,10 @@
self::expect(1, tearOff1.call());
c1 = new self::Class1::•(7.{core::int::unary-}());
self::expect(1, tearOff1.call());
- <T extends core::num* = dynamic>(self::Extension1|genericMethod::T*) →* core::int* genericTearOff0 = self::Extension1|get#genericMethod(c0);
+ <T extends core::num* = dynamic>(T*) →* core::int* genericTearOff0 = self::Extension1|get#genericMethod(c0);
self::expect(38, genericTearOff0.call<core::int*>(42));
self::expect(38, genericTearOff0.call<core::num*>(42));
- <T extends core::num* = dynamic>(self::Extension1|genericMethod::T*) →* core::int* genericTearOff1 = self::Extension1|get#genericMethod(c1);
+ <T extends core::num* = dynamic>(T*) →* core::int* genericTearOff1 = self::Extension1|get#genericMethod(c1);
self::expect(35, genericTearOff1.call<core::int*>(42));
self::expect(35, genericTearOff1.call<core::num*>(42));
}
@@ -87,10 +87,10 @@
self::expect(3, tearOff1.call());
c1 = new self::Class2::•(7.{core::int::unary-}());
self::expect(3, tearOff1.call());
- <T extends core::num* = dynamic>(self::Extension2|genericMethod::T*) →* core::int* genericTearOff0 = self::Extension2|get#genericMethod(c0);
+ <T extends core::num* = dynamic>(T*) →* core::int* genericTearOff0 = self::Extension2|get#genericMethod(c0);
self::expect(41, genericTearOff0.call<core::int*>(42));
self::expect(41, genericTearOff0.call<core::num*>(42));
- <T extends core::num* = dynamic>(self::Extension2|genericMethod::T*) →* core::int* genericTearOff1 = self::Extension2|get#genericMethod(c1);
+ <T extends core::num* = dynamic>(T*) →* core::int* genericTearOff1 = self::Extension2|get#genericMethod(c1);
self::expect(38, genericTearOff1.call<core::int*>(42));
self::expect(38, genericTearOff1.call<core::num*>(42));
}
diff --git a/pkg/front_end/testcases/extensions/null_aware.dart b/pkg/front_end/testcases/extensions/null_aware.dart
new file mode 100644
index 0000000..d645b13
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/null_aware.dart
@@ -0,0 +1,39 @@
+// Copyright (c) 2019, 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.
+
+class Class {
+ int field;
+}
+
+extension Extension on Class {
+ int get property => field;
+ void set property(int value) {
+ field = value;
+ }
+ int method() => field;
+}
+
+main() {
+ Class c;
+ expect(null, c?.property);
+ expect(null, c?.method);
+ expect(null, c?.method());
+ expect(null, c?.property = 42);
+ c = new Class();
+ expect(null, c?.property);
+ expect(null, c?.method());
+ var tearOff = c?.method;
+ expect(null, tearOff());
+ expect(42, c?.property = 42);
+ expect(42, tearOff());
+ expect(null, c?.property = null);
+ expect(42, c.property ??= 42);
+ expect(42, c.property ??= 87);
+}
+
+expect(expected, actual) {
+ if (expected != actual) {
+ throw 'Mismatch: expected=$expected, actual=$actual';
+ }
+}
\ No newline at end of file
diff --git a/pkg/front_end/testcases/extensions/null_aware.dart.outline.expect b/pkg/front_end/testcases/extensions/null_aware.dart.outline.expect
new file mode 100644
index 0000000..50dde61
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/null_aware.dart.outline.expect
@@ -0,0 +1,27 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class Class extends core::Object {
+ field core::int* field;
+ synthetic constructor •() → self::Class*
+ ;
+}
+extension Extension on self::Class* {
+ get property = self::Extension|get#property;
+ method method = self::Extension|method;
+ tearoff method = self::Extension|get#method;
+ set property = self::Extension|set#property;
+}
+static method Extension|get#property(final self::Class* #this) → core::int*
+ ;
+static method Extension|set#property(final self::Class* #this, core::int* value) → void
+ ;
+static method Extension|method(final self::Class* #this) → core::int*
+ ;
+static method Extension|get#method(final self::Class* #this) → () →* core::int*
+ return () → core::int* => self::Extension|method(#this);
+static method main() → dynamic
+ ;
+static method expect(dynamic expected, dynamic actual) → dynamic
+ ;
diff --git a/pkg/front_end/testcases/extensions/null_aware.dart.strong.expect b/pkg/front_end/testcases/extensions/null_aware.dart.strong.expect
new file mode 100644
index 0000000..6b4ef8f
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/null_aware.dart.strong.expect
@@ -0,0 +1,49 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class Class extends core::Object {
+ field core::int* field = null;
+ synthetic constructor •() → self::Class*
+ : super core::Object::•()
+ ;
+}
+extension Extension on self::Class* {
+ get property = self::Extension|get#property;
+ method method = self::Extension|method;
+ tearoff method = self::Extension|get#method;
+ set property = self::Extension|set#property;
+}
+static method Extension|get#property(final self::Class* #this) → core::int*
+ return #this.{self::Class::field};
+static method Extension|set#property(final self::Class* #this, core::int* value) → core::int* {
+ final core::int* #t1 = value;
+ #this.{self::Class::field} = value;
+ return #t1;
+}
+static method Extension|method(final self::Class* #this) → core::int*
+ return #this.{self::Class::field};
+static method Extension|get#method(final self::Class* #this) → () →* core::int*
+ return () → core::int* => self::Extension|method(#this);
+static method main() → dynamic {
+ self::Class* c;
+ self::expect(null, let final self::Class* #t2 = c in #t2.{core::Object::==}(null) ?{core::int*} null : self::Extension|get#property(#t2));
+ self::expect(null, let final self::Class* #t3 = c in #t3.{core::Object::==}(null) ?{() →* core::int*} null : self::Extension|get#method(#t3));
+ self::expect(null, let final self::Class* #t4 = c in #t4.{core::Object::==}(null) ?{core::int*} null : self::Extension|method(#t4));
+ self::expect(null, let final self::Class* #t5 = c in #t5.{core::Object::==}(null) ?{core::int*} null : self::Extension|set#property(#t5, 42));
+ c = new self::Class::•();
+ self::expect(null, let final self::Class* #t6 = c in #t6.{core::Object::==}(null) ?{core::int*} null : self::Extension|get#property(#t6));
+ self::expect(null, let final self::Class* #t7 = c in #t7.{core::Object::==}(null) ?{core::int*} null : self::Extension|method(#t7));
+ () →* core::int* tearOff = let final self::Class* #t8 = c in #t8.{core::Object::==}(null) ?{() →* core::int*} null : self::Extension|get#method(#t8);
+ self::expect(null, tearOff.call());
+ self::expect(42, let final self::Class* #t9 = c in #t9.{core::Object::==}(null) ?{core::int*} null : self::Extension|set#property(#t9, 42));
+ self::expect(42, tearOff.call());
+ self::expect(null, let final self::Class* #t10 = c in #t10.{core::Object::==}(null) ?{core::Null?} null : self::Extension|set#property(#t10, null));
+ self::expect(42, let final self::Class* #t11 = c in let final core::int* #t12 = self::Extension|get#property(#t11) in #t12.{core::num::==}(null) ?{core::int*} self::Extension|set#property(#t11, 42) : #t12);
+ self::expect(42, let final self::Class* #t13 = c in let final core::int* #t14 = self::Extension|get#property(#t13) in #t14.{core::num::==}(null) ?{core::int*} self::Extension|set#property(#t13, 87) : #t14);
+}
+static method expect(dynamic expected, dynamic actual) → dynamic {
+ if(!expected.{core::Object::==}(actual)) {
+ throw "Mismatch: expected=${expected}, actual=${actual}";
+ }
+}
diff --git a/pkg/front_end/testcases/extensions/null_aware.dart.strong.transformed.expect b/pkg/front_end/testcases/extensions/null_aware.dart.strong.transformed.expect
new file mode 100644
index 0000000..6b4ef8f
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/null_aware.dart.strong.transformed.expect
@@ -0,0 +1,49 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class Class extends core::Object {
+ field core::int* field = null;
+ synthetic constructor •() → self::Class*
+ : super core::Object::•()
+ ;
+}
+extension Extension on self::Class* {
+ get property = self::Extension|get#property;
+ method method = self::Extension|method;
+ tearoff method = self::Extension|get#method;
+ set property = self::Extension|set#property;
+}
+static method Extension|get#property(final self::Class* #this) → core::int*
+ return #this.{self::Class::field};
+static method Extension|set#property(final self::Class* #this, core::int* value) → core::int* {
+ final core::int* #t1 = value;
+ #this.{self::Class::field} = value;
+ return #t1;
+}
+static method Extension|method(final self::Class* #this) → core::int*
+ return #this.{self::Class::field};
+static method Extension|get#method(final self::Class* #this) → () →* core::int*
+ return () → core::int* => self::Extension|method(#this);
+static method main() → dynamic {
+ self::Class* c;
+ self::expect(null, let final self::Class* #t2 = c in #t2.{core::Object::==}(null) ?{core::int*} null : self::Extension|get#property(#t2));
+ self::expect(null, let final self::Class* #t3 = c in #t3.{core::Object::==}(null) ?{() →* core::int*} null : self::Extension|get#method(#t3));
+ self::expect(null, let final self::Class* #t4 = c in #t4.{core::Object::==}(null) ?{core::int*} null : self::Extension|method(#t4));
+ self::expect(null, let final self::Class* #t5 = c in #t5.{core::Object::==}(null) ?{core::int*} null : self::Extension|set#property(#t5, 42));
+ c = new self::Class::•();
+ self::expect(null, let final self::Class* #t6 = c in #t6.{core::Object::==}(null) ?{core::int*} null : self::Extension|get#property(#t6));
+ self::expect(null, let final self::Class* #t7 = c in #t7.{core::Object::==}(null) ?{core::int*} null : self::Extension|method(#t7));
+ () →* core::int* tearOff = let final self::Class* #t8 = c in #t8.{core::Object::==}(null) ?{() →* core::int*} null : self::Extension|get#method(#t8);
+ self::expect(null, tearOff.call());
+ self::expect(42, let final self::Class* #t9 = c in #t9.{core::Object::==}(null) ?{core::int*} null : self::Extension|set#property(#t9, 42));
+ self::expect(42, tearOff.call());
+ self::expect(null, let final self::Class* #t10 = c in #t10.{core::Object::==}(null) ?{core::Null?} null : self::Extension|set#property(#t10, null));
+ self::expect(42, let final self::Class* #t11 = c in let final core::int* #t12 = self::Extension|get#property(#t11) in #t12.{core::num::==}(null) ?{core::int*} self::Extension|set#property(#t11, 42) : #t12);
+ self::expect(42, let final self::Class* #t13 = c in let final core::int* #t14 = self::Extension|get#property(#t13) in #t14.{core::num::==}(null) ?{core::int*} self::Extension|set#property(#t13, 87) : #t14);
+}
+static method expect(dynamic expected, dynamic actual) → dynamic {
+ if(!expected.{core::Object::==}(actual)) {
+ throw "Mismatch: expected=${expected}, actual=${actual}";
+ }
+}
diff --git a/pkg/front_end/testcases/extensions/null_aware.dart.type_promotion.expect b/pkg/front_end/testcases/extensions/null_aware.dart.type_promotion.expect
new file mode 100644
index 0000000..dee5817
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/null_aware.dart.type_promotion.expect
@@ -0,0 +1,3 @@
+pkg/front_end/testcases/extensions/null_aware.dart:23:5: Context: Write to c@408
+ c = new Class();
+ ^
diff --git a/pkg/front_end/testcases/extensions/on_type_variable_inference.dart.strong.expect b/pkg/front_end/testcases/extensions/on_type_variable_inference.dart.strong.expect
index 7860276..f788aff 100644
--- a/pkg/front_end/testcases/extensions/on_type_variable_inference.dart.strong.expect
+++ b/pkg/front_end/testcases/extensions/on_type_variable_inference.dart.strong.expect
@@ -84,7 +84,7 @@
self::Extension|method<self::Struct*>(struct);
self::Extension|set#property<self::Struct*>(struct, self::Extension|get#property<self::StructA*>(structA));
self::Extension|method<self::StructA*>(structA);
- self::Extension|set#property<self::StructA*>(structA, self::Extension|get#property<self::Struct*>(struct));
+ self::Extension|set#property<self::StructA*>(structA, self::Extension|get#property<self::Struct*>(struct) as{TypeError} self::StructA*);
self::Extension|method<self::StructB*>(structB);
self::Extension|set#property<self::StructB*>(structB, self::Extension|get#property<self::StructB*>(structB));
self::Extension|method<self::Struct*>(new self::Struct::•());
diff --git a/pkg/front_end/testcases/extensions/on_type_variable_inference.dart.strong.transformed.expect b/pkg/front_end/testcases/extensions/on_type_variable_inference.dart.strong.transformed.expect
index 7860276..f788aff 100644
--- a/pkg/front_end/testcases/extensions/on_type_variable_inference.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/extensions/on_type_variable_inference.dart.strong.transformed.expect
@@ -84,7 +84,7 @@
self::Extension|method<self::Struct*>(struct);
self::Extension|set#property<self::Struct*>(struct, self::Extension|get#property<self::StructA*>(structA));
self::Extension|method<self::StructA*>(structA);
- self::Extension|set#property<self::StructA*>(structA, self::Extension|get#property<self::Struct*>(struct));
+ self::Extension|set#property<self::StructA*>(structA, self::Extension|get#property<self::Struct*>(struct) as{TypeError} self::StructA*);
self::Extension|method<self::StructB*>(structB);
self::Extension|set#property<self::StructB*>(structB, self::Extension|get#property<self::StructB*>(structB));
self::Extension|method<self::Struct*>(new self::Struct::•());
diff --git a/pkg/front_end/testcases/extensions/unnamed_extensions.dart b/pkg/front_end/testcases/extensions/unnamed_extensions.dart
new file mode 100644
index 0000000..d425a9f
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/unnamed_extensions.dart
@@ -0,0 +1,115 @@
+// Copyright (c) 2019, 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.
+
+class Class1 {
+ int field;
+
+ Class1(this.field);
+
+ String toString() => 'Class1($field)';
+}
+
+class Class2 {
+ int field;
+
+ Class2(this.field);
+
+ String toString() => 'Class2($field)';
+}
+
+extension on Class1 {
+ int method() {
+ print('Extension1.method on $this');
+ return field;
+ }
+ int genericMethod<T extends num>(T t) {
+ print('Extension1.genericMethod<$T>($t) on $this');
+ return field + t;
+ }
+ int get property {
+ print('Extension1.property get on $this');
+ return field;
+ }
+ set property(int value) {
+ field = value;
+ print('Extension1.property set($value) on $this');
+ value++;
+ }
+}
+
+
+extension on Class2 {
+ int method() {
+ print('Extension2.method on $this');
+ return field + 3;
+ }
+ int genericMethod<T extends num>(T t) {
+ print('Extension2.genericMethod<$T>($t) on $this');
+ return field + t + 4;
+ }
+ int get property {
+ print('Extension2.property get on $this');
+ return field + 5;
+ }
+ set property(int value) {
+ print('Extension2.property set($value) on $this');
+ value++;
+ field = value;
+ }
+}
+
+main() {
+ testExtension1();
+ testExtension2();
+}
+
+testExtension1() {
+ Class1 c0 = new Class1(0);
+ Class1 c1 = new Class1(1);
+ expect(0, c0.method());
+ expect(1, c1.method());
+ expect(1, c1?.method());
+ expect(42, c0.genericMethod(42));
+ expect(43, c0.genericMethod<num>(43));
+ expect(88, c1.genericMethod(87));
+ expect(89, c1.genericMethod<num>(88));
+ expect(0, c0.property);
+ expect(0, c0?.property);
+ expect(42, c0.property = 42);
+ expect(1, c1.property);
+ expect(87, c0.property = 87);
+ expect(27, c0.property = c1.property = 27);
+ expect(37, c1.property = c0.property = 37);
+ expect(77, c1.property = c0.property = c1.property = 77);
+ expect(67, c0.property = c1.property = c0.property = 67);
+}
+
+testExtension2() {
+ Class2 c0 = new Class2(0);
+ Class2 c1 = new Class2(1);
+ expect(3, c0.method());
+ expect(3, c0?.method());
+ expect(4, c1.method());
+ expect(46, c0.genericMethod(42));
+ expect(47, c0.genericMethod<num>(43));
+ expect(92, c1.genericMethod(87));
+ expect(93, c1.genericMethod<num>(88));
+ expect(5, c0.property);
+ expect(5, c0?.property);
+ expect(42, c0.property = 42);
+ expect(48, c0.property);
+ expect(6, c1.property);
+ expect(43, c1.property = 43);
+ expect(49, c1.property);
+ expect(49, c0.property = c1.property);
+ expect(55, c1.property = c0.property);
+ expect(61, c1.property = c0.property = c1.property);
+ expect(67, c0.property = c1.property = c0.property);
+}
+
+expect(expected, actual) {
+ if (expected != actual) {
+ throw 'Mismatch: expected=$expected, actual=$actual';
+ }
+}
\ No newline at end of file
diff --git a/pkg/front_end/testcases/extensions/unnamed_extensions.dart.outline.expect b/pkg/front_end/testcases/extensions/unnamed_extensions.dart.outline.expect
new file mode 100644
index 0000000..cc9bdfa
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/unnamed_extensions.dart.outline.expect
@@ -0,0 +1,66 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class Class1 extends core::Object {
+ field core::int* field;
+ constructor •(core::int* field) → self::Class1*
+ ;
+ method toString() → core::String*
+ ;
+}
+class Class2 extends core::Object {
+ field core::int* field;
+ constructor •(core::int* field) → self::Class2*
+ ;
+ method toString() → core::String*
+ ;
+}
+extension _extension#0 on self::Class1* {
+ method method = self::_extension#0|method;
+ tearoff method = self::_extension#0|get#method;
+ method genericMethod = self::_extension#0|genericMethod;
+ tearoff genericMethod = self::_extension#0|get#genericMethod;
+ get property = self::_extension#0|get#property;
+ set property = self::_extension#0|set#property;
+}
+extension _extension#1 on self::Class2* {
+ method method = self::_extension#1|method;
+ tearoff method = self::_extension#1|get#method;
+ method genericMethod = self::_extension#1|genericMethod;
+ tearoff genericMethod = self::_extension#1|get#genericMethod;
+ get property = self::_extension#1|get#property;
+ set property = self::_extension#1|set#property;
+}
+static method _extension#0|method(final self::Class1* #this) → core::int*
+ ;
+static method _extension#0|get#method(final self::Class1* #this) → () →* core::int*
+ return () → core::int* => self::_extension#0|method(#this);
+static method _extension#0|genericMethod<T extends core::num* = dynamic>(final self::Class1* #this, self::_extension#0|genericMethod::T* t) → core::int*
+ ;
+static method _extension#0|get#genericMethod(final self::Class1* #this) → <T extends core::num* = dynamic>(T*) →* core::int*
+ return <T extends core::num* = dynamic>(T* t) → core::int* => self::_extension#0|genericMethod<T*>(#this, t);
+static method _extension#0|get#property(final self::Class1* #this) → core::int*
+ ;
+static method _extension#0|set#property(final self::Class1* #this, core::int* value) → void
+ ;
+static method _extension#1|method(final self::Class2* #this) → core::int*
+ ;
+static method _extension#1|get#method(final self::Class2* #this) → () →* core::int*
+ return () → core::int* => self::_extension#1|method(#this);
+static method _extension#1|genericMethod<T extends core::num* = dynamic>(final self::Class2* #this, self::_extension#1|genericMethod::T* t) → core::int*
+ ;
+static method _extension#1|get#genericMethod(final self::Class2* #this) → <T extends core::num* = dynamic>(T*) →* core::int*
+ return <T extends core::num* = dynamic>(T* t) → core::int* => self::_extension#1|genericMethod<T*>(#this, t);
+static method _extension#1|get#property(final self::Class2* #this) → core::int*
+ ;
+static method _extension#1|set#property(final self::Class2* #this, core::int* value) → void
+ ;
+static method main() → dynamic
+ ;
+static method testExtension1() → dynamic
+ ;
+static method testExtension2() → dynamic
+ ;
+static method expect(dynamic expected, dynamic actual) → dynamic
+ ;
diff --git a/pkg/front_end/testcases/extensions/unnamed_extensions.dart.strong.expect b/pkg/front_end/testcases/extensions/unnamed_extensions.dart.strong.expect
new file mode 100644
index 0000000..ec79050
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/unnamed_extensions.dart.strong.expect
@@ -0,0 +1,133 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class Class1 extends core::Object {
+ field core::int* field;
+ constructor •(core::int* field) → self::Class1*
+ : self::Class1::field = field, super core::Object::•()
+ ;
+ method toString() → core::String*
+ return "Class1(${this.{self::Class1::field}})";
+}
+class Class2 extends core::Object {
+ field core::int* field;
+ constructor •(core::int* field) → self::Class2*
+ : self::Class2::field = field, super core::Object::•()
+ ;
+ method toString() → core::String*
+ return "Class2(${this.{self::Class2::field}})";
+}
+extension _extension#0 on self::Class1* {
+ method method = self::_extension#0|method;
+ tearoff method = self::_extension#0|get#method;
+ method genericMethod = self::_extension#0|genericMethod;
+ tearoff genericMethod = self::_extension#0|get#genericMethod;
+ get property = self::_extension#0|get#property;
+ set property = self::_extension#0|set#property;
+}
+extension _extension#1 on self::Class2* {
+ method method = self::_extension#1|method;
+ tearoff method = self::_extension#1|get#method;
+ method genericMethod = self::_extension#1|genericMethod;
+ tearoff genericMethod = self::_extension#1|get#genericMethod;
+ get property = self::_extension#1|get#property;
+ set property = self::_extension#1|set#property;
+}
+static method _extension#0|method(final self::Class1* #this) → core::int* {
+ core::print("Extension1.method on ${#this}");
+ return #this.{self::Class1::field};
+}
+static method _extension#0|get#method(final self::Class1* #this) → () →* core::int*
+ return () → core::int* => self::_extension#0|method(#this);
+static method _extension#0|genericMethod<T extends core::num* = dynamic>(final self::Class1* #this, self::_extension#0|genericMethod::T* t) → core::int* {
+ core::print("Extension1.genericMethod<${self::_extension#0|genericMethod::T*}>(${t}) on ${#this}");
+ return #this.{self::Class1::field}.{core::num::+}(t) as{TypeError} core::int*;
+}
+static method _extension#0|get#genericMethod(final self::Class1* #this) → <T extends core::num* = dynamic>(T*) →* core::int*
+ return <T extends core::num* = dynamic>(T* t) → core::int* => self::_extension#0|genericMethod<T*>(#this, t);
+static method _extension#0|get#property(final self::Class1* #this) → core::int* {
+ core::print("Extension1.property get on ${#this}");
+ return #this.{self::Class1::field};
+}
+static method _extension#0|set#property(final self::Class1* #this, core::int* value) → core::int* {
+ final core::int* #t1 = value;
+ #this.{self::Class1::field} = value;
+ core::print("Extension1.property set(${value}) on ${#this}");
+ value = value.{core::num::+}(1);
+ return #t1;
+}
+static method _extension#1|method(final self::Class2* #this) → core::int* {
+ core::print("Extension2.method on ${#this}");
+ return #this.{self::Class2::field}.{core::num::+}(3);
+}
+static method _extension#1|get#method(final self::Class2* #this) → () →* core::int*
+ return () → core::int* => self::_extension#1|method(#this);
+static method _extension#1|genericMethod<T extends core::num* = dynamic>(final self::Class2* #this, self::_extension#1|genericMethod::T* t) → core::int* {
+ core::print("Extension2.genericMethod<${self::_extension#1|genericMethod::T*}>(${t}) on ${#this}");
+ return #this.{self::Class2::field}.{core::num::+}(t).{core::num::+}(4) as{TypeError} core::int*;
+}
+static method _extension#1|get#genericMethod(final self::Class2* #this) → <T extends core::num* = dynamic>(T*) →* core::int*
+ return <T extends core::num* = dynamic>(T* t) → core::int* => self::_extension#1|genericMethod<T*>(#this, t);
+static method _extension#1|get#property(final self::Class2* #this) → core::int* {
+ core::print("Extension2.property get on ${#this}");
+ return #this.{self::Class2::field}.{core::num::+}(5);
+}
+static method _extension#1|set#property(final self::Class2* #this, core::int* value) → core::int* {
+ final core::int* #t2 = value;
+ core::print("Extension2.property set(${value}) on ${#this}");
+ value = value.{core::num::+}(1);
+ #this.{self::Class2::field} = value;
+ return #t2;
+}
+static method main() → dynamic {
+ self::testExtension1();
+ self::testExtension2();
+}
+static method testExtension1() → dynamic {
+ self::Class1* c0 = new self::Class1::•(0);
+ self::Class1* c1 = new self::Class1::•(1);
+ self::expect(0, self::_extension#0|method(c0));
+ self::expect(1, self::_extension#0|method(c1));
+ self::expect(1, let final self::Class1* #t3 = c1 in #t3.{core::Object::==}(null) ?{core::int*} null : self::_extension#0|method(#t3));
+ self::expect(42, self::_extension#0|genericMethod<core::int*>(c0, 42));
+ self::expect(43, self::_extension#0|genericMethod<core::num*>(c0, 43));
+ self::expect(88, self::_extension#0|genericMethod<core::int*>(c1, 87));
+ self::expect(89, self::_extension#0|genericMethod<core::num*>(c1, 88));
+ self::expect(0, self::_extension#0|get#property(c0));
+ self::expect(0, let final self::Class1* #t4 = c0 in #t4.{core::Object::==}(null) ?{core::int*} null : self::_extension#0|get#property(#t4));
+ self::expect(42, self::_extension#0|set#property(c0, 42));
+ self::expect(1, self::_extension#0|get#property(c1));
+ self::expect(87, self::_extension#0|set#property(c0, 87));
+ self::expect(27, self::_extension#0|set#property(c0, self::_extension#0|set#property(c1, 27)));
+ self::expect(37, self::_extension#0|set#property(c1, self::_extension#0|set#property(c0, 37)));
+ self::expect(77, self::_extension#0|set#property(c1, self::_extension#0|set#property(c0, self::_extension#0|set#property(c1, 77))));
+ self::expect(67, self::_extension#0|set#property(c0, self::_extension#0|set#property(c1, self::_extension#0|set#property(c0, 67))));
+}
+static method testExtension2() → dynamic {
+ self::Class2* c0 = new self::Class2::•(0);
+ self::Class2* c1 = new self::Class2::•(1);
+ self::expect(3, self::_extension#1|method(c0));
+ self::expect(3, let final self::Class2* #t5 = c0 in #t5.{core::Object::==}(null) ?{core::int*} null : self::_extension#1|method(#t5));
+ self::expect(4, self::_extension#1|method(c1));
+ self::expect(46, self::_extension#1|genericMethod<core::int*>(c0, 42));
+ self::expect(47, self::_extension#1|genericMethod<core::num*>(c0, 43));
+ self::expect(92, self::_extension#1|genericMethod<core::int*>(c1, 87));
+ self::expect(93, self::_extension#1|genericMethod<core::num*>(c1, 88));
+ self::expect(5, self::_extension#1|get#property(c0));
+ self::expect(5, let final self::Class2* #t6 = c0 in #t6.{core::Object::==}(null) ?{core::int*} null : self::_extension#1|get#property(#t6));
+ self::expect(42, self::_extension#1|set#property(c0, 42));
+ self::expect(48, self::_extension#1|get#property(c0));
+ self::expect(6, self::_extension#1|get#property(c1));
+ self::expect(43, self::_extension#1|set#property(c1, 43));
+ self::expect(49, self::_extension#1|get#property(c1));
+ self::expect(49, self::_extension#1|set#property(c0, self::_extension#1|get#property(c1)));
+ self::expect(55, self::_extension#1|set#property(c1, self::_extension#1|get#property(c0)));
+ self::expect(61, self::_extension#1|set#property(c1, self::_extension#1|set#property(c0, self::_extension#1|get#property(c1))));
+ self::expect(67, self::_extension#1|set#property(c0, self::_extension#1|set#property(c1, self::_extension#1|get#property(c0))));
+}
+static method expect(dynamic expected, dynamic actual) → dynamic {
+ if(!expected.{core::Object::==}(actual)) {
+ throw "Mismatch: expected=${expected}, actual=${actual}";
+ }
+}
diff --git a/pkg/front_end/testcases/extensions/unnamed_extensions.dart.strong.transformed.expect b/pkg/front_end/testcases/extensions/unnamed_extensions.dart.strong.transformed.expect
new file mode 100644
index 0000000..ec79050
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/unnamed_extensions.dart.strong.transformed.expect
@@ -0,0 +1,133 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class Class1 extends core::Object {
+ field core::int* field;
+ constructor •(core::int* field) → self::Class1*
+ : self::Class1::field = field, super core::Object::•()
+ ;
+ method toString() → core::String*
+ return "Class1(${this.{self::Class1::field}})";
+}
+class Class2 extends core::Object {
+ field core::int* field;
+ constructor •(core::int* field) → self::Class2*
+ : self::Class2::field = field, super core::Object::•()
+ ;
+ method toString() → core::String*
+ return "Class2(${this.{self::Class2::field}})";
+}
+extension _extension#0 on self::Class1* {
+ method method = self::_extension#0|method;
+ tearoff method = self::_extension#0|get#method;
+ method genericMethod = self::_extension#0|genericMethod;
+ tearoff genericMethod = self::_extension#0|get#genericMethod;
+ get property = self::_extension#0|get#property;
+ set property = self::_extension#0|set#property;
+}
+extension _extension#1 on self::Class2* {
+ method method = self::_extension#1|method;
+ tearoff method = self::_extension#1|get#method;
+ method genericMethod = self::_extension#1|genericMethod;
+ tearoff genericMethod = self::_extension#1|get#genericMethod;
+ get property = self::_extension#1|get#property;
+ set property = self::_extension#1|set#property;
+}
+static method _extension#0|method(final self::Class1* #this) → core::int* {
+ core::print("Extension1.method on ${#this}");
+ return #this.{self::Class1::field};
+}
+static method _extension#0|get#method(final self::Class1* #this) → () →* core::int*
+ return () → core::int* => self::_extension#0|method(#this);
+static method _extension#0|genericMethod<T extends core::num* = dynamic>(final self::Class1* #this, self::_extension#0|genericMethod::T* t) → core::int* {
+ core::print("Extension1.genericMethod<${self::_extension#0|genericMethod::T*}>(${t}) on ${#this}");
+ return #this.{self::Class1::field}.{core::num::+}(t) as{TypeError} core::int*;
+}
+static method _extension#0|get#genericMethod(final self::Class1* #this) → <T extends core::num* = dynamic>(T*) →* core::int*
+ return <T extends core::num* = dynamic>(T* t) → core::int* => self::_extension#0|genericMethod<T*>(#this, t);
+static method _extension#0|get#property(final self::Class1* #this) → core::int* {
+ core::print("Extension1.property get on ${#this}");
+ return #this.{self::Class1::field};
+}
+static method _extension#0|set#property(final self::Class1* #this, core::int* value) → core::int* {
+ final core::int* #t1 = value;
+ #this.{self::Class1::field} = value;
+ core::print("Extension1.property set(${value}) on ${#this}");
+ value = value.{core::num::+}(1);
+ return #t1;
+}
+static method _extension#1|method(final self::Class2* #this) → core::int* {
+ core::print("Extension2.method on ${#this}");
+ return #this.{self::Class2::field}.{core::num::+}(3);
+}
+static method _extension#1|get#method(final self::Class2* #this) → () →* core::int*
+ return () → core::int* => self::_extension#1|method(#this);
+static method _extension#1|genericMethod<T extends core::num* = dynamic>(final self::Class2* #this, self::_extension#1|genericMethod::T* t) → core::int* {
+ core::print("Extension2.genericMethod<${self::_extension#1|genericMethod::T*}>(${t}) on ${#this}");
+ return #this.{self::Class2::field}.{core::num::+}(t).{core::num::+}(4) as{TypeError} core::int*;
+}
+static method _extension#1|get#genericMethod(final self::Class2* #this) → <T extends core::num* = dynamic>(T*) →* core::int*
+ return <T extends core::num* = dynamic>(T* t) → core::int* => self::_extension#1|genericMethod<T*>(#this, t);
+static method _extension#1|get#property(final self::Class2* #this) → core::int* {
+ core::print("Extension2.property get on ${#this}");
+ return #this.{self::Class2::field}.{core::num::+}(5);
+}
+static method _extension#1|set#property(final self::Class2* #this, core::int* value) → core::int* {
+ final core::int* #t2 = value;
+ core::print("Extension2.property set(${value}) on ${#this}");
+ value = value.{core::num::+}(1);
+ #this.{self::Class2::field} = value;
+ return #t2;
+}
+static method main() → dynamic {
+ self::testExtension1();
+ self::testExtension2();
+}
+static method testExtension1() → dynamic {
+ self::Class1* c0 = new self::Class1::•(0);
+ self::Class1* c1 = new self::Class1::•(1);
+ self::expect(0, self::_extension#0|method(c0));
+ self::expect(1, self::_extension#0|method(c1));
+ self::expect(1, let final self::Class1* #t3 = c1 in #t3.{core::Object::==}(null) ?{core::int*} null : self::_extension#0|method(#t3));
+ self::expect(42, self::_extension#0|genericMethod<core::int*>(c0, 42));
+ self::expect(43, self::_extension#0|genericMethod<core::num*>(c0, 43));
+ self::expect(88, self::_extension#0|genericMethod<core::int*>(c1, 87));
+ self::expect(89, self::_extension#0|genericMethod<core::num*>(c1, 88));
+ self::expect(0, self::_extension#0|get#property(c0));
+ self::expect(0, let final self::Class1* #t4 = c0 in #t4.{core::Object::==}(null) ?{core::int*} null : self::_extension#0|get#property(#t4));
+ self::expect(42, self::_extension#0|set#property(c0, 42));
+ self::expect(1, self::_extension#0|get#property(c1));
+ self::expect(87, self::_extension#0|set#property(c0, 87));
+ self::expect(27, self::_extension#0|set#property(c0, self::_extension#0|set#property(c1, 27)));
+ self::expect(37, self::_extension#0|set#property(c1, self::_extension#0|set#property(c0, 37)));
+ self::expect(77, self::_extension#0|set#property(c1, self::_extension#0|set#property(c0, self::_extension#0|set#property(c1, 77))));
+ self::expect(67, self::_extension#0|set#property(c0, self::_extension#0|set#property(c1, self::_extension#0|set#property(c0, 67))));
+}
+static method testExtension2() → dynamic {
+ self::Class2* c0 = new self::Class2::•(0);
+ self::Class2* c1 = new self::Class2::•(1);
+ self::expect(3, self::_extension#1|method(c0));
+ self::expect(3, let final self::Class2* #t5 = c0 in #t5.{core::Object::==}(null) ?{core::int*} null : self::_extension#1|method(#t5));
+ self::expect(4, self::_extension#1|method(c1));
+ self::expect(46, self::_extension#1|genericMethod<core::int*>(c0, 42));
+ self::expect(47, self::_extension#1|genericMethod<core::num*>(c0, 43));
+ self::expect(92, self::_extension#1|genericMethod<core::int*>(c1, 87));
+ self::expect(93, self::_extension#1|genericMethod<core::num*>(c1, 88));
+ self::expect(5, self::_extension#1|get#property(c0));
+ self::expect(5, let final self::Class2* #t6 = c0 in #t6.{core::Object::==}(null) ?{core::int*} null : self::_extension#1|get#property(#t6));
+ self::expect(42, self::_extension#1|set#property(c0, 42));
+ self::expect(48, self::_extension#1|get#property(c0));
+ self::expect(6, self::_extension#1|get#property(c1));
+ self::expect(43, self::_extension#1|set#property(c1, 43));
+ self::expect(49, self::_extension#1|get#property(c1));
+ self::expect(49, self::_extension#1|set#property(c0, self::_extension#1|get#property(c1)));
+ self::expect(55, self::_extension#1|set#property(c1, self::_extension#1|get#property(c0)));
+ self::expect(61, self::_extension#1|set#property(c1, self::_extension#1|set#property(c0, self::_extension#1|get#property(c1))));
+ self::expect(67, self::_extension#1|set#property(c0, self::_extension#1|set#property(c1, self::_extension#1|get#property(c0))));
+}
+static method expect(dynamic expected, dynamic actual) → dynamic {
+ if(!expected.{core::Object::==}(actual)) {
+ throw "Mismatch: expected=${expected}, actual=${actual}";
+ }
+}
diff --git a/pkg/front_end/testcases/extensions/unnamed_extensions.dart.type_promotion.expect b/pkg/front_end/testcases/extensions/unnamed_extensions.dart.type_promotion.expect
new file mode 100644
index 0000000..a2934e5
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/unnamed_extensions.dart.type_promotion.expect
@@ -0,0 +1,6 @@
+pkg/front_end/testcases/extensions/unnamed_extensions.dart:37:10: Context: Write to value@744
+ value++;
+ ^^
+pkg/front_end/testcases/extensions/unnamed_extensions.dart:57:10: Context: Write to value@1195
+ value++;
+ ^^
diff --git a/pkg/front_end/testcases/general/annotation_variable_declaration.dart.strong.expect b/pkg/front_end/testcases/general/annotation_variable_declaration.dart.strong.expect
index 18047a8..023576c 100644
--- a/pkg/front_end/testcases/general/annotation_variable_declaration.dart.strong.expect
+++ b/pkg/front_end/testcases/general/annotation_variable_declaration.dart.strong.expect
@@ -25,9 +25,9 @@
@#C1 core::String* localWithInitializer = "hello";
@#C1 @#C2 dynamic localGroupPart1;
@#C1 @#C2 dynamic localGroupPart2;
- function naebdyr(@#C1 dynamic nestedFormal) → core::Null*
+ function naebdyr(@#C1 dynamic nestedFormal) → core::Null?
return null;
- (dynamic) →* core::Null* roedmus = (@#C1 dynamic closureFormal) → core::Null* => null;
+ (dynamic) →* core::Null? roedmus = (@#C1 dynamic closureFormal) → core::Null? => null;
}
method hest({@#C1 dynamic named = #C3}) → dynamic
return null;
diff --git a/pkg/front_end/testcases/general/annotation_variable_declaration.dart.strong.transformed.expect b/pkg/front_end/testcases/general/annotation_variable_declaration.dart.strong.transformed.expect
index 18047a8..023576c 100644
--- a/pkg/front_end/testcases/general/annotation_variable_declaration.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/general/annotation_variable_declaration.dart.strong.transformed.expect
@@ -25,9 +25,9 @@
@#C1 core::String* localWithInitializer = "hello";
@#C1 @#C2 dynamic localGroupPart1;
@#C1 @#C2 dynamic localGroupPart2;
- function naebdyr(@#C1 dynamic nestedFormal) → core::Null*
+ function naebdyr(@#C1 dynamic nestedFormal) → core::Null?
return null;
- (dynamic) →* core::Null* roedmus = (@#C1 dynamic closureFormal) → core::Null* => null;
+ (dynamic) →* core::Null? roedmus = (@#C1 dynamic closureFormal) → core::Null? => null;
}
method hest({@#C1 dynamic named = #C3}) → dynamic
return null;
diff --git a/pkg/front_end/testcases/general/async_nested.dart.strong.expect b/pkg/front_end/testcases/general/async_nested.dart.strong.expect
index c01b082..5c3da0c 100644
--- a/pkg/front_end/testcases/general/async_nested.dart.strong.expect
+++ b/pkg/front_end/testcases/general/async_nested.dart.strong.expect
@@ -11,10 +11,10 @@
constructor •(core::String* name, [core::List<self::Node*>* nested = #C1]) → self::Node*
: self::Node::name = name, self::Node::nested = nested, super core::Object::•() {}
method toString() → core::String*
- return "<${this.{self::Node::name}}:[${let final core::List<self::Node*>* #t1 = this.{self::Node::nested} in #t1.==(null) ?{core::String*} null : #t1.{core::Iterable::join}(", ")}]>";
+ return "<${this.{self::Node::name}}:[${let final core::List<self::Node*>* #t1 = this.{self::Node::nested} in #t1.{core::List::==}(null) ?{core::String*} null : #t1.{core::Iterable::join}(", ")}]>";
method toSimpleString() → dynamic {
- core::Iterable<dynamic>* tmp = let final core::List<self::Node*>* #t2 = this.{self::Node::nested} in #t2.==(null) ?{core::Iterable<dynamic>*} null : #t2.{core::Iterable::map}<dynamic>((self::Node* child) → dynamic => child.{self::Node::toSimpleString}());
- return "${this.{self::Node::name}} ${let final core::Iterable<dynamic>* #t3 = tmp in #t3.==(null) ?{core::String*} null : #t3.{core::Iterable::join}(" ")}".{core::String::trim}();
+ core::Iterable<dynamic>* tmp = let final core::List<self::Node*>* #t2 = this.{self::Node::nested} in #t2.{core::List::==}(null) ?{core::Iterable<dynamic>*} null : #t2.{core::Iterable::map}<dynamic>((self::Node* child) → dynamic => child.{self::Node::toSimpleString}());
+ return "${this.{self::Node::name}} ${let final core::Iterable<dynamic>* #t3 = tmp in #t3.{core::Object::==}(null) ?{core::String*} null : #t3.{core::Iterable::join}(" ")}".{core::String::trim}();
}
}
static method main() → void async {
diff --git a/pkg/front_end/testcases/general/async_nested.dart.strong.transformed.expect b/pkg/front_end/testcases/general/async_nested.dart.strong.transformed.expect
index 730f857..256ef3f 100644
--- a/pkg/front_end/testcases/general/async_nested.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/general/async_nested.dart.strong.transformed.expect
@@ -11,10 +11,10 @@
constructor •(core::String* name, [core::List<self::Node*>* nested = #C1]) → self::Node*
: self::Node::name = name, self::Node::nested = nested, super core::Object::•() {}
method toString() → core::String*
- return "<${this.{self::Node::name}}:[${let final core::List<self::Node*>* #t1 = this.{self::Node::nested} in #t1.==(null) ?{core::String*} null : #t1.{core::Iterable::join}(", ")}]>";
+ return "<${this.{self::Node::name}}:[${let final core::List<self::Node*>* #t1 = this.{self::Node::nested} in #t1.{core::List::==}(null) ?{core::String*} null : #t1.{core::Iterable::join}(", ")}]>";
method toSimpleString() → dynamic {
- core::Iterable<dynamic>* tmp = let final core::List<self::Node*>* #t2 = this.{self::Node::nested} in #t2.==(null) ?{core::Iterable<dynamic>*} null : #t2.{core::Iterable::map}<dynamic>((self::Node* child) → dynamic => child.{self::Node::toSimpleString}());
- return "${this.{self::Node::name}} ${let final core::Iterable<dynamic>* #t3 = tmp in #t3.==(null) ?{core::String*} null : #t3.{core::Iterable::join}(" ")}".{core::String::trim}();
+ core::Iterable<dynamic>* tmp = let final core::List<self::Node*>* #t2 = this.{self::Node::nested} in #t2.{core::List::==}(null) ?{core::Iterable<dynamic>*} null : #t2.{core::Iterable::map}<dynamic>((self::Node* child) → dynamic => child.{self::Node::toSimpleString}());
+ return "${this.{self::Node::name}} ${let final core::Iterable<dynamic>* #t3 = tmp in #t3.{core::Object::==}(null) ?{core::String*} null : #t3.{core::Iterable::join}(" ")}".{core::String::trim}();
}
}
static method main() → void /* originally async */ {
diff --git a/pkg/front_end/testcases/general/bug33099.dart.strong.expect b/pkg/front_end/testcases/general/bug33099.dart.strong.expect
index 537c6ae..98cc4a6 100644
--- a/pkg/front_end/testcases/general/bug33099.dart.strong.expect
+++ b/pkg/front_end/testcases/general/bug33099.dart.strong.expect
@@ -30,7 +30,7 @@
static const field self::_FailingTest* failingTest = #C1;
static method main() → dynamic {
mir::ClassMirror* classMirror = mir::reflectClass(self::MyTest2*);
- classMirror.{mir::ClassMirror::instanceMembers}.{core::Map::forEach}((core::Symbol* symbol, mir::MethodMirror* memberMirror) → core::Null* {
+ classMirror.{mir::ClassMirror::instanceMembers}.{core::Map::forEach}((core::Symbol* symbol, mir::MethodMirror* memberMirror) → core::Null? {
if(memberMirror.{mir::DeclarationMirror::simpleName}.{core::Symbol::==}(#C2)) {
core::print(memberMirror);
core::print(self::_hasFailingTestAnnotation(memberMirror));
diff --git a/pkg/front_end/testcases/general/bug33099.dart.strong.transformed.expect b/pkg/front_end/testcases/general/bug33099.dart.strong.transformed.expect
index 0a95528..f56cb2a 100644
--- a/pkg/front_end/testcases/general/bug33099.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/general/bug33099.dart.strong.transformed.expect
@@ -32,7 +32,7 @@
static const field self::_FailingTest* failingTest = #C1;
static method main() → dynamic {
mir::ClassMirror* classMirror = mir::reflectClass(self::MyTest2*);
- classMirror.{mir::ClassMirror::instanceMembers}.{core::Map::forEach}((core::Symbol* symbol, mir::MethodMirror* memberMirror) → core::Null* {
+ classMirror.{mir::ClassMirror::instanceMembers}.{core::Map::forEach}((core::Symbol* symbol, mir::MethodMirror* memberMirror) → core::Null? {
if(memberMirror.{mir::DeclarationMirror::simpleName}.{core::Symbol::==}(#C2)) {
core::print(memberMirror);
core::print(self::_hasFailingTestAnnotation(memberMirror));
diff --git a/pkg/front_end/testcases/general/bug33298.dart.strong.expect b/pkg/front_end/testcases/general/bug33298.dart.strong.expect
index 57354a6..57e3d95 100644
--- a/pkg/front_end/testcases/general/bug33298.dart.strong.expect
+++ b/pkg/front_end/testcases/general/bug33298.dart.strong.expect
@@ -43,6 +43,6 @@
core::List<core::String*>* list6 = <core::String*>["a", "b", "c"].{core::Iterable::map}<dynamic>(let final<BottomType> #t3 = invalid-expression "pkg/front_end/testcases/general/bug33298.dart:28:44: Error: The argument type 'T Function<T>(T)' can't be assigned to the parameter type 'dynamic Function(String)'.
Try changing the type of the parameter, or casting the argument to 'dynamic Function(String)'.
List<String> list6 = ['a', 'b', 'c'].map(c).toList();
- ^" in (let final self::C* #t4 = c in #t4.==(null) ?{<T extends core::Object* = dynamic>(self::C::call::T*) →* self::C::call::T*} null : #t4.{self::C::call}) as{TypeError} (core::String*) →* dynamic).{core::Iterable::toList}() as{TypeError} core::List<core::String*>*;
+ ^" in (let final self::C* #t4 = c in #t4.==(null) ?{<T extends core::Object* = dynamic>(T*) →* T*} null : #t4.{self::C::call}) as{TypeError} (core::String*) →* dynamic).{core::Iterable::toList}() as{TypeError} core::List<core::String*>*;
}
static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/general/bug33298.dart.strong.transformed.expect b/pkg/front_end/testcases/general/bug33298.dart.strong.transformed.expect
index 57354a6..57e3d95 100644
--- a/pkg/front_end/testcases/general/bug33298.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/general/bug33298.dart.strong.transformed.expect
@@ -43,6 +43,6 @@
core::List<core::String*>* list6 = <core::String*>["a", "b", "c"].{core::Iterable::map}<dynamic>(let final<BottomType> #t3 = invalid-expression "pkg/front_end/testcases/general/bug33298.dart:28:44: Error: The argument type 'T Function<T>(T)' can't be assigned to the parameter type 'dynamic Function(String)'.
Try changing the type of the parameter, or casting the argument to 'dynamic Function(String)'.
List<String> list6 = ['a', 'b', 'c'].map(c).toList();
- ^" in (let final self::C* #t4 = c in #t4.==(null) ?{<T extends core::Object* = dynamic>(self::C::call::T*) →* self::C::call::T*} null : #t4.{self::C::call}) as{TypeError} (core::String*) →* dynamic).{core::Iterable::toList}() as{TypeError} core::List<core::String*>*;
+ ^" in (let final self::C* #t4 = c in #t4.==(null) ?{<T extends core::Object* = dynamic>(T*) →* T*} null : #t4.{self::C::call}) as{TypeError} (core::String*) →* dynamic).{core::Iterable::toList}() as{TypeError} core::List<core::String*>*;
}
static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/general/bug37476.dart.strong.expect b/pkg/front_end/testcases/general/bug37476.dart.strong.expect
index 49098e1..cd1a2ae 100644
--- a/pkg/front_end/testcases/general/bug37476.dart.strong.expect
+++ b/pkg/front_end/testcases/general/bug37476.dart.strong.expect
@@ -8,7 +8,7 @@
;
method foo() → <S extends self::A::T* = dynamic>(S*) →* void {
core::print("foo: T = ${self::A::T*}");
- return <S extends self::A::T* = self::A::T*>(S* a) → core::Null* {};
+ return <S extends self::A::T* = self::A::T*>(S* a) → core::Null? {};
}
}
class B<T extends core::num* = core::num*> extends core::Object {
@@ -17,7 +17,7 @@
;
method foo() → (self::B::T*) →* void {
core::print("foo: T = ${self::B::T*}");
- return (self::B::T* a) → core::Null* {};
+ return (self::B::T* a) → core::Null? {};
}
}
static field self::A<core::num*>* a = new self::A::•<core::int*>();
diff --git a/pkg/front_end/testcases/general/bug37476.dart.strong.transformed.expect b/pkg/front_end/testcases/general/bug37476.dart.strong.transformed.expect
index 49098e1..cd1a2ae 100644
--- a/pkg/front_end/testcases/general/bug37476.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/general/bug37476.dart.strong.transformed.expect
@@ -8,7 +8,7 @@
;
method foo() → <S extends self::A::T* = dynamic>(S*) →* void {
core::print("foo: T = ${self::A::T*}");
- return <S extends self::A::T* = self::A::T*>(S* a) → core::Null* {};
+ return <S extends self::A::T* = self::A::T*>(S* a) → core::Null? {};
}
}
class B<T extends core::num* = core::num*> extends core::Object {
@@ -17,7 +17,7 @@
;
method foo() → (self::B::T*) →* void {
core::print("foo: T = ${self::B::T*}");
- return (self::B::T* a) → core::Null* {};
+ return (self::B::T* a) → core::Null? {};
}
}
static field self::A<core::num*>* a = new self::A::•<core::int*>();
diff --git a/pkg/front_end/testcases/general/compound_binary_implicit_as.dart b/pkg/front_end/testcases/general/compound_binary_implicit_as.dart
new file mode 100644
index 0000000..ea6ab25
--- /dev/null
+++ b/pkg/front_end/testcases/general/compound_binary_implicit_as.dart
@@ -0,0 +1,19 @@
+// Copyright (c) 2019, 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.
+
+class A {}
+
+class B extends A {
+ A operator +(B b) => new C();
+}
+
+class C extends A {}
+
+main() {
+ Map<int, B> map = {0: new B()};
+ try {
+ map[0] += new B();
+ throw 'Expected type error';
+ } catch (_) {}
+}
diff --git a/pkg/front_end/testcases/general/compound_binary_implicit_as.dart.outline.expect b/pkg/front_end/testcases/general/compound_binary_implicit_as.dart.outline.expect
new file mode 100644
index 0000000..36ce691
--- /dev/null
+++ b/pkg/front_end/testcases/general/compound_binary_implicit_as.dart.outline.expect
@@ -0,0 +1,20 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+ synthetic constructor •() → self::A*
+ ;
+}
+class B extends self::A {
+ synthetic constructor •() → self::B*
+ ;
+ operator +(self::B* b) → self::A*
+ ;
+}
+class C extends self::A {
+ synthetic constructor •() → self::C*
+ ;
+}
+static method main() → dynamic
+ ;
diff --git a/pkg/front_end/testcases/general/compound_binary_implicit_as.dart.strong.expect b/pkg/front_end/testcases/general/compound_binary_implicit_as.dart.strong.expect
new file mode 100644
index 0000000..3781401
--- /dev/null
+++ b/pkg/front_end/testcases/general/compound_binary_implicit_as.dart.strong.expect
@@ -0,0 +1,30 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+ synthetic constructor •() → self::A*
+ : super core::Object::•()
+ ;
+}
+class B extends self::A {
+ synthetic constructor •() → self::B*
+ : super self::A::•()
+ ;
+ operator +(self::B* b) → self::A*
+ return new self::C::•();
+}
+class C extends self::A {
+ synthetic constructor •() → self::C*
+ : super self::A::•()
+ ;
+}
+static method main() → dynamic {
+ core::Map<core::int*, self::B*>* map = <core::int*, self::B*>{0: new self::B::•()};
+ try {
+ let final core::Map<core::int*, self::B*>* #t1 = map in let final core::int* #t2 = 0 in #t1.{core::Map::[]=}(#t2, #t1.{core::Map::[]}(#t2).{self::B::+}(new self::B::•()) as{TypeError} self::B*);
+ throw "Expected type error";
+ }
+ on dynamic catch(final dynamic _) {
+ }
+}
diff --git a/pkg/front_end/testcases/general/compound_binary_implicit_as.dart.strong.transformed.expect b/pkg/front_end/testcases/general/compound_binary_implicit_as.dart.strong.transformed.expect
new file mode 100644
index 0000000..3781401
--- /dev/null
+++ b/pkg/front_end/testcases/general/compound_binary_implicit_as.dart.strong.transformed.expect
@@ -0,0 +1,30 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+ synthetic constructor •() → self::A*
+ : super core::Object::•()
+ ;
+}
+class B extends self::A {
+ synthetic constructor •() → self::B*
+ : super self::A::•()
+ ;
+ operator +(self::B* b) → self::A*
+ return new self::C::•();
+}
+class C extends self::A {
+ synthetic constructor •() → self::C*
+ : super self::A::•()
+ ;
+}
+static method main() → dynamic {
+ core::Map<core::int*, self::B*>* map = <core::int*, self::B*>{0: new self::B::•()};
+ try {
+ let final core::Map<core::int*, self::B*>* #t1 = map in let final core::int* #t2 = 0 in #t1.{core::Map::[]=}(#t2, #t1.{core::Map::[]}(#t2).{self::B::+}(new self::B::•()) as{TypeError} self::B*);
+ throw "Expected type error";
+ }
+ on dynamic catch(final dynamic _) {
+ }
+}
diff --git a/pkg/front_end/testcases/general/constructor_const_inference.dart.strong.expect b/pkg/front_end/testcases/general/constructor_const_inference.dart.strong.expect
index 9b8bc6d..45d397e 100644
--- a/pkg/front_end/testcases/general/constructor_const_inference.dart.strong.expect
+++ b/pkg/front_end/testcases/general/constructor_const_inference.dart.strong.expect
@@ -26,5 +26,5 @@
}
constants {
- #C1 = self::_Y<core::Null*> {}
+ #C1 = self::_Y<core::Null?> {}
}
diff --git a/pkg/front_end/testcases/general/constructor_const_inference.dart.strong.transformed.expect b/pkg/front_end/testcases/general/constructor_const_inference.dart.strong.transformed.expect
index 9b8bc6d..45d397e 100644
--- a/pkg/front_end/testcases/general/constructor_const_inference.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/general/constructor_const_inference.dart.strong.transformed.expect
@@ -26,5 +26,5 @@
}
constants {
- #C1 = self::_Y<core::Null*> {}
+ #C1 = self::_Y<core::Null?> {}
}
diff --git a/pkg/front_end/testcases/general/control_flow_collection_inference.dart.strong.expect b/pkg/front_end/testcases/general/control_flow_collection_inference.dart.strong.expect
index 5f32797..a7c5eb0 100644
--- a/pkg/front_end/testcases/general/control_flow_collection_inference.dart.strong.expect
+++ b/pkg/front_end/testcases/general/control_flow_collection_inference.dart.strong.expect
@@ -1208,10 +1208,10 @@
core::Map<dynamic, dynamic>* map11 = <dynamic, dynamic>{invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:109:70: Error: Expected ':' after this.
Map<dynamic, dynamic> map11 = {if (oracle(\"foo\")) \"bar\": 3.14 else 42};
^": null};
- core::Map<<BottomType>, core::Null*>* map12 = <<BottomType>, core::Null*>{invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:110:35: Error: Expected ':' after this.
+ core::Map<<BottomType>, core::Null?>* map12 = <<BottomType>, core::Null?>{invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:110:35: Error: Expected ':' after this.
var map12 = {if (oracle(\"foo\")) 42 else \"bar\": 3.14};
^": null};
- core::Map<<BottomType>, core::Null*>* map13 = <<BottomType>, core::Null*>{invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:111:52: Error: Expected ':' after this.
+ core::Map<<BottomType>, core::Null?>* map13 = <<BottomType>, core::Null?>{invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:111:52: Error: Expected ':' after this.
var map13 = {if (oracle(\"foo\")) \"bar\": 3.14 else 42};
^": null};
core::List<core::int*>* list20 = block {
diff --git a/pkg/front_end/testcases/general/control_flow_collection_inference.dart.strong.transformed.expect b/pkg/front_end/testcases/general/control_flow_collection_inference.dart.strong.transformed.expect
index 7f1ee70..5cc5798 100644
--- a/pkg/front_end/testcases/general/control_flow_collection_inference.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/general/control_flow_collection_inference.dart.strong.transformed.expect
@@ -1208,10 +1208,10 @@
core::Map<dynamic, dynamic>* map11 = <dynamic, dynamic>{invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:109:70: Error: Expected ':' after this.
Map<dynamic, dynamic> map11 = {if (oracle(\"foo\")) \"bar\": 3.14 else 42};
^": null};
- core::Map<<BottomType>, core::Null*>* map12 = <<BottomType>, core::Null*>{invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:110:35: Error: Expected ':' after this.
+ core::Map<<BottomType>, core::Null?>* map12 = <<BottomType>, core::Null?>{invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:110:35: Error: Expected ':' after this.
var map12 = {if (oracle(\"foo\")) 42 else \"bar\": 3.14};
^": null};
- core::Map<<BottomType>, core::Null*>* map13 = <<BottomType>, core::Null*>{invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:111:52: Error: Expected ':' after this.
+ core::Map<<BottomType>, core::Null?>* map13 = <<BottomType>, core::Null?>{invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:111:52: Error: Expected ':' after this.
var map13 = {if (oracle(\"foo\")) \"bar\": 3.14 else 42};
^": null};
core::List<core::int*>* list20 = block {
diff --git a/pkg/front_end/testcases/general/covariant_generic.dart.strong.expect b/pkg/front_end/testcases/general/covariant_generic.dart.strong.expect
index c7bba1c..684ab99 100644
--- a/pkg/front_end/testcases/general/covariant_generic.dart.strong.expect
+++ b/pkg/front_end/testcases/general/covariant_generic.dart.strong.expect
@@ -18,22 +18,22 @@
}
}
static method main() → dynamic {
- self::Foo<core::int*>* fooInt = new self::Foo::•<core::int*>(1, (core::int* x) → core::Null* {});
+ self::Foo<core::int*>* fooInt = new self::Foo::•<core::int*>(1, (core::int* x) → core::Null? {});
fooInt.{self::Foo::method}(3);
fooInt.{self::Foo::setter} = 3;
- fooInt.{self::Foo::withCallback}((core::int* x) → core::Null* {});
- fooInt.{self::Foo::withCallback}((core::num* x) → core::Null* {});
+ fooInt.{self::Foo::withCallback}((core::int* x) → core::Null? {});
+ fooInt.{self::Foo::withCallback}((core::num* x) → core::Null? {});
fooInt.{self::Foo::mutableField} = 3;
- fooInt.{self::Foo::mutableCallbackField} = (core::int* x) → core::Null* {};
+ fooInt.{self::Foo::mutableCallbackField} = (core::int* x) → core::Null? {};
self::Foo<core::num*>* fooNum = fooInt;
fooNum.{self::Foo::method}(3);
fooNum.{self::Foo::method}(2.5);
fooNum.{self::Foo::setter} = 3;
fooNum.{self::Foo::setter} = 2.5;
- fooNum.{self::Foo::withCallback}((core::num* x) → core::Null* {});
+ fooNum.{self::Foo::withCallback}((core::num* x) → core::Null? {});
fooNum.{self::Foo::mutableField} = 3;
fooNum.{self::Foo::mutableField} = 2.5;
(fooNum.{self::Foo::mutableCallbackField} as{TypeError} (core::num*) →* void).call(3);
(fooNum.{self::Foo::mutableCallbackField} as{TypeError} (core::num*) →* void).call(2.5);
- fooNum.{self::Foo::mutableCallbackField} = (core::num* x) → core::Null* {};
+ fooNum.{self::Foo::mutableCallbackField} = (core::num* x) → core::Null? {};
}
diff --git a/pkg/front_end/testcases/general/covariant_generic.dart.strong.transformed.expect b/pkg/front_end/testcases/general/covariant_generic.dart.strong.transformed.expect
index c7bba1c..684ab99 100644
--- a/pkg/front_end/testcases/general/covariant_generic.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/general/covariant_generic.dart.strong.transformed.expect
@@ -18,22 +18,22 @@
}
}
static method main() → dynamic {
- self::Foo<core::int*>* fooInt = new self::Foo::•<core::int*>(1, (core::int* x) → core::Null* {});
+ self::Foo<core::int*>* fooInt = new self::Foo::•<core::int*>(1, (core::int* x) → core::Null? {});
fooInt.{self::Foo::method}(3);
fooInt.{self::Foo::setter} = 3;
- fooInt.{self::Foo::withCallback}((core::int* x) → core::Null* {});
- fooInt.{self::Foo::withCallback}((core::num* x) → core::Null* {});
+ fooInt.{self::Foo::withCallback}((core::int* x) → core::Null? {});
+ fooInt.{self::Foo::withCallback}((core::num* x) → core::Null? {});
fooInt.{self::Foo::mutableField} = 3;
- fooInt.{self::Foo::mutableCallbackField} = (core::int* x) → core::Null* {};
+ fooInt.{self::Foo::mutableCallbackField} = (core::int* x) → core::Null? {};
self::Foo<core::num*>* fooNum = fooInt;
fooNum.{self::Foo::method}(3);
fooNum.{self::Foo::method}(2.5);
fooNum.{self::Foo::setter} = 3;
fooNum.{self::Foo::setter} = 2.5;
- fooNum.{self::Foo::withCallback}((core::num* x) → core::Null* {});
+ fooNum.{self::Foo::withCallback}((core::num* x) → core::Null? {});
fooNum.{self::Foo::mutableField} = 3;
fooNum.{self::Foo::mutableField} = 2.5;
(fooNum.{self::Foo::mutableCallbackField} as{TypeError} (core::num*) →* void).call(3);
(fooNum.{self::Foo::mutableCallbackField} as{TypeError} (core::num*) →* void).call(2.5);
- fooNum.{self::Foo::mutableCallbackField} = (core::num* x) → core::Null* {};
+ fooNum.{self::Foo::mutableCallbackField} = (core::num* x) → core::Null? {};
}
diff --git a/pkg/front_end/testcases/general/export_test.dart b/pkg/front_end/testcases/general/export_test.dart
index a95dbfa..13646cf 100644
--- a/pkg/front_end/testcases/general/export_test.dart
+++ b/pkg/front_end/testcases/general/export_test.dart
@@ -4,10 +4,9 @@
/// Test that exports are serialized in platform.dill.
-// Note: "dart:profiler" exports UserTag from "dart:developer". This is
-// somewhat brittle and we should extend this test framework to be able to deal
-// with multiple .dill files.
-import 'dart:profiler' show UserTag;
+// This is somewhat brittle and we should extend this test framework to be
+// able to deal with multiple .dill files.
+import 'dart:developer' show UserTag;
export 'dart:core' show print;
diff --git a/pkg/front_end/testcases/general/export_test.dart.outline.expect b/pkg/front_end/testcases/general/export_test.dart.outline.expect
index e337eae..a49370d 100644
--- a/pkg/front_end/testcases/general/export_test.dart.outline.expect
+++ b/pkg/front_end/testcases/general/export_test.dart.outline.expect
@@ -4,7 +4,7 @@
additionalExports = (core::print)
-import "dart:profiler";
+import "dart:developer";
export "dart:core";
static method main() → dynamic
diff --git a/pkg/front_end/testcases/general/export_test.dart.strong.expect b/pkg/front_end/testcases/general/export_test.dart.strong.expect
index 96ce0dd..3f5a303 100644
--- a/pkg/front_end/testcases/general/export_test.dart.strong.expect
+++ b/pkg/front_end/testcases/general/export_test.dart.strong.expect
@@ -5,7 +5,7 @@
additionalExports = (core::print)
-import "dart:profiler";
+import "dart:developer";
export "dart:core";
static method main() → dynamic {
diff --git a/pkg/front_end/testcases/general/export_test.dart.strong.transformed.expect b/pkg/front_end/testcases/general/export_test.dart.strong.transformed.expect
index 96ce0dd..3f5a303 100644
--- a/pkg/front_end/testcases/general/export_test.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/general/export_test.dart.strong.transformed.expect
@@ -5,7 +5,7 @@
additionalExports = (core::print)
-import "dart:profiler";
+import "dart:developer";
export "dart:core";
static method main() → dynamic {
diff --git a/pkg/front_end/testcases/general/expressions.dart.strong.expect b/pkg/front_end/testcases/general/expressions.dart.strong.expect
index bc4e719..7826eeb 100644
--- a/pkg/front_end/testcases/general/expressions.dart.strong.expect
+++ b/pkg/front_end/testcases/general/expressions.dart.strong.expect
@@ -51,25 +51,25 @@
core::print(#C2);
core::print(core::List::•<core::String*>(2).{core::Object::runtimeType});
self::foo(fisk: "Blorp gulp");
- function f() → core::Null* {
+ function f() → core::Null? {
core::print("f was called");
}
self::caller(f);
- self::caller(() → core::Null* {
+ self::caller(() → core::Null? {
core::print("<anon> was called");
});
- function g([dynamic message = #C1]) → core::Null* {
+ function g([dynamic message = #C1]) → core::Null? {
core::print(message);
}
g.call("Hello, World");
- self::caller(([dynamic x = #C1]) → core::Null* {
+ self::caller(([dynamic x = #C1]) → core::Null? {
core::print("<anon> was called with ${x}");
});
- function h({dynamic message = #C1}) → core::Null* {
+ function h({dynamic message = #C1}) → core::Null? {
core::print(message);
}
h.call(message: "Hello, World");
- self::caller(({dynamic x = #C1}) → core::Null* {
+ self::caller(({dynamic x = #C1}) → core::Null? {
core::print("<anon> was called with ${x}");
});
core::print(core::int*.{core::Object::toString}());
diff --git a/pkg/front_end/testcases/general/expressions.dart.strong.transformed.expect b/pkg/front_end/testcases/general/expressions.dart.strong.transformed.expect
index 741dfc4..d50717a 100644
--- a/pkg/front_end/testcases/general/expressions.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/general/expressions.dart.strong.transformed.expect
@@ -51,25 +51,25 @@
core::print(#C2);
core::print(core::_List::•<core::String*>(2).{core::Object::runtimeType});
self::foo(fisk: "Blorp gulp");
- function f() → core::Null* {
+ function f() → core::Null? {
core::print("f was called");
}
self::caller(f);
- self::caller(() → core::Null* {
+ self::caller(() → core::Null? {
core::print("<anon> was called");
});
- function g([dynamic message = #C1]) → core::Null* {
+ function g([dynamic message = #C1]) → core::Null? {
core::print(message);
}
g.call("Hello, World");
- self::caller(([dynamic x = #C1]) → core::Null* {
+ self::caller(([dynamic x = #C1]) → core::Null? {
core::print("<anon> was called with ${x}");
});
- function h({dynamic message = #C1}) → core::Null* {
+ function h({dynamic message = #C1}) → core::Null? {
core::print(message);
}
h.call(message: "Hello, World");
- self::caller(({dynamic x = #C1}) → core::Null* {
+ self::caller(({dynamic x = #C1}) → core::Null? {
core::print("<anon> was called with ${x}");
});
core::print(core::int*.{core::Object::toString}());
diff --git a/pkg/front_end/testcases/general/function_type_is_check.dart.strong.expect b/pkg/front_end/testcases/general/function_type_is_check.dart.strong.expect
index 7493073..e3d7cfb 100644
--- a/pkg/front_end/testcases/general/function_type_is_check.dart.strong.expect
+++ b/pkg/front_end/testcases/general/function_type_is_check.dart.strong.expect
@@ -14,5 +14,5 @@
return 100;
}
static method main() → dynamic {
- exp::Expect::equals(111, self::test(() → core::Null* => null).+(self::test((core::Object* o) → core::Null* => null)).+(self::test((core::Object* o, core::StackTrace* t) → core::Null* => null)));
+ exp::Expect::equals(111, self::test(() → core::Null? => null).+(self::test((core::Object* o) → core::Null? => null)).+(self::test((core::Object* o, core::StackTrace* t) → core::Null? => null)));
}
diff --git a/pkg/front_end/testcases/general/function_type_is_check.dart.strong.transformed.expect b/pkg/front_end/testcases/general/function_type_is_check.dart.strong.transformed.expect
index 7493073..e3d7cfb 100644
--- a/pkg/front_end/testcases/general/function_type_is_check.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/general/function_type_is_check.dart.strong.transformed.expect
@@ -14,5 +14,5 @@
return 100;
}
static method main() → dynamic {
- exp::Expect::equals(111, self::test(() → core::Null* => null).+(self::test((core::Object* o) → core::Null* => null)).+(self::test((core::Object* o, core::StackTrace* t) → core::Null* => null)));
+ exp::Expect::equals(111, self::test(() → core::Null? => null).+(self::test((core::Object* o) → core::Null? => null)).+(self::test((core::Object* o, core::StackTrace* t) → core::Null? => null)));
}
diff --git a/pkg/front_end/testcases/general/functions.dart.strong.expect b/pkg/front_end/testcases/general/functions.dart.strong.expect
index 7b58e1b..f6f35ca 100644
--- a/pkg/front_end/testcases/general/functions.dart.strong.expect
+++ b/pkg/front_end/testcases/general/functions.dart.strong.expect
@@ -7,7 +7,7 @@
f.call(a: "Hello, World");
f.call();
}
- local.call(({dynamic a = #C1}) → core::Null* {
+ local.call(({dynamic a = #C1}) → core::Null? {
core::print(a);
});
}
diff --git a/pkg/front_end/testcases/general/functions.dart.strong.transformed.expect b/pkg/front_end/testcases/general/functions.dart.strong.transformed.expect
index 7b58e1b..f6f35ca 100644
--- a/pkg/front_end/testcases/general/functions.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/general/functions.dart.strong.transformed.expect
@@ -7,7 +7,7 @@
f.call(a: "Hello, World");
f.call();
}
- local.call(({dynamic a = #C1}) → core::Null* {
+ local.call(({dynamic a = #C1}) → core::Null? {
core::print(a);
});
}
diff --git a/pkg/front_end/testcases/general/illegal_named_function_expression.dart.strong.expect b/pkg/front_end/testcases/general/illegal_named_function_expression.dart.strong.expect
index 71eaf54..9284232 100644
--- a/pkg/front_end/testcases/general/illegal_named_function_expression.dart.strong.expect
+++ b/pkg/front_end/testcases/general/illegal_named_function_expression.dart.strong.expect
@@ -14,7 +14,7 @@
import "dart:core" as core;
static method main() → dynamic {
- <T extends core::Object* = dynamic>(T*) →* core::Null* x = let final <T extends core::Object* = dynamic>(T*) →* core::Null* f = <T extends core::Object* = dynamic>(T* t) → core::Null* {} in f;
+ <T extends core::Object* = dynamic>(T*) →* core::Null? x = let final <T extends core::Object* = dynamic>(T*) →* core::Null? f = <T extends core::Object* = dynamic>(T* t) → core::Null? {} in f;
core::print(x.{core::Object::runtimeType});
- core::print(let final <T extends core::Object* = dynamic>(T*) →* core::Null* g = <T extends core::Object* = dynamic>(T* t) → core::Null* {} in g);
+ core::print(let final <T extends core::Object* = dynamic>(T*) →* core::Null? g = <T extends core::Object* = dynamic>(T* t) → core::Null? {} in g);
}
diff --git a/pkg/front_end/testcases/general/illegal_named_function_expression.dart.strong.transformed.expect b/pkg/front_end/testcases/general/illegal_named_function_expression.dart.strong.transformed.expect
index 71eaf54..9284232 100644
--- a/pkg/front_end/testcases/general/illegal_named_function_expression.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/general/illegal_named_function_expression.dart.strong.transformed.expect
@@ -14,7 +14,7 @@
import "dart:core" as core;
static method main() → dynamic {
- <T extends core::Object* = dynamic>(T*) →* core::Null* x = let final <T extends core::Object* = dynamic>(T*) →* core::Null* f = <T extends core::Object* = dynamic>(T* t) → core::Null* {} in f;
+ <T extends core::Object* = dynamic>(T*) →* core::Null? x = let final <T extends core::Object* = dynamic>(T*) →* core::Null? f = <T extends core::Object* = dynamic>(T* t) → core::Null? {} in f;
core::print(x.{core::Object::runtimeType});
- core::print(let final <T extends core::Object* = dynamic>(T*) →* core::Null* g = <T extends core::Object* = dynamic>(T* t) → core::Null* {} in g);
+ core::print(let final <T extends core::Object* = dynamic>(T*) →* core::Null? g = <T extends core::Object* = dynamic>(T* t) → core::Null? {} in g);
}
diff --git a/pkg/front_end/testcases/general/illegal_named_function_expression_scope.dart.strong.expect b/pkg/front_end/testcases/general/illegal_named_function_expression_scope.dart.strong.expect
index da7462d..ad827f9 100644
--- a/pkg/front_end/testcases/general/illegal_named_function_expression_scope.dart.strong.expect
+++ b/pkg/front_end/testcases/general/illegal_named_function_expression_scope.dart.strong.expect
@@ -11,5 +11,5 @@
static method main() → dynamic {
function f() → void {}
- core::print(let final () →* core::Null* f = () → core::Null* {} in f);
+ core::print(let final () →* core::Null? f = () → core::Null? {} in f);
}
diff --git a/pkg/front_end/testcases/general/illegal_named_function_expression_scope.dart.strong.transformed.expect b/pkg/front_end/testcases/general/illegal_named_function_expression_scope.dart.strong.transformed.expect
index da7462d..ad827f9 100644
--- a/pkg/front_end/testcases/general/illegal_named_function_expression_scope.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/general/illegal_named_function_expression_scope.dart.strong.transformed.expect
@@ -11,5 +11,5 @@
static method main() → dynamic {
function f() → void {}
- core::print(let final () →* core::Null* f = () → core::Null* {} in f);
+ core::print(let final () →* core::Null? f = () → core::Null? {} in f);
}
diff --git a/pkg/front_end/testcases/general/magic_const.dart.strong.expect b/pkg/front_end/testcases/general/magic_const.dart.strong.expect
index 6d9ece4..de74647 100644
--- a/pkg/front_end/testcases/general/magic_const.dart.strong.expect
+++ b/pkg/front_end/testcases/general/magic_const.dart.strong.expect
@@ -15,6 +15,21 @@
//
// Problems in library:
//
+// pkg/front_end/testcases/general/magic_const.dart:15:9: Error: Constant expression expected.
+// Try inserting 'const'.
+// foo({a: Constant(), b: Constant(), c: []}) {}
+// ^^^^^^^^
+//
+// pkg/front_end/testcases/general/magic_const.dart:15:24: Error: Constant expression expected.
+// Try inserting 'const'.
+// foo({a: Constant(), b: Constant(), c: []}) {}
+// ^^^^^^^^
+//
+// pkg/front_end/testcases/general/magic_const.dart:15:39: Error: Constant expression expected.
+// Try inserting 'const'.
+// foo({a: Constant(), b: Constant(), c: []}) {}
+// ^
+//
// pkg/front_end/testcases/general/magic_const.dart:18:9: Error: Cannot invoke a non-'const' constructor where a const expression is expected.
// Try using a constructor or factory that is 'const'.
// const NotConstant();
diff --git a/pkg/front_end/testcases/general/magic_const.dart.strong.transformed.expect b/pkg/front_end/testcases/general/magic_const.dart.strong.transformed.expect
index 6d9ece4..de74647 100644
--- a/pkg/front_end/testcases/general/magic_const.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/general/magic_const.dart.strong.transformed.expect
@@ -15,6 +15,21 @@
//
// Problems in library:
//
+// pkg/front_end/testcases/general/magic_const.dart:15:9: Error: Constant expression expected.
+// Try inserting 'const'.
+// foo({a: Constant(), b: Constant(), c: []}) {}
+// ^^^^^^^^
+//
+// pkg/front_end/testcases/general/magic_const.dart:15:24: Error: Constant expression expected.
+// Try inserting 'const'.
+// foo({a: Constant(), b: Constant(), c: []}) {}
+// ^^^^^^^^
+//
+// pkg/front_end/testcases/general/magic_const.dart:15:39: Error: Constant expression expected.
+// Try inserting 'const'.
+// foo({a: Constant(), b: Constant(), c: []}) {}
+// ^
+//
// pkg/front_end/testcases/general/magic_const.dart:18:9: Error: Cannot invoke a non-'const' constructor where a const expression is expected.
// Try using a constructor or factory that is 'const'.
// const NotConstant();
diff --git a/pkg/front_end/testcases/general/named_function_scope.dart.strong.expect b/pkg/front_end/testcases/general/named_function_scope.dart.strong.expect
index 982626e..d13b4f3 100644
--- a/pkg/front_end/testcases/general/named_function_scope.dart.strong.expect
+++ b/pkg/front_end/testcases/general/named_function_scope.dart.strong.expect
@@ -98,14 +98,14 @@
self::T* t;
self::V* v;
{
- function T() → core::Null* {}
+ function T() → core::Null? {}
}
{
dynamic v;
}
{
self::T* t;
- () →* core::Null* x = let final () →* core::Null* T = () → core::Null* {} in T;
+ () →* core::Null? x = let final () →* core::Null? T = () → core::Null? {} in T;
}
{
self::V* v;
diff --git a/pkg/front_end/testcases/general/named_function_scope.dart.strong.transformed.expect b/pkg/front_end/testcases/general/named_function_scope.dart.strong.transformed.expect
index 982626e..d13b4f3 100644
--- a/pkg/front_end/testcases/general/named_function_scope.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/general/named_function_scope.dart.strong.transformed.expect
@@ -98,14 +98,14 @@
self::T* t;
self::V* v;
{
- function T() → core::Null* {}
+ function T() → core::Null? {}
}
{
dynamic v;
}
{
self::T* t;
- () →* core::Null* x = let final () →* core::Null* T = () → core::Null* {} in T;
+ () →* core::Null? x = let final () →* core::Null? T = () → core::Null? {} in T;
}
{
self::V* v;
diff --git a/pkg/front_end/testcases/general/nested_property_set.dart b/pkg/front_end/testcases/general/nested_property_set.dart
new file mode 100644
index 0000000..6b12100
--- /dev/null
+++ b/pkg/front_end/testcases/general/nested_property_set.dart
@@ -0,0 +1,30 @@
+// Copyright (c) 2019, 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.
+
+class NumField {
+ num field;
+}
+
+class IntField {
+ int field;
+}
+
+class DoubleField {
+ double field;
+}
+
+main() {
+ IntField intField1 = new IntField();
+ IntField intField2 = new IntField();
+ NumField numField = new NumField();
+ DoubleField doubleField = new DoubleField();
+
+ intField1.field = intField2.field = numField.field;
+ intField1.field = numField.field = intField2.field;
+ try {
+ numField.field = 0.5;
+ intField1.field = doubleField.field = numField.field;
+ throw 'Should fail';
+ } catch (_) {}
+}
diff --git a/pkg/front_end/testcases/general/nested_property_set.dart.outline.expect b/pkg/front_end/testcases/general/nested_property_set.dart.outline.expect
new file mode 100644
index 0000000..3417b90
--- /dev/null
+++ b/pkg/front_end/testcases/general/nested_property_set.dart.outline.expect
@@ -0,0 +1,21 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class NumField extends core::Object {
+ field core::num* field;
+ synthetic constructor •() → self::NumField*
+ ;
+}
+class IntField extends core::Object {
+ field core::int* field;
+ synthetic constructor •() → self::IntField*
+ ;
+}
+class DoubleField extends core::Object {
+ field core::double* field;
+ synthetic constructor •() → self::DoubleField*
+ ;
+}
+static method main() → dynamic
+ ;
diff --git a/pkg/front_end/testcases/general/nested_property_set.dart.strong.expect b/pkg/front_end/testcases/general/nested_property_set.dart.strong.expect
new file mode 100644
index 0000000..1660b62
--- /dev/null
+++ b/pkg/front_end/testcases/general/nested_property_set.dart.strong.expect
@@ -0,0 +1,37 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class NumField extends core::Object {
+ field core::num* field = null;
+ synthetic constructor •() → self::NumField*
+ : super core::Object::•()
+ ;
+}
+class IntField extends core::Object {
+ field core::int* field = null;
+ synthetic constructor •() → self::IntField*
+ : super core::Object::•()
+ ;
+}
+class DoubleField extends core::Object {
+ field core::double* field = null;
+ synthetic constructor •() → self::DoubleField*
+ : super core::Object::•()
+ ;
+}
+static method main() → dynamic {
+ self::IntField* intField1 = new self::IntField::•();
+ self::IntField* intField2 = new self::IntField::•();
+ self::NumField* numField = new self::NumField::•();
+ self::DoubleField* doubleField = new self::DoubleField::•();
+ intField1.{self::IntField::field} = (intField2.{self::IntField::field} = numField.{self::NumField::field} as{TypeError} core::int*) as{TypeError} core::int*;
+ intField1.{self::IntField::field} = numField.{self::NumField::field} = intField2.{self::IntField::field};
+ try {
+ numField.{self::NumField::field} = 0.5;
+ intField1.{self::IntField::field} = (doubleField.{self::DoubleField::field} = numField.{self::NumField::field} as{TypeError} core::double*) as{TypeError} core::int*;
+ throw "Should fail";
+ }
+ on dynamic catch(final dynamic _) {
+ }
+}
diff --git a/pkg/front_end/testcases/general/nested_property_set.dart.strong.transformed.expect b/pkg/front_end/testcases/general/nested_property_set.dart.strong.transformed.expect
new file mode 100644
index 0000000..1660b62
--- /dev/null
+++ b/pkg/front_end/testcases/general/nested_property_set.dart.strong.transformed.expect
@@ -0,0 +1,37 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class NumField extends core::Object {
+ field core::num* field = null;
+ synthetic constructor •() → self::NumField*
+ : super core::Object::•()
+ ;
+}
+class IntField extends core::Object {
+ field core::int* field = null;
+ synthetic constructor •() → self::IntField*
+ : super core::Object::•()
+ ;
+}
+class DoubleField extends core::Object {
+ field core::double* field = null;
+ synthetic constructor •() → self::DoubleField*
+ : super core::Object::•()
+ ;
+}
+static method main() → dynamic {
+ self::IntField* intField1 = new self::IntField::•();
+ self::IntField* intField2 = new self::IntField::•();
+ self::NumField* numField = new self::NumField::•();
+ self::DoubleField* doubleField = new self::DoubleField::•();
+ intField1.{self::IntField::field} = (intField2.{self::IntField::field} = numField.{self::NumField::field} as{TypeError} core::int*) as{TypeError} core::int*;
+ intField1.{self::IntField::field} = numField.{self::NumField::field} = intField2.{self::IntField::field};
+ try {
+ numField.{self::NumField::field} = 0.5;
+ intField1.{self::IntField::field} = (doubleField.{self::DoubleField::field} = numField.{self::NumField::field} as{TypeError} core::double*) as{TypeError} core::int*;
+ throw "Should fail";
+ }
+ on dynamic catch(final dynamic _) {
+ }
+}
diff --git a/pkg/front_end/testcases/general/nested_variable_set.dart b/pkg/front_end/testcases/general/nested_variable_set.dart
new file mode 100644
index 0000000..4babd49
--- /dev/null
+++ b/pkg/front_end/testcases/general/nested_variable_set.dart
@@ -0,0 +1,18 @@
+// Copyright (c) 2019, 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.
+
+main() {
+ int intLocal1;
+ int intLocal2;
+ num numLocal;
+ double doubleLocal;
+
+ intLocal1 = intLocal2 = numLocal;
+ intLocal1 = numLocal = intLocal2;
+ numLocal = 0.5;
+ try {
+ intLocal1 = doubleLocal = numLocal;
+ throw 'Should fail';
+ } catch (_) {}
+}
diff --git a/pkg/front_end/testcases/general/nested_variable_set.dart.outline.expect b/pkg/front_end/testcases/general/nested_variable_set.dart.outline.expect
new file mode 100644
index 0000000..6a28c0d
--- /dev/null
+++ b/pkg/front_end/testcases/general/nested_variable_set.dart.outline.expect
@@ -0,0 +1,5 @@
+library;
+import self as self;
+
+static method main() → dynamic
+ ;
diff --git a/pkg/front_end/testcases/general/nested_variable_set.dart.strong.expect b/pkg/front_end/testcases/general/nested_variable_set.dart.strong.expect
new file mode 100644
index 0000000..7e193c1
--- /dev/null
+++ b/pkg/front_end/testcases/general/nested_variable_set.dart.strong.expect
@@ -0,0 +1,19 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+static method main() → dynamic {
+ core::int* intLocal1;
+ core::int* intLocal2;
+ core::num* numLocal;
+ core::double* doubleLocal;
+ intLocal1 = (intLocal2 = numLocal as{TypeError} core::int*) as{TypeError} core::int*;
+ intLocal1 = numLocal = intLocal2;
+ numLocal = 0.5;
+ try {
+ intLocal1 = (doubleLocal = numLocal as{TypeError} core::double*) as{TypeError} core::int*;
+ throw "Should fail";
+ }
+ on dynamic catch(final dynamic _) {
+ }
+}
diff --git a/pkg/front_end/testcases/general/nested_variable_set.dart.strong.transformed.expect b/pkg/front_end/testcases/general/nested_variable_set.dart.strong.transformed.expect
new file mode 100644
index 0000000..7e193c1
--- /dev/null
+++ b/pkg/front_end/testcases/general/nested_variable_set.dart.strong.transformed.expect
@@ -0,0 +1,19 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+static method main() → dynamic {
+ core::int* intLocal1;
+ core::int* intLocal2;
+ core::num* numLocal;
+ core::double* doubleLocal;
+ intLocal1 = (intLocal2 = numLocal as{TypeError} core::int*) as{TypeError} core::int*;
+ intLocal1 = numLocal = intLocal2;
+ numLocal = 0.5;
+ try {
+ intLocal1 = (doubleLocal = numLocal as{TypeError} core::double*) as{TypeError} core::int*;
+ throw "Should fail";
+ }
+ on dynamic catch(final dynamic _) {
+ }
+}
diff --git a/pkg/front_end/testcases/general/nested_variable_set.dart.type_promotion.expect b/pkg/front_end/testcases/general/nested_variable_set.dart.type_promotion.expect
new file mode 100644
index 0000000..6aa997e
--- /dev/null
+++ b/pkg/front_end/testcases/general/nested_variable_set.dart.type_promotion.expect
@@ -0,0 +1,21 @@
+pkg/front_end/testcases/general/nested_variable_set.dart:11:25: Context: Write to intLocal2@249
+ intLocal1 = intLocal2 = numLocal;
+ ^
+pkg/front_end/testcases/general/nested_variable_set.dart:11:13: Context: Write to intLocal1@232
+ intLocal1 = intLocal2 = numLocal;
+ ^
+pkg/front_end/testcases/general/nested_variable_set.dart:12:24: Context: Write to numLocal@266
+ intLocal1 = numLocal = intLocal2;
+ ^
+pkg/front_end/testcases/general/nested_variable_set.dart:12:13: Context: Write to intLocal1@232
+ intLocal1 = numLocal = intLocal2;
+ ^
+pkg/front_end/testcases/general/nested_variable_set.dart:13:12: Context: Write to numLocal@266
+ numLocal = 0.5;
+ ^
+pkg/front_end/testcases/general/nested_variable_set.dart:15:29: Context: Write to doubleLocal@285
+ intLocal1 = doubleLocal = numLocal;
+ ^
+pkg/front_end/testcases/general/nested_variable_set.dart:15:15: Context: Write to intLocal1@232
+ intLocal1 = doubleLocal = numLocal;
+ ^
diff --git a/pkg/front_end/testcases/general/non_covariant_checks.dart.strong.expect b/pkg/front_end/testcases/general/non_covariant_checks.dart.strong.expect
index 0b3bcfc..17ac3e7 100644
--- a/pkg/front_end/testcases/general/non_covariant_checks.dart.strong.expect
+++ b/pkg/front_end/testcases/general/non_covariant_checks.dart.strong.expect
@@ -19,7 +19,7 @@
generic-covariant-impl field <S extends self::C::T* = dynamic>(S*) →* S* field14;
generic-covariant-impl field (<S extends self::C::T* = dynamic>() →* S*) →* void field15;
constructor •(self::C::T* field1) → self::C<self::C::T*>*
- : self::C::field1 = field1, self::C::field2 = () → self::C::T* => field1, self::C::field3 = (self::C::T* t) → core::Null* {}, self::C::field4 = (self::C::T* t) → self::C::T* => t, self::C::field5 = () → () →* self::C::T* => () → self::C::T* => field1, self::C::field6 = (() →* self::C::T* f) → core::Null* {}, self::C::field7 = (() →* self::C::T* f) → self::C::T* => field1, self::C::field8 = ((self::C::T*) →* void f) → core::Null* {}, self::C::field9 = ((self::C::T*) →* void f) → self::C::T* => field1, self::C::field10 = ((self::C::T*) →* self::C::T* f) → core::Null* {}, self::C::field11 = ((self::C::T*) →* self::C::T* f) → self::C::T* => field1, self::C::field12 = <S extends self::C::T* = self::C::T*>() → core::Null* => null, self::C::field13 = <S extends self::C::T* = self::C::T*>(S* s) → core::Null* {}, self::C::field14 = <S extends self::C::T* = self::C::T*>(S* s) → S* => s, self::C::field15 = (<S extends self::C::T* = self::C::T*>() →* S* f) → core::Null* {}, super core::Object::•()
+ : self::C::field1 = field1, self::C::field2 = () → self::C::T* => field1, self::C::field3 = (self::C::T* t) → core::Null? {}, self::C::field4 = (self::C::T* t) → self::C::T* => t, self::C::field5 = () → () →* self::C::T* => () → self::C::T* => field1, self::C::field6 = (() →* self::C::T* f) → core::Null? {}, self::C::field7 = (() →* self::C::T* f) → self::C::T* => field1, self::C::field8 = ((self::C::T*) →* void f) → core::Null? {}, self::C::field9 = ((self::C::T*) →* void f) → self::C::T* => field1, self::C::field10 = ((self::C::T*) →* self::C::T* f) → core::Null? {}, self::C::field11 = ((self::C::T*) →* self::C::T* f) → self::C::T* => field1, self::C::field12 = <S extends self::C::T* = self::C::T*>() → core::Null? => null, self::C::field13 = <S extends self::C::T* = self::C::T*>(S* s) → core::Null? {}, self::C::field14 = <S extends self::C::T* = self::C::T*>(S* s) → S* => s, self::C::field15 = (<S extends self::C::T* = self::C::T*>() →* S* f) → core::Null? {}, super core::Object::•()
;
get getter1() → self::C::T*
return this.{self::C::field1};
@@ -308,7 +308,7 @@
on core::TypeError* catch(final core::TypeError* e) {
core::print(e);
}
- c.{self::C::setter3} = (core::num* n) → core::Null* {};
+ c.{self::C::setter3} = (core::num* n) → core::Null? {};
try {
c.{self::C::setter4} = (core::num* n) → core::double* => 0.5;
throw "TypeError expected";
@@ -323,7 +323,7 @@
on core::TypeError* catch(final core::TypeError* e) {
core::print(e);
}
- c.{self::C::setter6} = (() →* core::num* f) → core::Null* {};
+ c.{self::C::setter6} = (() →* core::num* f) → core::Null? {};
try {
c.{self::C::setter7} = (() →* core::num* f) → core::double* => 0.5;
throw "TypeError expected";
@@ -332,7 +332,7 @@
core::print(e);
}
try {
- c.{self::C::setter8} = ((core::double*) →* void f) → core::Null* {};
+ c.{self::C::setter8} = ((core::double*) →* void f) → core::Null? {};
throw "TypeError expected";
}
on core::TypeError* catch(final core::TypeError* e) {
@@ -346,7 +346,7 @@
core::print(e);
}
try {
- c.{self::C::setter10} = ((core::double*) →* core::num* f) → core::Null* {};
+ c.{self::C::setter10} = ((core::double*) →* core::num* f) → core::Null? {};
throw "TypeError expected";
}
on core::TypeError* catch(final core::TypeError* e) {
@@ -360,14 +360,14 @@
core::print(e);
}
try {
- c.{self::C::setter12} = <S extends core::num* = core::num*>() → core::Null* => null;
+ c.{self::C::setter12} = <S extends core::num* = core::num*>() → core::Null? => null;
throw "TypeError expected";
}
on core::TypeError* catch(final core::TypeError* e) {
core::print(e);
}
try {
- c.{self::C::setter13} = <S extends core::num* = core::num*>(S* s) → core::Null* {};
+ c.{self::C::setter13} = <S extends core::num* = core::num*>(S* s) → core::Null? {};
throw "TypeError expected";
}
on core::TypeError* catch(final core::TypeError* e) {
@@ -381,7 +381,7 @@
core::print(e);
}
try {
- c.{self::C::setter15} = (<S extends core::num* = core::num*>() →* S* f) → core::Null* {};
+ c.{self::C::setter15} = (<S extends core::num* = core::num*>() →* S* f) → core::Null? {};
throw "TypeError expected";
}
on core::TypeError* catch(final core::TypeError* e) {
@@ -401,7 +401,7 @@
on core::TypeError* catch(final core::TypeError* e) {
core::print(e);
}
- c.{self::C::method3}((core::num* n) → core::Null* {});
+ c.{self::C::method3}((core::num* n) → core::Null? {});
try {
c.{self::C::method4}((core::num* n) → core::double* => 0.5);
throw "TypeError expected";
@@ -416,7 +416,7 @@
on core::TypeError* catch(final core::TypeError* e) {
core::print(e);
}
- c.{self::C::method6}((() →* core::num* f) → core::Null* {});
+ c.{self::C::method6}((() →* core::num* f) → core::Null? {});
try {
c.{self::C::method7}((() →* core::num* f) → core::double* => 0.5);
throw "TypeError expected";
@@ -425,7 +425,7 @@
core::print(e);
}
try {
- c.{self::C::method8}(((core::double*) →* void f) → core::Null* {});
+ c.{self::C::method8}(((core::double*) →* void f) → core::Null? {});
throw "TypeError expected";
}
on core::TypeError* catch(final core::TypeError* e) {
@@ -439,7 +439,7 @@
core::print(e);
}
try {
- c.{self::C::method10}(((core::double*) →* core::num* f) → core::Null* {});
+ c.{self::C::method10}(((core::double*) →* core::num* f) → core::Null? {});
throw "TypeError expected";
}
on core::TypeError* catch(final core::TypeError* e) {
@@ -453,14 +453,14 @@
core::print(e);
}
try {
- c.{self::C::method12}(<S extends core::num* = core::num*>() → core::Null* => null);
+ c.{self::C::method12}(<S extends core::num* = core::num*>() → core::Null? => null);
throw "TypeError expected";
}
on core::TypeError* catch(final core::TypeError* e) {
core::print(e);
}
try {
- c.{self::C::method13}(<S extends core::num* = core::num*>(S* s) → core::Null* {});
+ c.{self::C::method13}(<S extends core::num* = core::num*>(S* s) → core::Null? {});
throw "TypeError expected";
}
on core::TypeError* catch(final core::TypeError* e) {
@@ -474,7 +474,7 @@
core::print(e);
}
try {
- c.{self::C::method15}((<S extends core::num* = core::num*>() →* S* f) → core::Null* {});
+ c.{self::C::method15}((<S extends core::num* = core::num*>() →* S* f) → core::Null? {});
throw "TypeError expected";
}
on core::TypeError* catch(final core::TypeError* e) {
diff --git a/pkg/front_end/testcases/general/non_covariant_checks.dart.strong.transformed.expect b/pkg/front_end/testcases/general/non_covariant_checks.dart.strong.transformed.expect
index 0b3bcfc..17ac3e7 100644
--- a/pkg/front_end/testcases/general/non_covariant_checks.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/general/non_covariant_checks.dart.strong.transformed.expect
@@ -19,7 +19,7 @@
generic-covariant-impl field <S extends self::C::T* = dynamic>(S*) →* S* field14;
generic-covariant-impl field (<S extends self::C::T* = dynamic>() →* S*) →* void field15;
constructor •(self::C::T* field1) → self::C<self::C::T*>*
- : self::C::field1 = field1, self::C::field2 = () → self::C::T* => field1, self::C::field3 = (self::C::T* t) → core::Null* {}, self::C::field4 = (self::C::T* t) → self::C::T* => t, self::C::field5 = () → () →* self::C::T* => () → self::C::T* => field1, self::C::field6 = (() →* self::C::T* f) → core::Null* {}, self::C::field7 = (() →* self::C::T* f) → self::C::T* => field1, self::C::field8 = ((self::C::T*) →* void f) → core::Null* {}, self::C::field9 = ((self::C::T*) →* void f) → self::C::T* => field1, self::C::field10 = ((self::C::T*) →* self::C::T* f) → core::Null* {}, self::C::field11 = ((self::C::T*) →* self::C::T* f) → self::C::T* => field1, self::C::field12 = <S extends self::C::T* = self::C::T*>() → core::Null* => null, self::C::field13 = <S extends self::C::T* = self::C::T*>(S* s) → core::Null* {}, self::C::field14 = <S extends self::C::T* = self::C::T*>(S* s) → S* => s, self::C::field15 = (<S extends self::C::T* = self::C::T*>() →* S* f) → core::Null* {}, super core::Object::•()
+ : self::C::field1 = field1, self::C::field2 = () → self::C::T* => field1, self::C::field3 = (self::C::T* t) → core::Null? {}, self::C::field4 = (self::C::T* t) → self::C::T* => t, self::C::field5 = () → () →* self::C::T* => () → self::C::T* => field1, self::C::field6 = (() →* self::C::T* f) → core::Null? {}, self::C::field7 = (() →* self::C::T* f) → self::C::T* => field1, self::C::field8 = ((self::C::T*) →* void f) → core::Null? {}, self::C::field9 = ((self::C::T*) →* void f) → self::C::T* => field1, self::C::field10 = ((self::C::T*) →* self::C::T* f) → core::Null? {}, self::C::field11 = ((self::C::T*) →* self::C::T* f) → self::C::T* => field1, self::C::field12 = <S extends self::C::T* = self::C::T*>() → core::Null? => null, self::C::field13 = <S extends self::C::T* = self::C::T*>(S* s) → core::Null? {}, self::C::field14 = <S extends self::C::T* = self::C::T*>(S* s) → S* => s, self::C::field15 = (<S extends self::C::T* = self::C::T*>() →* S* f) → core::Null? {}, super core::Object::•()
;
get getter1() → self::C::T*
return this.{self::C::field1};
@@ -308,7 +308,7 @@
on core::TypeError* catch(final core::TypeError* e) {
core::print(e);
}
- c.{self::C::setter3} = (core::num* n) → core::Null* {};
+ c.{self::C::setter3} = (core::num* n) → core::Null? {};
try {
c.{self::C::setter4} = (core::num* n) → core::double* => 0.5;
throw "TypeError expected";
@@ -323,7 +323,7 @@
on core::TypeError* catch(final core::TypeError* e) {
core::print(e);
}
- c.{self::C::setter6} = (() →* core::num* f) → core::Null* {};
+ c.{self::C::setter6} = (() →* core::num* f) → core::Null? {};
try {
c.{self::C::setter7} = (() →* core::num* f) → core::double* => 0.5;
throw "TypeError expected";
@@ -332,7 +332,7 @@
core::print(e);
}
try {
- c.{self::C::setter8} = ((core::double*) →* void f) → core::Null* {};
+ c.{self::C::setter8} = ((core::double*) →* void f) → core::Null? {};
throw "TypeError expected";
}
on core::TypeError* catch(final core::TypeError* e) {
@@ -346,7 +346,7 @@
core::print(e);
}
try {
- c.{self::C::setter10} = ((core::double*) →* core::num* f) → core::Null* {};
+ c.{self::C::setter10} = ((core::double*) →* core::num* f) → core::Null? {};
throw "TypeError expected";
}
on core::TypeError* catch(final core::TypeError* e) {
@@ -360,14 +360,14 @@
core::print(e);
}
try {
- c.{self::C::setter12} = <S extends core::num* = core::num*>() → core::Null* => null;
+ c.{self::C::setter12} = <S extends core::num* = core::num*>() → core::Null? => null;
throw "TypeError expected";
}
on core::TypeError* catch(final core::TypeError* e) {
core::print(e);
}
try {
- c.{self::C::setter13} = <S extends core::num* = core::num*>(S* s) → core::Null* {};
+ c.{self::C::setter13} = <S extends core::num* = core::num*>(S* s) → core::Null? {};
throw "TypeError expected";
}
on core::TypeError* catch(final core::TypeError* e) {
@@ -381,7 +381,7 @@
core::print(e);
}
try {
- c.{self::C::setter15} = (<S extends core::num* = core::num*>() →* S* f) → core::Null* {};
+ c.{self::C::setter15} = (<S extends core::num* = core::num*>() →* S* f) → core::Null? {};
throw "TypeError expected";
}
on core::TypeError* catch(final core::TypeError* e) {
@@ -401,7 +401,7 @@
on core::TypeError* catch(final core::TypeError* e) {
core::print(e);
}
- c.{self::C::method3}((core::num* n) → core::Null* {});
+ c.{self::C::method3}((core::num* n) → core::Null? {});
try {
c.{self::C::method4}((core::num* n) → core::double* => 0.5);
throw "TypeError expected";
@@ -416,7 +416,7 @@
on core::TypeError* catch(final core::TypeError* e) {
core::print(e);
}
- c.{self::C::method6}((() →* core::num* f) → core::Null* {});
+ c.{self::C::method6}((() →* core::num* f) → core::Null? {});
try {
c.{self::C::method7}((() →* core::num* f) → core::double* => 0.5);
throw "TypeError expected";
@@ -425,7 +425,7 @@
core::print(e);
}
try {
- c.{self::C::method8}(((core::double*) →* void f) → core::Null* {});
+ c.{self::C::method8}(((core::double*) →* void f) → core::Null? {});
throw "TypeError expected";
}
on core::TypeError* catch(final core::TypeError* e) {
@@ -439,7 +439,7 @@
core::print(e);
}
try {
- c.{self::C::method10}(((core::double*) →* core::num* f) → core::Null* {});
+ c.{self::C::method10}(((core::double*) →* core::num* f) → core::Null? {});
throw "TypeError expected";
}
on core::TypeError* catch(final core::TypeError* e) {
@@ -453,14 +453,14 @@
core::print(e);
}
try {
- c.{self::C::method12}(<S extends core::num* = core::num*>() → core::Null* => null);
+ c.{self::C::method12}(<S extends core::num* = core::num*>() → core::Null? => null);
throw "TypeError expected";
}
on core::TypeError* catch(final core::TypeError* e) {
core::print(e);
}
try {
- c.{self::C::method13}(<S extends core::num* = core::num*>(S* s) → core::Null* {});
+ c.{self::C::method13}(<S extends core::num* = core::num*>(S* s) → core::Null? {});
throw "TypeError expected";
}
on core::TypeError* catch(final core::TypeError* e) {
@@ -474,7 +474,7 @@
core::print(e);
}
try {
- c.{self::C::method15}((<S extends core::num* = core::num*>() →* S* f) → core::Null* {});
+ c.{self::C::method15}((<S extends core::num* = core::num*>() →* S* f) → core::Null? {});
throw "TypeError expected";
}
on core::TypeError* catch(final core::TypeError* e) {
diff --git a/pkg/front_end/testcases/general/null_aware.dart.strong.expect b/pkg/front_end/testcases/general/null_aware.dart.strong.expect
index 9cdabd6..8410392 100644
--- a/pkg/front_end/testcases/general/null_aware.dart.strong.expect
+++ b/pkg/front_end/testcases/general/null_aware.dart.strong.expect
@@ -11,7 +11,7 @@
}
static method main() → dynamic {
self::Foo* foo = new self::Foo::•();
- let final self::Foo* #t1 = foo in #t1.==(null) ?{core::int*} null : #t1.{self::Foo::field} = 5;
+ let final self::Foo* #t1 = foo in #t1.{core::Object::==}(null) ?{core::int*} null : #t1.{self::Foo::field} = 5;
self::Foo::staticField = 5;
let final self::Foo* #t2 = foo in #t2.{self::Foo::field}.{core::num::==}(null) ?{core::int*} #t2.{self::Foo::field} = 5 : null;
self::Foo::staticField.{core::num::==}(null) ?{core::int*} self::Foo::staticField = 5 : null;
diff --git a/pkg/front_end/testcases/general/null_aware.dart.strong.transformed.expect b/pkg/front_end/testcases/general/null_aware.dart.strong.transformed.expect
index 9cdabd6..8410392 100644
--- a/pkg/front_end/testcases/general/null_aware.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/general/null_aware.dart.strong.transformed.expect
@@ -11,7 +11,7 @@
}
static method main() → dynamic {
self::Foo* foo = new self::Foo::•();
- let final self::Foo* #t1 = foo in #t1.==(null) ?{core::int*} null : #t1.{self::Foo::field} = 5;
+ let final self::Foo* #t1 = foo in #t1.{core::Object::==}(null) ?{core::int*} null : #t1.{self::Foo::field} = 5;
self::Foo::staticField = 5;
let final self::Foo* #t2 = foo in #t2.{self::Foo::field}.{core::num::==}(null) ?{core::int*} #t2.{self::Foo::field} = 5 : null;
self::Foo::staticField.{core::num::==}(null) ?{core::int*} self::Foo::staticField = 5 : null;
diff --git a/runtime/lib/wasm_patch.dart b/pkg/front_end/testcases/general/null_aware_for_in.dart
similarity index 62%
rename from runtime/lib/wasm_patch.dart
rename to pkg/front_end/testcases/general/null_aware_for_in.dart
index 2af1b20..5a93b8e 100644
--- a/runtime/lib/wasm_patch.dart
+++ b/pkg/front_end/testcases/general/null_aware_for_in.dart
@@ -2,7 +2,12 @@
// 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.
-import "dart:_internal" show patch;
+class Class {}
-@patch
-int _callWasm(String name, int arg) native "Wasm_callFunction";
+main() {
+ var o;
+ if (false) {
+ // ignore: unused_local_variable
+ for (Class c in o?.iterable) {}
+ }
+}
diff --git a/pkg/front_end/testcases/general/null_aware_for_in.dart.outline.expect b/pkg/front_end/testcases/general/null_aware_for_in.dart.outline.expect
new file mode 100644
index 0000000..b23757d
--- /dev/null
+++ b/pkg/front_end/testcases/general/null_aware_for_in.dart.outline.expect
@@ -0,0 +1,10 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class Class extends core::Object {
+ synthetic constructor •() → self::Class*
+ ;
+}
+static method main() → dynamic
+ ;
diff --git a/pkg/front_end/testcases/general/null_aware_for_in.dart.strong.expect b/pkg/front_end/testcases/general/null_aware_for_in.dart.strong.expect
new file mode 100644
index 0000000..18203ab
--- /dev/null
+++ b/pkg/front_end/testcases/general/null_aware_for_in.dart.strong.expect
@@ -0,0 +1,17 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class Class extends core::Object {
+ synthetic constructor •() → self::Class*
+ : super core::Object::•()
+ ;
+}
+static method main() → dynamic {
+ dynamic o;
+ if(false) {
+ for (final dynamic #t1 in (let final dynamic #t2 = o in #t2.{core::Object::==}(null) ?{dynamic} null : #t2.iterable) as{TypeError} core::Iterable<dynamic>*) {
+ self::Class* c = #t1 as{TypeError} self::Class*;
+ }
+ }
+}
diff --git a/pkg/front_end/testcases/general/null_aware_for_in.dart.strong.transformed.expect b/pkg/front_end/testcases/general/null_aware_for_in.dart.strong.transformed.expect
new file mode 100644
index 0000000..18203ab
--- /dev/null
+++ b/pkg/front_end/testcases/general/null_aware_for_in.dart.strong.transformed.expect
@@ -0,0 +1,17 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class Class extends core::Object {
+ synthetic constructor •() → self::Class*
+ : super core::Object::•()
+ ;
+}
+static method main() → dynamic {
+ dynamic o;
+ if(false) {
+ for (final dynamic #t1 in (let final dynamic #t2 = o in #t2.{core::Object::==}(null) ?{dynamic} null : #t2.iterable) as{TypeError} core::Iterable<dynamic>*) {
+ self::Class* c = #t1 as{TypeError} self::Class*;
+ }
+ }
+}
diff --git a/pkg/front_end/testcases/general/operator_method_not_found.dart.strong.expect b/pkg/front_end/testcases/general/operator_method_not_found.dart.strong.expect
index 4860020..8eafc0b 100644
--- a/pkg/front_end/testcases/general/operator_method_not_found.dart.strong.expect
+++ b/pkg/front_end/testcases/general/operator_method_not_found.dart.strong.expect
@@ -275,7 +275,7 @@
Try correcting the name to the name of an existing method, or defining a method named '>>'.
print(foo >> 2);
^^");
- core::print(let final self::Foo* #t1 = foo in let final core::int* #t2 = 2 in let final core::int* #t3 = 2 in let final dynamic #t4 = invalid-expression "pkg/front_end/testcases/general/operator_method_not_found.dart:29:12: Error: The method '[]=' isn't defined for the class 'Foo'.
+ core::print(let final self::Foo* #t1 = foo in let final core::int* #t2 = 2 in let final core::int* #t3 = 2 in let final void #t4 = invalid-expression "pkg/front_end/testcases/general/operator_method_not_found.dart:29:12: Error: The method '[]=' isn't defined for the class 'Foo'.
- 'Foo' is from 'pkg/front_end/testcases/general/operator_method_not_found.dart'.
Try correcting the name to the name of an existing method, or defining a method named '[]='.
print(foo[2] = 2);
diff --git a/pkg/front_end/testcases/general/operator_method_not_found.dart.strong.transformed.expect b/pkg/front_end/testcases/general/operator_method_not_found.dart.strong.transformed.expect
index 4860020..8eafc0b 100644
--- a/pkg/front_end/testcases/general/operator_method_not_found.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/general/operator_method_not_found.dart.strong.transformed.expect
@@ -275,7 +275,7 @@
Try correcting the name to the name of an existing method, or defining a method named '>>'.
print(foo >> 2);
^^");
- core::print(let final self::Foo* #t1 = foo in let final core::int* #t2 = 2 in let final core::int* #t3 = 2 in let final dynamic #t4 = invalid-expression "pkg/front_end/testcases/general/operator_method_not_found.dart:29:12: Error: The method '[]=' isn't defined for the class 'Foo'.
+ core::print(let final self::Foo* #t1 = foo in let final core::int* #t2 = 2 in let final core::int* #t3 = 2 in let final void #t4 = invalid-expression "pkg/front_end/testcases/general/operator_method_not_found.dart:29:12: Error: The method '[]=' isn't defined for the class 'Foo'.
- 'Foo' is from 'pkg/front_end/testcases/general/operator_method_not_found.dart'.
Try correcting the name to the name of an existing method, or defining a method named '[]='.
print(foo[2] = 2);
diff --git a/pkg/front_end/testcases/general/qualified.dart.strong.transformed.expect b/pkg/front_end/testcases/general/qualified.dart.strong.transformed.expect
index 22e7c21..f45751f 100644
--- a/pkg/front_end/testcases/general/qualified.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/general/qualified.dart.strong.transformed.expect
@@ -59,7 +59,7 @@
: super core::Object::•()
;
static factory b<T extends core::Object* = dynamic>() → self::C<self::C::b::T*>*
- let <T extends core::Object* = dynamic>() →* lib::C<lib::C::b::T*>* #redirecting_factory = lib::C::b in let self::C::b::T* #typeArg0 = null in invalid-expression;
+ let <T extends core::Object* = dynamic>() →* lib::C<T*>* #redirecting_factory = lib::C::b in let self::C::b::T* #typeArg0 = null in invalid-expression;
}
static method main() → dynamic {
new self::C::•<core::String*>();
diff --git a/pkg/front_end/testcases/general/redirecting_factory.dart.strong.transformed.expect b/pkg/front_end/testcases/general/redirecting_factory.dart.strong.transformed.expect
index fca2b95..c9e154b 100644
--- a/pkg/front_end/testcases/general/redirecting_factory.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/general/redirecting_factory.dart.strong.transformed.expect
@@ -15,7 +15,7 @@
static field dynamic _redirecting# = <dynamic>[self::FooBase::•];
abstract get x() → core::int*;
static factory •<Tf extends core::Object* = dynamic>(core::int* x) → self::FooBase<self::FooBase::•::Tf*>*
- let <T extends core::Object* = dynamic>(core::int*) →* self::Foo<self::Foo::•::T*>* #redirecting_factory = self::Foo::• in let self::FooBase::•::Tf* #typeArg0 = null in invalid-expression;
+ let <T extends core::Object* = dynamic>(core::int*) →* self::Foo<T*>* #redirecting_factory = self::Foo::• in let self::FooBase::•::Tf* #typeArg0 = null in invalid-expression;
}
abstract class Foo<T extends core::Object* = dynamic> extends core::Object implements self::FooBase<dynamic> {
static field dynamic _redirecting# = <dynamic>[self::Foo::•];
@@ -40,7 +40,7 @@
class SimpleCase<A extends core::Object* = dynamic, B extends core::Object* = dynamic> extends core::Object {
static field dynamic _redirecting# = <dynamic>[self::SimpleCase::•];
static factory •<A extends core::Object* = dynamic, B extends core::Object* = dynamic>() → self::SimpleCase<self::SimpleCase::•::A*, self::SimpleCase::•::B*>*
- let <Ai extends core::Object* = dynamic, Bi extends core::Object* = dynamic>() →* self::SimpleCaseImpl<self::SimpleCaseImpl::•::Ai*, self::SimpleCaseImpl::•::Bi*>* #redirecting_factory = self::SimpleCaseImpl::• in let self::SimpleCase::•::A* #typeArg0 = null in let self::SimpleCase::•::B* #typeArg1 = null in invalid-expression;
+ let <Ai extends core::Object* = dynamic, Bi extends core::Object* = dynamic>() →* self::SimpleCaseImpl<Ai*, Bi*>* #redirecting_factory = self::SimpleCaseImpl::• in let self::SimpleCase::•::A* #typeArg0 = null in let self::SimpleCase::•::B* #typeArg1 = null in invalid-expression;
}
class SimpleCaseImpl<Ai extends core::Object* = dynamic, Bi extends core::Object* = dynamic> extends core::Object implements self::SimpleCase<self::SimpleCaseImpl::Ai*, self::SimpleCaseImpl::Bi*> {
static field dynamic _redirecting# = <dynamic>[self::SimpleCaseImpl::•];
diff --git a/pkg/front_end/testcases/general/redirecting_factory_const_inference.dart.strong.expect b/pkg/front_end/testcases/general/redirecting_factory_const_inference.dart.strong.expect
index 45acdcc..5f63429 100644
--- a/pkg/front_end/testcases/general/redirecting_factory_const_inference.dart.strong.expect
+++ b/pkg/front_end/testcases/general/redirecting_factory_const_inference.dart.strong.expect
@@ -31,5 +31,5 @@
}
constants {
- #C1 = self::_Y<core::Null*> {}
+ #C1 = self::_Y<core::Null?> {}
}
diff --git a/pkg/front_end/testcases/general/redirecting_factory_const_inference.dart.strong.transformed.expect b/pkg/front_end/testcases/general/redirecting_factory_const_inference.dart.strong.transformed.expect
index c84f680..a352dae88 100644
--- a/pkg/front_end/testcases/general/redirecting_factory_const_inference.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/general/redirecting_factory_const_inference.dart.strong.transformed.expect
@@ -31,5 +31,5 @@
}
constants {
- #C1 = self::_Y<core::Null*> {}
+ #C1 = self::_Y<core::Null?> {}
}
diff --git a/pkg/front_end/testcases/general/redirection_chain_type_arguments.dart.strong.transformed.expect b/pkg/front_end/testcases/general/redirection_chain_type_arguments.dart.strong.transformed.expect
index ce90e29..f3111be 100644
--- a/pkg/front_end/testcases/general/redirection_chain_type_arguments.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/general/redirection_chain_type_arguments.dart.strong.transformed.expect
@@ -11,7 +11,7 @@
: super core::Object::•()
;
static factory •<T extends core::Object* = dynamic>() → self::A<self::A::•::T*>*
- let <U extends core::Object* = dynamic, W extends core::Object* = dynamic>() →* self::B<self::B::•::U*, self::B::•::W*>* #redirecting_factory = self::B::• in let self::A::•::T* #typeArg0 = null in let core::num* #typeArg1 = null in invalid-expression;
+ let <U extends core::Object* = dynamic, W extends core::Object* = dynamic>() →* self::B<U*, W*>* #redirecting_factory = self::B::• in let self::A::•::T* #typeArg0 = null in let core::num* #typeArg1 = null in invalid-expression;
}
class B<U extends core::Object* = dynamic, W extends core::Object* = dynamic> extends self::A<self::B::U*> {
static field dynamic _redirecting# = <dynamic>[self::B::•];
diff --git a/pkg/front_end/testcases/general/redirection_chain_type_arguments_subst.dart.strong.transformed.expect b/pkg/front_end/testcases/general/redirection_chain_type_arguments_subst.dart.strong.transformed.expect
index 14e0fef..6aa25a9 100644
--- a/pkg/front_end/testcases/general/redirection_chain_type_arguments_subst.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/general/redirection_chain_type_arguments_subst.dart.strong.transformed.expect
@@ -11,7 +11,7 @@
: super core::Object::•()
;
static factory •<T extends core::Object* = dynamic>() → self::A<self::A::•::T*>*
- let <U extends core::Object* = dynamic, W extends core::Object* = dynamic>() →* self::B<self::B::•::U*, self::B::•::W*>* #redirecting_factory = self::B::• in let self::A::•::T* #typeArg0 = null in let core::List<self::A::•::T*>* #typeArg1 = null in invalid-expression;
+ let <U extends core::Object* = dynamic, W extends core::Object* = dynamic>() →* self::B<U*, W*>* #redirecting_factory = self::B::• in let self::A::•::T* #typeArg0 = null in let core::List<self::A::•::T*>* #typeArg1 = null in invalid-expression;
}
abstract class B<U extends core::Object* = dynamic, W extends core::Object* = dynamic> extends self::A<self::B::U*> {
static field dynamic _redirecting# = <dynamic>[self::B::•];
diff --git a/pkg/front_end/testcases/general/type_of_null.dart b/pkg/front_end/testcases/general/type_of_null.dart
index 0f7004e..39db639 100644
--- a/pkg/front_end/testcases/general/type_of_null.dart
+++ b/pkg/front_end/testcases/general/type_of_null.dart
@@ -10,22 +10,22 @@
Null foo() => null;
main() {
- /*@ typeArgs=Null* */ map(/*@ returnType=Null* */ () {},
+ /*@ typeArgs=Null? */ map(/*@ returnType=Null? */ () {},
/*@ returnType=<BottomType> */ () => throw "hello");
- /*@ typeArgs=Null* */ map(/*@ returnType=<BottomType> */ () => throw "hello",
- /*@ returnType=Null* */ () {});
- Null Function() f = /*@ returnType=Null* */ () {};
+ /*@ typeArgs=Null? */ map(/*@ returnType=<BottomType> */ () => throw "hello",
+ /*@ returnType=Null? */ () {});
+ Null Function() f = /*@ returnType=Null? */ () {};
/*@ typeArgs=Null* */ map(
foo, /*@ returnType=<BottomType> */ () => throw "hello");
/*@ typeArgs=Null* */ map(
/*@ returnType=<BottomType> */ () => throw "hello", foo);
- /*@ typeArgs=Null* */ map(/*@ returnType=Null* */ () {
+ /*@ typeArgs=Null? */ map(/*@ returnType=Null? */ () {
return null;
}, /*@ returnType=<BottomType> */ () => throw "hello");
- /*@ typeArgs=Null* */ map(/*@ returnType=<BottomType> */ () => throw "hello",
- /*@ returnType=Null* */ () {
+ /*@ typeArgs=Null? */ map(/*@ returnType=<BottomType> */ () => throw "hello",
+ /*@ returnType=Null? */ () {
return null;
});
- /*@ typeArgs=() ->* Null* */ id(/*@ returnType=Null* */ () {});
+ /*@ typeArgs=() ->* Null? */ id(/*@ returnType=Null? */ () {});
}
diff --git a/pkg/front_end/testcases/general/type_of_null.dart.strong.expect b/pkg/front_end/testcases/general/type_of_null.dart.strong.expect
index 0a6f445..40a4bed 100644
--- a/pkg/front_end/testcases/general/type_of_null.dart.strong.expect
+++ b/pkg/front_end/testcases/general/type_of_null.dart.strong.expect
@@ -8,18 +8,18 @@
static method foo() → core::Null*
return null;
static method main() → dynamic {
- self::map<core::Null*>(() → core::Null* {}, () → <BottomType>=> throw "hello");
- self::map<core::Null*>(() → <BottomType>=> throw "hello", () → core::Null* {});
- () →* core::Null* f = () → core::Null* {};
+ self::map<core::Null?>(() → core::Null? {}, () → <BottomType>=> throw "hello");
+ self::map<core::Null?>(() → <BottomType>=> throw "hello", () → core::Null? {});
+ () →* core::Null* f = () → core::Null? {};
self::map<core::Null*>(#C1, () → <BottomType>=> throw "hello");
self::map<core::Null*>(() → <BottomType>=> throw "hello", #C1);
- self::map<core::Null*>(() → core::Null* {
+ self::map<core::Null?>(() → core::Null? {
return null;
}, () → <BottomType>=> throw "hello");
- self::map<core::Null*>(() → <BottomType>=> throw "hello", () → core::Null* {
+ self::map<core::Null?>(() → <BottomType>=> throw "hello", () → core::Null? {
return null;
});
- self::id<() →* core::Null*>(() → core::Null* {});
+ self::id<() →* core::Null?>(() → core::Null? {});
}
constants {
diff --git a/pkg/front_end/testcases/general/type_of_null.dart.strong.transformed.expect b/pkg/front_end/testcases/general/type_of_null.dart.strong.transformed.expect
index 0a6f445..40a4bed 100644
--- a/pkg/front_end/testcases/general/type_of_null.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/general/type_of_null.dart.strong.transformed.expect
@@ -8,18 +8,18 @@
static method foo() → core::Null*
return null;
static method main() → dynamic {
- self::map<core::Null*>(() → core::Null* {}, () → <BottomType>=> throw "hello");
- self::map<core::Null*>(() → <BottomType>=> throw "hello", () → core::Null* {});
- () →* core::Null* f = () → core::Null* {};
+ self::map<core::Null?>(() → core::Null? {}, () → <BottomType>=> throw "hello");
+ self::map<core::Null?>(() → <BottomType>=> throw "hello", () → core::Null? {});
+ () →* core::Null* f = () → core::Null? {};
self::map<core::Null*>(#C1, () → <BottomType>=> throw "hello");
self::map<core::Null*>(() → <BottomType>=> throw "hello", #C1);
- self::map<core::Null*>(() → core::Null* {
+ self::map<core::Null?>(() → core::Null? {
return null;
}, () → <BottomType>=> throw "hello");
- self::map<core::Null*>(() → <BottomType>=> throw "hello", () → core::Null* {
+ self::map<core::Null?>(() → <BottomType>=> throw "hello", () → core::Null? {
return null;
});
- self::id<() →* core::Null*>(() → core::Null* {});
+ self::id<() →* core::Null?>(() → core::Null? {});
}
constants {
diff --git a/pkg/front_end/testcases/general/type_variable_bound_access.dart b/pkg/front_end/testcases/general/type_variable_bound_access.dart
new file mode 100644
index 0000000..720e493
--- /dev/null
+++ b/pkg/front_end/testcases/general/type_variable_bound_access.dart
@@ -0,0 +1,28 @@
+// Copyright (c) 2019, 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.
+
+class DynamicClass<T extends dynamic, S extends T> {
+ T field1;
+ T field2;
+
+ DynamicClass(this.field1, this.field2);
+
+ method() => field1 * field2;
+}
+
+class NumClass<T extends num, S extends T> {
+ T field1;
+ S field2;
+
+ NumClass(this.field1, this.field2);
+
+ num method1() => field1 * field2;
+
+ num method2() => field1 + field2.length;
+}
+
+main() {
+ new DynamicClass<num, int>(0.5, 2).method();
+ new NumClass<num, double>(2, 0.5).method1();
+}
diff --git a/pkg/front_end/testcases/general/type_variable_bound_access.dart.outline.expect b/pkg/front_end/testcases/general/type_variable_bound_access.dart.outline.expect
new file mode 100644
index 0000000..11781a4
--- /dev/null
+++ b/pkg/front_end/testcases/general/type_variable_bound_access.dart.outline.expect
@@ -0,0 +1,24 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class DynamicClass<T extends dynamic = dynamic, S extends self::DynamicClass::T* = dynamic> extends core::Object {
+ generic-covariant-impl field self::DynamicClass::T* field1;
+ generic-covariant-impl field self::DynamicClass::T* field2;
+ constructor •(self::DynamicClass::T* field1, self::DynamicClass::T* field2) → self::DynamicClass<self::DynamicClass::T*, self::DynamicClass::S*>*
+ ;
+ method method() → dynamic
+ ;
+}
+class NumClass<T extends core::num* = core::num*, S extends self::NumClass::T* = core::num*> extends core::Object {
+ generic-covariant-impl field self::NumClass::T* field1;
+ generic-covariant-impl field self::NumClass::S* field2;
+ constructor •(self::NumClass::T* field1, self::NumClass::S* field2) → self::NumClass<self::NumClass::T*, self::NumClass::S*>*
+ ;
+ method method1() → core::num*
+ ;
+ method method2() → core::num*
+ ;
+}
+static method main() → dynamic
+ ;
diff --git a/pkg/front_end/testcases/general/type_variable_bound_access.dart.strong.expect b/pkg/front_end/testcases/general/type_variable_bound_access.dart.strong.expect
new file mode 100644
index 0000000..79514a6
--- /dev/null
+++ b/pkg/front_end/testcases/general/type_variable_bound_access.dart.strong.expect
@@ -0,0 +1,39 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/general/type_variable_bound_access.dart:22:36: Error: The getter 'length' isn't defined for the class 'num'.
+// Try correcting the name to the name of an existing getter, or defining a getter or field named 'length'.
+// num method2() => field1 + field2.length;
+// ^^^^^^
+//
+import self as self;
+import "dart:core" as core;
+
+class DynamicClass<T extends dynamic = dynamic, S extends self::DynamicClass::T* = dynamic> extends core::Object {
+ generic-covariant-impl field self::DynamicClass::T* field1;
+ generic-covariant-impl field self::DynamicClass::T* field2;
+ constructor •(self::DynamicClass::T* field1, self::DynamicClass::T* field2) → self::DynamicClass<self::DynamicClass::T*, self::DynamicClass::S*>*
+ : self::DynamicClass::field1 = field1, self::DynamicClass::field2 = field2, super core::Object::•()
+ ;
+ method method() → dynamic
+ return this.{self::DynamicClass::field1}.*(this.{self::DynamicClass::field2});
+}
+class NumClass<T extends core::num* = core::num*, S extends self::NumClass::T* = core::num*> extends core::Object {
+ generic-covariant-impl field self::NumClass::T* field1;
+ generic-covariant-impl field self::NumClass::S* field2;
+ constructor •(self::NumClass::T* field1, self::NumClass::S* field2) → self::NumClass<self::NumClass::T*, self::NumClass::S*>*
+ : self::NumClass::field1 = field1, self::NumClass::field2 = field2, super core::Object::•()
+ ;
+ method method1() → core::num*
+ return this.{self::NumClass::field1}.{core::num::*}(this.{self::NumClass::field2});
+ method method2() → core::num*
+ return this.{self::NumClass::field1}.{core::num::+}(invalid-expression "pkg/front_end/testcases/general/type_variable_bound_access.dart:22:36: Error: The getter 'length' isn't defined for the class 'num'.
+Try correcting the name to the name of an existing getter, or defining a getter or field named 'length'.
+ num method2() => field1 + field2.length;
+ ^^^^^^" as{TypeError} core::num*);
+}
+static method main() → dynamic {
+ new self::DynamicClass::•<core::num*, core::int*>(0.5, 2).{self::DynamicClass::method}();
+ new self::NumClass::•<core::num*, core::double*>(2, 0.5).{self::NumClass::method1}();
+}
diff --git a/pkg/front_end/testcases/incremental_initialize_from_dill/changing_modules_10.yaml b/pkg/front_end/testcases/incremental_initialize_from_dill/changing_modules_10.yaml
new file mode 100644
index 0000000..abcb6aa
--- /dev/null
+++ b/pkg/front_end/testcases/incremental_initialize_from_dill/changing_modules_10.yaml
@@ -0,0 +1,61 @@
+# Copyright (c) 2019, 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.md file.
+
+# Compile an application with a number of modules.
+# Recompile the same thing again and make sure the calculated dependencies are
+# the same.
+
+type: newworld
+strong: true
+modules:
+ module:
+ module/a.dart: |
+ import 'package:module/b.dart';
+
+ class A extends A2<B> { }
+ class A2<T> { }
+ module/b.dart: |
+ class B { }
+ module/.packages: |
+ module:.
+worlds:
+ - entry: main.dart
+ sources:
+ main.dart: |
+ import 'package:module/a.dart';
+ class Foo extends A {}
+ .packages: |
+ module:module
+ modules:
+ - module
+ expectedLibraryCount: 3
+ neededDillLibraries:
+ - package:module/a.dart
+ - package:module/b.dart
+ expectedContent:
+ org-dartlang-test:///main.dart:
+ - Class Foo
+ package:module/a.dart:
+ - Class A
+ - Class A2
+ package:module/b.dart:
+ - Class B
+ - entry: main.dart
+ worldType: updated
+ expectInitializeFromDill: false
+ # Nothing actually updated, as such everything is expected as before.
+ modules:
+ - module
+ expectedLibraryCount: 3
+ neededDillLibraries:
+ - package:module/a.dart
+ - package:module/b.dart
+ expectedContent:
+ org-dartlang-test:///main.dart:
+ - Class Foo
+ package:module/a.dart:
+ - Class A
+ - Class A2
+ package:module/b.dart:
+ - Class B
\ No newline at end of file
diff --git a/pkg/front_end/testcases/incremental_initialize_from_dill/changing_modules_11.yaml b/pkg/front_end/testcases/incremental_initialize_from_dill/changing_modules_11.yaml
new file mode 100644
index 0000000..a4a6cd9
--- /dev/null
+++ b/pkg/front_end/testcases/incremental_initialize_from_dill/changing_modules_11.yaml
@@ -0,0 +1,61 @@
+# Copyright (c) 2019, 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.md file.
+
+# Compile an application with a number of modules.
+# Recompile the same thing again and make sure the calculated dependencies are
+# the same.
+
+type: newworld
+strong: true
+modules:
+ module:
+ module/a.dart: |
+ import 'package:module/b.dart';
+
+ class A implements A2<B> { }
+ class A2<T> { }
+ module/b.dart: |
+ class B { }
+ module/.packages: |
+ module:.
+worlds:
+ - entry: main.dart
+ sources:
+ main.dart: |
+ import 'package:module/a.dart';
+ class Foo extends A {}
+ .packages: |
+ module:module
+ modules:
+ - module
+ expectedLibraryCount: 3
+ neededDillLibraries:
+ - package:module/a.dart
+ - package:module/b.dart
+ expectedContent:
+ org-dartlang-test:///main.dart:
+ - Class Foo
+ package:module/a.dart:
+ - Class A
+ - Class A2
+ package:module/b.dart:
+ - Class B
+ - entry: main.dart
+ worldType: updated
+ expectInitializeFromDill: false
+ # Nothing actually updated, as such everything is expected as before.
+ modules:
+ - module
+ expectedLibraryCount: 3
+ neededDillLibraries:
+ - package:module/a.dart
+ - package:module/b.dart
+ expectedContent:
+ org-dartlang-test:///main.dart:
+ - Class Foo
+ package:module/a.dart:
+ - Class A
+ - Class A2
+ package:module/b.dart:
+ - Class B
\ No newline at end of file
diff --git a/pkg/front_end/testcases/incremental_initialize_from_dill/changing_modules_12.yaml b/pkg/front_end/testcases/incremental_initialize_from_dill/changing_modules_12.yaml
new file mode 100644
index 0000000..4f4762e
--- /dev/null
+++ b/pkg/front_end/testcases/incremental_initialize_from_dill/changing_modules_12.yaml
@@ -0,0 +1,40 @@
+# Copyright (c) 2019, 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.md file.
+
+# Compile an application with a modules that isn't used, but,
+# which - if loaded - pulls in more of itself.
+
+type: newworld
+strong: true
+modules:
+ module:
+ module/a.dart: |
+ import 'package:module/b.dart';
+ class A { }
+ module/b.dart: |
+ export 'package:module/a.dart';
+ class B { }
+ module/c.dart: |
+ export 'package:module/d.dart';
+ class C { }
+ module/d.dart: |
+ import 'package:module/c.dart';
+ class D { }
+ module/.packages: |
+ module:.
+worlds:
+ - entry: main.dart
+ sources:
+ main.dart: |
+ class Foo {}
+ .packages: |
+ module:module
+ modules:
+ - module
+ expectedLibraryCount: 1
+ # We don't import the module, and thus don't use it.
+ neededDillLibraries: []
+ expectedContent:
+ org-dartlang-test:///main.dart:
+ - Class Foo
diff --git a/pkg/front_end/testcases/incremental_initialize_from_dill/changing_modules_9.yaml b/pkg/front_end/testcases/incremental_initialize_from_dill/changing_modules_9.yaml
new file mode 100644
index 0000000..03cc5bd
--- /dev/null
+++ b/pkg/front_end/testcases/incremental_initialize_from_dill/changing_modules_9.yaml
@@ -0,0 +1,70 @@
+# Copyright (c) 2019, 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.md file.
+
+# Compile an application with a number of modules.
+# Recompile the same thing again and make sure the calculated dependencies are
+# the same.
+
+type: newworld
+strong: true
+modules:
+ moduleA:
+ moduleA/a.dart: |
+ export 'package:moduleB/b.dart';
+
+ class A { }
+ moduleA/.packages: |
+ moduleA:.
+ moduleB:../moduleB
+ moduleB:
+ moduleB/b.dart: |
+ class B {
+ int foo = 42;
+ }
+ moduleB/.packages: |
+ moduleB:.
+worlds:
+ - entry: main.dart
+ sources:
+ main.dart: |
+ import "package:moduleA/a.dart";
+
+ main() {
+ A a = new A();
+ }
+ .packages: |
+ moduleA:moduleA
+ moduleB:moduleB
+ modules:
+ - moduleA
+ - moduleB
+ expectedLibraryCount: 3
+ neededDillLibraries:
+ - package:moduleA/a.dart
+ - package:moduleB/b.dart
+ expectedContent:
+ org-dartlang-test:///main.dart:
+ - Procedure main
+ package:moduleA/a.dart:
+ - Class A
+ package:moduleB/b.dart:
+ - Class B
+ - entry: main.dart
+ worldType: updated
+ expectInitializeFromDill: false
+ # Nothing actually updated, as such everything is expected as before.
+ modules:
+ - moduleA
+ - moduleB
+ expectedLibraryCount: 3
+ neededDillLibraries:
+ - package:moduleA/a.dart
+ - package:moduleB/b.dart
+ expectedContent:
+ org-dartlang-test:///main.dart:
+ - Procedure main
+ package:moduleA/a.dart:
+ - Class A
+ package:moduleB/b.dart:
+ - Class B
\ No newline at end of file
diff --git a/pkg/front_end/testcases/inference/block_bodied_lambdas_infer_bottom_async.dart b/pkg/front_end/testcases/inference/block_bodied_lambdas_infer_bottom_async.dart
index bc39d50..5e47a90 100644
--- a/pkg/front_end/testcases/inference/block_bodied_lambdas_infer_bottom_async.dart
+++ b/pkg/front_end/testcases/inference/block_bodied_lambdas_infer_bottom_async.dart
@@ -8,7 +8,7 @@
import 'dart:async';
main() async {
- var /*@ type=() ->* Future<Null*>* */ f = /*@ returnType=Future<Null*>* */ () async {
+ var /*@ type=() ->* Future<Null?>* */ f = /*@ returnType=Future<Null?>* */ () async {
return null;
};
Future y = f();
diff --git a/pkg/front_end/testcases/inference/block_bodied_lambdas_infer_bottom_async.dart.strong.expect b/pkg/front_end/testcases/inference/block_bodied_lambdas_infer_bottom_async.dart.strong.expect
index c94fcd7..e0504e6 100644
--- a/pkg/front_end/testcases/inference/block_bodied_lambdas_infer_bottom_async.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/block_bodied_lambdas_infer_bottom_async.dart.strong.expect
@@ -6,7 +6,7 @@
import "dart:async";
static method main() → dynamic async {
- () →* asy::Future<core::Null*>* f = () → asy::Future<core::Null*>* async {
+ () →* asy::Future<core::Null?>* f = () → asy::Future<core::Null?>* async {
return null;
};
asy::Future<dynamic>* y = f.call();
diff --git a/pkg/front_end/testcases/inference/block_bodied_lambdas_infer_bottom_async.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/block_bodied_lambdas_infer_bottom_async.dart.strong.transformed.expect
index 77ac3db..e8faa37 100644
--- a/pkg/front_end/testcases/inference/block_bodied_lambdas_infer_bottom_async.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/block_bodied_lambdas_infer_bottom_async.dart.strong.transformed.expect
@@ -18,9 +18,9 @@
try {
#L1:
{
- () →* asy::Future<core::Null*>* f = () → asy::Future<core::Null*>* /* originally async */ {
- final asy::_AsyncAwaitCompleter<core::Null*>* :async_completer = new asy::_AsyncAwaitCompleter::•<core::Null*>();
- asy::FutureOr<core::Null*>* :return_value;
+ () →* asy::Future<core::Null?>* f = () → asy::Future<core::Null?>* /* originally async */ {
+ final asy::_AsyncAwaitCompleter<core::Null?>* :async_completer = new asy::_AsyncAwaitCompleter::•<core::Null?>();
+ asy::FutureOr<core::Null?>* :return_value;
dynamic :async_stack_trace;
dynamic :async_op_then;
dynamic :async_op_error;
diff --git a/pkg/front_end/testcases/inference/block_bodied_lambdas_infer_bottom_async_star.dart b/pkg/front_end/testcases/inference/block_bodied_lambdas_infer_bottom_async_star.dart
index 0fcd324..9b6202f 100644
--- a/pkg/front_end/testcases/inference/block_bodied_lambdas_infer_bottom_async_star.dart
+++ b/pkg/front_end/testcases/inference/block_bodied_lambdas_infer_bottom_async_star.dart
@@ -8,7 +8,7 @@
import 'dart:async';
main() async {
- var /*@ type=() ->* Stream<Null*>* */ f = /*@ returnType=Stream<Null*>* */ () async* {
+ var /*@ type=() ->* Stream<Null?>* */ f = /*@ returnType=Stream<Null?>* */ () async* {
yield null;
};
Stream y = f();
diff --git a/pkg/front_end/testcases/inference/block_bodied_lambdas_infer_bottom_async_star.dart.strong.expect b/pkg/front_end/testcases/inference/block_bodied_lambdas_infer_bottom_async_star.dart.strong.expect
index 399d883..3bfdf39 100644
--- a/pkg/front_end/testcases/inference/block_bodied_lambdas_infer_bottom_async_star.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/block_bodied_lambdas_infer_bottom_async_star.dart.strong.expect
@@ -6,7 +6,7 @@
import "dart:async";
static method main() → dynamic async {
- () →* asy::Stream<core::Null*>* f = () → asy::Stream<core::Null*>* async* {
+ () →* asy::Stream<core::Null?>* f = () → asy::Stream<core::Null?>* async* {
yield null;
};
asy::Stream<dynamic>* y = f.call();
diff --git a/pkg/front_end/testcases/inference/block_bodied_lambdas_infer_bottom_async_star.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/block_bodied_lambdas_infer_bottom_async_star.dart.strong.transformed.expect
index 1c649f3..ae912fe 100644
--- a/pkg/front_end/testcases/inference/block_bodied_lambdas_infer_bottom_async_star.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/block_bodied_lambdas_infer_bottom_async_star.dart.strong.transformed.expect
@@ -18,8 +18,8 @@
try {
#L1:
{
- () →* asy::Stream<core::Null*>* f = () → asy::Stream<core::Null*>* /* originally async* */ {
- asy::_AsyncStarStreamController<core::Null*>* :controller;
+ () →* asy::Stream<core::Null?>* f = () → asy::Stream<core::Null?>* /* originally async* */ {
+ asy::_AsyncStarStreamController<core::Null?>* :controller;
dynamic :controller_stream;
dynamic :async_stack_trace;
dynamic :async_op_then;
@@ -49,7 +49,7 @@
:async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
:async_op_then = asy::_asyncThenWrapperHelper(:async_op);
:async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
- :controller = new asy::_AsyncStarStreamController::•<core::Null*>(:async_op);
+ :controller = new asy::_AsyncStarStreamController::•<core::Null?>(:async_op);
:controller_stream = :controller.{asy::_AsyncStarStreamController::stream};
return :controller_stream;
};
diff --git a/pkg/front_end/testcases/inference/block_bodied_lambdas_infer_bottom_sync.dart b/pkg/front_end/testcases/inference/block_bodied_lambdas_infer_bottom_sync.dart
index 192fdd0..ff64ba7 100644
--- a/pkg/front_end/testcases/inference/block_bodied_lambdas_infer_bottom_sync.dart
+++ b/pkg/front_end/testcases/inference/block_bodied_lambdas_infer_bottom_sync.dart
@@ -9,18 +9,18 @@
void foo(int f(Object _)) {}
test() {
- var /*@ type=(Object*) ->* Null* */ f = /*@ returnType=Null* */ (Object x) {
+ var /*@ type=(Object*) ->* Null? */ f = /*@ returnType=Null? */ (Object x) {
return null;
};
String y = f(42);
- f = /*error:INVALID_CAST_FUNCTION_EXPR*/ /*@ returnType=Null* */ (/*@ type=Object* */ x) =>
+ f = /*error:INVALID_CAST_FUNCTION_EXPR*/ /*@ returnType=Null? */ (/*@ type=Object* */ x) =>
'hello';
- foo(/*@ returnType=Null* */ (/*@ type=Object* */ x) {
+ foo(/*@ returnType=Null? */ (/*@ type=Object* */ x) {
return null;
});
- foo(/*@ returnType=Null* */ (/*@ type=Object* */ x) {
+ foo(/*@ returnType=Null? */ (/*@ type=Object* */ x) {
throw "not implemented";
});
}
diff --git a/pkg/front_end/testcases/inference/block_bodied_lambdas_infer_bottom_sync.dart.strong.expect b/pkg/front_end/testcases/inference/block_bodied_lambdas_infer_bottom_sync.dart.strong.expect
index 851fe91..c1bf65f 100644
--- a/pkg/front_end/testcases/inference/block_bodied_lambdas_infer_bottom_sync.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/block_bodied_lambdas_infer_bottom_sync.dart.strong.expect
@@ -5,15 +5,15 @@
static field dynamic h = null;
static method foo((core::Object*) →* core::int* f) → void {}
static method test() → dynamic {
- (core::Object*) →* core::Null* f = (core::Object* x) → core::Null* {
+ (core::Object*) →* core::Null? f = (core::Object* x) → core::Null? {
return null;
};
core::String* y = f.call(42);
- f = (core::Object* x) → core::Null* => "hello" as{TypeError} core::Null*;
- self::foo((core::Object* x) → core::Null* {
+ f = (core::Object* x) → core::Null? => "hello" as{TypeError} core::Null?;
+ self::foo((core::Object* x) → core::Null? {
return null;
});
- self::foo((core::Object* x) → core::Null* {
+ self::foo((core::Object* x) → core::Null? {
throw "not implemented";
});
}
diff --git a/pkg/front_end/testcases/inference/block_bodied_lambdas_infer_bottom_sync.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/block_bodied_lambdas_infer_bottom_sync.dart.strong.transformed.expect
index 851fe91..c1bf65f 100644
--- a/pkg/front_end/testcases/inference/block_bodied_lambdas_infer_bottom_sync.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/block_bodied_lambdas_infer_bottom_sync.dart.strong.transformed.expect
@@ -5,15 +5,15 @@
static field dynamic h = null;
static method foo((core::Object*) →* core::int* f) → void {}
static method test() → dynamic {
- (core::Object*) →* core::Null* f = (core::Object* x) → core::Null* {
+ (core::Object*) →* core::Null? f = (core::Object* x) → core::Null? {
return null;
};
core::String* y = f.call(42);
- f = (core::Object* x) → core::Null* => "hello" as{TypeError} core::Null*;
- self::foo((core::Object* x) → core::Null* {
+ f = (core::Object* x) → core::Null? => "hello" as{TypeError} core::Null?;
+ self::foo((core::Object* x) → core::Null? {
return null;
});
- self::foo((core::Object* x) → core::Null* {
+ self::foo((core::Object* x) → core::Null? {
throw "not implemented";
});
}
diff --git a/pkg/front_end/testcases/inference/block_bodied_lambdas_infer_bottom_sync.dart.type_promotion.expect b/pkg/front_end/testcases/inference/block_bodied_lambdas_infer_bottom_sync.dart.type_promotion.expect
index 78cf9d6d..2fa431c 100644
--- a/pkg/front_end/testcases/inference/block_bodied_lambdas_infer_bottom_sync.dart.type_promotion.expect
+++ b/pkg/front_end/testcases/inference/block_bodied_lambdas_infer_bottom_sync.dart.type_promotion.expect
@@ -1,3 +1,3 @@
pkg/front_end/testcases/inference/block_bodied_lambdas_infer_bottom_sync.dart:17:5: Context: Write to f@353
- f = /*error:INVALID_CAST_FUNCTION_EXPR*/ /*@ returnType=Null* */ (/*@ type=Object* */ x) =>
+ f = /*error:INVALID_CAST_FUNCTION_EXPR*/ /*@ returnType=Null? */ (/*@ type=Object* */ x) =>
^
diff --git a/pkg/front_end/testcases/inference/block_bodied_lambdas_infer_bottom_sync_star.dart b/pkg/front_end/testcases/inference/block_bodied_lambdas_infer_bottom_sync_star.dart
index e4c6fe0..abfa763 100644
--- a/pkg/front_end/testcases/inference/block_bodied_lambdas_infer_bottom_sync_star.dart
+++ b/pkg/front_end/testcases/inference/block_bodied_lambdas_infer_bottom_sync_star.dart
@@ -6,7 +6,7 @@
library test;
main() {
- var /*@ type=() ->* Iterable<Null*>* */ f = /*@ returnType=Iterable<Null*>* */ () sync* {
+ var /*@ type=() ->* Iterable<Null?>* */ f = /*@ returnType=Iterable<Null?>* */ () sync* {
yield null;
};
Iterable y = f();
diff --git a/pkg/front_end/testcases/inference/block_bodied_lambdas_infer_bottom_sync_star.dart.strong.expect b/pkg/front_end/testcases/inference/block_bodied_lambdas_infer_bottom_sync_star.dart.strong.expect
index d55bbde..96ec582 100644
--- a/pkg/front_end/testcases/inference/block_bodied_lambdas_infer_bottom_sync_star.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/block_bodied_lambdas_infer_bottom_sync_star.dart.strong.expect
@@ -3,7 +3,7 @@
import "dart:core" as core;
static method main() → dynamic {
- () →* core::Iterable<core::Null*>* f = () → core::Iterable<core::Null*>* sync* {
+ () →* core::Iterable<core::Null?>* f = () → core::Iterable<core::Null?>* sync* {
yield null;
};
core::Iterable<dynamic>* y = f.call();
diff --git a/pkg/front_end/testcases/inference/block_bodied_lambdas_infer_bottom_sync_star.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/block_bodied_lambdas_infer_bottom_sync_star.dart.strong.transformed.expect
index 843ea40..f94cf54 100644
--- a/pkg/front_end/testcases/inference/block_bodied_lambdas_infer_bottom_sync_star.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/block_bodied_lambdas_infer_bottom_sync_star.dart.strong.transformed.expect
@@ -3,10 +3,10 @@
import "dart:core" as core;
static method main() → dynamic {
- () →* core::Iterable<core::Null*>* f = () → core::Iterable<core::Null*>* /* originally sync* */ {
+ () →* core::Iterable<core::Null?>* f = () → core::Iterable<core::Null?>* /* originally sync* */ {
dynamic :await_jump_var = 0;
dynamic :await_ctx_var;
- function :sync_op(core::_SyncIterator<core::Null*>* :iterator) → core::bool* yielding {
+ function :sync_op(core::_SyncIterator<core::Null?>* :iterator) → core::bool* yielding {
{
{
:iterator.{core::_SyncIterator::_current} = null;
@@ -15,7 +15,7 @@
}
return false;
}
- return new core::_SyncIterable::•<core::Null*>(:sync_op);
+ return new core::_SyncIterable::•<core::Null?>(:sync_op);
};
core::Iterable<dynamic>* y = f.call();
core::Iterable<core::String*>* z = f.call();
diff --git a/pkg/front_end/testcases/inference/block_bodied_lambdas_no_return.dart b/pkg/front_end/testcases/inference/block_bodied_lambdas_no_return.dart
index 44aca46..4ca0960 100644
--- a/pkg/front_end/testcases/inference/block_bodied_lambdas_no_return.dart
+++ b/pkg/front_end/testcases/inference/block_bodied_lambdas_no_return.dart
@@ -7,9 +7,9 @@
test1() {
List<int> o;
- var /*@ type=Iterable<Null*>* */ y =
- o. /*@ typeArgs=Null* */ /*@target=Iterable::map*/ map(
- /*@ returnType=Null* */ (/*@ type=int* */ x) {});
+ var /*@ type=Iterable<Null?>* */ y =
+ o. /*@ typeArgs=Null? */ /*@target=Iterable::map*/ map(
+ /*@ returnType=Null? */ (/*@ type=int* */ x) {});
Iterable<int> z = y;
}
diff --git a/pkg/front_end/testcases/inference/block_bodied_lambdas_no_return.dart.strong.expect b/pkg/front_end/testcases/inference/block_bodied_lambdas_no_return.dart.strong.expect
index a3d94e2..ae81c76 100644
--- a/pkg/front_end/testcases/inference/block_bodied_lambdas_no_return.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/block_bodied_lambdas_no_return.dart.strong.expect
@@ -4,7 +4,7 @@
static method test1() → dynamic {
core::List<core::int*>* o;
- core::Iterable<core::Null*>* y = o.{core::Iterable::map}<core::Null*>((core::int* x) → core::Null* {});
+ core::Iterable<core::Null?>* y = o.{core::Iterable::map}<core::Null?>((core::int* x) → core::Null? {});
core::Iterable<core::int*>* z = y;
}
static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/block_bodied_lambdas_no_return.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/block_bodied_lambdas_no_return.dart.strong.transformed.expect
index a3d94e2..ae81c76 100644
--- a/pkg/front_end/testcases/inference/block_bodied_lambdas_no_return.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/block_bodied_lambdas_no_return.dart.strong.transformed.expect
@@ -4,7 +4,7 @@
static method test1() → dynamic {
core::List<core::int*>* o;
- core::Iterable<core::Null*>* y = o.{core::Iterable::map}<core::Null*>((core::int* x) → core::Null* {});
+ core::Iterable<core::Null?>* y = o.{core::Iterable::map}<core::Null?>((core::int* x) → core::Null? {});
core::Iterable<core::int*>* z = y;
}
static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/block_bodied_lambdas_returns.dart b/pkg/front_end/testcases/inference/block_bodied_lambdas_returns.dart
index dad3714..30d096e 100644
--- a/pkg/front_end/testcases/inference/block_bodied_lambdas_returns.dart
+++ b/pkg/front_end/testcases/inference/block_bodied_lambdas_returns.dart
@@ -6,24 +6,24 @@
library test;
main() {
- var /*@ type=() ->* Null* */ a = /*@ returnType=Null* */ () {};
- var /*@ type=() ->* Null* */ b = /*@ returnType=Null* */ () {
+ var /*@ type=() ->* Null? */ a = /*@ returnType=Null? */ () {};
+ var /*@ type=() ->* Null? */ b = /*@ returnType=Null? */ () {
return;
};
- var /*@ type=() ->* Null* */ c = /*@ returnType=Null* */ () {
+ var /*@ type=() ->* Null? */ c = /*@ returnType=Null? */ () {
return null;
};
var /*@ type=() ->* int* */ d = /*@ returnType=int* */ () {
return 0;
};
- var /*@ type=(bool*) ->* Null* */ e = /*@ returnType=Null* */ (bool b) {
+ var /*@ type=(bool*) ->* Null? */ e = /*@ returnType=Null? */ (bool b) {
if (b) {
return;
} else {
return;
}
};
- var /*@ type=(bool*) ->* Null* */ f = /*@ returnType=Null* */ (bool b) {
+ var /*@ type=(bool*) ->* Null? */ f = /*@ returnType=Null? */ (bool b) {
if (b) {
return;
} else {
@@ -37,14 +37,14 @@
return 0;
}
};
- var /*@ type=(bool*) ->* Null* */ h = /*@ returnType=Null* */ (bool b) {
+ var /*@ type=(bool*) ->* Null? */ h = /*@ returnType=Null? */ (bool b) {
if (b) {
return null;
} else {
return;
}
};
- var /*@ type=(bool*) ->* Null* */ i = /*@ returnType=Null* */ (bool b) {
+ var /*@ type=(bool*) ->* Null? */ i = /*@ returnType=Null? */ (bool b) {
if (b) {
return null;
} else {
diff --git a/pkg/front_end/testcases/inference/block_bodied_lambdas_returns.dart.strong.expect b/pkg/front_end/testcases/inference/block_bodied_lambdas_returns.dart.strong.expect
index b6de6a5..3ccb306 100644
--- a/pkg/front_end/testcases/inference/block_bodied_lambdas_returns.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/block_bodied_lambdas_returns.dart.strong.expect
@@ -14,17 +14,17 @@
import "dart:core" as core;
static method main() → dynamic {
- () →* core::Null* a = () → core::Null* {};
- () →* core::Null* b = () → core::Null* {
+ () →* core::Null? a = () → core::Null? {};
+ () →* core::Null? b = () → core::Null? {
return;
};
- () →* core::Null* c = () → core::Null* {
+ () →* core::Null? c = () → core::Null? {
return null;
};
() →* core::int* d = () → core::int* {
return 0;
};
- (core::bool*) →* core::Null* e = (core::bool* b) → core::Null* {
+ (core::bool*) →* core::Null? e = (core::bool* b) → core::Null? {
if(b) {
return;
}
@@ -32,7 +32,7 @@
return;
}
};
- (core::bool*) →* core::Null* f = (core::bool* b) → core::Null* {
+ (core::bool*) →* core::Null? f = (core::bool* b) → core::Null? {
if(b) {
return;
}
@@ -48,7 +48,7 @@
return 0;
}
};
- (core::bool*) →* core::Null* h = (core::bool* b) → core::Null* {
+ (core::bool*) →* core::Null? h = (core::bool* b) → core::Null? {
if(b) {
return null;
}
@@ -56,7 +56,7 @@
return;
}
};
- (core::bool*) →* core::Null* i = (core::bool* b) → core::Null* {
+ (core::bool*) →* core::Null? i = (core::bool* b) → core::Null? {
if(b) {
return null;
}
diff --git a/pkg/front_end/testcases/inference/block_bodied_lambdas_returns.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/block_bodied_lambdas_returns.dart.strong.transformed.expect
index b6de6a5..3ccb306 100644
--- a/pkg/front_end/testcases/inference/block_bodied_lambdas_returns.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/block_bodied_lambdas_returns.dart.strong.transformed.expect
@@ -14,17 +14,17 @@
import "dart:core" as core;
static method main() → dynamic {
- () →* core::Null* a = () → core::Null* {};
- () →* core::Null* b = () → core::Null* {
+ () →* core::Null? a = () → core::Null? {};
+ () →* core::Null? b = () → core::Null? {
return;
};
- () →* core::Null* c = () → core::Null* {
+ () →* core::Null? c = () → core::Null? {
return null;
};
() →* core::int* d = () → core::int* {
return 0;
};
- (core::bool*) →* core::Null* e = (core::bool* b) → core::Null* {
+ (core::bool*) →* core::Null? e = (core::bool* b) → core::Null? {
if(b) {
return;
}
@@ -32,7 +32,7 @@
return;
}
};
- (core::bool*) →* core::Null* f = (core::bool* b) → core::Null* {
+ (core::bool*) →* core::Null? f = (core::bool* b) → core::Null? {
if(b) {
return;
}
@@ -48,7 +48,7 @@
return 0;
}
};
- (core::bool*) →* core::Null* h = (core::bool* b) → core::Null* {
+ (core::bool*) →* core::Null? h = (core::bool* b) → core::Null? {
if(b) {
return null;
}
@@ -56,7 +56,7 @@
return;
}
};
- (core::bool*) →* core::Null* i = (core::bool* b) → core::Null* {
+ (core::bool*) →* core::Null? i = (core::bool* b) → core::Null? {
if(b) {
return null;
}
diff --git a/pkg/front_end/testcases/inference/bottom_in_closure.dart b/pkg/front_end/testcases/inference/bottom_in_closure.dart
index c0f7ac8..b05f476 100644
--- a/pkg/front_end/testcases/inference/bottom_in_closure.dart
+++ b/pkg/front_end/testcases/inference/bottom_in_closure.dart
@@ -5,7 +5,7 @@
/*@testedFeatures=inference*/
library test;
-var v = /*@ returnType=Null* */ () => null;
+var v = /*@ returnType=Null? */ () => null;
main() {
v;
diff --git a/pkg/front_end/testcases/inference/bottom_in_closure.dart.outline.expect b/pkg/front_end/testcases/inference/bottom_in_closure.dart.outline.expect
index 5497bda..0eb1af7 100644
--- a/pkg/front_end/testcases/inference/bottom_in_closure.dart.outline.expect
+++ b/pkg/front_end/testcases/inference/bottom_in_closure.dart.outline.expect
@@ -2,6 +2,6 @@
import self as self;
import "dart:core" as core;
-static field () →* core::Null* v;
+static field () →* core::Null? v;
static method main() → dynamic
;
diff --git a/pkg/front_end/testcases/inference/bottom_in_closure.dart.strong.expect b/pkg/front_end/testcases/inference/bottom_in_closure.dart.strong.expect
index 15c380f..8325cbb 100644
--- a/pkg/front_end/testcases/inference/bottom_in_closure.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/bottom_in_closure.dart.strong.expect
@@ -2,7 +2,7 @@
import self as self;
import "dart:core" as core;
-static field () →* core::Null* v = () → core::Null* => null;
+static field () →* core::Null? v = () → core::Null? => null;
static method main() → dynamic {
self::v;
}
diff --git a/pkg/front_end/testcases/inference/bottom_in_closure.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/bottom_in_closure.dart.strong.transformed.expect
index 15c380f..8325cbb 100644
--- a/pkg/front_end/testcases/inference/bottom_in_closure.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/bottom_in_closure.dart.strong.transformed.expect
@@ -2,7 +2,7 @@
import self as self;
import "dart:core" as core;
-static field () →* core::Null* v = () → core::Null* => null;
+static field () →* core::Null? v = () → core::Null? => null;
static method main() → dynamic {
self::v;
}
diff --git a/pkg/front_end/testcases/inference/bug31133.dart b/pkg/front_end/testcases/inference/bug31133.dart
index c9680f4..b5ff4bf 100644
--- a/pkg/front_end/testcases/inference/bug31133.dart
+++ b/pkg/front_end/testcases/inference/bug31133.dart
@@ -7,10 +7,18 @@
void test() {
var /*@ type=int* */ i = 0;
- for (i++; i /*@target=num::<*/ < 10; i++) {}
- for (++i; i /*@target=num::<*/ < 10; i++) {}
- for (i--; i /*@target=num::>=*/ >= 0; i--) {}
- for (--i; i /*@target=num::>=*/ >= 0; i--) {}
+ for (i /*@ target=num::+ */ ++;
+ i /*@target=num::<*/ < 10;
+ i /*@ target=num::+ */ ++) {}
+ for (/*@ target=num::+ */ ++i;
+ i /*@target=num::<*/ < 10;
+ i /*@ target=num::+ */ ++) {}
+ for (i /*@ target=num::- */ --;
+ i /*@target=num::>=*/ >= 0;
+ i /*@ target=num::- */ --) {}
+ for (/*@ target=num::- */ --i;
+ i /*@target=num::>=*/ >= 0;
+ i /*@ target=num::- */ --) {}
}
main() {}
diff --git a/pkg/front_end/testcases/inference/bug31133.dart.type_promotion.expect b/pkg/front_end/testcases/inference/bug31133.dart.type_promotion.expect
index a8c2fb5..bf317e2 100644
--- a/pkg/front_end/testcases/inference/bug31133.dart.type_promotion.expect
+++ b/pkg/front_end/testcases/inference/bug31133.dart.type_promotion.expect
@@ -1,24 +1,24 @@
-pkg/front_end/testcases/inference/bug31133.dart:10:9: Context: Write to i@299
- for (i++; i /*@target=num::<*/ < 10; i++) {}
- ^^
-pkg/front_end/testcases/inference/bug31133.dart:10:41: Context: Write to i@299
- for (i++; i /*@target=num::<*/ < 10; i++) {}
- ^^
-pkg/front_end/testcases/inference/bug31133.dart:11:8: Context: Write to i@299
- for (++i; i /*@target=num::<*/ < 10; i++) {}
- ^^
-pkg/front_end/testcases/inference/bug31133.dart:11:41: Context: Write to i@299
- for (++i; i /*@target=num::<*/ < 10; i++) {}
- ^^
-pkg/front_end/testcases/inference/bug31133.dart:12:9: Context: Write to i@299
- for (i--; i /*@target=num::>=*/ >= 0; i--) {}
- ^^
-pkg/front_end/testcases/inference/bug31133.dart:12:42: Context: Write to i@299
- for (i--; i /*@target=num::>=*/ >= 0; i--) {}
- ^^
-pkg/front_end/testcases/inference/bug31133.dart:13:8: Context: Write to i@299
- for (--i; i /*@target=num::>=*/ >= 0; i--) {}
- ^^
-pkg/front_end/testcases/inference/bug31133.dart:13:42: Context: Write to i@299
- for (--i; i /*@target=num::>=*/ >= 0; i--) {}
- ^^
+pkg/front_end/testcases/inference/bug31133.dart:10:31: Context: Write to i@299
+ for (i /*@ target=num::+ */ ++;
+ ^^
+pkg/front_end/testcases/inference/bug31133.dart:12:30: Context: Write to i@299
+ i /*@ target=num::+ */ ++) {}
+ ^^
+pkg/front_end/testcases/inference/bug31133.dart:13:29: Context: Write to i@299
+ for (/*@ target=num::+ */ ++i;
+ ^^
+pkg/front_end/testcases/inference/bug31133.dart:15:30: Context: Write to i@299
+ i /*@ target=num::+ */ ++) {}
+ ^^
+pkg/front_end/testcases/inference/bug31133.dart:16:31: Context: Write to i@299
+ for (i /*@ target=num::- */ --;
+ ^^
+pkg/front_end/testcases/inference/bug31133.dart:18:30: Context: Write to i@299
+ i /*@ target=num::- */ --) {}
+ ^^
+pkg/front_end/testcases/inference/bug31133.dart:19:29: Context: Write to i@299
+ for (/*@ target=num::- */ --i;
+ ^^
+pkg/front_end/testcases/inference/bug31133.dart:21:30: Context: Write to i@299
+ i /*@ target=num::- */ --) {}
+ ^^
diff --git a/pkg/front_end/testcases/inference/coerce_bottom_and_null_types.dart b/pkg/front_end/testcases/inference/coerce_bottom_and_null_types.dart
index 45cfec1..da3d184 100644
--- a/pkg/front_end/testcases/inference/coerce_bottom_and_null_types.dart
+++ b/pkg/front_end/testcases/inference/coerce_bottom_and_null_types.dart
@@ -10,13 +10,13 @@
var /*@ type=dynamic */ b = null;
var /*@ type=dynamic */ c = throw 'foo';
var /*@ type=() ->* int* */ d = /*@ returnType=int* */ () => 0;
- var /*@ type=() ->* Null* */ e = /*@ returnType=Null* */ () => null;
+ var /*@ type=() ->* Null? */ e = /*@ returnType=Null? */ () => null;
var /*@ type=() ->* <BottomType> */ f = /*@ returnType=<BottomType> */ () =>
throw 'foo';
var /*@ type=() ->* int* */ g = /*@ returnType=int* */ () {
return 0;
};
- var /*@ type=() ->* Null* */ h = /*@ returnType=Null* */ () {
+ var /*@ type=() ->* Null? */ h = /*@ returnType=Null? */ () {
return null;
};
var /*@ type=() ->* <BottomType> */ i = /*@ returnType=<BottomType> */ () {
diff --git a/pkg/front_end/testcases/inference/coerce_bottom_and_null_types.dart.strong.expect b/pkg/front_end/testcases/inference/coerce_bottom_and_null_types.dart.strong.expect
index a4811d3..6d3a4af 100644
--- a/pkg/front_end/testcases/inference/coerce_bottom_and_null_types.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/coerce_bottom_and_null_types.dart.strong.expect
@@ -7,12 +7,12 @@
dynamic b = null;
dynamic c = throw "foo";
() →* core::int* d = () → core::int* => 0;
- () →* core::Null* e = () → core::Null* => null;
+ () →* core::Null? e = () → core::Null? => null;
() →* <BottomType>f = () → <BottomType>=> throw "foo";
() →* core::int* g = () → core::int* {
return 0;
};
- () →* core::Null* h = () → core::Null* {
+ () →* core::Null? h = () → core::Null? {
return null;
};
() →* <BottomType>i = () → <BottomType>{
diff --git a/pkg/front_end/testcases/inference/coerce_bottom_and_null_types.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/coerce_bottom_and_null_types.dart.strong.transformed.expect
index a4811d3..6d3a4af 100644
--- a/pkg/front_end/testcases/inference/coerce_bottom_and_null_types.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/coerce_bottom_and_null_types.dart.strong.transformed.expect
@@ -7,12 +7,12 @@
dynamic b = null;
dynamic c = throw "foo";
() →* core::int* d = () → core::int* => 0;
- () →* core::Null* e = () → core::Null* => null;
+ () →* core::Null? e = () → core::Null? => null;
() →* <BottomType>f = () → <BottomType>=> throw "foo";
() →* core::int* g = () → core::int* {
return 0;
};
- () →* core::Null* h = () → core::Null* {
+ () →* core::Null? h = () → core::Null? {
return null;
};
() →* <BottomType>i = () → <BottomType>{
diff --git a/pkg/front_end/testcases/inference/complex_predecrement.dart b/pkg/front_end/testcases/inference/complex_predecrement.dart
index ed84362..02b6f5a 100644
--- a/pkg/front_end/testcases/inference/complex_predecrement.dart
+++ b/pkg/front_end/testcases/inference/complex_predecrement.dart
@@ -7,5 +7,6 @@
main() {
var /*@ type=List<int*>* */ foo = /*@ typeArgs=int* */ [1, 2, 3];
- print(--foo /*@target=List::[]=*/ [0]);
+ print(/*@ target=num::- */ --foo /*@target=List::[]*/ /*@target=List::[]=*/ [
+ 0]);
}
diff --git a/pkg/front_end/testcases/inference/constructors_infer_from_arguments_redirecting_factory_to_factory.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/constructors_infer_from_arguments_redirecting_factory_to_factory.dart.strong.transformed.expect
index 47257c7..0bd8d51 100644
--- a/pkg/front_end/testcases/inference/constructors_infer_from_arguments_redirecting_factory_to_factory.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/constructors_infer_from_arguments_redirecting_factory_to_factory.dart.strong.transformed.expect
@@ -7,7 +7,7 @@
abstract get t() → self::C::T*;
abstract set t(generic-covariant-impl self::C::T* x) → void;
static factory •<T extends core::Object* = dynamic>(self::C::•::T* t) → self::C<self::C::•::T*>*
- let <T extends core::Object* = dynamic>(self::CImpl::•::T*) →* self::CImpl<self::CImpl::•::T*>* #redirecting_factory = self::CImpl::• in let self::C::•::T* #typeArg0 = null in invalid-expression;
+ let <T extends core::Object* = dynamic>(T*) →* self::CImpl<T*>* #redirecting_factory = self::CImpl::• in let self::C::•::T* #typeArg0 = null in invalid-expression;
}
class CImpl<T extends core::Object* = dynamic> extends core::Object implements self::C<self::CImpl::T*> {
generic-covariant-impl field self::CImpl::T* t;
diff --git a/pkg/front_end/testcases/inference/downwards_inference_annotations_for_loop_variable.dart b/pkg/front_end/testcases/inference/downwards_inference_annotations_for_loop_variable.dart
index 5ca6726..4481a40 100644
--- a/pkg/front_end/testcases/inference/downwards_inference_annotations_for_loop_variable.dart
+++ b/pkg/front_end/testcases/inference/downwards_inference_annotations_for_loop_variable.dart
@@ -10,9 +10,12 @@
}
void test() {
- for (@Foo(/*@ typeArgs=String* */ const []) int i = 0;
- i /*@target=num::<*/< 1; i++) {}
- for (@Foo(/*@ typeArgs=String* */ const []) int i in /*@ typeArgs=int* */[0]) {}
+ for (@Foo(/*@ typeArgs=String* */ const [])
+ int i = 0;
+ i /*@target=num::<*/ < 1;
+ i /*@ target=num::+ */ ++) {}
+ for (@Foo(/*@ typeArgs=String* */ const [])
+ int i in /*@ typeArgs=int* */ [0]) {}
}
main() {}
diff --git a/pkg/front_end/testcases/inference/downwards_inference_annotations_for_loop_variable.dart.type_promotion.expect b/pkg/front_end/testcases/inference/downwards_inference_annotations_for_loop_variable.dart.type_promotion.expect
index 5b124f4..40956e2b4 100644
--- a/pkg/front_end/testcases/inference/downwards_inference_annotations_for_loop_variable.dart.type_promotion.expect
+++ b/pkg/front_end/testcases/inference/downwards_inference_annotations_for_loop_variable.dart.type_promotion.expect
@@ -1,3 +1,3 @@
-pkg/front_end/testcases/inference/downwards_inference_annotations_for_loop_variable.dart:14:34: Context: Write to i@370
- i /*@target=num::<*/< 1; i++) {}
- ^^
+pkg/front_end/testcases/inference/downwards_inference_annotations_for_loop_variable.dart:16:30: Context: Write to i@372
+ i /*@ target=num::+ */ ++) {}
+ ^^
diff --git a/pkg/front_end/testcases/inference/downwards_inference_annotations_parameter_local.dart b/pkg/front_end/testcases/inference/downwards_inference_annotations_parameter_local.dart
index c568ab4..1d09fe8 100644
--- a/pkg/front_end/testcases/inference/downwards_inference_annotations_parameter_local.dart
+++ b/pkg/front_end/testcases/inference/downwards_inference_annotations_parameter_local.dart
@@ -11,7 +11,7 @@
void test() {
void f(@Foo(/*@ typeArgs=String* */ const []) /*@ type=dynamic */ x) {}
- var /*@ type=(dynamic) ->* Null* */ x = /*@ returnType=Null* */ (@Foo(/*@ typeArgs=String* */ const []) /*@ type=dynamic */
+ var /*@ type=(dynamic) ->* Null? */ x = /*@ returnType=Null? */ (@Foo(/*@ typeArgs=String* */ const []) /*@ type=dynamic */
x) {};
}
diff --git a/pkg/front_end/testcases/inference/downwards_inference_annotations_parameter_local.dart.strong.expect b/pkg/front_end/testcases/inference/downwards_inference_annotations_parameter_local.dart.strong.expect
index 8bb1470..402205d 100644
--- a/pkg/front_end/testcases/inference/downwards_inference_annotations_parameter_local.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/downwards_inference_annotations_parameter_local.dart.strong.expect
@@ -9,7 +9,7 @@
}
static method test() → void {
function f(@#C1 dynamic x) → void {}
- (dynamic) →* core::Null* x = (@#C1 dynamic x) → core::Null* {};
+ (dynamic) →* core::Null? x = (@#C1 dynamic x) → core::Null? {};
}
static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/downwards_inference_annotations_parameter_local.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/downwards_inference_annotations_parameter_local.dart.strong.transformed.expect
index 8bb1470..402205d 100644
--- a/pkg/front_end/testcases/inference/downwards_inference_annotations_parameter_local.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/downwards_inference_annotations_parameter_local.dart.strong.transformed.expect
@@ -9,7 +9,7 @@
}
static method test() → void {
function f(@#C1 dynamic x) → void {}
- (dynamic) →* core::Null* x = (@#C1 dynamic x) → core::Null* {};
+ (dynamic) →* core::Null? x = (@#C1 dynamic x) → core::Null? {};
}
static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/downwards_inference_annotations_type_variable_local.dart b/pkg/front_end/testcases/inference/downwards_inference_annotations_type_variable_local.dart
index 2eae17d..432c249 100644
--- a/pkg/front_end/testcases/inference/downwards_inference_annotations_type_variable_local.dart
+++ b/pkg/front_end/testcases/inference/downwards_inference_annotations_type_variable_local.dart
@@ -11,8 +11,8 @@
void test() {
void f<@Foo(/*@ typeArgs=String* */ const []) T>() {}
- var /*@ type=<@Foo::•(const <String*>[]) T extends Object* = dynamic>() ->* Null* */ x =
- <@Foo(/*@ typeArgs=String* */ const []) T> /*@ returnType=Null* */ () {};
+ var /*@ type=<@Foo::•(const <String*>[]) T extends Object* = dynamic>() ->* Null? */ x =
+ <@Foo(/*@ typeArgs=String* */ const []) T> /*@ returnType=Null? */ () {};
}
main() {}
diff --git a/pkg/front_end/testcases/inference/downwards_inference_annotations_type_variable_local.dart.strong.expect b/pkg/front_end/testcases/inference/downwards_inference_annotations_type_variable_local.dart.strong.expect
index 4fcf15f..5002d4f 100644
--- a/pkg/front_end/testcases/inference/downwards_inference_annotations_type_variable_local.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/downwards_inference_annotations_type_variable_local.dart.strong.expect
@@ -9,6 +9,6 @@
}
static method test() → void {
function f<@self::Foo::•(const <core::String*>[]) T extends core::Object* = dynamic>() → void {}
- <@self::Foo::•(const <core::String*>[]) T extends core::Object* = dynamic>() →* core::Null* x = <@self::Foo::•(const <core::String*>[]) T extends core::Object* = dynamic>() → core::Null* {};
+ <@self::Foo::•(const <core::String*>[]) T extends core::Object* = dynamic>() →* core::Null? x = <@self::Foo::•(const <core::String*>[]) T extends core::Object* = dynamic>() → core::Null? {};
}
static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/downwards_inference_annotations_type_variable_local.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/downwards_inference_annotations_type_variable_local.dart.strong.transformed.expect
index 4fcf15f..5002d4f 100644
--- a/pkg/front_end/testcases/inference/downwards_inference_annotations_type_variable_local.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/downwards_inference_annotations_type_variable_local.dart.strong.transformed.expect
@@ -9,6 +9,6 @@
}
static method test() → void {
function f<@self::Foo::•(const <core::String*>[]) T extends core::Object* = dynamic>() → void {}
- <@self::Foo::•(const <core::String*>[]) T extends core::Object* = dynamic>() →* core::Null* x = <@self::Foo::•(const <core::String*>[]) T extends core::Object* = dynamic>() → core::Null* {};
+ <@self::Foo::•(const <core::String*>[]) T extends core::Object* = dynamic>() →* core::Null? x = <@self::Foo::•(const <core::String*>[]) T extends core::Object* = dynamic>() → core::Null? {};
}
static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/downwards_inference_on_function_expressions.dart b/pkg/front_end/testcases/inference/downwards_inference_on_function_expressions.dart
index 907a37c..c8bea76 100644
--- a/pkg/front_end/testcases/inference/downwards_inference_on_function_expressions.dart
+++ b/pkg/front_end/testcases/inference/downwards_inference_on_function_expressions.dart
@@ -9,7 +9,7 @@
void test() {
{
- Function2<int, String> l0 = /*@ returnType=Null* */ (int x) => null;
+ Function2<int, String> l0 = /*@ returnType=Null? */ (int x) => null;
Function2<int, String> l1 = /*@ returnType=String* */ (int x) => "hello";
Function2<int, String>
l2 = /*error:INVALID_ASSIGNMENT*/ /*@ returnType=String* */ (String x) =>
@@ -21,7 +21,7 @@
};
}
{
- Function2<int, String> l0 = /*@ returnType=Null* */ (/*@ type=int* */ x) => null;
+ Function2<int, String> l0 = /*@ returnType=Null? */ (/*@ type=int* */ x) => null;
Function2<int, String> l1 = /*@ returnType=String* */ (/*@ type=int* */ x) =>
"hello";
Function2<int, String>
@@ -35,7 +35,7 @@
};
}
{
- Function2<int, List<String>> l0 = /*@ returnType=Null* */ (int x) => null;
+ Function2<int, List<String>> l0 = /*@ returnType=Null? */ (int x) => null;
Function2<int, List<String>> l1 = /*@ returnType=List<String*>* */ (int
x) => /*@ typeArgs=String* */ ["hello"];
Function2<int, List<String>>
diff --git a/pkg/front_end/testcases/inference/downwards_inference_on_function_expressions.dart.strong.expect b/pkg/front_end/testcases/inference/downwards_inference_on_function_expressions.dart.strong.expect
index 65b35d1..7c74d42 100644
--- a/pkg/front_end/testcases/inference/downwards_inference_on_function_expressions.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/downwards_inference_on_function_expressions.dart.strong.expect
@@ -64,7 +64,7 @@
typedef Function2<S extends core::Object* = dynamic, T extends core::Object* = dynamic> = (S*) →* T*;
static method test() → void {
{
- (core::int*) →* core::String* l0 = (core::int* x) → core::Null* => null;
+ (core::int*) →* core::String* l0 = (core::int* x) → core::Null? => null;
(core::int*) →* core::String* l1 = (core::int* x) → core::String* => "hello";
(core::int*) →* core::String* l2 = let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_function_expressions.dart:15:69: Error: A value of type 'String Function(String)' can't be assigned to a variable of type 'String Function(int)'.
Try changing the type of the left hand side, or casting the right hand side to 'String Function(int)'.
@@ -82,7 +82,7 @@
};
}
{
- (core::int*) →* core::String* l0 = (core::int* x) → core::Null* => null;
+ (core::int*) →* core::String* l0 = (core::int* x) → core::Null? => null;
(core::int*) →* core::String* l1 = (core::int* x) → core::String* => "hello";
(core::int*) →* core::String* l2 = (core::int* x) → core::String* => let final<BottomType> #t4 = invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_function_expressions.dart:29:13: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
Try changing the type of the left hand side, or casting the right hand side to 'String'.
@@ -102,7 +102,7 @@
};
}
{
- (core::int*) →* core::List<core::String*>* l0 = (core::int* x) → core::Null* => null;
+ (core::int*) →* core::List<core::String*>* l0 = (core::int* x) → core::Null? => null;
(core::int*) →* core::List<core::String*>* l1 = (core::int* x) → core::List<core::String*>* => <core::String*>["hello"];
(core::int*) →* core::List<core::String*>* l2 = let final<BottomType> #t7 = invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_function_expressions.dart:42:76: Error: A value of type 'List<String> Function(String)' can't be assigned to a variable of type 'List<String> Function(int)'.
- 'List' is from 'dart:core'.
diff --git a/pkg/front_end/testcases/inference/downwards_inference_on_function_expressions.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/downwards_inference_on_function_expressions.dart.strong.transformed.expect
index 65b35d1..7c74d42 100644
--- a/pkg/front_end/testcases/inference/downwards_inference_on_function_expressions.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/downwards_inference_on_function_expressions.dart.strong.transformed.expect
@@ -64,7 +64,7 @@
typedef Function2<S extends core::Object* = dynamic, T extends core::Object* = dynamic> = (S*) →* T*;
static method test() → void {
{
- (core::int*) →* core::String* l0 = (core::int* x) → core::Null* => null;
+ (core::int*) →* core::String* l0 = (core::int* x) → core::Null? => null;
(core::int*) →* core::String* l1 = (core::int* x) → core::String* => "hello";
(core::int*) →* core::String* l2 = let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_function_expressions.dart:15:69: Error: A value of type 'String Function(String)' can't be assigned to a variable of type 'String Function(int)'.
Try changing the type of the left hand side, or casting the right hand side to 'String Function(int)'.
@@ -82,7 +82,7 @@
};
}
{
- (core::int*) →* core::String* l0 = (core::int* x) → core::Null* => null;
+ (core::int*) →* core::String* l0 = (core::int* x) → core::Null? => null;
(core::int*) →* core::String* l1 = (core::int* x) → core::String* => "hello";
(core::int*) →* core::String* l2 = (core::int* x) → core::String* => let final<BottomType> #t4 = invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_function_expressions.dart:29:13: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
Try changing the type of the left hand side, or casting the right hand side to 'String'.
@@ -102,7 +102,7 @@
};
}
{
- (core::int*) →* core::List<core::String*>* l0 = (core::int* x) → core::Null* => null;
+ (core::int*) →* core::List<core::String*>* l0 = (core::int* x) → core::Null? => null;
(core::int*) →* core::List<core::String*>* l1 = (core::int* x) → core::List<core::String*>* => <core::String*>["hello"];
(core::int*) →* core::List<core::String*>* l2 = let final<BottomType> #t7 = invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_function_expressions.dart:42:76: Error: A value of type 'List<String> Function(String)' can't be assigned to a variable of type 'List<String> Function(int)'.
- 'List' is from 'dart:core'.
diff --git a/pkg/front_end/testcases/inference/downwards_inference_on_generic_function_expressions.dart b/pkg/front_end/testcases/inference/downwards_inference_on_generic_function_expressions.dart
index 35f9b53..bd01ae5 100644
--- a/pkg/front_end/testcases/inference/downwards_inference_on_generic_function_expressions.dart
+++ b/pkg/front_end/testcases/inference/downwards_inference_on_generic_function_expressions.dart
@@ -9,7 +9,7 @@
{
String f<S>(int x) => null;
var /*@ type=<S extends Object* = dynamic>(int*) ->* String* */ v = f;
- v = <T> /*@ returnType=Null* */ (int x) => null;
+ v = <T> /*@ returnType=Null? */ (int x) => null;
v = <T> /*@ returnType=String* */ (int x) => "hello";
v = /*error:INVALID_ASSIGNMENT*/ <T> /*@ returnType=String* */ (String x) =>
"hello";
@@ -21,7 +21,7 @@
{
String f<S>(int x) => null;
var /*@ type=<S extends Object* = dynamic>(int*) ->* String* */ v = f;
- v = <T> /*@ returnType=Null* */ (/*@ type=int* */ x) => null;
+ v = <T> /*@ returnType=Null? */ (/*@ type=int* */ x) => null;
v = <T> /*@ returnType=String* */ (/*@ type=int* */ x) => "hello";
v = /*info:INFERRED_TYPE_CLOSURE, error:INVALID_ASSIGNMENT*/ <
T> /*@ returnType=String* */ (/*@ type=int* */ x) =>
@@ -36,7 +36,7 @@
{
List<String> f<S>(int x) => null;
var /*@ type=<S extends Object* = dynamic>(int*) ->* List<String*>* */ v = f;
- v = <T> /*@ returnType=Null* */ (int x) => null;
+ v = <T> /*@ returnType=Null? */ (int x) => null;
v = <T> /*@ returnType=List<String*>* */ (int x) => /*@ typeArgs=String* */ [
"hello"
];
diff --git a/pkg/front_end/testcases/inference/downwards_inference_on_generic_function_expressions.dart.strong.expect b/pkg/front_end/testcases/inference/downwards_inference_on_generic_function_expressions.dart.strong.expect
index e415ae5..3adb8ba 100644
--- a/pkg/front_end/testcases/inference/downwards_inference_on_generic_function_expressions.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/downwards_inference_on_generic_function_expressions.dart.strong.expect
@@ -66,7 +66,7 @@
function f<S extends core::Object* = dynamic>(core::int* x) → core::String*
return null;
<S extends core::Object* = dynamic>(core::int*) →* core::String* v = f;
- v = <T extends core::Object* = dynamic>(core::int* x) → core::Null* => null;
+ v = <T extends core::Object* = dynamic>(core::int* x) → core::Null? => null;
v = <T extends core::Object* = dynamic>(core::int* x) → core::String* => "hello";
v = let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_generic_function_expressions.dart:14:68: Error: A value of type 'String Function<T>(String)' can't be assigned to a variable of type 'String Function<S>(int)'.
Try changing the type of the left hand side, or casting the right hand side to 'String Function<S>(int)'.
@@ -87,7 +87,7 @@
function f<S extends core::Object* = dynamic>(core::int* x) → core::String*
return null;
<S extends core::Object* = dynamic>(core::int*) →* core::String* v = f;
- v = <T extends core::Object* = dynamic>(core::int* x) → core::Null* => null;
+ v = <T extends core::Object* = dynamic>(core::int* x) → core::Null? => null;
v = <T extends core::Object* = dynamic>(core::int* x) → core::String* => "hello";
v = <T extends core::Object* = dynamic>(core::int* x) → core::String* => let final<BottomType> #t4 = invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_generic_function_expressions.dart:28:9: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
Try changing the type of the left hand side, or casting the right hand side to 'String'.
@@ -110,7 +110,7 @@
function f<S extends core::Object* = dynamic>(core::int* x) → core::List<core::String*>*
return null;
<S extends core::Object* = dynamic>(core::int*) →* core::List<core::String*>* v = f;
- v = <T extends core::Object* = dynamic>(core::int* x) → core::Null* => null;
+ v = <T extends core::Object* = dynamic>(core::int* x) → core::Null? => null;
v = <T extends core::Object* = dynamic>(core::int* x) → core::List<core::String*>* => <core::String*>["hello"];
v = let final<BottomType> #t7 = invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_generic_function_expressions.dart:43:75: Error: A value of type 'List<String> Function<T>(String)' can't be assigned to a variable of type 'List<String> Function<S>(int)'.
- 'List' is from 'dart:core'.
diff --git a/pkg/front_end/testcases/inference/downwards_inference_on_generic_function_expressions.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/downwards_inference_on_generic_function_expressions.dart.strong.transformed.expect
index e415ae5..3adb8ba 100644
--- a/pkg/front_end/testcases/inference/downwards_inference_on_generic_function_expressions.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/downwards_inference_on_generic_function_expressions.dart.strong.transformed.expect
@@ -66,7 +66,7 @@
function f<S extends core::Object* = dynamic>(core::int* x) → core::String*
return null;
<S extends core::Object* = dynamic>(core::int*) →* core::String* v = f;
- v = <T extends core::Object* = dynamic>(core::int* x) → core::Null* => null;
+ v = <T extends core::Object* = dynamic>(core::int* x) → core::Null? => null;
v = <T extends core::Object* = dynamic>(core::int* x) → core::String* => "hello";
v = let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_generic_function_expressions.dart:14:68: Error: A value of type 'String Function<T>(String)' can't be assigned to a variable of type 'String Function<S>(int)'.
Try changing the type of the left hand side, or casting the right hand side to 'String Function<S>(int)'.
@@ -87,7 +87,7 @@
function f<S extends core::Object* = dynamic>(core::int* x) → core::String*
return null;
<S extends core::Object* = dynamic>(core::int*) →* core::String* v = f;
- v = <T extends core::Object* = dynamic>(core::int* x) → core::Null* => null;
+ v = <T extends core::Object* = dynamic>(core::int* x) → core::Null? => null;
v = <T extends core::Object* = dynamic>(core::int* x) → core::String* => "hello";
v = <T extends core::Object* = dynamic>(core::int* x) → core::String* => let final<BottomType> #t4 = invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_generic_function_expressions.dart:28:9: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
Try changing the type of the left hand side, or casting the right hand side to 'String'.
@@ -110,7 +110,7 @@
function f<S extends core::Object* = dynamic>(core::int* x) → core::List<core::String*>*
return null;
<S extends core::Object* = dynamic>(core::int*) →* core::List<core::String*>* v = f;
- v = <T extends core::Object* = dynamic>(core::int* x) → core::Null* => null;
+ v = <T extends core::Object* = dynamic>(core::int* x) → core::Null? => null;
v = <T extends core::Object* = dynamic>(core::int* x) → core::List<core::String*>* => <core::String*>["hello"];
v = let final<BottomType> #t7 = invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_generic_function_expressions.dart:43:75: Error: A value of type 'List<String> Function<T>(String)' can't be assigned to a variable of type 'List<String> Function<S>(int)'.
- 'List' is from 'dart:core'.
diff --git a/pkg/front_end/testcases/inference/downwards_inference_on_generic_function_expressions.dart.type_promotion.expect b/pkg/front_end/testcases/inference/downwards_inference_on_generic_function_expressions.dart.type_promotion.expect
index 5f2ce87..370bfb82 100644
--- a/pkg/front_end/testcases/inference/downwards_inference_on_generic_function_expressions.dart.type_promotion.expect
+++ b/pkg/front_end/testcases/inference/downwards_inference_on_generic_function_expressions.dart.type_promotion.expect
@@ -1,5 +1,5 @@
pkg/front_end/testcases/inference/downwards_inference_on_generic_function_expressions.dart:12:7: Context: Write to v@380
- v = <T> /*@ returnType=Null* */ (int x) => null;
+ v = <T> /*@ returnType=Null? */ (int x) => null;
^
pkg/front_end/testcases/inference/downwards_inference_on_generic_function_expressions.dart:13:7: Context: Write to v@380
v = <T> /*@ returnType=String* */ (int x) => "hello";
@@ -14,7 +14,7 @@
v = <T> /*@ returnType=String* */ (int x) {
^
pkg/front_end/testcases/inference/downwards_inference_on_generic_function_expressions.dart:24:7: Context: Write to v@889
- v = <T> /*@ returnType=Null* */ (/*@ type=int* */ x) => null;
+ v = <T> /*@ returnType=Null? */ (/*@ type=int* */ x) => null;
^
pkg/front_end/testcases/inference/downwards_inference_on_generic_function_expressions.dart:25:7: Context: Write to v@889
v = <T> /*@ returnType=String* */ (/*@ type=int* */ x) => "hello";
@@ -29,7 +29,7 @@
v = <T> /*@ returnType=String* */ (/*@ type=int* */ x) {
^
pkg/front_end/testcases/inference/downwards_inference_on_generic_function_expressions.dart:39:7: Context: Write to v@1531
- v = <T> /*@ returnType=Null* */ (int x) => null;
+ v = <T> /*@ returnType=Null? */ (int x) => null;
^
pkg/front_end/testcases/inference/downwards_inference_on_generic_function_expressions.dart:40:7: Context: Write to v@1531
v = <T> /*@ returnType=List<String*>* */ (int x) => /*@ typeArgs=String* */ [
diff --git a/pkg/front_end/testcases/inference/for_loop_empty_condition.dart b/pkg/front_end/testcases/inference/for_loop_empty_condition.dart
index ee2a836..95f321e 100644
--- a/pkg/front_end/testcases/inference/for_loop_empty_condition.dart
+++ b/pkg/front_end/testcases/inference/for_loop_empty_condition.dart
@@ -6,7 +6,7 @@
library test;
void test() {
- for (num x = 0;; x++) {
+ for (num x = 0;; x /*@ target=num::+ */ ++) {
if (x /*@target=num::>=*/ >= 10) break;
if (x is int) {
var /*@ type=int* */ y = /*@ promotedType=int* */ x;
diff --git a/pkg/front_end/testcases/inference/for_loop_empty_condition.dart.type_promotion.expect b/pkg/front_end/testcases/inference/for_loop_empty_condition.dart.type_promotion.expect
index 8598d0c..3f8990b 100644
--- a/pkg/front_end/testcases/inference/for_loop_empty_condition.dart.type_promotion.expect
+++ b/pkg/front_end/testcases/inference/for_loop_empty_condition.dart.type_promotion.expect
@@ -1,6 +1,6 @@
-pkg/front_end/testcases/inference/for_loop_empty_condition.dart:9:21: Context: Write to x@287
- for (num x = 0;; x++) {
- ^^
+pkg/front_end/testcases/inference/for_loop_empty_condition.dart:9:43: Context: Write to x@287
+ for (num x = 0;; x /*@ target=num::+ */ ++) {
+ ^^
pkg/front_end/testcases/inference/for_loop_empty_condition.dart:11:11: Context: Possible promotion of x@287
if (x is int) {
^^
diff --git a/pkg/front_end/testcases/inference/for_loop_initializer_expression.dart b/pkg/front_end/testcases/inference/for_loop_initializer_expression.dart
index 4aa9f97..28684ac 100644
--- a/pkg/front_end/testcases/inference/for_loop_initializer_expression.dart
+++ b/pkg/front_end/testcases/inference/for_loop_initializer_expression.dart
@@ -7,7 +7,7 @@
void test() {
num x;
- for (x = 0; x /*@target=num::<*/ < 10; x++) {
+ for (x = 0; x /*@target=num::<*/ < 10; x /*@ target=num::+ */ ++) {
if (x is int) {
var /*@ type=int* */ y = /*@ promotedType=int* */ x;
}
diff --git a/pkg/front_end/testcases/inference/for_loop_initializer_expression.dart.type_promotion.expect b/pkg/front_end/testcases/inference/for_loop_initializer_expression.dart.type_promotion.expect
index 84d17d3..0a6dba0 100644
--- a/pkg/front_end/testcases/inference/for_loop_initializer_expression.dart.type_promotion.expect
+++ b/pkg/front_end/testcases/inference/for_loop_initializer_expression.dart.type_promotion.expect
@@ -1,9 +1,9 @@
pkg/front_end/testcases/inference/for_loop_initializer_expression.dart:10:10: Context: Write to x@282
- for (x = 0; x /*@target=num::<*/ < 10; x++) {
+ for (x = 0; x /*@target=num::<*/ < 10; x /*@ target=num::+ */ ++) {
^
-pkg/front_end/testcases/inference/for_loop_initializer_expression.dart:10:43: Context: Write to x@282
- for (x = 0; x /*@target=num::<*/ < 10; x++) {
- ^^
+pkg/front_end/testcases/inference/for_loop_initializer_expression.dart:10:65: Context: Write to x@282
+ for (x = 0; x /*@target=num::<*/ < 10; x /*@ target=num::+ */ ++) {
+ ^^
pkg/front_end/testcases/inference/for_loop_initializer_expression.dart:11:11: Context: Possible promotion of x@282
if (x is int) {
^^
diff --git a/pkg/front_end/testcases/inference/for_loop_promotion.dart b/pkg/front_end/testcases/inference/for_loop_promotion.dart
index 3aa1cd8..e134425 100644
--- a/pkg/front_end/testcases/inference/for_loop_promotion.dart
+++ b/pkg/front_end/testcases/inference/for_loop_promotion.dart
@@ -6,7 +6,7 @@
library test;
void test() {
- for (num x = 0; x /*@target=num::<*/ < 10; x++) {
+ for (num x = 0; x /*@target=num::<*/ < 10; x /*@ target=num::+ */ ++) {
if (x is int) {
var /*@ type=int* */ y = /*@ promotedType=int* */ x;
}
diff --git a/pkg/front_end/testcases/inference/for_loop_promotion.dart.type_promotion.expect b/pkg/front_end/testcases/inference/for_loop_promotion.dart.type_promotion.expect
index 5cf87fe..9171867 100644
--- a/pkg/front_end/testcases/inference/for_loop_promotion.dart.type_promotion.expect
+++ b/pkg/front_end/testcases/inference/for_loop_promotion.dart.type_promotion.expect
@@ -1,6 +1,6 @@
-pkg/front_end/testcases/inference/for_loop_promotion.dart:9:47: Context: Write to x@287
- for (num x = 0; x /*@target=num::<*/ < 10; x++) {
- ^^
+pkg/front_end/testcases/inference/for_loop_promotion.dart:9:69: Context: Write to x@287
+ for (num x = 0; x /*@target=num::<*/ < 10; x /*@ target=num::+ */ ++) {
+ ^^
pkg/front_end/testcases/inference/for_loop_promotion.dart:10:11: Context: Possible promotion of x@287
if (x is int) {
^^
diff --git a/pkg/front_end/testcases/inference/future_then_downwards_method_target.dart b/pkg/front_end/testcases/inference/future_then_downwards_method_target.dart
index f7d4cd3..0477b7b 100644
--- a/pkg/front_end/testcases/inference/future_then_downwards_method_target.dart
+++ b/pkg/front_end/testcases/inference/future_then_downwards_method_target.dart
@@ -13,7 +13,7 @@
. /*@ typeArgs=List<dynamic>* */ /*@target=Future::then*/ then(
/*@ returnType=List<dynamic>* */ (/*@ type=int* */ x) => /*@ typeArgs=dynamic */ [])
. /*@target=Future::whenComplete*/ whenComplete(
- /*@ returnType=Null* */ () {});
+ /*@ returnType=Null? */ () {});
b = f. /*@ typeArgs=List<int*>* */ /*@target=Future::then*/ then(
/*@ returnType=List<int*>* */ (/*@ type=int* */ x) => /*@ typeArgs=int* */ []);
}
diff --git a/pkg/front_end/testcases/inference/future_then_downwards_method_target.dart.strong.expect b/pkg/front_end/testcases/inference/future_then_downwards_method_target.dart.strong.expect
index a535e1e..e129de8 100644
--- a/pkg/front_end/testcases/inference/future_then_downwards_method_target.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/future_then_downwards_method_target.dart.strong.expect
@@ -7,7 +7,7 @@
static method test() → dynamic {
asy::Future<core::int*>* f;
- asy::Future<core::List<core::int*>*>* b = f.{asy::Future::then}<core::List<dynamic>*>((core::int* x) → core::List<dynamic>* => <dynamic>[]).{asy::Future::whenComplete}(() → core::Null* {}) as{TypeError} asy::Future<core::List<core::int*>*>*;
+ asy::Future<core::List<core::int*>*>* b = f.{asy::Future::then}<core::List<dynamic>*>((core::int* x) → core::List<dynamic>* => <dynamic>[]).{asy::Future::whenComplete}(() → core::Null? {}) as{TypeError} asy::Future<core::List<core::int*>*>*;
b = f.{asy::Future::then}<core::List<core::int*>*>((core::int* x) → core::List<core::int*>* => <core::int*>[]);
}
static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/future_then_downwards_method_target.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/future_then_downwards_method_target.dart.strong.transformed.expect
index a535e1e..e129de8 100644
--- a/pkg/front_end/testcases/inference/future_then_downwards_method_target.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_then_downwards_method_target.dart.strong.transformed.expect
@@ -7,7 +7,7 @@
static method test() → dynamic {
asy::Future<core::int*>* f;
- asy::Future<core::List<core::int*>*>* b = f.{asy::Future::then}<core::List<dynamic>*>((core::int* x) → core::List<dynamic>* => <dynamic>[]).{asy::Future::whenComplete}(() → core::Null* {}) as{TypeError} asy::Future<core::List<core::int*>*>*;
+ asy::Future<core::List<core::int*>*>* b = f.{asy::Future::then}<core::List<dynamic>*>((core::int* x) → core::List<dynamic>* => <dynamic>[]).{asy::Future::whenComplete}(() → core::Null? {}) as{TypeError} asy::Future<core::List<core::int*>*>*;
b = f.{asy::Future::then}<core::List<core::int*>*>((core::int* x) → core::List<core::int*>* => <core::int*>[]);
}
static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/generic_methods_uses_greatest_lower_bound.dart b/pkg/front_end/testcases/inference/generic_methods_uses_greatest_lower_bound.dart
index be4bd21..34aede8 100644
--- a/pkg/front_end/testcases/inference/generic_methods_uses_greatest_lower_bound.dart
+++ b/pkg/front_end/testcases/inference/generic_methods_uses_greatest_lower_bound.dart
@@ -12,6 +12,6 @@
main() {
var /*@ type=(num*) ->* List<int*>* */ v = /*@ typeArgs=(num*) ->* List<int*>* */ generic(
- /*@ returnType=Null* */ (F f) => null,
- /*@ returnType=Null* */ (G g) => null);
+ /*@ returnType=Null? */ (F f) => null,
+ /*@ returnType=Null? */ (G g) => null);
}
diff --git a/pkg/front_end/testcases/inference/generic_methods_uses_greatest_lower_bound.dart.strong.expect b/pkg/front_end/testcases/inference/generic_methods_uses_greatest_lower_bound.dart.strong.expect
index e8ba7cf..4a105fb 100644
--- a/pkg/front_end/testcases/inference/generic_methods_uses_greatest_lower_bound.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/generic_methods_uses_greatest_lower_bound.dart.strong.expect
@@ -7,5 +7,5 @@
static method generic<T extends core::Object* = dynamic>((self::generic::T*) →* dynamic a, (self::generic::T*) →* dynamic b) → self::generic::T*
return null;
static method main() → dynamic {
- (core::num*) →* core::List<core::int*>* v = self::generic<(core::num*) →* core::List<core::int*>*>(((core::int*) →* core::Iterable<core::num*>* f) → core::Null* => null, ((core::double*) →* core::List<core::int*>* g) → core::Null* => null);
+ (core::num*) →* core::List<core::int*>* v = self::generic<(core::num*) →* core::List<core::int*>*>(((core::int*) →* core::Iterable<core::num*>* f) → core::Null? => null, ((core::double*) →* core::List<core::int*>* g) → core::Null? => null);
}
diff --git a/pkg/front_end/testcases/inference/generic_methods_uses_greatest_lower_bound.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/generic_methods_uses_greatest_lower_bound.dart.strong.transformed.expect
index e8ba7cf..4a105fb 100644
--- a/pkg/front_end/testcases/inference/generic_methods_uses_greatest_lower_bound.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/generic_methods_uses_greatest_lower_bound.dart.strong.transformed.expect
@@ -7,5 +7,5 @@
static method generic<T extends core::Object* = dynamic>((self::generic::T*) →* dynamic a, (self::generic::T*) →* dynamic b) → self::generic::T*
return null;
static method main() → dynamic {
- (core::num*) →* core::List<core::int*>* v = self::generic<(core::num*) →* core::List<core::int*>*>(((core::int*) →* core::Iterable<core::num*>* f) → core::Null* => null, ((core::double*) →* core::List<core::int*>* g) → core::Null* => null);
+ (core::num*) →* core::List<core::int*>* v = self::generic<(core::num*) →* core::List<core::int*>*>(((core::int*) →* core::Iterable<core::num*>* f) → core::Null? => null, ((core::double*) →* core::List<core::int*>* g) → core::Null? => null);
}
diff --git a/pkg/front_end/testcases/inference/infer_assign_to_implicit_this.dart b/pkg/front_end/testcases/inference/infer_assign_to_implicit_this.dart
index 74bb832..118957d 100644
--- a/pkg/front_end/testcases/inference/infer_assign_to_implicit_this.dart
+++ b/pkg/front_end/testcases/inference/infer_assign_to_implicit_this.dart
@@ -23,17 +23,34 @@
void test() {
/*@target=Test::member*/ member = /*@ typeArgs=B* */ f();
- /*@target=Test::member*/ member ??= /*@ typeArgs=B* */ f();
+
+ /*@target=Test::member*/ /*@target=Test::member*/ member
+ /*@ target=Object::== */ ??= /*@ typeArgs=B* */ f();
+
/*@target=Test::member*/ member += /*@ typeArgs=dynamic */ f();
+
/*@target=Test::member*/ member *= /*@ typeArgs=dynamic */ f();
+
/*@target=Test::member*/ member &= /*@ typeArgs=dynamic */ f();
+
-- /*@target=Test::member*/ member;
+
/*@target=Test::member*/ member--;
- var /*@ type=B* */ v1 = /*@target=Test::member*/ member = /*@ typeArgs=B* */ f();
- var /*@ type=B* */ v2 = /*@target=Test::member*/ member ??= /*@ typeArgs=B* */ f();
- var /*@ type=B* */ v4 = /*@target=Test::member*/ member *= /*@ typeArgs=dynamic */ f();
- var /*@ type=C* */ v5 = /*@target=Test::member*/ member &= /*@ typeArgs=dynamic */ f();
+
+ var /*@ type=B* */ v1 = /*@target=Test::member*/ member =
+ /*@ typeArgs=B* */ f();
+
+ var /*@ type=B* */ v2 = /*@target=Test::member*/ /*@target=Test::member*/
+ member /*@ target=Object::== */ ??= /*@ typeArgs=B* */ f();
+
+ var /*@ type=B* */ v4 = /*@target=Test::member*/ member *=
+ /*@ typeArgs=dynamic */ f();
+
+ var /*@ type=C* */ v5 = /*@target=Test::member*/ member &=
+ /*@ typeArgs=dynamic */ f();
+
var /*@ type=B* */ v6 = -- /*@target=Test::member*/ member;
+
var /*@ type=B* */ v7 = /*@target=Test::member*/ member--;
}
}
diff --git a/pkg/front_end/testcases/inference/infer_assign_to_implicit_this_upwards.dart b/pkg/front_end/testcases/inference/infer_assign_to_implicit_this_upwards.dart
index d60a4c3..0f111a2 100644
--- a/pkg/front_end/testcases/inference/infer_assign_to_implicit_this_upwards.dart
+++ b/pkg/front_end/testcases/inference/infer_assign_to_implicit_this_upwards.dart
@@ -14,9 +14,14 @@
void test() {
var /*@ type=int* */ v1 = /*@target=Test1::t*/ t = getInt();
- var /*@ type=int* */ v4 = /*@target=Test1::t*/ t ??= getInt();
+
+ var /*@ type=int* */ v4 = /*@target=Test1::t*/ /*@target=Test1::t*/ t
+ /*@ target=num::== */ ??= getInt();
+
var /*@ type=int* */ v7 = /*@target=Test1::t*/ t += getInt();
+
var /*@ type=int* */ v10 = ++ /*@target=Test1::t*/ t;
+
var /*@ type=int* */ v11 = /*@target=Test1::t*/ t++;
}
}
@@ -26,15 +31,28 @@
void test() {
var /*@ type=int* */ v1 = /*@target=Test2::t*/ t = getInt();
+
var /*@ type=num* */ v2 = /*@target=Test2::t*/ t = getNum();
+
var /*@ type=double* */ v3 = /*@target=Test2::t*/ t = getDouble();
- var /*@ type=num* */ v4 = /*@target=Test2::t*/ t ??= getInt();
- var /*@ type=num* */ v5 = /*@target=Test2::t*/ t ??= getNum();
- var /*@ type=num* */ v6 = /*@target=Test2::t*/ t ??= getDouble();
+
+ var /*@ type=num* */ v4 = /*@target=Test2::t*/ /*@target=Test2::t*/ t
+ /*@ target=num::== */ ??= getInt();
+
+ var /*@ type=num* */ v5 = /*@target=Test2::t*/ /*@target=Test2::t*/ t
+ /*@ target=num::== */ ??= getNum();
+
+ var /*@ type=num* */ v6 = /*@target=Test2::t*/ /*@target=Test2::t*/ t
+ /*@ target=num::== */ ??= getDouble();
+
var /*@ type=num* */ v7 = /*@target=Test2::t*/ t += getInt();
+
var /*@ type=num* */ v8 = /*@target=Test2::t*/ t += getNum();
+
var /*@ type=num* */ v9 = /*@target=Test2::t*/ t += getDouble();
+
var /*@ type=num* */ v10 = ++ /*@target=Test2::t*/ t;
+
var /*@ type=num* */ v11 = /*@target=Test2::t*/ t++;
}
}
@@ -44,11 +62,18 @@
void test3() {
var /*@ type=double* */ v3 = /*@target=Test3::t*/ t = getDouble();
- var /*@ type=double* */ v6 = /*@target=Test3::t*/ t ??= getDouble();
+
+ var /*@ type=double* */ v6 = /*@target=Test3::t*/ /*@target=Test3::t*/ t
+ /*@ target=num::== */ ??= getDouble();
+
var /*@ type=double* */ v7 = /*@target=Test3::t*/ t += getInt();
+
var /*@ type=double* */ v8 = /*@target=Test3::t*/ t += getNum();
+
var /*@ type=double* */ v9 = /*@target=Test3::t*/ t += getDouble();
+
var /*@ type=double* */ v10 = ++ /*@target=Test3::t*/ t;
+
var /*@ type=double* */ v11 = /*@target=Test3::t*/ t++;
}
}
diff --git a/pkg/front_end/testcases/inference/infer_assign_to_index_full.dart b/pkg/front_end/testcases/inference/infer_assign_to_index_full.dart
index 16a2336..d344928 100644
--- a/pkg/front_end/testcases/inference/infer_assign_to_index_full.dart
+++ b/pkg/front_end/testcases/inference/infer_assign_to_index_full.dart
@@ -26,26 +26,55 @@
void test() {
Test t = /*@ typeArgs=Test* */ f();
- t /*@target=Test::[]=*/ [/*@ typeArgs=dynamic */ f()] = /*@ typeArgs=B* */ f();
- t /*@target=Test::[]=*/ [/*@ typeArgs=dynamic */ f()] ??= /*@ typeArgs=B* */ f();
+
t /*@target=Test::[]=*/ [
- /*@ typeArgs=dynamic */ f()] += /*@ typeArgs=dynamic */ f();
- t /*@target=Test::[]=*/ [
- /*@ typeArgs=dynamic */ f()] *= /*@ typeArgs=dynamic */ f();
- t /*@target=Test::[]=*/ [
- /*@ typeArgs=dynamic */ f()] &= /*@ typeArgs=dynamic */ f();
- --t /*@target=Test::[]=*/ [/*@ typeArgs=dynamic */ f()];
- t /*@target=Test::[]=*/ [/*@ typeArgs=dynamic */ f()]--;
+ /*@ typeArgs=Index* */ f()] = /*@ typeArgs=B* */ f();
+
+ t /*@target=Test::[]*/ [/*@ typeArgs=Index* */ f()]
+ /*@ target=Object::== */ /*@ target=Test::[]= */
+ ??= /*@ typeArgs=B* */ f();
+
+ t /*@target=Test::[]*/ /*@target=Test::[]=*/ [/*@ typeArgs=Index* */ f()]
+ /*@ target=B::+ */ += /*@ typeArgs=C* */ f();
+
+ t /*@target=Test::[]*/ /*@target=Test::[]=*/ [/*@ typeArgs=Index* */ f()]
+ /*@ target=B::* */ *= /*@ typeArgs=B* */ f();
+
+ t /*@target=Test::[]*/ /*@target=Test::[]=*/ [/*@ typeArgs=Index* */ f()]
+ /*@ target=B::& */ &= /*@ typeArgs=A* */ f();
+
+ t /*@target=Test::[]*/ [/*@ typeArgs=Index* */ f()];
+
+ /*@ target=B::- */ --t /*@target=Test::[]*/ /*@target=Test::[]=*/ [
+ /*@ typeArgs=Index* */ f()];
+
+ t /*@target=Test::[]*/ /*@target=Test::[]=*/ [
+ /*@ typeArgs=Index* */ f()] /*@ target=B::- */ --;
+
var /*@ type=B* */ v1 = t /*@target=Test::[]=*/ [
- /*@ typeArgs=dynamic */ f()] = /*@ typeArgs=B* */ f();
- var /*@ type=B* */ v2 = t /*@target=Test::[]=*/ [
- /*@ typeArgs=dynamic */ f()] ??= /*@ typeArgs=B* */ f();
- var /*@ type=B* */ v4 = t /*@target=Test::[]=*/ [
- /*@ typeArgs=dynamic */ f()] *= /*@ typeArgs=dynamic */ f();
- var /*@ type=C* */ v5 = t /*@target=Test::[]=*/ [
- /*@ typeArgs=dynamic */ f()] &= /*@ typeArgs=dynamic */ f();
- var /*@ type=B* */ v6 = --t /*@target=Test::[]=*/ [/*@ typeArgs=dynamic */ f()];
- var /*@ type=B* */ v7 = t /*@target=Test::[]=*/ [/*@ typeArgs=dynamic */ f()]--;
+ /*@ typeArgs=Index* */ f()] = /*@ typeArgs=B* */ f();
+
+ var /*@ type=B* */ v2 = t /*@target=Test::[]*/ [
+ /*@ typeArgs=Index* */ f()]
+ /*@ target=Object::== */ /*@ target=Test::[]= */
+ ??= /*@ typeArgs=B* */ f();
+
+ var /*@ type=B* */ v4 = t /*@target=Test::[]*/ /*@target=Test::[]=*/ [
+ /*@ typeArgs=Index* */ f()]
+ /*@ target=B::* */ *= /*@ typeArgs=B* */ f();
+
+ var /*@ type=C* */ v5 = t /*@target=Test::[]*/ /*@target=Test::[]=*/ [
+ /*@ typeArgs=Index* */ f()]
+ /*@ target=B::& */ &= /*@ typeArgs=A* */ f();
+
+ var /*@ type=B* */ v6 = t /*@target=Test::[]*/ [/*@ typeArgs=Index* */ f()];
+
+ var /*@ type=B* */ v7 =
+ /*@ target=B::- */ --t /*@target=Test::[]*/ /*@target=Test::[]=*/ [
+ /*@ typeArgs=Index* */ f()];
+
+ var /*@ type=B* */ v8 = t /*@target=Test::[]*/ /*@target=Test::[]=*/ [
+ /*@ typeArgs=Index* */ f()] /*@ target=B::- */ --;
}
}
diff --git a/pkg/front_end/testcases/inference/infer_assign_to_index_full.dart.strong.expect b/pkg/front_end/testcases/inference/infer_assign_to_index_full.dart.strong.expect
index 40716cc..4711ea5 100644
--- a/pkg/front_end/testcases/inference/infer_assign_to_index_full.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/infer_assign_to_index_full.dart.strong.expect
@@ -39,19 +39,21 @@
operator []=(self::Index* i, self::B* v) → void {}
method test() → void {
self::Test* t = self::f<self::Test*>();
- t.{self::Test::[]=}(self::f<dynamic>() as{TypeError} self::Index*, self::f<self::B*>());
- let final self::Test* #t1 = t in let final dynamic #t2 = self::f<dynamic>() in #t1.{self::Test::[]}(#t2 as{TypeError} self::Index*).{core::Object::==}(null) ?{self::B*} let final self::B* #t3 = self::f<self::B*>() in let final void #t4 = #t1.{self::Test::[]=}(#t2 as{TypeError} self::Index*, #t3) in #t3 : null;
- let final self::Test* #t5 = t in let final dynamic #t6 = self::f<dynamic>() in #t5.{self::Test::[]=}(#t6 as{TypeError} self::Index*, #t5.{self::Test::[]}(#t6 as{TypeError} self::Index*).{self::B::+}(self::f<dynamic>() as{TypeError} self::C*) as{TypeError} self::B*);
- let final self::Test* #t7 = t in let final dynamic #t8 = self::f<dynamic>() in #t7.{self::Test::[]=}(#t8 as{TypeError} self::Index*, #t7.{self::Test::[]}(#t8 as{TypeError} self::Index*).{self::B::*}(self::f<dynamic>() as{TypeError} self::B*));
- let final self::Test* #t9 = t in let final dynamic #t10 = self::f<dynamic>() in #t9.{self::Test::[]=}(#t10 as{TypeError} self::Index*, #t9.{self::Test::[]}(#t10 as{TypeError} self::Index*).{self::B::&}(self::f<dynamic>() as{TypeError} self::A*));
- let final self::Test* #t11 = t in let final dynamic #t12 = self::f<dynamic>() in let final self::B* #t13 = #t11.{self::Test::[]}(#t12 as{TypeError} self::Index*).{self::B::-}(1) in let final void #t14 = #t11.{self::Test::[]=}(#t12 as{TypeError} self::Index*, #t13) in #t13;
- let final self::Test* #t15 = t in let final dynamic #t16 = self::f<dynamic>() in #t15.{self::Test::[]=}(#t16 as{TypeError} self::Index*, #t15.{self::Test::[]}(#t16 as{TypeError} self::Index*).{self::B::-}(1));
- self::B* v1 = let final self::Test* #t17 = t in let final dynamic #t18 = self::f<dynamic>() in let final self::B* #t19 = self::f<self::B*>() in let final void #t20 = #t17.{self::Test::[]=}(#t18 as{TypeError} self::Index*, #t19) in #t19;
- self::B* v2 = let final self::Test* #t21 = t in let final dynamic #t22 = self::f<dynamic>() in let final self::B* #t23 = #t21.{self::Test::[]}(#t22 as{TypeError} self::Index*) in #t23.{core::Object::==}(null) ?{self::B*} let final self::B* #t24 = self::f<self::B*>() in let final void #t25 = #t21.{self::Test::[]=}(#t22 as{TypeError} self::Index*, #t24) in #t24 : #t23;
- self::B* v4 = let final self::Test* #t26 = t in let final dynamic #t27 = self::f<dynamic>() in let final self::B* #t28 = #t26.{self::Test::[]}(#t27 as{TypeError} self::Index*).{self::B::*}(self::f<dynamic>() as{TypeError} self::B*) in let final void #t29 = #t26.{self::Test::[]=}(#t27 as{TypeError} self::Index*, #t28) in #t28;
- self::C* v5 = let final self::Test* #t30 = t in let final dynamic #t31 = self::f<dynamic>() in let final self::C* #t32 = #t30.{self::Test::[]}(#t31 as{TypeError} self::Index*).{self::B::&}(self::f<dynamic>() as{TypeError} self::A*) in let final void #t33 = #t30.{self::Test::[]=}(#t31 as{TypeError} self::Index*, #t32) in #t32;
- self::B* v6 = let final self::Test* #t34 = t in let final dynamic #t35 = self::f<dynamic>() in let final self::B* #t36 = #t34.{self::Test::[]}(#t35 as{TypeError} self::Index*).{self::B::-}(1) in let final void #t37 = #t34.{self::Test::[]=}(#t35 as{TypeError} self::Index*, #t36) in #t36;
- self::B* v7 = let final self::Test* #t38 = t in let final dynamic #t39 = self::f<dynamic>() in let final self::B* #t40 = #t38.{self::Test::[]}(#t39 as{TypeError} self::Index*) in let final void #t41 = #t38.{self::Test::[]=}(#t39 as{TypeError} self::Index*, #t40.{self::B::-}(1)) in #t40;
+ t.{self::Test::[]=}(self::f<self::Index*>(), self::f<self::B*>());
+ let final self::Test* #t1 = t in let final self::Index* #t2 = self::f<self::Index*>() in #t1.{self::Test::[]}(#t2).{core::Object::==}(null) ?{self::B*} #t1.{self::Test::[]=}(#t2, self::f<self::B*>()) : null;
+ let final self::Test* #t3 = t in let final self::Index* #t4 = self::f<self::Index*>() in #t3.{self::Test::[]=}(#t4, #t3.{self::Test::[]}(#t4).{self::B::+}(self::f<self::C*>()) as{TypeError} self::B*);
+ let final self::Test* #t5 = t in let final self::Index* #t6 = self::f<self::Index*>() in #t5.{self::Test::[]=}(#t6, #t5.{self::Test::[]}(#t6).{self::B::*}(self::f<self::B*>()));
+ let final self::Test* #t7 = t in let final self::Index* #t8 = self::f<self::Index*>() in #t7.{self::Test::[]=}(#t8, #t7.{self::Test::[]}(#t8).{self::B::&}(self::f<self::A*>()));
+ t.{self::Test::[]}(self::f<self::Index*>());
+ let final self::Test* #t9 = t in let final self::Index* #t10 = self::f<self::Index*>() in let final self::B* #t11 = #t9.{self::Test::[]}(#t10).{self::B::-}(1) in let final void #t12 = #t9.{self::Test::[]=}(#t10, #t11) in #t11;
+ let final self::Test* #t13 = t in let final self::Index* #t14 = self::f<self::Index*>() in #t13.{self::Test::[]=}(#t14, #t13.{self::Test::[]}(#t14).{self::B::-}(1));
+ self::B* v1 = let final self::Test* #t15 = t in let final self::Index* #t16 = self::f<self::Index*>() in let final self::B* #t17 = self::f<self::B*>() in let final void #t18 = #t15.{self::Test::[]=}(#t16, #t17) in #t17;
+ self::B* v2 = let final self::Test* #t19 = t in let final self::Index* #t20 = self::f<self::Index*>() in let final self::B* #t21 = #t19.{self::Test::[]}(#t20) in #t21.{core::Object::==}(null) ?{self::B*} let final self::B* #t22 = self::f<self::B*>() in let final void #t23 = #t19.{self::Test::[]=}(#t20, #t22) in #t22 : #t21;
+ self::B* v4 = let final self::Test* #t24 = t in let final self::Index* #t25 = self::f<self::Index*>() in let final self::B* #t26 = #t24.{self::Test::[]}(#t25).{self::B::*}(self::f<self::B*>()) in let final void #t27 = #t24.{self::Test::[]=}(#t25, #t26) in #t26;
+ self::C* v5 = let final self::Test* #t28 = t in let final self::Index* #t29 = self::f<self::Index*>() in let final self::C* #t30 = #t28.{self::Test::[]}(#t29).{self::B::&}(self::f<self::A*>()) in let final void #t31 = #t28.{self::Test::[]=}(#t29, #t30) in #t30;
+ self::B* v6 = t.{self::Test::[]}(self::f<self::Index*>());
+ self::B* v7 = let final self::Test* #t32 = t in let final self::Index* #t33 = self::f<self::Index*>() in let final self::B* #t34 = #t32.{self::Test::[]}(#t33).{self::B::-}(1) in let final void #t35 = #t32.{self::Test::[]=}(#t33, #t34) in #t34;
+ self::B* v8 = let final self::Test* #t36 = t in let final self::Index* #t37 = self::f<self::Index*>() in let final self::B* #t38 = #t36.{self::Test::[]}(#t37) in let final void #t39 = #t36.{self::Test::[]=}(#t37, #t38.{self::B::-}(1)) in #t38;
}
}
static method f<T extends core::Object* = dynamic>() → self::f::T*
diff --git a/pkg/front_end/testcases/inference/infer_assign_to_index_full.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/infer_assign_to_index_full.dart.strong.transformed.expect
index 40716cc..4711ea5 100644
--- a/pkg/front_end/testcases/inference/infer_assign_to_index_full.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/infer_assign_to_index_full.dart.strong.transformed.expect
@@ -39,19 +39,21 @@
operator []=(self::Index* i, self::B* v) → void {}
method test() → void {
self::Test* t = self::f<self::Test*>();
- t.{self::Test::[]=}(self::f<dynamic>() as{TypeError} self::Index*, self::f<self::B*>());
- let final self::Test* #t1 = t in let final dynamic #t2 = self::f<dynamic>() in #t1.{self::Test::[]}(#t2 as{TypeError} self::Index*).{core::Object::==}(null) ?{self::B*} let final self::B* #t3 = self::f<self::B*>() in let final void #t4 = #t1.{self::Test::[]=}(#t2 as{TypeError} self::Index*, #t3) in #t3 : null;
- let final self::Test* #t5 = t in let final dynamic #t6 = self::f<dynamic>() in #t5.{self::Test::[]=}(#t6 as{TypeError} self::Index*, #t5.{self::Test::[]}(#t6 as{TypeError} self::Index*).{self::B::+}(self::f<dynamic>() as{TypeError} self::C*) as{TypeError} self::B*);
- let final self::Test* #t7 = t in let final dynamic #t8 = self::f<dynamic>() in #t7.{self::Test::[]=}(#t8 as{TypeError} self::Index*, #t7.{self::Test::[]}(#t8 as{TypeError} self::Index*).{self::B::*}(self::f<dynamic>() as{TypeError} self::B*));
- let final self::Test* #t9 = t in let final dynamic #t10 = self::f<dynamic>() in #t9.{self::Test::[]=}(#t10 as{TypeError} self::Index*, #t9.{self::Test::[]}(#t10 as{TypeError} self::Index*).{self::B::&}(self::f<dynamic>() as{TypeError} self::A*));
- let final self::Test* #t11 = t in let final dynamic #t12 = self::f<dynamic>() in let final self::B* #t13 = #t11.{self::Test::[]}(#t12 as{TypeError} self::Index*).{self::B::-}(1) in let final void #t14 = #t11.{self::Test::[]=}(#t12 as{TypeError} self::Index*, #t13) in #t13;
- let final self::Test* #t15 = t in let final dynamic #t16 = self::f<dynamic>() in #t15.{self::Test::[]=}(#t16 as{TypeError} self::Index*, #t15.{self::Test::[]}(#t16 as{TypeError} self::Index*).{self::B::-}(1));
- self::B* v1 = let final self::Test* #t17 = t in let final dynamic #t18 = self::f<dynamic>() in let final self::B* #t19 = self::f<self::B*>() in let final void #t20 = #t17.{self::Test::[]=}(#t18 as{TypeError} self::Index*, #t19) in #t19;
- self::B* v2 = let final self::Test* #t21 = t in let final dynamic #t22 = self::f<dynamic>() in let final self::B* #t23 = #t21.{self::Test::[]}(#t22 as{TypeError} self::Index*) in #t23.{core::Object::==}(null) ?{self::B*} let final self::B* #t24 = self::f<self::B*>() in let final void #t25 = #t21.{self::Test::[]=}(#t22 as{TypeError} self::Index*, #t24) in #t24 : #t23;
- self::B* v4 = let final self::Test* #t26 = t in let final dynamic #t27 = self::f<dynamic>() in let final self::B* #t28 = #t26.{self::Test::[]}(#t27 as{TypeError} self::Index*).{self::B::*}(self::f<dynamic>() as{TypeError} self::B*) in let final void #t29 = #t26.{self::Test::[]=}(#t27 as{TypeError} self::Index*, #t28) in #t28;
- self::C* v5 = let final self::Test* #t30 = t in let final dynamic #t31 = self::f<dynamic>() in let final self::C* #t32 = #t30.{self::Test::[]}(#t31 as{TypeError} self::Index*).{self::B::&}(self::f<dynamic>() as{TypeError} self::A*) in let final void #t33 = #t30.{self::Test::[]=}(#t31 as{TypeError} self::Index*, #t32) in #t32;
- self::B* v6 = let final self::Test* #t34 = t in let final dynamic #t35 = self::f<dynamic>() in let final self::B* #t36 = #t34.{self::Test::[]}(#t35 as{TypeError} self::Index*).{self::B::-}(1) in let final void #t37 = #t34.{self::Test::[]=}(#t35 as{TypeError} self::Index*, #t36) in #t36;
- self::B* v7 = let final self::Test* #t38 = t in let final dynamic #t39 = self::f<dynamic>() in let final self::B* #t40 = #t38.{self::Test::[]}(#t39 as{TypeError} self::Index*) in let final void #t41 = #t38.{self::Test::[]=}(#t39 as{TypeError} self::Index*, #t40.{self::B::-}(1)) in #t40;
+ t.{self::Test::[]=}(self::f<self::Index*>(), self::f<self::B*>());
+ let final self::Test* #t1 = t in let final self::Index* #t2 = self::f<self::Index*>() in #t1.{self::Test::[]}(#t2).{core::Object::==}(null) ?{self::B*} #t1.{self::Test::[]=}(#t2, self::f<self::B*>()) : null;
+ let final self::Test* #t3 = t in let final self::Index* #t4 = self::f<self::Index*>() in #t3.{self::Test::[]=}(#t4, #t3.{self::Test::[]}(#t4).{self::B::+}(self::f<self::C*>()) as{TypeError} self::B*);
+ let final self::Test* #t5 = t in let final self::Index* #t6 = self::f<self::Index*>() in #t5.{self::Test::[]=}(#t6, #t5.{self::Test::[]}(#t6).{self::B::*}(self::f<self::B*>()));
+ let final self::Test* #t7 = t in let final self::Index* #t8 = self::f<self::Index*>() in #t7.{self::Test::[]=}(#t8, #t7.{self::Test::[]}(#t8).{self::B::&}(self::f<self::A*>()));
+ t.{self::Test::[]}(self::f<self::Index*>());
+ let final self::Test* #t9 = t in let final self::Index* #t10 = self::f<self::Index*>() in let final self::B* #t11 = #t9.{self::Test::[]}(#t10).{self::B::-}(1) in let final void #t12 = #t9.{self::Test::[]=}(#t10, #t11) in #t11;
+ let final self::Test* #t13 = t in let final self::Index* #t14 = self::f<self::Index*>() in #t13.{self::Test::[]=}(#t14, #t13.{self::Test::[]}(#t14).{self::B::-}(1));
+ self::B* v1 = let final self::Test* #t15 = t in let final self::Index* #t16 = self::f<self::Index*>() in let final self::B* #t17 = self::f<self::B*>() in let final void #t18 = #t15.{self::Test::[]=}(#t16, #t17) in #t17;
+ self::B* v2 = let final self::Test* #t19 = t in let final self::Index* #t20 = self::f<self::Index*>() in let final self::B* #t21 = #t19.{self::Test::[]}(#t20) in #t21.{core::Object::==}(null) ?{self::B*} let final self::B* #t22 = self::f<self::B*>() in let final void #t23 = #t19.{self::Test::[]=}(#t20, #t22) in #t22 : #t21;
+ self::B* v4 = let final self::Test* #t24 = t in let final self::Index* #t25 = self::f<self::Index*>() in let final self::B* #t26 = #t24.{self::Test::[]}(#t25).{self::B::*}(self::f<self::B*>()) in let final void #t27 = #t24.{self::Test::[]=}(#t25, #t26) in #t26;
+ self::C* v5 = let final self::Test* #t28 = t in let final self::Index* #t29 = self::f<self::Index*>() in let final self::C* #t30 = #t28.{self::Test::[]}(#t29).{self::B::&}(self::f<self::A*>()) in let final void #t31 = #t28.{self::Test::[]=}(#t29, #t30) in #t30;
+ self::B* v6 = t.{self::Test::[]}(self::f<self::Index*>());
+ self::B* v7 = let final self::Test* #t32 = t in let final self::Index* #t33 = self::f<self::Index*>() in let final self::B* #t34 = #t32.{self::Test::[]}(#t33).{self::B::-}(1) in let final void #t35 = #t32.{self::Test::[]=}(#t33, #t34) in #t34;
+ self::B* v8 = let final self::Test* #t36 = t in let final self::Index* #t37 = self::f<self::Index*>() in let final self::B* #t38 = #t36.{self::Test::[]}(#t37) in let final void #t39 = #t36.{self::Test::[]=}(#t37, #t38.{self::B::-}(1)) in #t38;
}
}
static method f<T extends core::Object* = dynamic>() → self::f::T*
diff --git a/pkg/front_end/testcases/inference/infer_assign_to_local.dart b/pkg/front_end/testcases/inference/infer_assign_to_local.dart
index d13afe6..ebc99ac 100644
--- a/pkg/front_end/testcases/inference/infer_assign_to_local.dart
+++ b/pkg/front_end/testcases/inference/infer_assign_to_local.dart
@@ -22,17 +22,19 @@
B local;
local = /*@ typeArgs=B* */ f();
local ??= /*@ typeArgs=B* */ f();
- local += /*@ typeArgs=dynamic */ f();
- local *= /*@ typeArgs=dynamic */ f();
- local &= /*@ typeArgs=dynamic */ f();
- --local;
- local--;
+ local /*@ target=B::+ */ += /*@ typeArgs=C* */ f();
+ local /*@ target=B::* */ *= /*@ typeArgs=B* */ f();
+ local /*@ target=B::& */ &= /*@ typeArgs=A* */ f();
+ /*@ target=B::- */ --local;
+ local /*@ target=B::- */ --;
var /*@ type=B* */ v1 = local = /*@ typeArgs=B* */ f();
var /*@ type=B* */ v2 = local ??= /*@ typeArgs=B* */ f();
- var /*@ type=B* */ v4 = local *= /*@ typeArgs=dynamic */ f();
- var /*@ type=C* */ v5 = local &= /*@ typeArgs=dynamic */ f();
- var /*@ type=B* */ v6 = --local;
- var /*@ type=B* */ v7 = local--;
+ var /*@ type=A* */ v3 = local /*@ target=B::+ */ += /*@ typeArgs=C* */ f();
+ var /*@ type=B* */ v4 = local /*@ target=B::* */ *= /*@ typeArgs=B* */ f();
+ var /*@ type=C* */ v5 = local /*@ target=B::& */ &= /*@ typeArgs=A* */ f();
+ var /*@ type=B* */ v6 = /*@ target=B::- */ --local;
+ var /*@ type=B* */ v7 = /*@ type=B* */ local
+ /*@ type=B* */ /*@ target=B::- */ --;
}
main() {}
diff --git a/pkg/front_end/testcases/inference/infer_assign_to_local.dart.strong.expect b/pkg/front_end/testcases/inference/infer_assign_to_local.dart.strong.expect
index 1762f98..35c6164 100644
--- a/pkg/front_end/testcases/inference/infer_assign_to_local.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/infer_assign_to_local.dart.strong.expect
@@ -31,15 +31,16 @@
self::B* local;
local = self::f<self::B*>();
local.{core::Object::==}(null) ?{self::B*} local = self::f<self::B*>() : null;
- local = local.{self::B::+}(self::f<dynamic>() as{TypeError} self::C*) as{TypeError} self::B*;
- local = local.{self::B::*}(self::f<dynamic>() as{TypeError} self::B*);
- local = local.{self::B::&}(self::f<dynamic>() as{TypeError} self::A*);
+ local = local.{self::B::+}(self::f<self::C*>()) as{TypeError} self::B*;
+ local = local.{self::B::*}(self::f<self::B*>());
+ local = local.{self::B::&}(self::f<self::A*>());
local = local.{self::B::-}(1);
local = local.{self::B::-}(1);
self::B* v1 = local = self::f<self::B*>();
self::B* v2 = let final self::B* #t1 = local in #t1.{core::Object::==}(null) ?{self::B*} local = self::f<self::B*>() : #t1;
- self::B* v4 = local = local.{self::B::*}(self::f<dynamic>() as{TypeError} self::B*);
- self::C* v5 = local = local.{self::B::&}(self::f<dynamic>() as{TypeError} self::A*);
+ self::A* v3 = local = local.{self::B::+}(self::f<self::C*>()) as{TypeError} self::B*;
+ self::B* v4 = local = local.{self::B::*}(self::f<self::B*>());
+ self::C* v5 = local = local.{self::B::&}(self::f<self::A*>());
self::B* v6 = local = local.{self::B::-}(1);
self::B* v7 = let final self::B* #t2 = local in let final self::B* #t3 = local = #t2.{self::B::-}(1) in #t2;
}
diff --git a/pkg/front_end/testcases/inference/infer_assign_to_local.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/infer_assign_to_local.dart.strong.transformed.expect
index 1762f98..35c6164 100644
--- a/pkg/front_end/testcases/inference/infer_assign_to_local.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/infer_assign_to_local.dart.strong.transformed.expect
@@ -31,15 +31,16 @@
self::B* local;
local = self::f<self::B*>();
local.{core::Object::==}(null) ?{self::B*} local = self::f<self::B*>() : null;
- local = local.{self::B::+}(self::f<dynamic>() as{TypeError} self::C*) as{TypeError} self::B*;
- local = local.{self::B::*}(self::f<dynamic>() as{TypeError} self::B*);
- local = local.{self::B::&}(self::f<dynamic>() as{TypeError} self::A*);
+ local = local.{self::B::+}(self::f<self::C*>()) as{TypeError} self::B*;
+ local = local.{self::B::*}(self::f<self::B*>());
+ local = local.{self::B::&}(self::f<self::A*>());
local = local.{self::B::-}(1);
local = local.{self::B::-}(1);
self::B* v1 = local = self::f<self::B*>();
self::B* v2 = let final self::B* #t1 = local in #t1.{core::Object::==}(null) ?{self::B*} local = self::f<self::B*>() : #t1;
- self::B* v4 = local = local.{self::B::*}(self::f<dynamic>() as{TypeError} self::B*);
- self::C* v5 = local = local.{self::B::&}(self::f<dynamic>() as{TypeError} self::A*);
+ self::A* v3 = local = local.{self::B::+}(self::f<self::C*>()) as{TypeError} self::B*;
+ self::B* v4 = local = local.{self::B::*}(self::f<self::B*>());
+ self::C* v5 = local = local.{self::B::&}(self::f<self::A*>());
self::B* v6 = local = local.{self::B::-}(1);
self::B* v7 = let final self::B* #t2 = local in let final self::B* #t3 = local = #t2.{self::B::-}(1) in #t2;
}
diff --git a/pkg/front_end/testcases/inference/infer_assign_to_local.dart.type_promotion.expect b/pkg/front_end/testcases/inference/infer_assign_to_local.dart.type_promotion.expect
index c9be4b0..e0dc7dd 100644
--- a/pkg/front_end/testcases/inference/infer_assign_to_local.dart.type_promotion.expect
+++ b/pkg/front_end/testcases/inference/infer_assign_to_local.dart.type_promotion.expect
@@ -4,36 +4,39 @@
pkg/front_end/testcases/inference/infer_assign_to_local.dart:24:9: Context: Write to local@474
local ??= /*@ typeArgs=B* */ f();
^^^
-pkg/front_end/testcases/inference/infer_assign_to_local.dart:25:9: Context: Write to local@474
- local += /*@ typeArgs=dynamic */ f();
- ^^
-pkg/front_end/testcases/inference/infer_assign_to_local.dart:26:9: Context: Write to local@474
- local *= /*@ typeArgs=dynamic */ f();
- ^^
-pkg/front_end/testcases/inference/infer_assign_to_local.dart:27:9: Context: Write to local@474
- local &= /*@ typeArgs=dynamic */ f();
- ^^
-pkg/front_end/testcases/inference/infer_assign_to_local.dart:28:3: Context: Write to local@474
- --local;
- ^^
-pkg/front_end/testcases/inference/infer_assign_to_local.dart:29:8: Context: Write to local@474
- local--;
- ^^
+pkg/front_end/testcases/inference/infer_assign_to_local.dart:25:28: Context: Write to local@474
+ local /*@ target=B::+ */ += /*@ typeArgs=C* */ f();
+ ^^
+pkg/front_end/testcases/inference/infer_assign_to_local.dart:26:28: Context: Write to local@474
+ local /*@ target=B::* */ *= /*@ typeArgs=B* */ f();
+ ^^
+pkg/front_end/testcases/inference/infer_assign_to_local.dart:27:28: Context: Write to local@474
+ local /*@ target=B::& */ &= /*@ typeArgs=A* */ f();
+ ^^
+pkg/front_end/testcases/inference/infer_assign_to_local.dart:28:22: Context: Write to local@474
+ /*@ target=B::- */ --local;
+ ^^
+pkg/front_end/testcases/inference/infer_assign_to_local.dart:29:28: Context: Write to local@474
+ local /*@ target=B::- */ --;
+ ^^
pkg/front_end/testcases/inference/infer_assign_to_local.dart:30:33: Context: Write to local@474
var /*@ type=B* */ v1 = local = /*@ typeArgs=B* */ f();
^
pkg/front_end/testcases/inference/infer_assign_to_local.dart:31:33: Context: Write to local@474
var /*@ type=B* */ v2 = local ??= /*@ typeArgs=B* */ f();
^^^
-pkg/front_end/testcases/inference/infer_assign_to_local.dart:32:33: Context: Write to local@474
- var /*@ type=B* */ v4 = local *= /*@ typeArgs=dynamic */ f();
- ^^
-pkg/front_end/testcases/inference/infer_assign_to_local.dart:33:33: Context: Write to local@474
- var /*@ type=C* */ v5 = local &= /*@ typeArgs=dynamic */ f();
- ^^
-pkg/front_end/testcases/inference/infer_assign_to_local.dart:34:27: Context: Write to local@474
- var /*@ type=B* */ v6 = --local;
- ^^
-pkg/front_end/testcases/inference/infer_assign_to_local.dart:35:32: Context: Write to local@474
- var /*@ type=B* */ v7 = local--;
- ^^
+pkg/front_end/testcases/inference/infer_assign_to_local.dart:32:52: Context: Write to local@474
+ var /*@ type=A* */ v3 = local /*@ target=B::+ */ += /*@ typeArgs=C* */ f();
+ ^^
+pkg/front_end/testcases/inference/infer_assign_to_local.dart:33:52: Context: Write to local@474
+ var /*@ type=B* */ v4 = local /*@ target=B::* */ *= /*@ typeArgs=B* */ f();
+ ^^
+pkg/front_end/testcases/inference/infer_assign_to_local.dart:34:52: Context: Write to local@474
+ var /*@ type=C* */ v5 = local /*@ target=B::& */ &= /*@ typeArgs=A* */ f();
+ ^^
+pkg/front_end/testcases/inference/infer_assign_to_local.dart:35:46: Context: Write to local@474
+ var /*@ type=B* */ v6 = /*@ target=B::- */ --local;
+ ^^
+pkg/front_end/testcases/inference/infer_assign_to_local.dart:37:41: Context: Write to local@474
+ /*@ type=B* */ /*@ target=B::- */ --;
+ ^^
diff --git a/pkg/front_end/testcases/inference/infer_assign_to_local_upwards.dart b/pkg/front_end/testcases/inference/infer_assign_to_local_upwards.dart
index 98ac8ac..fef536a 100644
--- a/pkg/front_end/testcases/inference/infer_assign_to_local_upwards.dart
+++ b/pkg/front_end/testcases/inference/infer_assign_to_local_upwards.dart
@@ -12,9 +12,9 @@
void test1(int t) {
var /*@ type=int* */ v1 = t = getInt();
var /*@ type=int* */ v4 = t ??= getInt();
- var /*@ type=int* */ v7 = t += getInt();
- var /*@ type=int* */ v10 = ++t;
- var /*@ type=int* */ v11 = t++;
+ var /*@ type=int* */ v7 = t /*@target=num::+*/ += getInt();
+ var /*@ type=int* */ v10 = /*@target=num::+*/ ++t;
+ var /*@ type=int* */ v11 = /*@ type=int* */ t /*@ type=int* */ /*@target=num::+*/ ++;
}
void test2(num t) {
@@ -24,21 +24,22 @@
var /*@ type=num* */ v4 = t ??= getInt();
var /*@ type=num* */ v5 = t ??= getNum();
var /*@ type=num* */ v6 = t ??= getDouble();
- var /*@ type=num* */ v7 = t += getInt();
- var /*@ type=num* */ v8 = t += getNum();
- var /*@ type=num* */ v9 = t += getDouble();
- var /*@ type=num* */ v10 = ++t;
- var /*@ type=num* */ v11 = t++;
+ var /*@ type=num* */ v7 = t /*@target=num::+*/ += getInt();
+ var /*@ type=num* */ v8 = t /*@target=num::+*/ += getNum();
+ var /*@ type=num* */ v9 = t /*@target=num::+*/ += getDouble();
+ var /*@ type=num* */ v10 = /*@target=num::+*/ ++t;
+ var /*@ type=num* */ v11 = /*@ type=num* */ t /*@ type=num* */ /*@target=num::+*/ ++;
}
void test3(double t) {
var /*@ type=double* */ v3 = t = getDouble();
var /*@ type=double* */ v6 = t ??= getDouble();
- var /*@ type=double* */ v7 = t += getInt();
- var /*@ type=double* */ v8 = t += getNum();
- var /*@ type=double* */ v9 = t += getDouble();
- var /*@ type=double* */ v10 = ++t;
- var /*@ type=double* */ v11 = t++;
+ var /*@ type=double* */ v7 = t /*@target=double::+*/ += getInt();
+ var /*@ type=double* */ v8 = t /*@target=double::+*/ += getNum();
+ var /*@ type=double* */ v9 = t /*@target=double::+*/ += getDouble();
+ var /*@ type=double* */ v10 = /*@target=double::+*/ ++t;
+ var /*@ type=double* */ v11 = /*@ type=double* */ t
+ /*@ type=double* */ /*@target=double::+*/ ++;
}
main() {}
diff --git a/pkg/front_end/testcases/inference/infer_assign_to_local_upwards.dart.type_promotion.expect b/pkg/front_end/testcases/inference/infer_assign_to_local_upwards.dart.type_promotion.expect
index e3a6044..80ef25c 100644
--- a/pkg/front_end/testcases/inference/infer_assign_to_local_upwards.dart.type_promotion.expect
+++ b/pkg/front_end/testcases/inference/infer_assign_to_local_upwards.dart.type_promotion.expect
@@ -4,15 +4,15 @@
pkg/front_end/testcases/inference/infer_assign_to_local_upwards.dart:14:31: Context: Write to t@343
var /*@ type=int* */ v4 = t ??= getInt();
^^^
-pkg/front_end/testcases/inference/infer_assign_to_local_upwards.dart:15:31: Context: Write to t@343
- var /*@ type=int* */ v7 = t += getInt();
- ^^
-pkg/front_end/testcases/inference/infer_assign_to_local_upwards.dart:16:30: Context: Write to t@343
- var /*@ type=int* */ v10 = ++t;
- ^^
-pkg/front_end/testcases/inference/infer_assign_to_local_upwards.dart:17:31: Context: Write to t@343
- var /*@ type=int* */ v11 = t++;
- ^^
+pkg/front_end/testcases/inference/infer_assign_to_local_upwards.dart:15:50: Context: Write to t@343
+ var /*@ type=int* */ v7 = t /*@target=num::+*/ += getInt();
+ ^^
+pkg/front_end/testcases/inference/infer_assign_to_local_upwards.dart:16:49: Context: Write to t@343
+ var /*@ type=int* */ v10 = /*@target=num::+*/ ++t;
+ ^^
+pkg/front_end/testcases/inference/infer_assign_to_local_upwards.dart:17:85: Context: Write to t@343
+ var /*@ type=int* */ v11 = /*@ type=int* */ t /*@ type=int* */ /*@target=num::+*/ ++;
+ ^^
pkg/front_end/testcases/inference/infer_assign_to_local_upwards.dart:21:31: Context: Write to t@343
var /*@ type=int* */ v1 = t = getInt();
^
@@ -31,39 +31,39 @@
pkg/front_end/testcases/inference/infer_assign_to_local_upwards.dart:26:31: Context: Write to t@343
var /*@ type=num* */ v6 = t ??= getDouble();
^^^
-pkg/front_end/testcases/inference/infer_assign_to_local_upwards.dart:27:31: Context: Write to t@343
- var /*@ type=num* */ v7 = t += getInt();
- ^^
-pkg/front_end/testcases/inference/infer_assign_to_local_upwards.dart:28:31: Context: Write to t@343
- var /*@ type=num* */ v8 = t += getNum();
- ^^
-pkg/front_end/testcases/inference/infer_assign_to_local_upwards.dart:29:31: Context: Write to t@343
- var /*@ type=num* */ v9 = t += getDouble();
- ^^
-pkg/front_end/testcases/inference/infer_assign_to_local_upwards.dart:30:30: Context: Write to t@343
- var /*@ type=num* */ v10 = ++t;
- ^^
-pkg/front_end/testcases/inference/infer_assign_to_local_upwards.dart:31:31: Context: Write to t@343
- var /*@ type=num* */ v11 = t++;
- ^^
+pkg/front_end/testcases/inference/infer_assign_to_local_upwards.dart:27:50: Context: Write to t@343
+ var /*@ type=num* */ v7 = t /*@target=num::+*/ += getInt();
+ ^^
+pkg/front_end/testcases/inference/infer_assign_to_local_upwards.dart:28:50: Context: Write to t@343
+ var /*@ type=num* */ v8 = t /*@target=num::+*/ += getNum();
+ ^^
+pkg/front_end/testcases/inference/infer_assign_to_local_upwards.dart:29:50: Context: Write to t@343
+ var /*@ type=num* */ v9 = t /*@target=num::+*/ += getDouble();
+ ^^
+pkg/front_end/testcases/inference/infer_assign_to_local_upwards.dart:30:49: Context: Write to t@343
+ var /*@ type=num* */ v10 = /*@target=num::+*/ ++t;
+ ^^
+pkg/front_end/testcases/inference/infer_assign_to_local_upwards.dart:31:85: Context: Write to t@343
+ var /*@ type=num* */ v11 = /*@ type=num* */ t /*@ type=num* */ /*@target=num::+*/ ++;
+ ^^
pkg/front_end/testcases/inference/infer_assign_to_local_upwards.dart:35:34: Context: Write to t@343
var /*@ type=double* */ v3 = t = getDouble();
^
pkg/front_end/testcases/inference/infer_assign_to_local_upwards.dart:36:34: Context: Write to t@343
var /*@ type=double* */ v6 = t ??= getDouble();
^^^
-pkg/front_end/testcases/inference/infer_assign_to_local_upwards.dart:37:34: Context: Write to t@343
- var /*@ type=double* */ v7 = t += getInt();
- ^^
-pkg/front_end/testcases/inference/infer_assign_to_local_upwards.dart:38:34: Context: Write to t@343
- var /*@ type=double* */ v8 = t += getNum();
- ^^
-pkg/front_end/testcases/inference/infer_assign_to_local_upwards.dart:39:34: Context: Write to t@343
- var /*@ type=double* */ v9 = t += getDouble();
- ^^
-pkg/front_end/testcases/inference/infer_assign_to_local_upwards.dart:40:33: Context: Write to t@343
- var /*@ type=double* */ v10 = ++t;
- ^^
-pkg/front_end/testcases/inference/infer_assign_to_local_upwards.dart:41:34: Context: Write to t@343
- var /*@ type=double* */ v11 = t++;
- ^^
+pkg/front_end/testcases/inference/infer_assign_to_local_upwards.dart:37:56: Context: Write to t@343
+ var /*@ type=double* */ v7 = t /*@target=double::+*/ += getInt();
+ ^^
+pkg/front_end/testcases/inference/infer_assign_to_local_upwards.dart:38:56: Context: Write to t@343
+ var /*@ type=double* */ v8 = t /*@target=double::+*/ += getNum();
+ ^^
+pkg/front_end/testcases/inference/infer_assign_to_local_upwards.dart:39:56: Context: Write to t@343
+ var /*@ type=double* */ v9 = t /*@target=double::+*/ += getDouble();
+ ^^
+pkg/front_end/testcases/inference/infer_assign_to_local_upwards.dart:40:55: Context: Write to t@343
+ var /*@ type=double* */ v10 = /*@target=double::+*/ ++t;
+ ^^
+pkg/front_end/testcases/inference/infer_assign_to_local_upwards.dart:42:49: Context: Write to t@343
+ /*@ type=double* */ /*@target=double::+*/ ++;
+ ^^
diff --git a/pkg/front_end/testcases/inference/infer_assign_to_property_full.dart b/pkg/front_end/testcases/inference/infer_assign_to_property_full.dart
index b3bffe0..0fc74d0 100644
--- a/pkg/front_end/testcases/inference/infer_assign_to_property_full.dart
+++ b/pkg/front_end/testcases/inference/infer_assign_to_property_full.dart
@@ -23,22 +23,46 @@
static void test(Test t) {
t. /*@target=Test::member*/ member = /*@ typeArgs=B* */ f();
- t. /*@target=Test::member*/ member ??= /*@ typeArgs=B* */ f();
- t. /*@target=Test::member*/ member += /*@ typeArgs=dynamic */ f();
- t. /*@target=Test::member*/ member *= /*@ typeArgs=dynamic */ f();
- t. /*@target=Test::member*/ member &= /*@ typeArgs=dynamic */ f();
- --t. /*@target=Test::member*/ member;
- t. /*@target=Test::member*/ member--;
+ /*@ type=Test* */ t
+ . /*@target=Test::member*/ /*@target=Test::member*/ member
+ /*@target=Object::==*/ ??= /*@ typeArgs=B* */ f();
+ /*@ type=Test* */ t
+ . /*@target=Test::member*/ /*@target=Test::member*/ member
+ /*@ target=B::+ */ += /*@ typeArgs=C* */ f();
+ /*@ type=Test* */ t
+ . /*@target=Test::member*/ /*@target=Test::member*/ member
+ /*@ target=B::* */ *= /*@ typeArgs=B* */ f();
+ /*@ type=Test* */ t
+ . /*@target=Test::member*/ /*@target=Test::member*/ member
+ /*@ target=B::& */ &= /*@ typeArgs=A* */ f();
+ /*@ target=B::- */ -- /*@ type=Test* */ t
+ . /*@target=Test::member*/ /*@target=Test::member*/ member;
+ /*@ type=Test* */ t
+ . /*@target=Test::member*/ /*@target=Test::member*/ member
+ /*@ target=B::- */ --;
var /*@ type=B* */ v1 =
t. /*@target=Test::member*/ member = /*@ typeArgs=B* */ f();
var /*@ type=B* */ v2 =
- t. /*@target=Test::member*/ member ??= /*@ typeArgs=B* */ f();
+ /*@ type=Test* */ t
+ . /*@target=Test::member*/ /*@target=Test::member*/ member
+ /*@target=Object::==*/ ??= /*@ typeArgs=B* */ f();
+ var /*@ type=A* */ v3 =
+ /*@ type=Test* */ t
+ . /*@target=Test::member*/ /*@target=Test::member*/ member
+ /*@ target=B::+ */ += /*@ typeArgs=C* */ f();
var /*@ type=B* */ v4 =
- t. /*@target=Test::member*/ member *= /*@ typeArgs=dynamic */ f();
+ /*@ type=Test* */ t
+ . /*@target=Test::member*/ /*@target=Test::member*/ member
+ /*@ target=B::* */ *= /*@ typeArgs=B* */ f();
var /*@ type=C* */ v5 =
- t. /*@target=Test::member*/ member &= /*@ typeArgs=dynamic */ f();
- var /*@ type=B* */ v6 = --t. /*@target=Test::member*/ member;
- var /*@ type=B* */ v7 = t. /*@target=Test::member*/ member--;
+ /*@ type=Test* */ t
+ . /*@target=Test::member*/ /*@target=Test::member*/ member
+ /*@ target=B::& */ &= /*@ typeArgs=A* */ f();
+ var /*@ type=B* */ v6 = /*@ target=B::- */ -- /*@ type=Test* */ t
+ . /*@target=Test::member*/ /*@target=Test::member*/ member;
+ var /*@ type=B* */ v7 = /*@ type=Test* */ t
+ . /*@ type=B* */ /*@target=Test::member*/ /*@target=Test::member*/
+ member /*@ type=B* */ /*@ target=B::- */ --;
}
}
diff --git a/pkg/front_end/testcases/inference/infer_assign_to_property_full.dart.strong.expect b/pkg/front_end/testcases/inference/infer_assign_to_property_full.dart.strong.expect
index def1efc..5809936 100644
--- a/pkg/front_end/testcases/inference/infer_assign_to_property_full.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/infer_assign_to_property_full.dart.strong.expect
@@ -33,17 +33,18 @@
static method test(self::Test* t) → void {
t.{self::Test::member} = self::f<self::B*>();
let final self::Test* #t1 = t in #t1.{self::Test::member}.{core::Object::==}(null) ?{self::B*} #t1.{self::Test::member} = self::f<self::B*>() : null;
- let final self::Test* #t2 = t in #t2.{self::Test::member} = #t2.{self::Test::member}.{self::B::+}(self::f<dynamic>() as{TypeError} self::C*) as{TypeError} self::B*;
- let final self::Test* #t3 = t in #t3.{self::Test::member} = #t3.{self::Test::member}.{self::B::*}(self::f<dynamic>() as{TypeError} self::B*);
- let final self::Test* #t4 = t in #t4.{self::Test::member} = #t4.{self::Test::member}.{self::B::&}(self::f<dynamic>() as{TypeError} self::A*);
+ let final self::Test* #t2 = t in #t2.{self::Test::member} = #t2.{self::Test::member}.{self::B::+}(self::f<self::C*>()) as{TypeError} self::B*;
+ let final self::Test* #t3 = t in #t3.{self::Test::member} = #t3.{self::Test::member}.{self::B::*}(self::f<self::B*>());
+ let final self::Test* #t4 = t in #t4.{self::Test::member} = #t4.{self::Test::member}.{self::B::&}(self::f<self::A*>());
let final self::Test* #t5 = t in #t5.{self::Test::member} = #t5.{self::Test::member}.{self::B::-}(1);
let final self::Test* #t6 = t in #t6.{self::Test::member} = #t6.{self::Test::member}.{self::B::-}(1);
self::B* v1 = t.{self::Test::member} = self::f<self::B*>();
self::B* v2 = let final self::Test* #t7 = t in let final self::B* #t8 = #t7.{self::Test::member} in #t8.{core::Object::==}(null) ?{self::B*} #t7.{self::Test::member} = self::f<self::B*>() : #t8;
- self::B* v4 = let final self::Test* #t9 = t in #t9.{self::Test::member} = #t9.{self::Test::member}.{self::B::*}(self::f<dynamic>() as{TypeError} self::B*);
- self::C* v5 = let final self::Test* #t10 = t in #t10.{self::Test::member} = #t10.{self::Test::member}.{self::B::&}(self::f<dynamic>() as{TypeError} self::A*);
- self::B* v6 = let final self::Test* #t11 = t in #t11.{self::Test::member} = #t11.{self::Test::member}.{self::B::-}(1);
- self::B* v7 = let final self::Test* #t12 = t in let final self::B* #t13 = #t12.{self::Test::member} in let final self::B* #t14 = #t12.{self::Test::member} = #t13.{self::B::-}(1) in #t13;
+ self::A* v3 = let final self::Test* #t9 = t in #t9.{self::Test::member} = #t9.{self::Test::member}.{self::B::+}(self::f<self::C*>()) as{TypeError} self::B*;
+ self::B* v4 = let final self::Test* #t10 = t in #t10.{self::Test::member} = #t10.{self::Test::member}.{self::B::*}(self::f<self::B*>());
+ self::C* v5 = let final self::Test* #t11 = t in #t11.{self::Test::member} = #t11.{self::Test::member}.{self::B::&}(self::f<self::A*>());
+ self::B* v6 = let final self::Test* #t12 = t in #t12.{self::Test::member} = #t12.{self::Test::member}.{self::B::-}(1);
+ self::B* v7 = let final self::Test* #t13 = t in let final self::B* #t14 = #t13.{self::Test::member} in let final self::B* #t15 = #t13.{self::Test::member} = #t14.{self::B::-}(1) in #t14;
}
}
static method f<T extends core::Object* = dynamic>() → self::f::T*
diff --git a/pkg/front_end/testcases/inference/infer_assign_to_property_full.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/infer_assign_to_property_full.dart.strong.transformed.expect
index def1efc..5809936 100644
--- a/pkg/front_end/testcases/inference/infer_assign_to_property_full.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/infer_assign_to_property_full.dart.strong.transformed.expect
@@ -33,17 +33,18 @@
static method test(self::Test* t) → void {
t.{self::Test::member} = self::f<self::B*>();
let final self::Test* #t1 = t in #t1.{self::Test::member}.{core::Object::==}(null) ?{self::B*} #t1.{self::Test::member} = self::f<self::B*>() : null;
- let final self::Test* #t2 = t in #t2.{self::Test::member} = #t2.{self::Test::member}.{self::B::+}(self::f<dynamic>() as{TypeError} self::C*) as{TypeError} self::B*;
- let final self::Test* #t3 = t in #t3.{self::Test::member} = #t3.{self::Test::member}.{self::B::*}(self::f<dynamic>() as{TypeError} self::B*);
- let final self::Test* #t4 = t in #t4.{self::Test::member} = #t4.{self::Test::member}.{self::B::&}(self::f<dynamic>() as{TypeError} self::A*);
+ let final self::Test* #t2 = t in #t2.{self::Test::member} = #t2.{self::Test::member}.{self::B::+}(self::f<self::C*>()) as{TypeError} self::B*;
+ let final self::Test* #t3 = t in #t3.{self::Test::member} = #t3.{self::Test::member}.{self::B::*}(self::f<self::B*>());
+ let final self::Test* #t4 = t in #t4.{self::Test::member} = #t4.{self::Test::member}.{self::B::&}(self::f<self::A*>());
let final self::Test* #t5 = t in #t5.{self::Test::member} = #t5.{self::Test::member}.{self::B::-}(1);
let final self::Test* #t6 = t in #t6.{self::Test::member} = #t6.{self::Test::member}.{self::B::-}(1);
self::B* v1 = t.{self::Test::member} = self::f<self::B*>();
self::B* v2 = let final self::Test* #t7 = t in let final self::B* #t8 = #t7.{self::Test::member} in #t8.{core::Object::==}(null) ?{self::B*} #t7.{self::Test::member} = self::f<self::B*>() : #t8;
- self::B* v4 = let final self::Test* #t9 = t in #t9.{self::Test::member} = #t9.{self::Test::member}.{self::B::*}(self::f<dynamic>() as{TypeError} self::B*);
- self::C* v5 = let final self::Test* #t10 = t in #t10.{self::Test::member} = #t10.{self::Test::member}.{self::B::&}(self::f<dynamic>() as{TypeError} self::A*);
- self::B* v6 = let final self::Test* #t11 = t in #t11.{self::Test::member} = #t11.{self::Test::member}.{self::B::-}(1);
- self::B* v7 = let final self::Test* #t12 = t in let final self::B* #t13 = #t12.{self::Test::member} in let final self::B* #t14 = #t12.{self::Test::member} = #t13.{self::B::-}(1) in #t13;
+ self::A* v3 = let final self::Test* #t9 = t in #t9.{self::Test::member} = #t9.{self::Test::member}.{self::B::+}(self::f<self::C*>()) as{TypeError} self::B*;
+ self::B* v4 = let final self::Test* #t10 = t in #t10.{self::Test::member} = #t10.{self::Test::member}.{self::B::*}(self::f<self::B*>());
+ self::C* v5 = let final self::Test* #t11 = t in #t11.{self::Test::member} = #t11.{self::Test::member}.{self::B::&}(self::f<self::A*>());
+ self::B* v6 = let final self::Test* #t12 = t in #t12.{self::Test::member} = #t12.{self::Test::member}.{self::B::-}(1);
+ self::B* v7 = let final self::Test* #t13 = t in let final self::B* #t14 = #t13.{self::Test::member} in let final self::B* #t15 = #t13.{self::Test::member} = #t14.{self::B::-}(1) in #t14;
}
}
static method f<T extends core::Object* = dynamic>() → self::f::T*
diff --git a/pkg/front_end/testcases/inference/infer_assign_to_property_null_aware.dart b/pkg/front_end/testcases/inference/infer_assign_to_property_null_aware.dart
index 3c0dfaa..55d9fb1 100644
--- a/pkg/front_end/testcases/inference/infer_assign_to_property_null_aware.dart
+++ b/pkg/front_end/testcases/inference/infer_assign_to_property_null_aware.dart
@@ -22,7 +22,8 @@
B member;
static void test(Test t) {
- t?. /*@target=Test::member*/ member = /*@ typeArgs=B* */ f();
+ /*@ type=Test* */ /*@target=Object::==*/ t?. /*@target=Test::member*/
+ member = /*@ typeArgs=B* */ f();
t?. /*@target=Test::member*/ member ??= /*@ typeArgs=B* */ f();
t?. /*@target=Test::member*/ member += /*@ typeArgs=dynamic */ f();
t?. /*@target=Test::member*/ member *= /*@ typeArgs=dynamic */ f();
@@ -30,7 +31,8 @@
--t?. /*@target=Test::member*/ member;
t?. /*@target=Test::member*/ member--;
var /*@ type=B* */ v1 =
- t?. /*@target=Test::member*/ member = /*@ typeArgs=B* */ f();
+ /*@ type=Test* */ /*@target=Object::==*/ t?. /*@target=Test::member*/
+ member = /*@ typeArgs=B* */ f();
var /*@ type=B* */ v2 =
t?. /*@target=Test::member*/ member ??= /*@ typeArgs=B* */ f();
var /*@ type=B* */ v4 =
diff --git a/pkg/front_end/testcases/inference/infer_assign_to_property_null_aware.dart.strong.expect b/pkg/front_end/testcases/inference/infer_assign_to_property_null_aware.dart.strong.expect
index 1a893e5..6c00bcb4 100644
--- a/pkg/front_end/testcases/inference/infer_assign_to_property_null_aware.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/infer_assign_to_property_null_aware.dart.strong.expect
@@ -31,14 +31,14 @@
: super core::Object::•()
;
static method test(self::Test* t) → void {
- let final self::Test* #t1 = t in #t1.==(null) ?{self::B*} null : #t1.{self::Test::member} = self::f<self::B*>();
+ let final self::Test* #t1 = t in #t1.{core::Object::==}(null) ?{self::B*} null : #t1.{self::Test::member} = self::f<self::B*>();
let final self::Test* #t2 = t in #t2.==(null) ?{self::B*} null : #t2.{self::Test::member}.{core::Object::==}(null) ?{self::B*} #t2.{self::Test::member} = self::f<self::B*>() : null;
let final self::Test* #t3 = t in #t3.==(null) ?{self::A*} null : #t3.{self::Test::member} = #t3.{self::Test::member}.{self::B::+}(self::f<dynamic>() as{TypeError} self::C*) as{TypeError} self::B*;
let final self::Test* #t4 = t in #t4.==(null) ?{self::B*} null : #t4.{self::Test::member} = #t4.{self::Test::member}.{self::B::*}(self::f<dynamic>() as{TypeError} self::B*);
let final self::Test* #t5 = t in #t5.==(null) ?{self::C*} null : #t5.{self::Test::member} = #t5.{self::Test::member}.{self::B::&}(self::f<dynamic>() as{TypeError} self::A*);
let final self::Test* #t6 = t in #t6.==(null) ?{self::B*} null : #t6.{self::Test::member} = #t6.{self::Test::member}.{self::B::-}(1);
let final self::Test* #t7 = t in #t7.==(null) ?{self::B*} null : #t7.{self::Test::member} = #t7.{self::Test::member}.{self::B::-}(1);
- self::B* v1 = let final self::Test* #t8 = t in #t8.==(null) ?{self::B*} null : #t8.{self::Test::member} = self::f<self::B*>();
+ self::B* v1 = let final self::Test* #t8 = t in #t8.{core::Object::==}(null) ?{self::B*} null : #t8.{self::Test::member} = self::f<self::B*>();
self::B* v2 = let final self::Test* #t9 = t in #t9.==(null) ?{self::B*} null : let final self::B* #t10 = #t9.{self::Test::member} in #t10.{core::Object::==}(null) ?{self::B*} #t9.{self::Test::member} = self::f<self::B*>() : #t10;
self::B* v4 = let final self::Test* #t11 = t in #t11.==(null) ?{self::B*} null : #t11.{self::Test::member} = #t11.{self::Test::member}.{self::B::*}(self::f<dynamic>() as{TypeError} self::B*);
self::C* v5 = let final self::Test* #t12 = t in #t12.==(null) ?{self::C*} null : #t12.{self::Test::member} = #t12.{self::Test::member}.{self::B::&}(self::f<dynamic>() as{TypeError} self::A*);
diff --git a/pkg/front_end/testcases/inference/infer_assign_to_property_null_aware.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/infer_assign_to_property_null_aware.dart.strong.transformed.expect
index 1a893e5..6c00bcb4 100644
--- a/pkg/front_end/testcases/inference/infer_assign_to_property_null_aware.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/infer_assign_to_property_null_aware.dart.strong.transformed.expect
@@ -31,14 +31,14 @@
: super core::Object::•()
;
static method test(self::Test* t) → void {
- let final self::Test* #t1 = t in #t1.==(null) ?{self::B*} null : #t1.{self::Test::member} = self::f<self::B*>();
+ let final self::Test* #t1 = t in #t1.{core::Object::==}(null) ?{self::B*} null : #t1.{self::Test::member} = self::f<self::B*>();
let final self::Test* #t2 = t in #t2.==(null) ?{self::B*} null : #t2.{self::Test::member}.{core::Object::==}(null) ?{self::B*} #t2.{self::Test::member} = self::f<self::B*>() : null;
let final self::Test* #t3 = t in #t3.==(null) ?{self::A*} null : #t3.{self::Test::member} = #t3.{self::Test::member}.{self::B::+}(self::f<dynamic>() as{TypeError} self::C*) as{TypeError} self::B*;
let final self::Test* #t4 = t in #t4.==(null) ?{self::B*} null : #t4.{self::Test::member} = #t4.{self::Test::member}.{self::B::*}(self::f<dynamic>() as{TypeError} self::B*);
let final self::Test* #t5 = t in #t5.==(null) ?{self::C*} null : #t5.{self::Test::member} = #t5.{self::Test::member}.{self::B::&}(self::f<dynamic>() as{TypeError} self::A*);
let final self::Test* #t6 = t in #t6.==(null) ?{self::B*} null : #t6.{self::Test::member} = #t6.{self::Test::member}.{self::B::-}(1);
let final self::Test* #t7 = t in #t7.==(null) ?{self::B*} null : #t7.{self::Test::member} = #t7.{self::Test::member}.{self::B::-}(1);
- self::B* v1 = let final self::Test* #t8 = t in #t8.==(null) ?{self::B*} null : #t8.{self::Test::member} = self::f<self::B*>();
+ self::B* v1 = let final self::Test* #t8 = t in #t8.{core::Object::==}(null) ?{self::B*} null : #t8.{self::Test::member} = self::f<self::B*>();
self::B* v2 = let final self::Test* #t9 = t in #t9.==(null) ?{self::B*} null : let final self::B* #t10 = #t9.{self::Test::member} in #t10.{core::Object::==}(null) ?{self::B*} #t9.{self::Test::member} = self::f<self::B*>() : #t10;
self::B* v4 = let final self::Test* #t11 = t in #t11.==(null) ?{self::B*} null : #t11.{self::Test::member} = #t11.{self::Test::member}.{self::B::*}(self::f<dynamic>() as{TypeError} self::B*);
self::C* v5 = let final self::Test* #t12 = t in #t12.==(null) ?{self::C*} null : #t12.{self::Test::member} = #t12.{self::Test::member}.{self::B::&}(self::f<dynamic>() as{TypeError} self::A*);
diff --git a/pkg/front_end/testcases/inference/infer_assign_to_property_null_aware_upwards.dart b/pkg/front_end/testcases/inference/infer_assign_to_property_null_aware_upwards.dart
index e245dfe..eab5036 100644
--- a/pkg/front_end/testcases/inference/infer_assign_to_property_null_aware_upwards.dart
+++ b/pkg/front_end/testcases/inference/infer_assign_to_property_null_aware_upwards.dart
@@ -13,7 +13,8 @@
int prop;
static void test(Test1 t) {
- var /*@ type=int* */ v1 = t?. /*@target=Test1::prop*/ prop = getInt();
+ var /*@ type=int* */ v1 = /*@ type=Test1* */ /*@target=Object::==*/ t
+ ?. /*@target=Test1::prop*/ prop = getInt();
var /*@ type=int* */ v4 = t?. /*@target=Test1::prop*/ prop ??= getInt();
var /*@ type=int* */ v7 = t?. /*@target=Test1::prop*/ prop += getInt();
var /*@ type=int* */ v10 = ++t?. /*@target=Test1::prop*/ prop;
@@ -25,9 +26,12 @@
num prop;
static void test(Test2 t) {
- var /*@ type=int* */ v1 = t?. /*@target=Test2::prop*/ prop = getInt();
- var /*@ type=num* */ v2 = t?. /*@target=Test2::prop*/ prop = getNum();
- var /*@ type=double* */ v3 = t?. /*@target=Test2::prop*/ prop = getDouble();
+ var /*@ type=int* */ v1 = /*@ type=Test2* */ /*@target=Object::==*/ t
+ ?. /*@target=Test2::prop*/ prop = getInt();
+ var /*@ type=num* */ v2 = /*@ type=Test2* */ /*@target=Object::==*/ t
+ ?. /*@target=Test2::prop*/ prop = getNum();
+ var /*@ type=double* */ v3 = /*@ type=Test2* */ /*@target=Object::==*/ t
+ ?. /*@target=Test2::prop*/ prop = getDouble();
var /*@ type=num* */ v4 = t?. /*@target=Test2::prop*/ prop ??= getInt();
var /*@ type=num* */ v5 = t?. /*@target=Test2::prop*/ prop ??= getNum();
var /*@ type=num* */ v6 = t?. /*@target=Test2::prop*/ prop ??= getDouble();
@@ -43,11 +47,15 @@
double prop;
static void test3(Test3 t) {
- var /*@ type=double* */ v3 = t?. /*@target=Test3::prop*/ prop = getDouble();
- var /*@ type=double* */ v6 = t?. /*@target=Test3::prop*/ prop ??= getDouble();
+ var /*@ type=double* */ v3 =
+ /*@ type=Test3* */ /*@target=Object::==*/ t
+ ?. /*@target=Test3::prop*/ prop = getDouble();
+ var /*@ type=double* */ v6 =
+ t?. /*@target=Test3::prop*/ prop ??= getDouble();
var /*@ type=double* */ v7 = t?. /*@target=Test3::prop*/ prop += getInt();
var /*@ type=double* */ v8 = t?. /*@target=Test3::prop*/ prop += getNum();
- var /*@ type=double* */ v9 = t?. /*@target=Test3::prop*/ prop += getDouble();
+ var /*@ type=double* */ v9 =
+ t?. /*@target=Test3::prop*/ prop += getDouble();
var /*@ type=double* */ v10 = ++t?. /*@target=Test3::prop*/ prop;
var /*@ type=double* */ v11 = t?. /*@target=Test3::prop*/ prop++;
}
diff --git a/pkg/front_end/testcases/inference/infer_assign_to_property_null_aware_upwards.dart.strong.expect b/pkg/front_end/testcases/inference/infer_assign_to_property_null_aware_upwards.dart.strong.expect
index 2b996bb..891b1bd 100644
--- a/pkg/front_end/testcases/inference/infer_assign_to_property_null_aware_upwards.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/infer_assign_to_property_null_aware_upwards.dart.strong.expect
@@ -8,7 +8,7 @@
: super core::Object::•()
;
static method test(self::Test1* t) → void {
- core::int* v1 = let final self::Test1* #t1 = t in #t1.==(null) ?{core::int*} null : #t1.{self::Test1::prop} = self::getInt();
+ core::int* v1 = let final self::Test1* #t1 = t in #t1.{core::Object::==}(null) ?{core::int*} null : #t1.{self::Test1::prop} = self::getInt();
core::int* v4 = let final self::Test1* #t2 = t in #t2.==(null) ?{core::int*} null : let final core::int* #t3 = #t2.{self::Test1::prop} in #t3.{core::num::==}(null) ?{core::int*} #t2.{self::Test1::prop} = self::getInt() : #t3;
core::int* v7 = let final self::Test1* #t4 = t in #t4.==(null) ?{core::int*} null : #t4.{self::Test1::prop} = #t4.{self::Test1::prop}.{core::num::+}(self::getInt());
core::int* v10 = let final self::Test1* #t5 = t in #t5.==(null) ?{core::int*} null : #t5.{self::Test1::prop} = #t5.{self::Test1::prop}.{core::num::+}(1);
@@ -21,9 +21,9 @@
: super core::Object::•()
;
static method test(self::Test2* t) → void {
- core::int* v1 = let final self::Test2* #t9 = t in #t9.==(null) ?{core::int*} null : #t9.{self::Test2::prop} = self::getInt();
- core::num* v2 = let final self::Test2* #t10 = t in #t10.==(null) ?{core::num*} null : #t10.{self::Test2::prop} = self::getNum();
- core::double* v3 = let final self::Test2* #t11 = t in #t11.==(null) ?{core::double*} null : #t11.{self::Test2::prop} = self::getDouble();
+ core::int* v1 = let final self::Test2* #t9 = t in #t9.{core::Object::==}(null) ?{core::int*} null : #t9.{self::Test2::prop} = self::getInt();
+ core::num* v2 = let final self::Test2* #t10 = t in #t10.{core::Object::==}(null) ?{core::num*} null : #t10.{self::Test2::prop} = self::getNum();
+ core::double* v3 = let final self::Test2* #t11 = t in #t11.{core::Object::==}(null) ?{core::double*} null : #t11.{self::Test2::prop} = self::getDouble();
core::num* v4 = let final self::Test2* #t12 = t in #t12.==(null) ?{core::num*} null : let final core::num* #t13 = #t12.{self::Test2::prop} in #t13.{core::num::==}(null) ?{core::num*} #t12.{self::Test2::prop} = self::getInt() : #t13;
core::num* v5 = let final self::Test2* #t14 = t in #t14.==(null) ?{core::num*} null : let final core::num* #t15 = #t14.{self::Test2::prop} in #t15.{core::num::==}(null) ?{core::num*} #t14.{self::Test2::prop} = self::getNum() : #t15;
core::num* v6 = let final self::Test2* #t16 = t in #t16.==(null) ?{core::num*} null : let final core::num* #t17 = #t16.{self::Test2::prop} in #t17.{core::num::==}(null) ?{core::num*} #t16.{self::Test2::prop} = self::getDouble() : #t17;
@@ -40,7 +40,7 @@
: super core::Object::•()
;
static method test3(self::Test3* t) → void {
- core::double* v3 = let final self::Test3* #t25 = t in #t25.==(null) ?{core::double*} null : #t25.{self::Test3::prop} = self::getDouble();
+ core::double* v3 = let final self::Test3* #t25 = t in #t25.{core::Object::==}(null) ?{core::double*} null : #t25.{self::Test3::prop} = self::getDouble();
core::double* v6 = let final self::Test3* #t26 = t in #t26.==(null) ?{core::double*} null : let final core::double* #t27 = #t26.{self::Test3::prop} in #t27.{core::num::==}(null) ?{core::double*} #t26.{self::Test3::prop} = self::getDouble() : #t27;
core::double* v7 = let final self::Test3* #t28 = t in #t28.==(null) ?{core::double*} null : #t28.{self::Test3::prop} = #t28.{self::Test3::prop}.{core::double::+}(self::getInt());
core::double* v8 = let final self::Test3* #t29 = t in #t29.==(null) ?{core::double*} null : #t29.{self::Test3::prop} = #t29.{self::Test3::prop}.{core::double::+}(self::getNum());
diff --git a/pkg/front_end/testcases/inference/infer_assign_to_property_null_aware_upwards.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/infer_assign_to_property_null_aware_upwards.dart.strong.transformed.expect
index 2b996bb..891b1bd 100644
--- a/pkg/front_end/testcases/inference/infer_assign_to_property_null_aware_upwards.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/infer_assign_to_property_null_aware_upwards.dart.strong.transformed.expect
@@ -8,7 +8,7 @@
: super core::Object::•()
;
static method test(self::Test1* t) → void {
- core::int* v1 = let final self::Test1* #t1 = t in #t1.==(null) ?{core::int*} null : #t1.{self::Test1::prop} = self::getInt();
+ core::int* v1 = let final self::Test1* #t1 = t in #t1.{core::Object::==}(null) ?{core::int*} null : #t1.{self::Test1::prop} = self::getInt();
core::int* v4 = let final self::Test1* #t2 = t in #t2.==(null) ?{core::int*} null : let final core::int* #t3 = #t2.{self::Test1::prop} in #t3.{core::num::==}(null) ?{core::int*} #t2.{self::Test1::prop} = self::getInt() : #t3;
core::int* v7 = let final self::Test1* #t4 = t in #t4.==(null) ?{core::int*} null : #t4.{self::Test1::prop} = #t4.{self::Test1::prop}.{core::num::+}(self::getInt());
core::int* v10 = let final self::Test1* #t5 = t in #t5.==(null) ?{core::int*} null : #t5.{self::Test1::prop} = #t5.{self::Test1::prop}.{core::num::+}(1);
@@ -21,9 +21,9 @@
: super core::Object::•()
;
static method test(self::Test2* t) → void {
- core::int* v1 = let final self::Test2* #t9 = t in #t9.==(null) ?{core::int*} null : #t9.{self::Test2::prop} = self::getInt();
- core::num* v2 = let final self::Test2* #t10 = t in #t10.==(null) ?{core::num*} null : #t10.{self::Test2::prop} = self::getNum();
- core::double* v3 = let final self::Test2* #t11 = t in #t11.==(null) ?{core::double*} null : #t11.{self::Test2::prop} = self::getDouble();
+ core::int* v1 = let final self::Test2* #t9 = t in #t9.{core::Object::==}(null) ?{core::int*} null : #t9.{self::Test2::prop} = self::getInt();
+ core::num* v2 = let final self::Test2* #t10 = t in #t10.{core::Object::==}(null) ?{core::num*} null : #t10.{self::Test2::prop} = self::getNum();
+ core::double* v3 = let final self::Test2* #t11 = t in #t11.{core::Object::==}(null) ?{core::double*} null : #t11.{self::Test2::prop} = self::getDouble();
core::num* v4 = let final self::Test2* #t12 = t in #t12.==(null) ?{core::num*} null : let final core::num* #t13 = #t12.{self::Test2::prop} in #t13.{core::num::==}(null) ?{core::num*} #t12.{self::Test2::prop} = self::getInt() : #t13;
core::num* v5 = let final self::Test2* #t14 = t in #t14.==(null) ?{core::num*} null : let final core::num* #t15 = #t14.{self::Test2::prop} in #t15.{core::num::==}(null) ?{core::num*} #t14.{self::Test2::prop} = self::getNum() : #t15;
core::num* v6 = let final self::Test2* #t16 = t in #t16.==(null) ?{core::num*} null : let final core::num* #t17 = #t16.{self::Test2::prop} in #t17.{core::num::==}(null) ?{core::num*} #t16.{self::Test2::prop} = self::getDouble() : #t17;
@@ -40,7 +40,7 @@
: super core::Object::•()
;
static method test3(self::Test3* t) → void {
- core::double* v3 = let final self::Test3* #t25 = t in #t25.==(null) ?{core::double*} null : #t25.{self::Test3::prop} = self::getDouble();
+ core::double* v3 = let final self::Test3* #t25 = t in #t25.{core::Object::==}(null) ?{core::double*} null : #t25.{self::Test3::prop} = self::getDouble();
core::double* v6 = let final self::Test3* #t26 = t in #t26.==(null) ?{core::double*} null : let final core::double* #t27 = #t26.{self::Test3::prop} in #t27.{core::num::==}(null) ?{core::double*} #t26.{self::Test3::prop} = self::getDouble() : #t27;
core::double* v7 = let final self::Test3* #t28 = t in #t28.==(null) ?{core::double*} null : #t28.{self::Test3::prop} = #t28.{self::Test3::prop}.{core::double::+}(self::getInt());
core::double* v8 = let final self::Test3* #t29 = t in #t29.==(null) ?{core::double*} null : #t29.{self::Test3::prop} = #t29.{self::Test3::prop}.{core::double::+}(self::getNum());
diff --git a/pkg/front_end/testcases/inference/infer_assign_to_property_super.dart b/pkg/front_end/testcases/inference/infer_assign_to_property_super.dart
index 2982026..26313de 100644
--- a/pkg/front_end/testcases/inference/infer_assign_to_property_super.dart
+++ b/pkg/front_end/testcases/inference/infer_assign_to_property_super.dart
@@ -25,22 +25,52 @@
class Test extends Base {
void test() {
super. /*@target=Base::member*/ member = /*@ typeArgs=B* */ f();
- super. /*@target=Base::member*/ member ??= /*@ typeArgs=B* */ f();
- super. /*@target=Base::member*/ member += /*@ typeArgs=dynamic */ f();
- super. /*@target=Base::member*/ member *= /*@ typeArgs=dynamic */ f();
- super. /*@target=Base::member*/ member &= /*@ typeArgs=dynamic */ f();
- --super. /*@target=Base::member*/ member;
- super. /*@target=Base::member*/ member--;
+
+ super. /*@target=Base::member*/ /*@target=Base::member*/ member
+ /*@ target=Object::== */ ??= /*@ typeArgs=B* */ f();
+
+ super. /*@target=Base::member*/ /*@target=Base::member*/ member
+ /*@ target=B::+ */ += /*@ typeArgs=C* */ f();
+
+ super. /*@target=Base::member*/ /*@target=Base::member*/ member
+ /*@ target=B::* */ *= /*@ typeArgs=B* */ f();
+
+ super. /*@target=Base::member*/ /*@target=Base::member*/ member
+ /*@ target=B::& */ &= /*@ typeArgs=A* */ f();
+
+ /*@ target=B::- */ --super
+ . /*@target=Base::member*/ /*@target=Base::member*/ member;
+
+ super. /*@target=Base::member*/ /*@target=Base::member*/ member
+ /*@ target=B::- */ --;
+
var /*@ type=B* */ v1 =
super. /*@target=Base::member*/ member = /*@ typeArgs=B* */ f();
+
var /*@ type=B* */ v2 =
- super. /*@target=Base::member*/ member ??= /*@ typeArgs=B* */ f();
+ super. /*@target=Base::member*/ /*@target=Base::member*/ member
+ /*@ target=Object::== */ ??= /*@ typeArgs=B* */ f();
+
+ var /*@ type=A* */ v3 =
+ super. /*@target=Base::member*/ /*@target=Base::member*/ member
+ /*@ target=B::+ */ += /*@ typeArgs=C* */ f();
+
var /*@ type=B* */ v4 =
- super. /*@target=Base::member*/ member *= /*@ typeArgs=dynamic */ f();
+ super. /*@target=Base::member*/ /*@target=Base::member*/ member
+ /*@ target=B::* */ *= /*@ typeArgs=B* */ f();
+
var /*@ type=C* */ v5 =
- super. /*@target=Base::member*/ member &= /*@ typeArgs=dynamic */ f();
- var /*@ type=B* */ v6 = --super. /*@target=Base::member*/ member;
- var /*@ type=B* */ v7 = super. /*@target=Base::member*/ member--;
+ super. /*@target=Base::member*/ /*@target=Base::member*/ member
+ /*@ target=B::& */ &= /*@ typeArgs=A* */ f();
+
+ var /*@ type=B* */ v6 =
+ /*@ target=B::- */ --super
+ . /*@target=Base::member*/ /*@target=Base::member*/ member;
+
+ var /*@ type=B* */ v7 = super
+ . /*@ type=B* */ /*@target=Base::member*/ /*@target=Base::member*/
+ member
+ /*@ type=B* */ /*@ target=B::- */ --;
}
}
diff --git a/pkg/front_end/testcases/inference/infer_assign_to_property_super.dart.strong.expect b/pkg/front_end/testcases/inference/infer_assign_to_property_super.dart.strong.expect
index 50d58e2..eb317ce 100644
--- a/pkg/front_end/testcases/inference/infer_assign_to_property_super.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/infer_assign_to_property_super.dart.strong.expect
@@ -38,15 +38,16 @@
method test() → void {
super.{self::Base::member} = self::f<self::B*>();
super.{self::Base::member}.{core::Object::==}(null) ?{self::B*} super.{self::Base::member} = self::f<self::B*>() : null;
- super.{self::Base::member} = super.{self::Base::member}.{self::B::+}(self::f<dynamic>() as{TypeError} self::C*) as{TypeError} self::B*;
- super.{self::Base::member} = super.{self::Base::member}.{self::B::*}(self::f<dynamic>() as{TypeError} self::B*);
- super.{self::Base::member} = super.{self::Base::member}.{self::B::&}(self::f<dynamic>() as{TypeError} self::A*);
+ super.{self::Base::member} = super.{self::Base::member}.{self::B::+}(self::f<self::C*>()) as{TypeError} self::B*;
+ super.{self::Base::member} = super.{self::Base::member}.{self::B::*}(self::f<self::B*>());
+ super.{self::Base::member} = super.{self::Base::member}.{self::B::&}(self::f<self::A*>());
super.{self::Base::member} = super.{self::Base::member}.{self::B::-}(1);
super.{self::Base::member} = super.{self::Base::member}.{self::B::-}(1);
self::B* v1 = super.{self::Base::member} = self::f<self::B*>();
self::B* v2 = let final self::B* #t1 = super.{self::Base::member} in #t1.{core::Object::==}(null) ?{self::B*} super.{self::Base::member} = self::f<self::B*>() : #t1;
- self::B* v4 = super.{self::Base::member} = super.{self::Base::member}.{self::B::*}(self::f<dynamic>() as{TypeError} self::B*);
- self::C* v5 = super.{self::Base::member} = super.{self::Base::member}.{self::B::&}(self::f<dynamic>() as{TypeError} self::A*);
+ self::A* v3 = super.{self::Base::member} = super.{self::Base::member}.{self::B::+}(self::f<self::C*>()) as{TypeError} self::B*;
+ self::B* v4 = super.{self::Base::member} = super.{self::Base::member}.{self::B::*}(self::f<self::B*>());
+ self::C* v5 = super.{self::Base::member} = super.{self::Base::member}.{self::B::&}(self::f<self::A*>());
self::B* v6 = super.{self::Base::member} = super.{self::Base::member}.{self::B::-}(1);
self::B* v7 = let final self::B* #t2 = super.{self::Base::member} in let final self::B* #t3 = super.{self::Base::member} = #t2.{self::B::-}(1) in #t2;
}
diff --git a/pkg/front_end/testcases/inference/infer_assign_to_property_super.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/infer_assign_to_property_super.dart.strong.transformed.expect
index 50d58e2..eb317ce 100644
--- a/pkg/front_end/testcases/inference/infer_assign_to_property_super.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/infer_assign_to_property_super.dart.strong.transformed.expect
@@ -38,15 +38,16 @@
method test() → void {
super.{self::Base::member} = self::f<self::B*>();
super.{self::Base::member}.{core::Object::==}(null) ?{self::B*} super.{self::Base::member} = self::f<self::B*>() : null;
- super.{self::Base::member} = super.{self::Base::member}.{self::B::+}(self::f<dynamic>() as{TypeError} self::C*) as{TypeError} self::B*;
- super.{self::Base::member} = super.{self::Base::member}.{self::B::*}(self::f<dynamic>() as{TypeError} self::B*);
- super.{self::Base::member} = super.{self::Base::member}.{self::B::&}(self::f<dynamic>() as{TypeError} self::A*);
+ super.{self::Base::member} = super.{self::Base::member}.{self::B::+}(self::f<self::C*>()) as{TypeError} self::B*;
+ super.{self::Base::member} = super.{self::Base::member}.{self::B::*}(self::f<self::B*>());
+ super.{self::Base::member} = super.{self::Base::member}.{self::B::&}(self::f<self::A*>());
super.{self::Base::member} = super.{self::Base::member}.{self::B::-}(1);
super.{self::Base::member} = super.{self::Base::member}.{self::B::-}(1);
self::B* v1 = super.{self::Base::member} = self::f<self::B*>();
self::B* v2 = let final self::B* #t1 = super.{self::Base::member} in #t1.{core::Object::==}(null) ?{self::B*} super.{self::Base::member} = self::f<self::B*>() : #t1;
- self::B* v4 = super.{self::Base::member} = super.{self::Base::member}.{self::B::*}(self::f<dynamic>() as{TypeError} self::B*);
- self::C* v5 = super.{self::Base::member} = super.{self::Base::member}.{self::B::&}(self::f<dynamic>() as{TypeError} self::A*);
+ self::A* v3 = super.{self::Base::member} = super.{self::Base::member}.{self::B::+}(self::f<self::C*>()) as{TypeError} self::B*;
+ self::B* v4 = super.{self::Base::member} = super.{self::Base::member}.{self::B::*}(self::f<self::B*>());
+ self::C* v5 = super.{self::Base::member} = super.{self::Base::member}.{self::B::&}(self::f<self::A*>());
self::B* v6 = super.{self::Base::member} = super.{self::Base::member}.{self::B::-}(1);
self::B* v7 = let final self::B* #t2 = super.{self::Base::member} in let final self::B* #t3 = super.{self::Base::member} = #t2.{self::B::-}(1) in #t2;
}
diff --git a/pkg/front_end/testcases/inference/infer_assign_to_property_super_upwards.dart b/pkg/front_end/testcases/inference/infer_assign_to_property_super_upwards.dart
index b906755..804769e 100644
--- a/pkg/front_end/testcases/inference/infer_assign_to_property_super_upwards.dart
+++ b/pkg/front_end/testcases/inference/infer_assign_to_property_super_upwards.dart
@@ -17,33 +17,70 @@
class Test1 extends Base {
void test() {
- var /*@ type=int* */ v1 = super. /*@target=Base::intProp*/ intProp = getInt();
+ var /*@ type=int* */ v1 =
+ super. /*@target=Base::intProp*/ intProp = getInt();
+
var /*@ type=int* */ v4 =
- super. /*@target=Base::intProp*/ intProp ??= getInt();
- var /*@ type=int* */ v7 = super. /*@target=Base::intProp*/ intProp += getInt();
- var /*@ type=int* */ v10 = ++super. /*@target=Base::intProp*/ intProp;
- var /*@ type=int* */ v11 = super. /*@target=Base::intProp*/ intProp++;
+ super. /*@target=Base::intProp*/ /*@target=Base::intProp*/ intProp
+ /*@ target=num::==*/ ??= getInt();
+
+ var /*@ type=int* */ v7 =
+ super. /*@target=Base::intProp*/ /*@target=Base::intProp*/ intProp
+ /*@ target=num::+ */ += getInt();
+
+ var /*@ type=int* */ v10 = /*@ target=num::+ */ ++super
+ . /*@target=Base::intProp*/ /*@target=Base::intProp*/ intProp;
+
+ var /*@ type=int* */ v11 = super
+ . /*@ type=int* */ /*@target=Base::intProp*/ /*@target=Base::intProp*/
+ intProp /*@ type=int* */ /*@ target=num::+ */ ++;
}
}
class Test2 extends Base {
void test() {
- var /*@ type=int* */ v1 = super. /*@target=Base::numProp*/ numProp = getInt();
- var /*@ type=num* */ v2 = super. /*@target=Base::numProp*/ numProp = getNum();
+ var /*@ type=int* */ v1 =
+ super. /*@target=Base::numProp*/ numProp = getInt();
+
+ var /*@ type=num* */ v2 =
+ super. /*@target=Base::numProp*/ numProp = getNum();
+
var /*@ type=double* */ v3 =
super. /*@target=Base::numProp*/ numProp = getDouble();
+
var /*@ type=num* */ v4 =
- super. /*@target=Base::numProp*/ numProp ??= getInt();
+ super. /*@target=Base::numProp*/ /*@target=Base::numProp*/ numProp
+ /*@ target=num::==*/ ??= getInt();
+
var /*@ type=num* */ v5 =
- super. /*@target=Base::numProp*/ numProp ??= getNum();
+ super. /*@target=Base::numProp*/ /*@target=Base::numProp*/ numProp
+ /*@ target=num::==*/ ??= getNum();
+
var /*@ type=num* */ v6 =
- super. /*@target=Base::numProp*/ numProp ??= getDouble();
- var /*@ type=num* */ v7 = super. /*@target=Base::numProp*/ numProp += getInt();
- var /*@ type=num* */ v8 = super. /*@target=Base::numProp*/ numProp += getNum();
- var /*@ type=num* */ v9 =
- super. /*@target=Base::numProp*/ numProp += getDouble();
- var /*@ type=num* */ v10 = ++super. /*@target=Base::numProp*/ numProp;
- var /*@ type=num* */ v11 = super. /*@target=Base::numProp*/ numProp++;
+ super. /*@target=Base::numProp*/ /*@target=Base::numProp*/ numProp
+ /*@ target=num::==*/ ??= getDouble();
+
+ var /*@ type=num* */ v7 =
+ super. /*@target=Base::numProp*/ /*@target=Base::numProp*/ numProp
+ /*@ target=num::+ */ += getInt();
+
+ var /*@ type=num* */ v8 =
+ super. /*@target=Base::numProp*/ /*@target=Base::numProp*/ numProp
+ /*@ target=num::+ */ += getNum();
+
+ var /*@ type=num* */ v9 = super
+ .
+ /*@target=Base::numProp*/ /*@target=Base::numProp*/ numProp
+ /*@ target=num::+ */ += getDouble();
+
+ var /*@ type=num* */ v10 = /*@ target=num::+ */ ++super
+ . /*@target=Base::numProp*/ /*@target=Base::numProp*/ numProp;
+
+ var /*@ type=num* */ v11 = super
+ .
+ /*@ type=num* */ /*@target=Base::numProp*/ /*@target=Base::numProp*/
+ numProp
+ /*@ type=num* */ /*@ target=num::+ */ ++;
}
}
@@ -51,16 +88,30 @@
void test3() {
var /*@ type=double* */ v3 =
super. /*@target=Base::doubleProp*/ doubleProp = getDouble();
- var /*@ type=double* */ v6 =
- super. /*@target=Base::doubleProp*/ doubleProp ??= getDouble();
- var /*@ type=double* */ v7 =
- super. /*@target=Base::doubleProp*/ doubleProp += getInt();
- var /*@ type=double* */ v8 =
- super. /*@target=Base::doubleProp*/ doubleProp += getNum();
- var /*@ type=double* */ v9 =
- super. /*@target=Base::doubleProp*/ doubleProp += getDouble();
- var /*@ type=double* */ v10 = ++super. /*@target=Base::doubleProp*/ doubleProp;
- var /*@ type=double* */ v11 = super. /*@target=Base::doubleProp*/ doubleProp++;
+
+ var /*@ type=double* */ v6 = super
+ . /*@target=Base::doubleProp*/ /*@target=Base::doubleProp*/ doubleProp
+ /*@ target=num::==*/ ??= getDouble();
+
+ var /*@ type=double* */ v7 = super
+ . /*@target=Base::doubleProp*/ /*@target=Base::doubleProp*/ doubleProp
+ /*@ target=double::+ */ += getInt();
+
+ var /*@ type=double* */ v8 = super
+ . /*@target=Base::doubleProp*/ /*@target=Base::doubleProp*/ doubleProp
+ /*@ target=double::+ */ += getNum();
+
+ var /*@ type=double* */ v9 = super
+ . /*@target=Base::doubleProp*/ /*@target=Base::doubleProp*/ doubleProp
+ /*@ target=double::+ */ += getDouble();
+
+ var /*@ type=double* */ v10 = /*@ target=double::+ */ ++super
+ . /*@target=Base::doubleProp*/ /*@target=Base::doubleProp*/ doubleProp;
+
+ var /*@ type=double* */ v11 = super
+ . /*@ type=double* */ /*@target=Base::doubleProp*/ /*@target=Base::doubleProp*/
+ doubleProp
+ /*@ type=double* */ /*@ target=double::+ */ ++;
}
}
diff --git a/pkg/front_end/testcases/inference/infer_assign_to_property_upwards.dart b/pkg/front_end/testcases/inference/infer_assign_to_property_upwards.dart
index 37e74b9..10dac09 100644
--- a/pkg/front_end/testcases/inference/infer_assign_to_property_upwards.dart
+++ b/pkg/front_end/testcases/inference/infer_assign_to_property_upwards.dart
@@ -14,10 +14,18 @@
static void test(Test1 t) {
var /*@ type=int* */ v1 = t. /*@target=Test1::prop*/ prop = getInt();
- var /*@ type=int* */ v4 = t. /*@target=Test1::prop*/ prop ??= getInt();
- var /*@ type=int* */ v7 = t. /*@target=Test1::prop*/ prop += getInt();
- var /*@ type=int* */ v10 = ++t. /*@target=Test1::prop*/ prop;
- var /*@ type=int* */ v11 = t. /*@target=Test1::prop*/ prop++;
+ var /*@ type=int* */ v4 = /*@ type=Test1* */ t
+ . /*@target=Test1::prop*/ /*@target=Test1::prop*/ prop
+ /*@target=num::==*/ ??= getInt();
+ var /*@ type=int* */ v7 =
+ /*@ type=Test1* */ t
+ . /*@target=Test1::prop*/ /*@target=Test1::prop*/ prop
+ /*@ target=num::+ */ += getInt();
+ var /*@ type=int* */ v10 = /*@ target=num::+ */ ++ /*@ type=Test1* */ t
+ . /*@target=Test1::prop*/ /*@target=Test1::prop*/ prop;
+ var /*@ type=int* */ v11 = /*@ type=Test1* */ t
+ . /*@ type=int* */ /*@target=Test1::prop*/ /*@target=Test1::prop*/
+ prop /*@ type=int* */ /*@ target=num::+ */ ++;
}
}
@@ -28,14 +36,32 @@
var /*@ type=int* */ v1 = t. /*@target=Test2::prop*/ prop = getInt();
var /*@ type=num* */ v2 = t. /*@target=Test2::prop*/ prop = getNum();
var /*@ type=double* */ v3 = t. /*@target=Test2::prop*/ prop = getDouble();
- var /*@ type=num* */ v4 = t. /*@target=Test2::prop*/ prop ??= getInt();
- var /*@ type=num* */ v5 = t. /*@target=Test2::prop*/ prop ??= getNum();
- var /*@ type=num* */ v6 = t. /*@target=Test2::prop*/ prop ??= getDouble();
- var /*@ type=num* */ v7 = t. /*@target=Test2::prop*/ prop += getInt();
- var /*@ type=num* */ v8 = t. /*@target=Test2::prop*/ prop += getNum();
- var /*@ type=num* */ v9 = t. /*@target=Test2::prop*/ prop += getDouble();
- var /*@ type=num* */ v10 = ++t. /*@target=Test2::prop*/ prop;
- var /*@ type=num* */ v11 = t. /*@target=Test2::prop*/ prop++;
+ var /*@ type=num* */ v4 = /*@ type=Test2* */ t
+ . /*@target=Test2::prop*/ /*@target=Test2::prop*/ prop
+ /*@target=num::==*/ ??= getInt();
+ var /*@ type=num* */ v5 = /*@ type=Test2* */ t
+ . /*@target=Test2::prop*/ /*@target=Test2::prop*/ prop
+ /*@target=num::==*/ ??= getNum();
+ var /*@ type=num* */ v6 = /*@ type=Test2* */ t
+ . /*@target=Test2::prop*/ /*@target=Test2::prop*/ prop
+ /*@target=num::==*/ ??= getDouble();
+ var /*@ type=num* */ v7 =
+ /*@ type=Test2* */ t
+ . /*@target=Test2::prop*/ /*@target=Test2::prop*/ prop
+ /*@ target=num::+ */ += getInt();
+ var /*@ type=num* */ v8 =
+ /*@ type=Test2* */ t
+ . /*@target=Test2::prop*/ /*@target=Test2::prop*/ prop
+ /*@ target=num::+ */ += getNum();
+ var /*@ type=num* */ v9 =
+ /*@ type=Test2* */ t
+ . /*@target=Test2::prop*/ /*@target=Test2::prop*/ prop
+ /*@ target=num::+ */ += getDouble();
+ var /*@ type=num* */ v10 = /*@ target=num::+ */ ++ /*@ type=Test2* */ t
+ . /*@target=Test2::prop*/ /*@target=Test2::prop*/ prop;
+ var /*@ type=num* */ v11 = /*@ type=Test2* */ t
+ . /*@ type=num* */ /*@target=Test2::prop*/ /*@target=Test2::prop*/
+ prop /*@ type=num* */ /*@ target=num::+ */ ++;
}
}
@@ -44,12 +70,28 @@
static void test3(Test3 t) {
var /*@ type=double* */ v3 = t. /*@target=Test3::prop*/ prop = getDouble();
- var /*@ type=double* */ v6 = t. /*@target=Test3::prop*/ prop ??= getDouble();
- var /*@ type=double* */ v7 = t. /*@target=Test3::prop*/ prop += getInt();
- var /*@ type=double* */ v8 = t. /*@target=Test3::prop*/ prop += getNum();
- var /*@ type=double* */ v9 = t. /*@target=Test3::prop*/ prop += getDouble();
- var /*@ type=double* */ v10 = ++t. /*@target=Test3::prop*/ prop;
- var /*@ type=double* */ v11 = t. /*@target=Test3::prop*/ prop++;
+ var /*@ type=double* */ v6 =
+ /*@ type=Test3* */ t. /*@target=Test3::prop*/ /*@target=Test3::prop*/
+ prop /*@target=num::==*/ ??= getDouble();
+ var /*@ type=double* */ v7 =
+ /*@ type=Test3* */ t
+ . /*@target=Test3::prop*/ /*@target=Test3::prop*/ prop
+ /*@ target=double::+ */ += getInt();
+ var /*@ type=double* */ v8 =
+ /*@ type=Test3* */ t
+ . /*@target=Test3::prop*/ /*@target=Test3::prop*/ prop
+ /*@ target=double::+ */ += getNum();
+ var /*@ type=double* */ v9 =
+ /*@ type=Test3* */ t
+ . /*@target=Test3::prop*/ /*@target=Test3::prop*/ prop
+ /*@ target=double::+ */ += getDouble();
+ var /*@ type=double* */ v10 = /*@ target=double::+ */ ++ /*@ type=Test3* */ t
+ .
+ /*@target=Test3::prop*/ /*@target=Test3::prop*/
+ prop;
+ var /*@ type=double* */ v11 = /*@ type=Test3* */ t.
+ /*@ type=double* */ /*@target=Test3::prop*/ /*@target=Test3::prop*/
+ prop /*@ type=double* */ /*@ target=double::+ */ ++;
}
}
diff --git a/pkg/front_end/testcases/inference/infer_assign_to_static.dart b/pkg/front_end/testcases/inference/infer_assign_to_static.dart
index 56a5f89..33bd5fe 100644
--- a/pkg/front_end/testcases/inference/infer_assign_to_static.dart
+++ b/pkg/front_end/testcases/inference/infer_assign_to_static.dart
@@ -24,34 +24,72 @@
void test_topLevelVariable() {
topLevelVariable = /*@ typeArgs=B* */ f();
- topLevelVariable ??= /*@ typeArgs=B* */ f();
- topLevelVariable += /*@ typeArgs=dynamic */ f();
- topLevelVariable *= /*@ typeArgs=dynamic */ f();
- topLevelVariable &= /*@ typeArgs=dynamic */ f();
- --topLevelVariable;
- topLevelVariable--;
+
+ topLevelVariable /*@ target=Object::== */ ??= /*@ typeArgs=B* */ f();
+
+ topLevelVariable /*@ target=B::+ */ += /*@ typeArgs=C* */ f();
+
+ topLevelVariable /*@ target=B::* */ *= /*@ typeArgs=B* */ f();
+
+ topLevelVariable /*@ target=B::& */ &= /*@ typeArgs=A* */ f();
+
+ /*@ target=B::- */ --topLevelVariable;
+
+ topLevelVariable /*@ target=B::- */ --;
+
var /*@ type=B* */ v1 = topLevelVariable = /*@ typeArgs=B* */ f();
- var /*@ type=B* */ v2 = topLevelVariable ??= /*@ typeArgs=B* */ f();
- var /*@ type=B* */ v4 = topLevelVariable *= /*@ typeArgs=dynamic */ f();
- var /*@ type=C* */ v5 = topLevelVariable &= /*@ typeArgs=dynamic */ f();
- var /*@ type=B* */ v6 = --topLevelVariable;
- var /*@ type=B* */ v7 = topLevelVariable--;
+
+ var /*@ type=B* */ v2 =
+ topLevelVariable /*@ target=Object::== */ ??= /*@ typeArgs=B* */ f();
+
+ var /*@ type=A* */ v3 =
+ topLevelVariable /*@ target=B::+ */ += /*@ typeArgs=C* */ f();
+
+ var /*@ type=B* */ v4 =
+ topLevelVariable /*@ target=B::* */ *= /*@ typeArgs=B* */ f();
+
+ var /*@ type=C* */ v5 =
+ topLevelVariable /*@ target=B::& */ &= /*@ typeArgs=A* */ f();
+
+ var /*@ type=B* */ v6 = /*@ target=B::- */ --topLevelVariable;
+
+ var /*@ type=B* */ v7 = /*@ type=B* */ topLevelVariable
+ /*@ type=B* */ /*@ target=B::- */ --;
}
void test_staticVariable() {
B.staticVariable = /*@ typeArgs=B* */ f();
- B.staticVariable ??= /*@ typeArgs=B* */ f();
- B.staticVariable += /*@ typeArgs=dynamic */ f();
- B.staticVariable *= /*@ typeArgs=dynamic */ f();
- B.staticVariable &= /*@ typeArgs=dynamic */ f();
- --B.staticVariable;
- B.staticVariable--;
+
+ B.staticVariable /*@ target=Object::== */ ??= /*@ typeArgs=B* */ f();
+
+ B.staticVariable /*@ target=B::+ */ += /*@ typeArgs=C* */ f();
+
+ B.staticVariable /*@ target=B::* */ *= /*@ typeArgs=B* */ f();
+
+ B.staticVariable /*@ target=B::& */ &= /*@ typeArgs=A* */ f();
+
+ /*@ target=B::- */ --B.staticVariable;
+
+ B.staticVariable /*@ target=B::- */ --;
+
var /*@ type=B* */ v1 = B.staticVariable = /*@ typeArgs=B* */ f();
- var /*@ type=B* */ v2 = B.staticVariable ??= /*@ typeArgs=B* */ f();
- var /*@ type=B* */ v4 = B.staticVariable *= /*@ typeArgs=dynamic */ f();
- var /*@ type=C* */ v5 = B.staticVariable &= /*@ typeArgs=dynamic */ f();
- var /*@ type=B* */ v6 = --B.staticVariable;
- var /*@ type=B* */ v7 = B.staticVariable--;
+
+ var /*@ type=B* */ v2 =
+ B.staticVariable /*@ target=Object::== */ ??= /*@ typeArgs=B* */ f();
+
+ var /*@ type=A* */ v3 =
+ B.staticVariable /*@ target=B::+ */ += /*@ typeArgs=C* */ f();
+
+ var /*@ type=B* */ v4 =
+ B.staticVariable /*@ target=B::* */ *= /*@ typeArgs=B* */ f();
+
+ var /*@ type=C* */ v5 =
+ B.staticVariable /*@ target=B::& */ &= /*@ typeArgs=A* */ f();
+
+ var /*@ type=B* */ v6 = /*@ target=B::- */ --B.staticVariable;
+
+ var /*@ type=B* */ v7 =
+ B. /*@ type=B* */ staticVariable /*@ type=B* */ /*@ target=B::- */ --;
}
main() {}
diff --git a/pkg/front_end/testcases/inference/infer_assign_to_static.dart.strong.expect b/pkg/front_end/testcases/inference/infer_assign_to_static.dart.strong.expect
index 8ef6b74..2c07ffd 100644
--- a/pkg/front_end/testcases/inference/infer_assign_to_static.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/infer_assign_to_static.dart.strong.expect
@@ -32,30 +32,32 @@
static method test_topLevelVariable() → void {
self::topLevelVariable = self::f<self::B*>();
self::topLevelVariable.{core::Object::==}(null) ?{self::B*} self::topLevelVariable = self::f<self::B*>() : null;
- self::topLevelVariable = self::topLevelVariable.{self::B::+}(self::f<dynamic>() as{TypeError} self::C*) as{TypeError} self::B*;
- self::topLevelVariable = self::topLevelVariable.{self::B::*}(self::f<dynamic>() as{TypeError} self::B*);
- self::topLevelVariable = self::topLevelVariable.{self::B::&}(self::f<dynamic>() as{TypeError} self::A*);
+ self::topLevelVariable = self::topLevelVariable.{self::B::+}(self::f<self::C*>()) as{TypeError} self::B*;
+ self::topLevelVariable = self::topLevelVariable.{self::B::*}(self::f<self::B*>());
+ self::topLevelVariable = self::topLevelVariable.{self::B::&}(self::f<self::A*>());
self::topLevelVariable = self::topLevelVariable.{self::B::-}(1);
self::topLevelVariable = self::topLevelVariable.{self::B::-}(1);
self::B* v1 = self::topLevelVariable = self::f<self::B*>();
self::B* v2 = let final self::B* #t1 = self::topLevelVariable in #t1.{core::Object::==}(null) ?{self::B*} self::topLevelVariable = self::f<self::B*>() : #t1;
- self::B* v4 = self::topLevelVariable = self::topLevelVariable.{self::B::*}(self::f<dynamic>() as{TypeError} self::B*);
- self::C* v5 = self::topLevelVariable = self::topLevelVariable.{self::B::&}(self::f<dynamic>() as{TypeError} self::A*);
+ self::A* v3 = self::topLevelVariable = self::topLevelVariable.{self::B::+}(self::f<self::C*>()) as{TypeError} self::B*;
+ self::B* v4 = self::topLevelVariable = self::topLevelVariable.{self::B::*}(self::f<self::B*>());
+ self::C* v5 = self::topLevelVariable = self::topLevelVariable.{self::B::&}(self::f<self::A*>());
self::B* v6 = self::topLevelVariable = self::topLevelVariable.{self::B::-}(1);
self::B* v7 = let final self::B* #t2 = self::topLevelVariable in let final self::B* #t3 = self::topLevelVariable = #t2.{self::B::-}(1) in #t2;
}
static method test_staticVariable() → void {
self::B::staticVariable = self::f<self::B*>();
self::B::staticVariable.{core::Object::==}(null) ?{self::B*} self::B::staticVariable = self::f<self::B*>() : null;
- self::B::staticVariable = self::B::staticVariable.{self::B::+}(self::f<dynamic>() as{TypeError} self::C*) as{TypeError} self::B*;
- self::B::staticVariable = self::B::staticVariable.{self::B::*}(self::f<dynamic>() as{TypeError} self::B*);
- self::B::staticVariable = self::B::staticVariable.{self::B::&}(self::f<dynamic>() as{TypeError} self::A*);
+ self::B::staticVariable = self::B::staticVariable.{self::B::+}(self::f<self::C*>()) as{TypeError} self::B*;
+ self::B::staticVariable = self::B::staticVariable.{self::B::*}(self::f<self::B*>());
+ self::B::staticVariable = self::B::staticVariable.{self::B::&}(self::f<self::A*>());
self::B::staticVariable = self::B::staticVariable.{self::B::-}(1);
self::B::staticVariable = self::B::staticVariable.{self::B::-}(1);
self::B* v1 = self::B::staticVariable = self::f<self::B*>();
self::B* v2 = let final self::B* #t4 = self::B::staticVariable in #t4.{core::Object::==}(null) ?{self::B*} self::B::staticVariable = self::f<self::B*>() : #t4;
- self::B* v4 = self::B::staticVariable = self::B::staticVariable.{self::B::*}(self::f<dynamic>() as{TypeError} self::B*);
- self::C* v5 = self::B::staticVariable = self::B::staticVariable.{self::B::&}(self::f<dynamic>() as{TypeError} self::A*);
+ self::A* v3 = self::B::staticVariable = self::B::staticVariable.{self::B::+}(self::f<self::C*>()) as{TypeError} self::B*;
+ self::B* v4 = self::B::staticVariable = self::B::staticVariable.{self::B::*}(self::f<self::B*>());
+ self::C* v5 = self::B::staticVariable = self::B::staticVariable.{self::B::&}(self::f<self::A*>());
self::B* v6 = self::B::staticVariable = self::B::staticVariable.{self::B::-}(1);
self::B* v7 = let final self::B* #t5 = self::B::staticVariable in let final self::B* #t6 = self::B::staticVariable = #t5.{self::B::-}(1) in #t5;
}
diff --git a/pkg/front_end/testcases/inference/infer_assign_to_static.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/infer_assign_to_static.dart.strong.transformed.expect
index 8ef6b74..2c07ffd 100644
--- a/pkg/front_end/testcases/inference/infer_assign_to_static.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/infer_assign_to_static.dart.strong.transformed.expect
@@ -32,30 +32,32 @@
static method test_topLevelVariable() → void {
self::topLevelVariable = self::f<self::B*>();
self::topLevelVariable.{core::Object::==}(null) ?{self::B*} self::topLevelVariable = self::f<self::B*>() : null;
- self::topLevelVariable = self::topLevelVariable.{self::B::+}(self::f<dynamic>() as{TypeError} self::C*) as{TypeError} self::B*;
- self::topLevelVariable = self::topLevelVariable.{self::B::*}(self::f<dynamic>() as{TypeError} self::B*);
- self::topLevelVariable = self::topLevelVariable.{self::B::&}(self::f<dynamic>() as{TypeError} self::A*);
+ self::topLevelVariable = self::topLevelVariable.{self::B::+}(self::f<self::C*>()) as{TypeError} self::B*;
+ self::topLevelVariable = self::topLevelVariable.{self::B::*}(self::f<self::B*>());
+ self::topLevelVariable = self::topLevelVariable.{self::B::&}(self::f<self::A*>());
self::topLevelVariable = self::topLevelVariable.{self::B::-}(1);
self::topLevelVariable = self::topLevelVariable.{self::B::-}(1);
self::B* v1 = self::topLevelVariable = self::f<self::B*>();
self::B* v2 = let final self::B* #t1 = self::topLevelVariable in #t1.{core::Object::==}(null) ?{self::B*} self::topLevelVariable = self::f<self::B*>() : #t1;
- self::B* v4 = self::topLevelVariable = self::topLevelVariable.{self::B::*}(self::f<dynamic>() as{TypeError} self::B*);
- self::C* v5 = self::topLevelVariable = self::topLevelVariable.{self::B::&}(self::f<dynamic>() as{TypeError} self::A*);
+ self::A* v3 = self::topLevelVariable = self::topLevelVariable.{self::B::+}(self::f<self::C*>()) as{TypeError} self::B*;
+ self::B* v4 = self::topLevelVariable = self::topLevelVariable.{self::B::*}(self::f<self::B*>());
+ self::C* v5 = self::topLevelVariable = self::topLevelVariable.{self::B::&}(self::f<self::A*>());
self::B* v6 = self::topLevelVariable = self::topLevelVariable.{self::B::-}(1);
self::B* v7 = let final self::B* #t2 = self::topLevelVariable in let final self::B* #t3 = self::topLevelVariable = #t2.{self::B::-}(1) in #t2;
}
static method test_staticVariable() → void {
self::B::staticVariable = self::f<self::B*>();
self::B::staticVariable.{core::Object::==}(null) ?{self::B*} self::B::staticVariable = self::f<self::B*>() : null;
- self::B::staticVariable = self::B::staticVariable.{self::B::+}(self::f<dynamic>() as{TypeError} self::C*) as{TypeError} self::B*;
- self::B::staticVariable = self::B::staticVariable.{self::B::*}(self::f<dynamic>() as{TypeError} self::B*);
- self::B::staticVariable = self::B::staticVariable.{self::B::&}(self::f<dynamic>() as{TypeError} self::A*);
+ self::B::staticVariable = self::B::staticVariable.{self::B::+}(self::f<self::C*>()) as{TypeError} self::B*;
+ self::B::staticVariable = self::B::staticVariable.{self::B::*}(self::f<self::B*>());
+ self::B::staticVariable = self::B::staticVariable.{self::B::&}(self::f<self::A*>());
self::B::staticVariable = self::B::staticVariable.{self::B::-}(1);
self::B::staticVariable = self::B::staticVariable.{self::B::-}(1);
self::B* v1 = self::B::staticVariable = self::f<self::B*>();
self::B* v2 = let final self::B* #t4 = self::B::staticVariable in #t4.{core::Object::==}(null) ?{self::B*} self::B::staticVariable = self::f<self::B*>() : #t4;
- self::B* v4 = self::B::staticVariable = self::B::staticVariable.{self::B::*}(self::f<dynamic>() as{TypeError} self::B*);
- self::C* v5 = self::B::staticVariable = self::B::staticVariable.{self::B::&}(self::f<dynamic>() as{TypeError} self::A*);
+ self::A* v3 = self::B::staticVariable = self::B::staticVariable.{self::B::+}(self::f<self::C*>()) as{TypeError} self::B*;
+ self::B* v4 = self::B::staticVariable = self::B::staticVariable.{self::B::*}(self::f<self::B*>());
+ self::C* v5 = self::B::staticVariable = self::B::staticVariable.{self::B::&}(self::f<self::A*>());
self::B* v6 = self::B::staticVariable = self::B::staticVariable.{self::B::-}(1);
self::B* v7 = let final self::B* #t5 = self::B::staticVariable in let final self::B* #t6 = self::B::staticVariable = #t5.{self::B::-}(1) in #t5;
}
diff --git a/pkg/front_end/testcases/inference/infer_assign_to_static_upwards.dart b/pkg/front_end/testcases/inference/infer_assign_to_static_upwards.dart
index bfb7da2..eb199fc 100644
--- a/pkg/front_end/testcases/inference/infer_assign_to_static_upwards.dart
+++ b/pkg/front_end/testcases/inference/infer_assign_to_static_upwards.dart
@@ -15,34 +15,61 @@
void test1() {
var /*@ type=int* */ v1 = topLevelInt = getInt();
- var /*@ type=int* */ v4 = topLevelInt ??= getInt();
- var /*@ type=int* */ v7 = topLevelInt += getInt();
- var /*@ type=int* */ v10 = ++topLevelInt;
- var /*@ type=int* */ v11 = topLevelInt++;
+
+ var /*@ type=int* */ v4 = topLevelInt /*@ target=num::== */ ??= getInt();
+
+ var /*@ type=int* */ v7 = topLevelInt /*@ target=num::+ */ += getInt();
+
+ var /*@ type=int* */ v10 = /*@ target=num::+ */ ++topLevelInt;
+
+ var /*@ type=int* */ v11 = /*@ type=int* */ topLevelInt
+ /*@ type=int* */ /*@ target=num::+ */ ++;
}
void test2() {
var /*@ type=int* */ v1 = topLevelNum = getInt();
+
var /*@ type=num* */ v2 = topLevelNum = getNum();
+
var /*@ type=double* */ v3 = topLevelNum = getDouble();
- var /*@ type=num* */ v4 = topLevelNum ??= getInt();
- var /*@ type=num* */ v5 = topLevelNum ??= getNum();
- var /*@ type=num* */ v6 = topLevelNum ??= getDouble();
- var /*@ type=num* */ v7 = topLevelNum += getInt();
- var /*@ type=num* */ v8 = topLevelNum += getNum();
- var /*@ type=num* */ v9 = topLevelNum += getDouble();
- var /*@ type=num* */ v10 = ++topLevelNum;
- var /*@ type=num* */ v11 = topLevelNum++;
+
+ var /*@ type=num* */ v4 = topLevelNum /*@ target=num::== */ ??= getInt();
+
+ var /*@ type=num* */ v5 = topLevelNum /*@ target=num::== */ ??= getNum();
+
+ var /*@ type=num* */ v6 = topLevelNum /*@ target=num::== */ ??= getDouble();
+
+ var /*@ type=num* */ v7 = topLevelNum /*@ target=num::+ */ += getInt();
+
+ var /*@ type=num* */ v8 = topLevelNum /*@ target=num::+ */ += getNum();
+
+ var /*@ type=num* */ v9 = topLevelNum /*@ target=num::+ */ += getDouble();
+
+ var /*@ type=num* */ v10 = /*@ target=num::+ */ ++topLevelNum;
+
+ var /*@ type=num* */ v11 = /*@ type=num* */ topLevelNum
+ /*@ type=num* */ /*@ target=num::+ */ ++;
}
void test3() {
var /*@ type=double* */ v3 = topLevelDouble = getDouble();
- var /*@ type=double* */ v6 = topLevelDouble ??= getDouble();
- var /*@ type=double* */ v7 = topLevelDouble += getInt();
- var /*@ type=double* */ v8 = topLevelDouble += getNum();
- var /*@ type=double* */ v9 = topLevelDouble += getDouble();
- var /*@ type=double* */ v10 = ++topLevelDouble;
- var /*@ type=double* */ v11 = topLevelDouble++;
+
+ var /*@ type=double* */ v6 =
+ topLevelDouble /*@ target=num::== */ ??= getDouble();
+
+ var /*@ type=double* */ v7 =
+ topLevelDouble /*@ target=double::+ */ += getInt();
+
+ var /*@ type=double* */ v8 =
+ topLevelDouble /*@ target=double::+ */ += getNum();
+
+ var /*@ type=double* */ v9 =
+ topLevelDouble /*@ target=double::+ */ += getDouble();
+
+ var /*@ type=double* */ v10 = /*@ target=double::+ */ ++topLevelDouble;
+
+ var /*@ type=double* */ v11 = /*@ type=double* */ topLevelDouble
+ /*@ type=double* */ /*@ target=double::+ */ ++;
}
main() {}
diff --git a/pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart.strong.expect b/pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart.strong.expect
index 0122ef4..0dd5e96 100644
--- a/pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart.strong.expect
@@ -134,33 +134,43 @@
^" in "hi" as{TypeError} self::B*;
self::b = new self::B::•(3);
self::c1 = <dynamic>[];
- self::c1 = let final core::Set<dynamic>* #t5 = col::LinkedHashSet::•<dynamic>() in #t5;
+ self::c1 = let final<BottomType> #t5 = invalid-expression "pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart:41:59: Error: A value of type 'Set<dynamic>' can't be assigned to a variable of type 'List<dynamic>'.
+ - 'Set' is from 'dart:core'.
+ - 'List' is from 'dart:core'.
+Try changing the type of the left hand side, or casting the right hand side to 'List<dynamic>'.
+ c1 = /*error:INVALID_ASSIGNMENT*/ /*@typeArgs=dynamic*/ {};
+ ^" in (let final core::Set<dynamic>* #t6 = col::LinkedHashSet::•<dynamic>() in #t6) as{TypeError} core::List<dynamic>*;
self::c2 = <dynamic>[];
- self::c2 = let final core::Set<dynamic>* #t6 = col::LinkedHashSet::•<dynamic>() in #t6;
+ self::c2 = let final<BottomType> #t7 = invalid-expression "pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart:43:59: Error: A value of type 'Set<dynamic>' can't be assigned to a variable of type 'List<dynamic>'.
+ - 'Set' is from 'dart:core'.
+ - 'List' is from 'dart:core'.
+Try changing the type of the left hand side, or casting the right hand side to 'List<dynamic>'.
+ c2 = /*error:INVALID_ASSIGNMENT*/ /*@typeArgs=dynamic*/ {};
+ ^" in (let final core::Set<dynamic>* #t8 = col::LinkedHashSet::•<dynamic>() in #t8) as{TypeError} core::List<dynamic>*;
self::d = <dynamic, dynamic>{};
- self::d = let final<BottomType> #t7 = invalid-expression "pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart:45:36: Error: A value of type 'int' can't be assigned to a variable of type 'Map<dynamic, dynamic>'.
+ self::d = let final<BottomType> #t9 = invalid-expression "pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart:45:36: Error: A value of type 'int' can't be assigned to a variable of type 'Map<dynamic, dynamic>'.
- 'Map' is from 'dart:core'.
Try changing the type of the left hand side, or casting the right hand side to 'Map<dynamic, dynamic>'.
d = /*error:INVALID_ASSIGNMENT*/ 3;
^" in 3 as{TypeError} core::Map<dynamic, dynamic>*;
self::e = new self::A::•();
- self::e = let final<BottomType> #t8 = invalid-expression "pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart:47:67: Error: A value of type 'Map<dynamic, dynamic>' can't be assigned to a variable of type 'A'.
+ self::e = let final<BottomType> #t10 = invalid-expression "pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart:47:67: Error: A value of type 'Map<dynamic, dynamic>' can't be assigned to a variable of type 'A'.
- 'Map' is from 'dart:core'.
- 'A' is from 'pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart'.
Try changing the type of the left hand side, or casting the right hand side to 'A'.
e = /*error:INVALID_ASSIGNMENT*/ /*@typeArgs=dynamic, dynamic*/ {};
^" in <dynamic, dynamic>{} as{TypeError} self::A*;
self::f = 3;
- self::f = let final<BottomType> #t9 = invalid-expression "pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart:49:36: Error: A value of type 'bool' can't be assigned to a variable of type 'int'.
+ self::f = let final<BottomType> #t11 = invalid-expression "pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart:49:36: Error: A value of type 'bool' can't be assigned to a variable of type 'int'.
Try changing the type of the left hand side, or casting the right hand side to 'int'.
f = /*error:INVALID_ASSIGNMENT*/ false;
^" in false as{TypeError} core::int*;
self::g = 1;
- self::g = let final<BottomType> #t10 = invalid-expression "pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart:51:36: Error: A value of type 'bool' can't be assigned to a variable of type 'int'.
+ self::g = let final<BottomType> #t12 = invalid-expression "pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart:51:36: Error: A value of type 'bool' can't be assigned to a variable of type 'int'.
Try changing the type of the left hand side, or casting the right hand side to 'int'.
g = /*error:INVALID_ASSIGNMENT*/ false;
^" in false as{TypeError} core::int*;
- self::h = let final<BottomType> #t11 = invalid-expression "pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart:52:36: Error: A value of type 'bool' can't be assigned to a variable of type 'B'.
+ self::h = let final<BottomType> #t13 = invalid-expression "pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart:52:36: Error: A value of type 'bool' can't be assigned to a variable of type 'B'.
- 'B' is from 'pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart'.
Try changing the type of the left hand side, or casting the right hand side to 'B'.
h = /*error:INVALID_ASSIGNMENT*/ false;
@@ -168,12 +178,12 @@
self::h = new self::B::•("b");
self::i = false;
self::j = new self::B::•("b");
- self::j = let final<BottomType> #t12 = invalid-expression "pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart:56:36: Error: A value of type 'bool' can't be assigned to a variable of type 'B'.
+ self::j = let final<BottomType> #t14 = invalid-expression "pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart:56:36: Error: A value of type 'bool' can't be assigned to a variable of type 'B'.
- 'B' is from 'pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart'.
Try changing the type of the left hand side, or casting the right hand side to 'B'.
j = /*error:INVALID_ASSIGNMENT*/ false;
^" in false as{TypeError} self::B*;
- self::j = let final<BottomType> #t13 = invalid-expression "pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart:57:58: Error: A value of type 'List<dynamic>' can't be assigned to a variable of type 'B'.
+ self::j = let final<BottomType> #t15 = invalid-expression "pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart:57:58: Error: A value of type 'List<dynamic>' can't be assigned to a variable of type 'B'.
- 'List' is from 'dart:core'.
- 'B' is from 'pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart'.
Try changing the type of the left hand side, or casting the right hand side to 'B'.
diff --git a/pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart.strong.transformed.expect
index 93049fd1..1766be7 100644
--- a/pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart.strong.transformed.expect
@@ -1,107 +1,197 @@
library test;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart:19:46: Error: Getter not found: 'x'.
+// var b = new B(/*error:UNDEFINED_IDENTIFIER*/ x); // allocations
+// ^
+//
+// pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart:21:34: Error: Getter not found: 'x'.
+// /*error:UNDEFINED_IDENTIFIER*/ x
+// ^
+//
+// pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart:32:58: Error: The method 'unary-' isn't defined for the class 'A'.
+// - 'A' is from 'pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart'.
+// Try correcting the name to the name of an existing method, or defining a method named 'unary-'.
+// var i = /*error:UNDEFINED_OPERATOR,info:DYNAMIC_INVOKE*/ -new A();
+// ^
+//
+// pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart:36:36: Error: A value of type 'String' can't be assigned to a variable of type 'A'.
+// - 'A' is from 'pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart'.
+// Try changing the type of the left hand side, or casting the right hand side to 'A'.
+// a = /*error:INVALID_ASSIGNMENT*/ "hi";
+// ^
+//
+// pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart:38:36: Error: A value of type 'String' can't be assigned to a variable of type 'B'.
+// - 'B' is from 'pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart'.
+// Try changing the type of the left hand side, or casting the right hand side to 'B'.
+// b = /*error:INVALID_ASSIGNMENT*/ "hi";
+// ^
+//
+// pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart:41:59: Error: A value of type 'Set<dynamic>' can't be assigned to a variable of type 'List<dynamic>'.
+// - 'Set' is from 'dart:core'.
+// - 'List' is from 'dart:core'.
+// Try changing the type of the left hand side, or casting the right hand side to 'List<dynamic>'.
+// c1 = /*error:INVALID_ASSIGNMENT*/ /*@typeArgs=dynamic*/ {};
+// ^
+//
+// pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart:43:59: Error: A value of type 'Set<dynamic>' can't be assigned to a variable of type 'List<dynamic>'.
+// - 'Set' is from 'dart:core'.
+// - 'List' is from 'dart:core'.
+// Try changing the type of the left hand side, or casting the right hand side to 'List<dynamic>'.
+// c2 = /*error:INVALID_ASSIGNMENT*/ /*@typeArgs=dynamic*/ {};
+// ^
+//
+// pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart:45:36: Error: A value of type 'int' can't be assigned to a variable of type 'Map<dynamic, dynamic>'.
+// - 'Map' is from 'dart:core'.
+// Try changing the type of the left hand side, or casting the right hand side to 'Map<dynamic, dynamic>'.
+// d = /*error:INVALID_ASSIGNMENT*/ 3;
+// ^
+//
+// pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart:47:67: Error: A value of type 'Map<dynamic, dynamic>' can't be assigned to a variable of type 'A'.
+// - 'Map' is from 'dart:core'.
+// - 'A' is from 'pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart'.
+// Try changing the type of the left hand side, or casting the right hand side to 'A'.
+// e = /*error:INVALID_ASSIGNMENT*/ /*@typeArgs=dynamic, dynamic*/ {};
+// ^
+//
+// pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart:49:36: Error: A value of type 'bool' can't be assigned to a variable of type 'int'.
+// Try changing the type of the left hand side, or casting the right hand side to 'int'.
+// f = /*error:INVALID_ASSIGNMENT*/ false;
+// ^
+//
+// pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart:51:36: Error: A value of type 'bool' can't be assigned to a variable of type 'int'.
+// Try changing the type of the left hand side, or casting the right hand side to 'int'.
+// g = /*error:INVALID_ASSIGNMENT*/ false;
+// ^
+//
+// pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart:52:36: Error: A value of type 'bool' can't be assigned to a variable of type 'B'.
+// - 'B' is from 'pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart'.
+// Try changing the type of the left hand side, or casting the right hand side to 'B'.
+// h = /*error:INVALID_ASSIGNMENT*/ false;
+// ^
+//
+// pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart:56:36: Error: A value of type 'bool' can't be assigned to a variable of type 'B'.
+// - 'B' is from 'pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart'.
+// Try changing the type of the left hand side, or casting the right hand side to 'B'.
+// j = /*error:INVALID_ASSIGNMENT*/ false;
+// ^
+//
+// pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart:57:58: Error: A value of type 'List<dynamic>' can't be assigned to a variable of type 'B'.
+// - 'List' is from 'dart:core'.
+// - 'B' is from 'pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart'.
+// Try changing the type of the left hand side, or casting the right hand side to 'B'.
+// j = /*error:INVALID_ASSIGNMENT*/ /*@typeArgs=dynamic*/ [];
+// ^
+//
import self as self;
import "dart:core" as core;
+import "dart:collection" as col;
class A extends core::Object {
- field core::int x = null;
- synthetic constructor •() → self::A
+ field core::int* x = null;
+ synthetic constructor •() → self::A*
: super core::Object::•()
;
- operator +(dynamic other) → self::B
+ operator +(dynamic other) → self::B*
return null;
}
class B extends self::A {
- constructor •(dynamic ignore) → self::B
+ constructor •(dynamic ignore) → self::B*
: super self::A::•()
;
}
-static field self::A a = new self::A::•();
-static field self::B b = new self::B::•(invalid-expression "pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart:19:61: Error: Getter not found: 'x'.
-var b = new B(/*error:UNDEFINED_IDENTIFIER*/ x); // allocations
- ^");
-static field core::List<dynamic> c1 = <dynamic>[invalid-expression "pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart:21:34: Error: Getter not found: 'x'.
+static field self::A* a = new self::A::•();
+static field self::B* b = new self::B::•(invalid-expression "pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart:19:46: Error: Getter not found: 'x'.
+var b = new B(/*error:UNDEFINED_IDENTIFIER*/ x); // allocations
+ ^");
+static field core::List<dynamic>* c1 = <dynamic>[invalid-expression "pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart:21:34: Error: Getter not found: 'x'.
/*error:UNDEFINED_IDENTIFIER*/ x
^"];
-static field core::List<dynamic> c2 = const <dynamic>[];
-static field core::Map<dynamic, dynamic> d = <dynamic, dynamic>{"a": "b"};
-static field self::A e = let final self::A #t1 = new self::A::•() in let final core::int #t2 = #t1.{self::A::x} = 3 in #t1;
-static field core::int f = 2.{core::num::+}(3);
-static field core::int g = 3.{core::int::unary-}();
-static field self::B h = new self::A::•().{self::A::+}(3);
-static field dynamic i = let final self::A #t3 = new self::A::•() in invalid-expression "pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart:34:79: Error: The method 'unary-' isn't defined for the class 'A'.
+static field core::List<dynamic>* c2 = #C1;
+static field core::Map<dynamic, dynamic>* d = <dynamic, dynamic>{"a": "b"};
+static field self::A* e = let final self::A* #t1 = new self::A::•() in let final core::int* #t2 = #t1.{self::A::x} = 3 in #t1;
+static field core::int* f = 2.{core::num::+}(3);
+static field core::int* g = 3.{core::int::unary-}();
+static field self::B* h = new self::A::•().{self::A::+}(3);
+static field dynamic i = invalid-expression "pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart:32:58: Error: The method 'unary-' isn't defined for the class 'A'.
- 'A' is from 'pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart'.
Try correcting the name to the name of an existing method, or defining a method named 'unary-'.
-var i = /*error:UNDEFINED_OPERATOR,info:DYNAMIC_INVOKE*/ -new A();
- ^";
-static field self::B j = null as self::B;
+var i = /*error:UNDEFINED_OPERATOR,info:DYNAMIC_INVOKE*/ -new A();
+ ^";
+static field self::B* j = null as self::B*;
static method test1() → dynamic {
- self::a = let final<BottomType> #t4 = invalid-expression "pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart:38:36: Error: A value of type 'String' can't be assigned to a variable of type 'A'.
+ self::a = let final<BottomType> #t3 = invalid-expression "pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart:36:36: Error: A value of type 'String' can't be assigned to a variable of type 'A'.
- 'A' is from 'pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart'.
Try changing the type of the left hand side, or casting the right hand side to 'A'.
a = /*error:INVALID_ASSIGNMENT*/ \"hi\";
- ^" in "hi" as{TypeError} self::A;
+ ^" in "hi" as{TypeError} self::A*;
self::a = new self::B::•(3);
- self::b = let final<BottomType> #t5 = invalid-expression "pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart:40:36: Error: A value of type 'String' can't be assigned to a variable of type 'B'.
+ self::b = let final<BottomType> #t4 = invalid-expression "pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart:38:36: Error: A value of type 'String' can't be assigned to a variable of type 'B'.
- 'B' is from 'pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart'.
Try changing the type of the left hand side, or casting the right hand side to 'B'.
b = /*error:INVALID_ASSIGNMENT*/ \"hi\";
- ^" in "hi" as{TypeError} self::B;
+ ^" in "hi" as{TypeError} self::B*;
self::b = new self::B::•(3);
self::c1 = <dynamic>[];
- self::c1 = let final<BottomType> #t6 = invalid-expression "pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart:43:68: Error: A value of type 'Map<dynamic, dynamic>' can't be assigned to a variable of type 'List<dynamic>'.
- - 'Map' is from 'dart:core'.
+ self::c1 = let final<BottomType> #t5 = invalid-expression "pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart:41:59: Error: A value of type 'Set<dynamic>' can't be assigned to a variable of type 'List<dynamic>'.
+ - 'Set' is from 'dart:core'.
- 'List' is from 'dart:core'.
Try changing the type of the left hand side, or casting the right hand side to 'List<dynamic>'.
- c1 = /*error:INVALID_ASSIGNMENT*/ /*@typeArgs=dynamic, dynamic*/ {};
- ^" in <dynamic, dynamic>{} as{TypeError} core::List<dynamic>;
+ c1 = /*error:INVALID_ASSIGNMENT*/ /*@typeArgs=dynamic*/ {};
+ ^" in (let final core::Set<dynamic>* #t6 = col::LinkedHashSet::•<dynamic>() in #t6) as{TypeError} core::List<dynamic>*;
self::c2 = <dynamic>[];
- self::c2 = let final<BottomType> #t7 = invalid-expression "pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart:45:68: Error: A value of type 'Map<dynamic, dynamic>' can't be assigned to a variable of type 'List<dynamic>'.
- - 'Map' is from 'dart:core'.
+ self::c2 = let final<BottomType> #t7 = invalid-expression "pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart:43:59: Error: A value of type 'Set<dynamic>' can't be assigned to a variable of type 'List<dynamic>'.
+ - 'Set' is from 'dart:core'.
- 'List' is from 'dart:core'.
Try changing the type of the left hand side, or casting the right hand side to 'List<dynamic>'.
- c2 = /*error:INVALID_ASSIGNMENT*/ /*@typeArgs=dynamic, dynamic*/ {};
- ^" in <dynamic, dynamic>{} as{TypeError} core::List<dynamic>;
+ c2 = /*error:INVALID_ASSIGNMENT*/ /*@typeArgs=dynamic*/ {};
+ ^" in (let final core::Set<dynamic>* #t8 = col::LinkedHashSet::•<dynamic>() in #t8) as{TypeError} core::List<dynamic>*;
self::d = <dynamic, dynamic>{};
- self::d = let final<BottomType> #t8 = invalid-expression "pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart:47:36: Error: A value of type 'int' can't be assigned to a variable of type 'Map<dynamic, dynamic>'.
+ self::d = let final<BottomType> #t9 = invalid-expression "pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart:45:36: Error: A value of type 'int' can't be assigned to a variable of type 'Map<dynamic, dynamic>'.
- 'Map' is from 'dart:core'.
Try changing the type of the left hand side, or casting the right hand side to 'Map<dynamic, dynamic>'.
d = /*error:INVALID_ASSIGNMENT*/ 3;
- ^" in 3 as{TypeError} core::Map<dynamic, dynamic>;
+ ^" in 3 as{TypeError} core::Map<dynamic, dynamic>*;
self::e = new self::A::•();
- self::e = let final<BottomType> #t9 = invalid-expression "pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart:49:67: Error: A value of type 'Map<dynamic, dynamic>' can't be assigned to a variable of type 'A'.
+ self::e = let final<BottomType> #t10 = invalid-expression "pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart:47:67: Error: A value of type 'Map<dynamic, dynamic>' can't be assigned to a variable of type 'A'.
- 'Map' is from 'dart:core'.
- 'A' is from 'pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart'.
Try changing the type of the left hand side, or casting the right hand side to 'A'.
e = /*error:INVALID_ASSIGNMENT*/ /*@typeArgs=dynamic, dynamic*/ {};
- ^" in <dynamic, dynamic>{} as{TypeError} self::A;
+ ^" in <dynamic, dynamic>{} as{TypeError} self::A*;
self::f = 3;
- self::f = let final<BottomType> #t10 = invalid-expression "pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart:51:36: Error: A value of type 'bool' can't be assigned to a variable of type 'int'.
+ self::f = let final<BottomType> #t11 = invalid-expression "pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart:49:36: Error: A value of type 'bool' can't be assigned to a variable of type 'int'.
Try changing the type of the left hand side, or casting the right hand side to 'int'.
f = /*error:INVALID_ASSIGNMENT*/ false;
- ^" in false as{TypeError} core::int;
+ ^" in false as{TypeError} core::int*;
self::g = 1;
- self::g = let final<BottomType> #t11 = invalid-expression "pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart:53:36: Error: A value of type 'bool' can't be assigned to a variable of type 'int'.
+ self::g = let final<BottomType> #t12 = invalid-expression "pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart:51:36: Error: A value of type 'bool' can't be assigned to a variable of type 'int'.
Try changing the type of the left hand side, or casting the right hand side to 'int'.
g = /*error:INVALID_ASSIGNMENT*/ false;
- ^" in false as{TypeError} core::int;
- self::h = let final<BottomType> #t12 = invalid-expression "pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart:54:36: Error: A value of type 'bool' can't be assigned to a variable of type 'B'.
+ ^" in false as{TypeError} core::int*;
+ self::h = let final<BottomType> #t13 = invalid-expression "pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart:52:36: Error: A value of type 'bool' can't be assigned to a variable of type 'B'.
- 'B' is from 'pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart'.
Try changing the type of the left hand side, or casting the right hand side to 'B'.
h = /*error:INVALID_ASSIGNMENT*/ false;
- ^" in false as{TypeError} self::B;
+ ^" in false as{TypeError} self::B*;
self::h = new self::B::•("b");
self::i = false;
self::j = new self::B::•("b");
- self::j = let final<BottomType> #t13 = invalid-expression "pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart:58:36: Error: A value of type 'bool' can't be assigned to a variable of type 'B'.
+ self::j = let final<BottomType> #t14 = invalid-expression "pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart:56:36: Error: A value of type 'bool' can't be assigned to a variable of type 'B'.
- 'B' is from 'pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart'.
Try changing the type of the left hand side, or casting the right hand side to 'B'.
j = /*error:INVALID_ASSIGNMENT*/ false;
- ^" in false as{TypeError} self::B;
- self::j = let final<BottomType> #t14 = invalid-expression "pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart:59:58: Error: A value of type 'List<dynamic>' can't be assigned to a variable of type 'B'.
+ ^" in false as{TypeError} self::B*;
+ self::j = let final<BottomType> #t15 = invalid-expression "pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart:57:58: Error: A value of type 'List<dynamic>' can't be assigned to a variable of type 'B'.
- 'List' is from 'dart:core'.
- 'B' is from 'pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart'.
Try changing the type of the left hand side, or casting the right hand side to 'B'.
j = /*error:INVALID_ASSIGNMENT*/ /*@typeArgs=dynamic*/ [];
- ^" in <dynamic>[] as{TypeError} self::B;
+ ^" in <dynamic>[] as{TypeError} self::B*;
}
static method main() → dynamic {}
+
+constants {
+ #C1 = <dynamic>[]
+}
diff --git a/pkg/front_end/testcases/inference/infer_types_on_loop_indices_for_loop_with_inference.dart b/pkg/front_end/testcases/inference/infer_types_on_loop_indices_for_loop_with_inference.dart
index 963a6a0..46e0672 100644
--- a/pkg/front_end/testcases/inference/infer_types_on_loop_indices_for_loop_with_inference.dart
+++ b/pkg/front_end/testcases/inference/infer_types_on_loop_indices_for_loop_with_inference.dart
@@ -6,7 +6,9 @@
library test;
test() {
- for (var /*@ type=int* */ i = 0; i /*@target=num::<*/ < 10; i++) {
+ for (var /*@ type=int* */ i = 0;
+ i /*@target=num::<*/ < 10;
+ i /*@ target=num::+ */ ++) {
int j = i /*@target=num::+*/ + 1;
}
}
diff --git a/pkg/front_end/testcases/inference/infer_types_on_loop_indices_for_loop_with_inference.dart.type_promotion.expect b/pkg/front_end/testcases/inference/infer_types_on_loop_indices_for_loop_with_inference.dart.type_promotion.expect
index 5e037d0..dabdbac 100644
--- a/pkg/front_end/testcases/inference/infer_types_on_loop_indices_for_loop_with_inference.dart.type_promotion.expect
+++ b/pkg/front_end/testcases/inference/infer_types_on_loop_indices_for_loop_with_inference.dart.type_promotion.expect
@@ -1,3 +1,3 @@
-pkg/front_end/testcases/inference/infer_types_on_loop_indices_for_loop_with_inference.dart:9:64: Context: Write to i@299
- for (var /*@ type=int* */ i = 0; i /*@target=num::<*/ < 10; i++) {
- ^^
+pkg/front_end/testcases/inference/infer_types_on_loop_indices_for_loop_with_inference.dart:11:30: Context: Write to i@299
+ i /*@ target=num::+ */ ++) {
+ ^^
diff --git a/pkg/front_end/testcases/inference/inferred_type_block_closure_no_args_no_return.dart b/pkg/front_end/testcases/inference/inferred_type_block_closure_no_args_no_return.dart
index dab289a..f1fd89e 100644
--- a/pkg/front_end/testcases/inference/inferred_type_block_closure_no_args_no_return.dart
+++ b/pkg/front_end/testcases/inference/inferred_type_block_closure_no_args_no_return.dart
@@ -6,5 +6,5 @@
library test;
main() {
- var /*@ type=() ->* Null* */ f = /*@ returnType=Null* */ () {};
+ var /*@ type=() ->* Null? */ f = /*@ returnType=Null? */ () {};
}
diff --git a/pkg/front_end/testcases/inference/inferred_type_block_closure_no_args_no_return.dart.strong.expect b/pkg/front_end/testcases/inference/inferred_type_block_closure_no_args_no_return.dart.strong.expect
index 12479df..64040c7 100644
--- a/pkg/front_end/testcases/inference/inferred_type_block_closure_no_args_no_return.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/inferred_type_block_closure_no_args_no_return.dart.strong.expect
@@ -3,5 +3,5 @@
import "dart:core" as core;
static method main() → dynamic {
- () →* core::Null* f = () → core::Null* {};
+ () →* core::Null? f = () → core::Null? {};
}
diff --git a/pkg/front_end/testcases/inference/inferred_type_block_closure_no_args_no_return.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/inferred_type_block_closure_no_args_no_return.dart.strong.transformed.expect
index 12479df..64040c7 100644
--- a/pkg/front_end/testcases/inference/inferred_type_block_closure_no_args_no_return.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/inferred_type_block_closure_no_args_no_return.dart.strong.transformed.expect
@@ -3,5 +3,5 @@
import "dart:core" as core;
static method main() → dynamic {
- () →* core::Null* f = () → core::Null* {};
+ () →* core::Null? f = () → core::Null? {};
}
diff --git a/pkg/front_end/testcases/inference/inferred_type_block_closure_no_args_no_return_void_context.dart b/pkg/front_end/testcases/inference/inferred_type_block_closure_no_args_no_return_void_context.dart
index 713085c..0d24e42 100644
--- a/pkg/front_end/testcases/inference/inferred_type_block_closure_no_args_no_return_void_context.dart
+++ b/pkg/front_end/testcases/inference/inferred_type_block_closure_no_args_no_return_void_context.dart
@@ -10,5 +10,5 @@
}
main() {
- var /*@ type=C* */ c = new C(/*@ returnType=Null* */ () {});
+ var /*@ type=C* */ c = new C(/*@ returnType=Null? */ () {});
}
diff --git a/pkg/front_end/testcases/inference/inferred_type_block_closure_no_args_no_return_void_context.dart.strong.expect b/pkg/front_end/testcases/inference/inferred_type_block_closure_no_args_no_return_void_context.dart.strong.expect
index b33a922..e20719a 100644
--- a/pkg/front_end/testcases/inference/inferred_type_block_closure_no_args_no_return_void_context.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/inferred_type_block_closure_no_args_no_return_void_context.dart.strong.expect
@@ -7,5 +7,5 @@
: super core::Object::•() {}
}
static method main() → dynamic {
- self::C* c = new self::C::•(() → core::Null* {});
+ self::C* c = new self::C::•(() → core::Null? {});
}
diff --git a/pkg/front_end/testcases/inference/inferred_type_block_closure_no_args_no_return_void_context.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/inferred_type_block_closure_no_args_no_return_void_context.dart.strong.transformed.expect
index b33a922..e20719a 100644
--- a/pkg/front_end/testcases/inference/inferred_type_block_closure_no_args_no_return_void_context.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/inferred_type_block_closure_no_args_no_return_void_context.dart.strong.transformed.expect
@@ -7,5 +7,5 @@
: super core::Object::•() {}
}
static method main() → dynamic {
- self::C* c = new self::C::•(() → core::Null* {});
+ self::C* c = new self::C::•(() → core::Null? {});
}
diff --git a/pkg/front_end/testcases/inference/instantiate_tearoff_after_contravariance_check.dart b/pkg/front_end/testcases/inference/instantiate_tearoff_after_contravariance_check.dart
index afc7289..58437b6 100644
--- a/pkg/front_end/testcases/inference/instantiate_tearoff_after_contravariance_check.dart
+++ b/pkg/front_end/testcases/inference/instantiate_tearoff_after_contravariance_check.dart
@@ -6,7 +6,7 @@
library test;
class C<T> {
- void Function(T) f<U>(U x) => /*@ returnType=Null* */ (/*@ type=C::T* */ y) {};
+ void Function(T) f<U>(U x) => /*@ returnType=Null? */ (/*@ type=C::T* */ y) {};
}
void test(C<String> c) {
diff --git a/pkg/front_end/testcases/inference/instantiate_tearoff_after_contravariance_check.dart.strong.expect b/pkg/front_end/testcases/inference/instantiate_tearoff_after_contravariance_check.dart.strong.expect
index d7f5411..4d47083 100644
--- a/pkg/front_end/testcases/inference/instantiate_tearoff_after_contravariance_check.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/instantiate_tearoff_after_contravariance_check.dart.strong.expect
@@ -7,7 +7,7 @@
: super core::Object::•()
;
method f<U extends core::Object* = dynamic>(self::C::f::U* x) → (self::C::T*) →* void
- return (self::C::T* y) → core::Null* {};
+ return (self::C::T* y) → core::Null? {};
}
static method test(self::C<core::String*>* c) → void {
(core::int*) →* (core::String*) →* void tearoff = c.{self::C::f} as{TypeError} <U extends core::Object* = dynamic>(U*) →* (core::String*) →* void<core::int*>;
diff --git a/pkg/front_end/testcases/inference/instantiate_tearoff_after_contravariance_check.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/instantiate_tearoff_after_contravariance_check.dart.strong.transformed.expect
index d7f5411..4d47083 100644
--- a/pkg/front_end/testcases/inference/instantiate_tearoff_after_contravariance_check.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/instantiate_tearoff_after_contravariance_check.dart.strong.transformed.expect
@@ -7,7 +7,7 @@
: super core::Object::•()
;
method f<U extends core::Object* = dynamic>(self::C::f::U* x) → (self::C::T*) →* void
- return (self::C::T* y) → core::Null* {};
+ return (self::C::T* y) → core::Null? {};
}
static method test(self::C<core::String*>* c) → void {
(core::int*) →* (core::String*) →* void tearoff = c.{self::C::f} as{TypeError} <U extends core::Object* = dynamic>(U*) →* (core::String*) →* void<core::int*>;
diff --git a/pkg/front_end/testcases/inference/list_literals_can_infer_null_bottom.dart b/pkg/front_end/testcases/inference/list_literals_can_infer_null_bottom.dart
index 3ed4a7e..52be7b9 100644
--- a/pkg/front_end/testcases/inference/list_literals_can_infer_null_bottom.dart
+++ b/pkg/front_end/testcases/inference/list_literals_can_infer_null_bottom.dart
@@ -6,7 +6,7 @@
library test;
test1() {
- var /*@ type=List<Null*>* */ x = /*@ typeArgs=Null* */ [null];
+ var /*@ type=List<Null?>* */ x = /*@ typeArgs=Null? */ [null];
x. /*@target=List::add*/ add(/*error:INVALID_CAST_LITERAL*/ 42);
}
diff --git a/pkg/front_end/testcases/inference/list_literals_can_infer_null_bottom.dart.strong.expect b/pkg/front_end/testcases/inference/list_literals_can_infer_null_bottom.dart.strong.expect
index 11889f3..dafc04b 100644
--- a/pkg/front_end/testcases/inference/list_literals_can_infer_null_bottom.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/list_literals_can_infer_null_bottom.dart.strong.expect
@@ -3,7 +3,7 @@
import "dart:core" as core;
static method test1() → dynamic {
- core::List<core::Null*>* x = <core::Null*>[null];
- x.{core::List::add}(42 as{TypeError} core::Null*);
+ core::List<core::Null?>* x = <core::Null?>[null];
+ x.{core::List::add}(42 as{TypeError} core::Null?);
}
static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/list_literals_can_infer_null_bottom.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/list_literals_can_infer_null_bottom.dart.strong.transformed.expect
index 11889f3..dafc04b 100644
--- a/pkg/front_end/testcases/inference/list_literals_can_infer_null_bottom.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/list_literals_can_infer_null_bottom.dart.strong.transformed.expect
@@ -3,7 +3,7 @@
import "dart:core" as core;
static method test1() → dynamic {
- core::List<core::Null*>* x = <core::Null*>[null];
- x.{core::List::add}(42 as{TypeError} core::Null*);
+ core::List<core::Null?>* x = <core::Null?>[null];
+ x.{core::List::add}(42 as{TypeError} core::Null?);
}
static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/map_literals.dart.strong.expect b/pkg/front_end/testcases/inference/map_literals.dart.strong.expect
index 3436fff..2449679 100644
--- a/pkg/front_end/testcases/inference/map_literals.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/map_literals.dart.strong.expect
@@ -2,29 +2,29 @@
//
// Problems in library:
//
-// pkg/front_end/testcases/inference/map_literals.dart:12:46: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-// Try changing the type of the left hand side, or casting the right hand side to 'int'.
+// pkg/front_end/testcases/inference/map_literals.dart:12:46: Error: The argument type 'String' can't be assigned to the parameter type 'int'.
+// Try changing the type of the parameter, or casting the argument to 'int'.
// /*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ 'hi'] = 'w';
// ^
//
-// pkg/front_end/testcases/inference/map_literals.dart:14:46: Error: A value of type 'double' can't be assigned to a variable of type 'int'.
-// Try changing the type of the left hand side, or casting the right hand side to 'int'.
+// pkg/front_end/testcases/inference/map_literals.dart:14:46: Error: The argument type 'double' can't be assigned to the parameter type 'int'.
+// Try changing the type of the parameter, or casting the argument to 'int'.
// /*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ 4.0] = 'u';
// ^
//
-// pkg/front_end/testcases/inference/map_literals.dart:15:61: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
-// Try changing the type of the left hand side, or casting the right hand side to 'String'.
+// pkg/front_end/testcases/inference/map_literals.dart:15:61: Error: The argument type 'int' can't be assigned to the parameter type 'String'.
+// Try changing the type of the parameter, or casting the argument to 'String'.
// x /*@target=Map::[]=*/ [3] = /*error:INVALID_ASSIGNMENT*/ 42;
// ^
//
-// pkg/front_end/testcases/inference/map_literals.dart:27:46: Error: A value of type 'String' can't be assigned to a variable of type 'num'.
-// Try changing the type of the left hand side, or casting the right hand side to 'num'.
+// pkg/front_end/testcases/inference/map_literals.dart:27:46: Error: The argument type 'String' can't be assigned to the parameter type 'num'.
+// Try changing the type of the parameter, or casting the argument to 'num'.
// /*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ 'hi'] = 'w';
// ^
//
-// pkg/front_end/testcases/inference/map_literals.dart:29:61: Error: A value of type 'int' can't be assigned to a variable of type 'Pattern'.
+// pkg/front_end/testcases/inference/map_literals.dart:29:61: Error: The argument type 'int' can't be assigned to the parameter type 'Pattern'.
// - 'Pattern' is from 'dart:core'.
-// Try changing the type of the left hand side, or casting the right hand side to 'Pattern'.
+// Try changing the type of the parameter, or casting the argument to 'Pattern'.
// x /*@target=Map::[]=*/ [3] = /*error:INVALID_ASSIGNMENT*/ 42;
// ^
//
@@ -34,16 +34,16 @@
static method test1() → dynamic {
core::Map<core::int*, core::String*>* x = <core::int*, core::String*>{1: "x", 2: "y"};
x.{core::Map::[]=}(3, "z");
- x.{core::Map::[]=}(let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/inference/map_literals.dart:12:46: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-Try changing the type of the left hand side, or casting the right hand side to 'int'.
+ x.{core::Map::[]=}(let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/inference/map_literals.dart:12:46: Error: The argument type 'String' can't be assigned to the parameter type 'int'.
+Try changing the type of the parameter, or casting the argument to 'int'.
/*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ 'hi'] = 'w';
^" in "hi" as{TypeError} core::int*, "w");
- x.{core::Map::[]=}(let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/inference/map_literals.dart:14:46: Error: A value of type 'double' can't be assigned to a variable of type 'int'.
-Try changing the type of the left hand side, or casting the right hand side to 'int'.
+ x.{core::Map::[]=}(let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/inference/map_literals.dart:14:46: Error: The argument type 'double' can't be assigned to the parameter type 'int'.
+Try changing the type of the parameter, or casting the argument to 'int'.
/*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ 4.0] = 'u';
^" in 4.0 as{TypeError} core::int*, "u");
- x.{core::Map::[]=}(3, let final<BottomType> #t3 = invalid-expression "pkg/front_end/testcases/inference/map_literals.dart:15:61: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
-Try changing the type of the left hand side, or casting the right hand side to 'String'.
+ x.{core::Map::[]=}(3, let final<BottomType> #t3 = invalid-expression "pkg/front_end/testcases/inference/map_literals.dart:15:61: Error: The argument type 'int' can't be assigned to the parameter type 'String'.
+Try changing the type of the parameter, or casting the argument to 'String'.
x /*@target=Map::[]=*/ [3] = /*error:INVALID_ASSIGNMENT*/ 42;
^" in 42 as{TypeError} core::String*);
core::Map<core::num*, core::String*>* y = x;
@@ -51,14 +51,14 @@
static method test2() → dynamic {
core::Map<core::num*, core::Pattern*>* x = <core::num*, core::Pattern*>{1: "x", 2: "y", 3.0: core::RegExp::•(".")};
x.{core::Map::[]=}(3, "z");
- x.{core::Map::[]=}(let final<BottomType> #t4 = invalid-expression "pkg/front_end/testcases/inference/map_literals.dart:27:46: Error: A value of type 'String' can't be assigned to a variable of type 'num'.
-Try changing the type of the left hand side, or casting the right hand side to 'num'.
+ x.{core::Map::[]=}(let final<BottomType> #t4 = invalid-expression "pkg/front_end/testcases/inference/map_literals.dart:27:46: Error: The argument type 'String' can't be assigned to the parameter type 'num'.
+Try changing the type of the parameter, or casting the argument to 'num'.
/*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ 'hi'] = 'w';
^" in "hi" as{TypeError} core::num*, "w");
x.{core::Map::[]=}(4.0, "u");
- x.{core::Map::[]=}(3, let final<BottomType> #t5 = invalid-expression "pkg/front_end/testcases/inference/map_literals.dart:29:61: Error: A value of type 'int' can't be assigned to a variable of type 'Pattern'.
+ x.{core::Map::[]=}(3, let final<BottomType> #t5 = invalid-expression "pkg/front_end/testcases/inference/map_literals.dart:29:61: Error: The argument type 'int' can't be assigned to the parameter type 'Pattern'.
- 'Pattern' is from 'dart:core'.
-Try changing the type of the left hand side, or casting the right hand side to 'Pattern'.
+Try changing the type of the parameter, or casting the argument to 'Pattern'.
x /*@target=Map::[]=*/ [3] = /*error:INVALID_ASSIGNMENT*/ 42;
^" in 42 as{TypeError} core::Pattern*);
core::Pattern* p = null;
diff --git a/pkg/front_end/testcases/inference/map_literals.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/map_literals.dart.strong.transformed.expect
index 3436fff..2449679 100644
--- a/pkg/front_end/testcases/inference/map_literals.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/map_literals.dart.strong.transformed.expect
@@ -2,29 +2,29 @@
//
// Problems in library:
//
-// pkg/front_end/testcases/inference/map_literals.dart:12:46: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-// Try changing the type of the left hand side, or casting the right hand side to 'int'.
+// pkg/front_end/testcases/inference/map_literals.dart:12:46: Error: The argument type 'String' can't be assigned to the parameter type 'int'.
+// Try changing the type of the parameter, or casting the argument to 'int'.
// /*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ 'hi'] = 'w';
// ^
//
-// pkg/front_end/testcases/inference/map_literals.dart:14:46: Error: A value of type 'double' can't be assigned to a variable of type 'int'.
-// Try changing the type of the left hand side, or casting the right hand side to 'int'.
+// pkg/front_end/testcases/inference/map_literals.dart:14:46: Error: The argument type 'double' can't be assigned to the parameter type 'int'.
+// Try changing the type of the parameter, or casting the argument to 'int'.
// /*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ 4.0] = 'u';
// ^
//
-// pkg/front_end/testcases/inference/map_literals.dart:15:61: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
-// Try changing the type of the left hand side, or casting the right hand side to 'String'.
+// pkg/front_end/testcases/inference/map_literals.dart:15:61: Error: The argument type 'int' can't be assigned to the parameter type 'String'.
+// Try changing the type of the parameter, or casting the argument to 'String'.
// x /*@target=Map::[]=*/ [3] = /*error:INVALID_ASSIGNMENT*/ 42;
// ^
//
-// pkg/front_end/testcases/inference/map_literals.dart:27:46: Error: A value of type 'String' can't be assigned to a variable of type 'num'.
-// Try changing the type of the left hand side, or casting the right hand side to 'num'.
+// pkg/front_end/testcases/inference/map_literals.dart:27:46: Error: The argument type 'String' can't be assigned to the parameter type 'num'.
+// Try changing the type of the parameter, or casting the argument to 'num'.
// /*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ 'hi'] = 'w';
// ^
//
-// pkg/front_end/testcases/inference/map_literals.dart:29:61: Error: A value of type 'int' can't be assigned to a variable of type 'Pattern'.
+// pkg/front_end/testcases/inference/map_literals.dart:29:61: Error: The argument type 'int' can't be assigned to the parameter type 'Pattern'.
// - 'Pattern' is from 'dart:core'.
-// Try changing the type of the left hand side, or casting the right hand side to 'Pattern'.
+// Try changing the type of the parameter, or casting the argument to 'Pattern'.
// x /*@target=Map::[]=*/ [3] = /*error:INVALID_ASSIGNMENT*/ 42;
// ^
//
@@ -34,16 +34,16 @@
static method test1() → dynamic {
core::Map<core::int*, core::String*>* x = <core::int*, core::String*>{1: "x", 2: "y"};
x.{core::Map::[]=}(3, "z");
- x.{core::Map::[]=}(let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/inference/map_literals.dart:12:46: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-Try changing the type of the left hand side, or casting the right hand side to 'int'.
+ x.{core::Map::[]=}(let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/inference/map_literals.dart:12:46: Error: The argument type 'String' can't be assigned to the parameter type 'int'.
+Try changing the type of the parameter, or casting the argument to 'int'.
/*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ 'hi'] = 'w';
^" in "hi" as{TypeError} core::int*, "w");
- x.{core::Map::[]=}(let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/inference/map_literals.dart:14:46: Error: A value of type 'double' can't be assigned to a variable of type 'int'.
-Try changing the type of the left hand side, or casting the right hand side to 'int'.
+ x.{core::Map::[]=}(let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/inference/map_literals.dart:14:46: Error: The argument type 'double' can't be assigned to the parameter type 'int'.
+Try changing the type of the parameter, or casting the argument to 'int'.
/*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ 4.0] = 'u';
^" in 4.0 as{TypeError} core::int*, "u");
- x.{core::Map::[]=}(3, let final<BottomType> #t3 = invalid-expression "pkg/front_end/testcases/inference/map_literals.dart:15:61: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
-Try changing the type of the left hand side, or casting the right hand side to 'String'.
+ x.{core::Map::[]=}(3, let final<BottomType> #t3 = invalid-expression "pkg/front_end/testcases/inference/map_literals.dart:15:61: Error: The argument type 'int' can't be assigned to the parameter type 'String'.
+Try changing the type of the parameter, or casting the argument to 'String'.
x /*@target=Map::[]=*/ [3] = /*error:INVALID_ASSIGNMENT*/ 42;
^" in 42 as{TypeError} core::String*);
core::Map<core::num*, core::String*>* y = x;
@@ -51,14 +51,14 @@
static method test2() → dynamic {
core::Map<core::num*, core::Pattern*>* x = <core::num*, core::Pattern*>{1: "x", 2: "y", 3.0: core::RegExp::•(".")};
x.{core::Map::[]=}(3, "z");
- x.{core::Map::[]=}(let final<BottomType> #t4 = invalid-expression "pkg/front_end/testcases/inference/map_literals.dart:27:46: Error: A value of type 'String' can't be assigned to a variable of type 'num'.
-Try changing the type of the left hand side, or casting the right hand side to 'num'.
+ x.{core::Map::[]=}(let final<BottomType> #t4 = invalid-expression "pkg/front_end/testcases/inference/map_literals.dart:27:46: Error: The argument type 'String' can't be assigned to the parameter type 'num'.
+Try changing the type of the parameter, or casting the argument to 'num'.
/*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ 'hi'] = 'w';
^" in "hi" as{TypeError} core::num*, "w");
x.{core::Map::[]=}(4.0, "u");
- x.{core::Map::[]=}(3, let final<BottomType> #t5 = invalid-expression "pkg/front_end/testcases/inference/map_literals.dart:29:61: Error: A value of type 'int' can't be assigned to a variable of type 'Pattern'.
+ x.{core::Map::[]=}(3, let final<BottomType> #t5 = invalid-expression "pkg/front_end/testcases/inference/map_literals.dart:29:61: Error: The argument type 'int' can't be assigned to the parameter type 'Pattern'.
- 'Pattern' is from 'dart:core'.
-Try changing the type of the left hand side, or casting the right hand side to 'Pattern'.
+Try changing the type of the parameter, or casting the argument to 'Pattern'.
x /*@target=Map::[]=*/ [3] = /*error:INVALID_ASSIGNMENT*/ 42;
^" in 42 as{TypeError} core::Pattern*);
core::Pattern* p = null;
diff --git a/pkg/front_end/testcases/inference/map_literals_can_infer_null.dart b/pkg/front_end/testcases/inference/map_literals_can_infer_null.dart
index 1d3ab85..5cce7ec 100644
--- a/pkg/front_end/testcases/inference/map_literals_can_infer_null.dart
+++ b/pkg/front_end/testcases/inference/map_literals_can_infer_null.dart
@@ -6,7 +6,7 @@
library test;
test1() {
- var /*@ type=Map<Null*, Null*>* */ x = /*@ typeArgs=Null*, Null* */ {null: null};
+ var /*@ type=Map<Null?, Null?>* */ x = /*@ typeArgs=Null?, Null? */ {null: null};
x /*@target=Map::[]=*/ [
/*error:INVALID_CAST_LITERAL*/ 3] = /*error:INVALID_CAST_LITERAL*/ 'z';
}
diff --git a/pkg/front_end/testcases/inference/map_literals_can_infer_null.dart.strong.expect b/pkg/front_end/testcases/inference/map_literals_can_infer_null.dart.strong.expect
index 57e9d39..38d6f76 100644
--- a/pkg/front_end/testcases/inference/map_literals_can_infer_null.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/map_literals_can_infer_null.dart.strong.expect
@@ -3,7 +3,7 @@
import "dart:core" as core;
static method test1() → dynamic {
- core::Map<core::Null*, core::Null*>* x = <core::Null*, core::Null*>{null: null};
- x.{core::Map::[]=}(3 as{TypeError} core::Null*, "z" as{TypeError} core::Null*);
+ core::Map<core::Null?, core::Null?>* x = <core::Null?, core::Null?>{null: null};
+ x.{core::Map::[]=}(3 as{TypeError} core::Null?, "z" as{TypeError} core::Null?);
}
static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/map_literals_can_infer_null.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/map_literals_can_infer_null.dart.strong.transformed.expect
index 57e9d39..38d6f76 100644
--- a/pkg/front_end/testcases/inference/map_literals_can_infer_null.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/map_literals_can_infer_null.dart.strong.transformed.expect
@@ -3,7 +3,7 @@
import "dart:core" as core;
static method test1() → dynamic {
- core::Map<core::Null*, core::Null*>* x = <core::Null*, core::Null*>{null: null};
- x.{core::Map::[]=}(3 as{TypeError} core::Null*, "z" as{TypeError} core::Null*);
+ core::Map<core::Null?, core::Null?>* x = <core::Null?, core::Null?>{null: null};
+ x.{core::Map::[]=}(3 as{TypeError} core::Null?, "z" as{TypeError} core::Null?);
}
static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/map_literals_top_level.dart.strong.expect b/pkg/front_end/testcases/inference/map_literals_top_level.dart.strong.expect
index 0fb8116..7af3179 100644
--- a/pkg/front_end/testcases/inference/map_literals_top_level.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/map_literals_top_level.dart.strong.expect
@@ -2,29 +2,29 @@
//
// Problems in library:
//
-// pkg/front_end/testcases/inference/map_literals_top_level.dart:11:67: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-// Try changing the type of the left hand side, or casting the right hand side to 'int'.
+// pkg/front_end/testcases/inference/map_literals_top_level.dart:11:67: Error: The argument type 'String' can't be assigned to the parameter type 'int'.
+// Try changing the type of the parameter, or casting the argument to 'int'.
// x1 /*@target=Map::[]=*/ [/*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ 'hi'] = 'w';
// ^
//
-// pkg/front_end/testcases/inference/map_literals_top_level.dart:12:67: Error: A value of type 'double' can't be assigned to a variable of type 'int'.
-// Try changing the type of the left hand side, or casting the right hand side to 'int'.
+// pkg/front_end/testcases/inference/map_literals_top_level.dart:12:67: Error: The argument type 'double' can't be assigned to the parameter type 'int'.
+// Try changing the type of the parameter, or casting the argument to 'int'.
// x1 /*@target=Map::[]=*/ [/*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ 4.0] = 'u';
// ^
//
-// pkg/front_end/testcases/inference/map_literals_top_level.dart:13:62: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
-// Try changing the type of the left hand side, or casting the right hand side to 'String'.
+// pkg/front_end/testcases/inference/map_literals_top_level.dart:13:62: Error: The argument type 'int' can't be assigned to the parameter type 'String'.
+// Try changing the type of the parameter, or casting the argument to 'String'.
// x1 /*@target=Map::[]=*/ [3] = /*error:INVALID_ASSIGNMENT*/ 42;
// ^
//
-// pkg/front_end/testcases/inference/map_literals_top_level.dart:20:67: Error: A value of type 'String' can't be assigned to a variable of type 'num'.
-// Try changing the type of the left hand side, or casting the right hand side to 'num'.
+// pkg/front_end/testcases/inference/map_literals_top_level.dart:20:67: Error: The argument type 'String' can't be assigned to the parameter type 'num'.
+// Try changing the type of the parameter, or casting the argument to 'num'.
// x2 /*@target=Map::[]=*/ [/*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ 'hi'] = 'w';
// ^
//
-// pkg/front_end/testcases/inference/map_literals_top_level.dart:22:62: Error: A value of type 'int' can't be assigned to a variable of type 'Pattern'.
+// pkg/front_end/testcases/inference/map_literals_top_level.dart:22:62: Error: The argument type 'int' can't be assigned to the parameter type 'Pattern'.
// - 'Pattern' is from 'dart:core'.
-// Try changing the type of the left hand side, or casting the right hand side to 'Pattern'.
+// Try changing the type of the parameter, or casting the argument to 'Pattern'.
// x2 /*@target=Map::[]=*/ [3] = /*error:INVALID_ASSIGNMENT*/ 42;
// ^
//
@@ -35,30 +35,30 @@
static field core::Map<core::num*, core::Pattern*>* x2 = <core::num*, core::Pattern*>{1: "x", 2: "y", 3.0: core::RegExp::•(".")};
static method test1() → dynamic {
self::x1.{core::Map::[]=}(3, "z");
- self::x1.{core::Map::[]=}(let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/inference/map_literals_top_level.dart:11:67: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-Try changing the type of the left hand side, or casting the right hand side to 'int'.
+ self::x1.{core::Map::[]=}(let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/inference/map_literals_top_level.dart:11:67: Error: The argument type 'String' can't be assigned to the parameter type 'int'.
+Try changing the type of the parameter, or casting the argument to 'int'.
x1 /*@target=Map::[]=*/ [/*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ 'hi'] = 'w';
^" in "hi" as{TypeError} core::int*, "w");
- self::x1.{core::Map::[]=}(let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/inference/map_literals_top_level.dart:12:67: Error: A value of type 'double' can't be assigned to a variable of type 'int'.
-Try changing the type of the left hand side, or casting the right hand side to 'int'.
+ self::x1.{core::Map::[]=}(let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/inference/map_literals_top_level.dart:12:67: Error: The argument type 'double' can't be assigned to the parameter type 'int'.
+Try changing the type of the parameter, or casting the argument to 'int'.
x1 /*@target=Map::[]=*/ [/*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ 4.0] = 'u';
^" in 4.0 as{TypeError} core::int*, "u");
- self::x1.{core::Map::[]=}(3, let final<BottomType> #t3 = invalid-expression "pkg/front_end/testcases/inference/map_literals_top_level.dart:13:62: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
-Try changing the type of the left hand side, or casting the right hand side to 'String'.
+ self::x1.{core::Map::[]=}(3, let final<BottomType> #t3 = invalid-expression "pkg/front_end/testcases/inference/map_literals_top_level.dart:13:62: Error: The argument type 'int' can't be assigned to the parameter type 'String'.
+Try changing the type of the parameter, or casting the argument to 'String'.
x1 /*@target=Map::[]=*/ [3] = /*error:INVALID_ASSIGNMENT*/ 42;
^" in 42 as{TypeError} core::String*);
core::Map<core::num*, core::String*>* y = self::x1;
}
static method test2() → dynamic {
self::x2.{core::Map::[]=}(3, "z");
- self::x2.{core::Map::[]=}(let final<BottomType> #t4 = invalid-expression "pkg/front_end/testcases/inference/map_literals_top_level.dart:20:67: Error: A value of type 'String' can't be assigned to a variable of type 'num'.
-Try changing the type of the left hand side, or casting the right hand side to 'num'.
+ self::x2.{core::Map::[]=}(let final<BottomType> #t4 = invalid-expression "pkg/front_end/testcases/inference/map_literals_top_level.dart:20:67: Error: The argument type 'String' can't be assigned to the parameter type 'num'.
+Try changing the type of the parameter, or casting the argument to 'num'.
x2 /*@target=Map::[]=*/ [/*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ 'hi'] = 'w';
^" in "hi" as{TypeError} core::num*, "w");
self::x2.{core::Map::[]=}(4.0, "u");
- self::x2.{core::Map::[]=}(3, let final<BottomType> #t5 = invalid-expression "pkg/front_end/testcases/inference/map_literals_top_level.dart:22:62: Error: A value of type 'int' can't be assigned to a variable of type 'Pattern'.
+ self::x2.{core::Map::[]=}(3, let final<BottomType> #t5 = invalid-expression "pkg/front_end/testcases/inference/map_literals_top_level.dart:22:62: Error: The argument type 'int' can't be assigned to the parameter type 'Pattern'.
- 'Pattern' is from 'dart:core'.
-Try changing the type of the left hand side, or casting the right hand side to 'Pattern'.
+Try changing the type of the parameter, or casting the argument to 'Pattern'.
x2 /*@target=Map::[]=*/ [3] = /*error:INVALID_ASSIGNMENT*/ 42;
^" in 42 as{TypeError} core::Pattern*);
core::Pattern* p = null;
diff --git a/pkg/front_end/testcases/inference/map_literals_top_level.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/map_literals_top_level.dart.strong.transformed.expect
index 0fb8116..7af3179 100644
--- a/pkg/front_end/testcases/inference/map_literals_top_level.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/map_literals_top_level.dart.strong.transformed.expect
@@ -2,29 +2,29 @@
//
// Problems in library:
//
-// pkg/front_end/testcases/inference/map_literals_top_level.dart:11:67: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-// Try changing the type of the left hand side, or casting the right hand side to 'int'.
+// pkg/front_end/testcases/inference/map_literals_top_level.dart:11:67: Error: The argument type 'String' can't be assigned to the parameter type 'int'.
+// Try changing the type of the parameter, or casting the argument to 'int'.
// x1 /*@target=Map::[]=*/ [/*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ 'hi'] = 'w';
// ^
//
-// pkg/front_end/testcases/inference/map_literals_top_level.dart:12:67: Error: A value of type 'double' can't be assigned to a variable of type 'int'.
-// Try changing the type of the left hand side, or casting the right hand side to 'int'.
+// pkg/front_end/testcases/inference/map_literals_top_level.dart:12:67: Error: The argument type 'double' can't be assigned to the parameter type 'int'.
+// Try changing the type of the parameter, or casting the argument to 'int'.
// x1 /*@target=Map::[]=*/ [/*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ 4.0] = 'u';
// ^
//
-// pkg/front_end/testcases/inference/map_literals_top_level.dart:13:62: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
-// Try changing the type of the left hand side, or casting the right hand side to 'String'.
+// pkg/front_end/testcases/inference/map_literals_top_level.dart:13:62: Error: The argument type 'int' can't be assigned to the parameter type 'String'.
+// Try changing the type of the parameter, or casting the argument to 'String'.
// x1 /*@target=Map::[]=*/ [3] = /*error:INVALID_ASSIGNMENT*/ 42;
// ^
//
-// pkg/front_end/testcases/inference/map_literals_top_level.dart:20:67: Error: A value of type 'String' can't be assigned to a variable of type 'num'.
-// Try changing the type of the left hand side, or casting the right hand side to 'num'.
+// pkg/front_end/testcases/inference/map_literals_top_level.dart:20:67: Error: The argument type 'String' can't be assigned to the parameter type 'num'.
+// Try changing the type of the parameter, or casting the argument to 'num'.
// x2 /*@target=Map::[]=*/ [/*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ 'hi'] = 'w';
// ^
//
-// pkg/front_end/testcases/inference/map_literals_top_level.dart:22:62: Error: A value of type 'int' can't be assigned to a variable of type 'Pattern'.
+// pkg/front_end/testcases/inference/map_literals_top_level.dart:22:62: Error: The argument type 'int' can't be assigned to the parameter type 'Pattern'.
// - 'Pattern' is from 'dart:core'.
-// Try changing the type of the left hand side, or casting the right hand side to 'Pattern'.
+// Try changing the type of the parameter, or casting the argument to 'Pattern'.
// x2 /*@target=Map::[]=*/ [3] = /*error:INVALID_ASSIGNMENT*/ 42;
// ^
//
@@ -35,30 +35,30 @@
static field core::Map<core::num*, core::Pattern*>* x2 = <core::num*, core::Pattern*>{1: "x", 2: "y", 3.0: core::RegExp::•(".")};
static method test1() → dynamic {
self::x1.{core::Map::[]=}(3, "z");
- self::x1.{core::Map::[]=}(let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/inference/map_literals_top_level.dart:11:67: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-Try changing the type of the left hand side, or casting the right hand side to 'int'.
+ self::x1.{core::Map::[]=}(let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/inference/map_literals_top_level.dart:11:67: Error: The argument type 'String' can't be assigned to the parameter type 'int'.
+Try changing the type of the parameter, or casting the argument to 'int'.
x1 /*@target=Map::[]=*/ [/*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ 'hi'] = 'w';
^" in "hi" as{TypeError} core::int*, "w");
- self::x1.{core::Map::[]=}(let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/inference/map_literals_top_level.dart:12:67: Error: A value of type 'double' can't be assigned to a variable of type 'int'.
-Try changing the type of the left hand side, or casting the right hand side to 'int'.
+ self::x1.{core::Map::[]=}(let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/inference/map_literals_top_level.dart:12:67: Error: The argument type 'double' can't be assigned to the parameter type 'int'.
+Try changing the type of the parameter, or casting the argument to 'int'.
x1 /*@target=Map::[]=*/ [/*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ 4.0] = 'u';
^" in 4.0 as{TypeError} core::int*, "u");
- self::x1.{core::Map::[]=}(3, let final<BottomType> #t3 = invalid-expression "pkg/front_end/testcases/inference/map_literals_top_level.dart:13:62: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
-Try changing the type of the left hand side, or casting the right hand side to 'String'.
+ self::x1.{core::Map::[]=}(3, let final<BottomType> #t3 = invalid-expression "pkg/front_end/testcases/inference/map_literals_top_level.dart:13:62: Error: The argument type 'int' can't be assigned to the parameter type 'String'.
+Try changing the type of the parameter, or casting the argument to 'String'.
x1 /*@target=Map::[]=*/ [3] = /*error:INVALID_ASSIGNMENT*/ 42;
^" in 42 as{TypeError} core::String*);
core::Map<core::num*, core::String*>* y = self::x1;
}
static method test2() → dynamic {
self::x2.{core::Map::[]=}(3, "z");
- self::x2.{core::Map::[]=}(let final<BottomType> #t4 = invalid-expression "pkg/front_end/testcases/inference/map_literals_top_level.dart:20:67: Error: A value of type 'String' can't be assigned to a variable of type 'num'.
-Try changing the type of the left hand side, or casting the right hand side to 'num'.
+ self::x2.{core::Map::[]=}(let final<BottomType> #t4 = invalid-expression "pkg/front_end/testcases/inference/map_literals_top_level.dart:20:67: Error: The argument type 'String' can't be assigned to the parameter type 'num'.
+Try changing the type of the parameter, or casting the argument to 'num'.
x2 /*@target=Map::[]=*/ [/*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ 'hi'] = 'w';
^" in "hi" as{TypeError} core::num*, "w");
self::x2.{core::Map::[]=}(4.0, "u");
- self::x2.{core::Map::[]=}(3, let final<BottomType> #t5 = invalid-expression "pkg/front_end/testcases/inference/map_literals_top_level.dart:22:62: Error: A value of type 'int' can't be assigned to a variable of type 'Pattern'.
+ self::x2.{core::Map::[]=}(3, let final<BottomType> #t5 = invalid-expression "pkg/front_end/testcases/inference/map_literals_top_level.dart:22:62: Error: The argument type 'int' can't be assigned to the parameter type 'Pattern'.
- 'Pattern' is from 'dart:core'.
-Try changing the type of the left hand side, or casting the right hand side to 'Pattern'.
+Try changing the type of the parameter, or casting the argument to 'Pattern'.
x2 /*@target=Map::[]=*/ [3] = /*error:INVALID_ASSIGNMENT*/ 42;
^" in 42 as{TypeError} core::Pattern*);
core::Pattern* p = null;
diff --git a/pkg/front_end/testcases/inference/null_aware_method_invocation.dart b/pkg/front_end/testcases/inference/null_aware_method_invocation.dart
index 13e2704..62e84f5 100644
--- a/pkg/front_end/testcases/inference/null_aware_method_invocation.dart
+++ b/pkg/front_end/testcases/inference/null_aware_method_invocation.dart
@@ -10,8 +10,9 @@
}
g(C c) {
- var /*@ type=int* */ x = c?. /*@target=C::f*/ f();
- c?. /*@target=C::f*/ f();
+ var /*@ type=int* */ x = /*@ type=C* */ /*@target=Object::==*/ c
+ ?. /*@target=C::f*/ f();
+ /*@ type=C* */ /*@target=Object::==*/ c?. /*@target=C::f*/ f();
}
main() {}
diff --git a/pkg/front_end/testcases/inference/null_aware_method_invocation.dart.strong.expect b/pkg/front_end/testcases/inference/null_aware_method_invocation.dart.strong.expect
index 718b355..127fa61 100644
--- a/pkg/front_end/testcases/inference/null_aware_method_invocation.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/null_aware_method_invocation.dart.strong.expect
@@ -10,7 +10,7 @@
return null;
}
static method g(self::C* c) → dynamic {
- core::int* x = let final self::C* #t1 = c in #t1.==(null) ?{core::int*} null : #t1.{self::C::f}();
- let final self::C* #t2 = c in #t2.==(null) ?{core::int*} null : #t2.{self::C::f}();
+ core::int* x = let final self::C* #t1 = c in #t1.{core::Object::==}(null) ?{core::int*} null : #t1.{self::C::f}();
+ let final self::C* #t2 = c in #t2.{core::Object::==}(null) ?{core::int*} null : #t2.{self::C::f}();
}
static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/null_aware_method_invocation.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/null_aware_method_invocation.dart.strong.transformed.expect
index 718b355..127fa61 100644
--- a/pkg/front_end/testcases/inference/null_aware_method_invocation.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/null_aware_method_invocation.dart.strong.transformed.expect
@@ -10,7 +10,7 @@
return null;
}
static method g(self::C* c) → dynamic {
- core::int* x = let final self::C* #t1 = c in #t1.==(null) ?{core::int*} null : #t1.{self::C::f}();
- let final self::C* #t2 = c in #t2.==(null) ?{core::int*} null : #t2.{self::C::f}();
+ core::int* x = let final self::C* #t1 = c in #t1.{core::Object::==}(null) ?{core::int*} null : #t1.{self::C::f}();
+ let final self::C* #t2 = c in #t2.{core::Object::==}(null) ?{core::int*} null : #t2.{self::C::f}();
}
static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/null_aware_property_get.dart b/pkg/front_end/testcases/inference/null_aware_property_get.dart
index f565a26..112432b 100644
--- a/pkg/front_end/testcases/inference/null_aware_property_get.dart
+++ b/pkg/front_end/testcases/inference/null_aware_property_get.dart
@@ -10,8 +10,9 @@
}
void f(C c) {
- var /*@ type=int* */ x = c?. /*@target=C::x*/ x;
- c?. /*@target=C::x*/ x;
+ var /*@ type=int* */ x = /*@ type=C* */ /*@target=Object::==*/ c
+ ?. /*@target=C::x*/ x;
+ /*@ type=C* */ /*@target=Object::==*/ c?. /*@target=C::x*/ x;
}
main() {}
diff --git a/pkg/front_end/testcases/inference/null_aware_property_get.dart.strong.expect b/pkg/front_end/testcases/inference/null_aware_property_get.dart.strong.expect
index 4c40eb5..0d14e2b 100644
--- a/pkg/front_end/testcases/inference/null_aware_property_get.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/null_aware_property_get.dart.strong.expect
@@ -9,7 +9,7 @@
;
}
static method f(self::C* c) → void {
- core::int* x = let final self::C* #t1 = c in #t1.==(null) ?{core::int*} null : #t1.{self::C::x};
- let final self::C* #t2 = c in #t2.==(null) ?{core::int*} null : #t2.{self::C::x};
+ core::int* x = let final self::C* #t1 = c in #t1.{core::Object::==}(null) ?{core::int*} null : #t1.{self::C::x};
+ let final self::C* #t2 = c in #t2.{core::Object::==}(null) ?{core::int*} null : #t2.{self::C::x};
}
static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/null_aware_property_get.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/null_aware_property_get.dart.strong.transformed.expect
index 4c40eb5..0d14e2b 100644
--- a/pkg/front_end/testcases/inference/null_aware_property_get.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/null_aware_property_get.dart.strong.transformed.expect
@@ -9,7 +9,7 @@
;
}
static method f(self::C* c) → void {
- core::int* x = let final self::C* #t1 = c in #t1.==(null) ?{core::int*} null : #t1.{self::C::x};
- let final self::C* #t2 = c in #t2.==(null) ?{core::int*} null : #t2.{self::C::x};
+ core::int* x = let final self::C* #t1 = c in #t1.{core::Object::==}(null) ?{core::int*} null : #t1.{self::C::x};
+ let final self::C* #t2 = c in #t2.{core::Object::==}(null) ?{core::int*} null : #t2.{self::C::x};
}
static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/null_literal_should_not_infer_as_bottom.dart b/pkg/front_end/testcases/inference/null_literal_should_not_infer_as_bottom.dart
index 2bcd9b9..42550db 100644
--- a/pkg/front_end/testcases/inference/null_literal_should_not_infer_as_bottom.dart
+++ b/pkg/front_end/testcases/inference/null_literal_should_not_infer_as_bottom.dart
@@ -9,10 +9,10 @@
void foo(int f(Object _)) {}
test() {
- var /*@ type=(Object*) ->* Null* */ f = /*@ returnType=Null* */ (Object x) => null;
+ var /*@ type=(Object*) ->* Null? */ f = /*@ returnType=Null? */ (Object x) => null;
String y = /*info:DYNAMIC_CAST*/ f(42);
- f = /*@ returnType=Null* */ (/*@ type=Object* */ x) => 'hello';
+ f = /*@ returnType=Null? */ (/*@ type=Object* */ x) => 'hello';
var /*@ type=dynamic */ g = null;
g = 'hello';
@@ -21,7 +21,7 @@
h = 'hello';
(/*info:DYNAMIC_INVOKE*/ h.foo());
- foo(/*@ returnType=Null* */ (/*@ type=Object* */ x) => null);
+ foo(/*@ returnType=Null? */ (/*@ type=Object* */ x) => null);
foo(/*@ returnType=<BottomType> */ (/*@ type=Object* */ x) =>
throw "not implemented");
}
diff --git a/pkg/front_end/testcases/inference/null_literal_should_not_infer_as_bottom.dart.strong.expect b/pkg/front_end/testcases/inference/null_literal_should_not_infer_as_bottom.dart.strong.expect
index f63bf12..20b5208 100644
--- a/pkg/front_end/testcases/inference/null_literal_should_not_infer_as_bottom.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/null_literal_should_not_infer_as_bottom.dart.strong.expect
@@ -5,15 +5,15 @@
static field dynamic h = null;
static method foo((core::Object*) →* core::int* f) → void {}
static method test() → dynamic {
- (core::Object*) →* core::Null* f = (core::Object* x) → core::Null* => null;
+ (core::Object*) →* core::Null? f = (core::Object* x) → core::Null? => null;
core::String* y = f.call(42);
- f = (core::Object* x) → core::Null* => "hello" as{TypeError} core::Null*;
+ f = (core::Object* x) → core::Null? => "hello" as{TypeError} core::Null?;
dynamic g = null;
g = "hello";
g.foo();
self::h = "hello";
self::h.foo();
- self::foo((core::Object* x) → core::Null* => null);
+ self::foo((core::Object* x) → core::Null? => null);
self::foo((core::Object* x) → <BottomType>=> throw "not implemented");
}
static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/null_literal_should_not_infer_as_bottom.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/null_literal_should_not_infer_as_bottom.dart.strong.transformed.expect
index f63bf12..20b5208 100644
--- a/pkg/front_end/testcases/inference/null_literal_should_not_infer_as_bottom.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/null_literal_should_not_infer_as_bottom.dart.strong.transformed.expect
@@ -5,15 +5,15 @@
static field dynamic h = null;
static method foo((core::Object*) →* core::int* f) → void {}
static method test() → dynamic {
- (core::Object*) →* core::Null* f = (core::Object* x) → core::Null* => null;
+ (core::Object*) →* core::Null? f = (core::Object* x) → core::Null? => null;
core::String* y = f.call(42);
- f = (core::Object* x) → core::Null* => "hello" as{TypeError} core::Null*;
+ f = (core::Object* x) → core::Null? => "hello" as{TypeError} core::Null?;
dynamic g = null;
g = "hello";
g.foo();
self::h = "hello";
self::h.foo();
- self::foo((core::Object* x) → core::Null* => null);
+ self::foo((core::Object* x) → core::Null? => null);
self::foo((core::Object* x) → <BottomType>=> throw "not implemented");
}
static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/null_literal_should_not_infer_as_bottom.dart.type_promotion.expect b/pkg/front_end/testcases/inference/null_literal_should_not_infer_as_bottom.dart.type_promotion.expect
index 43e9255..9262c18 100644
--- a/pkg/front_end/testcases/inference/null_literal_should_not_infer_as_bottom.dart.type_promotion.expect
+++ b/pkg/front_end/testcases/inference/null_literal_should_not_infer_as_bottom.dart.type_promotion.expect
@@ -1,5 +1,5 @@
pkg/front_end/testcases/inference/null_literal_should_not_infer_as_bottom.dart:15:5: Context: Write to f@353
- f = /*@ returnType=Null* */ (/*@ type=Object* */ x) => 'hello';
+ f = /*@ returnType=Null? */ (/*@ type=Object* */ x) => 'hello';
^
pkg/front_end/testcases/inference/null_literal_should_not_infer_as_bottom.dart:18:5: Context: Write to g@537
g = 'hello';
diff --git a/pkg/front_end/testcases/inference/parameter_defaults_downwards.dart b/pkg/front_end/testcases/inference/parameter_defaults_downwards.dart
index 668875a..b0671b2 100644
--- a/pkg/front_end/testcases/inference/parameter_defaults_downwards.dart
+++ b/pkg/front_end/testcases/inference/parameter_defaults_downwards.dart
@@ -12,8 +12,8 @@
main() {
void optional_local([List<int> x = /*@ typeArgs=int* */ const []]) {}
void named_local({List<int> x: /*@ typeArgs=int* */ const []}) {}
- var /*@ type=([List<int*>*]) ->* Null* */ optional_closure = /*@ returnType=Null* */ (
+ var /*@ type=([List<int*>*]) ->* Null? */ optional_closure = /*@ returnType=Null? */ (
[List<int> x = /*@ typeArgs=int* */ const []]) {};
- var /*@ type=({x: List<int*>*}) ->* Null* */ name_closure = /*@ returnType=Null* */ (
+ var /*@ type=({x: List<int*>*}) ->* Null? */ name_closure = /*@ returnType=Null? */ (
{List<int> x: /*@ typeArgs=int* */ const []}) {};
}
diff --git a/pkg/front_end/testcases/inference/parameter_defaults_downwards.dart.strong.expect b/pkg/front_end/testcases/inference/parameter_defaults_downwards.dart.strong.expect
index 27d3688..0c97dce 100644
--- a/pkg/front_end/testcases/inference/parameter_defaults_downwards.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/parameter_defaults_downwards.dart.strong.expect
@@ -7,8 +7,8 @@
static method main() → dynamic {
function optional_local([core::List<core::int*>* x = #C1]) → void {}
function named_local({core::List<core::int*>* x = #C1}) → void {}
- ([core::List<core::int*>*]) →* core::Null* optional_closure = ([core::List<core::int*>* x = #C1]) → core::Null* {};
- ({x: core::List<core::int*>*}) →* core::Null* name_closure = ({core::List<core::int*>* x = #C1}) → core::Null* {};
+ ([core::List<core::int*>*]) →* core::Null? optional_closure = ([core::List<core::int*>* x = #C1]) → core::Null? {};
+ ({x: core::List<core::int*>*}) →* core::Null? name_closure = ({core::List<core::int*>* x = #C1}) → core::Null? {};
}
constants {
diff --git a/pkg/front_end/testcases/inference/parameter_defaults_downwards.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/parameter_defaults_downwards.dart.strong.transformed.expect
index 27d3688..0c97dce 100644
--- a/pkg/front_end/testcases/inference/parameter_defaults_downwards.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/parameter_defaults_downwards.dart.strong.transformed.expect
@@ -7,8 +7,8 @@
static method main() → dynamic {
function optional_local([core::List<core::int*>* x = #C1]) → void {}
function named_local({core::List<core::int*>* x = #C1}) → void {}
- ([core::List<core::int*>*]) →* core::Null* optional_closure = ([core::List<core::int*>* x = #C1]) → core::Null* {};
- ({x: core::List<core::int*>*}) →* core::Null* name_closure = ({core::List<core::int*>* x = #C1}) → core::Null* {};
+ ([core::List<core::int*>*]) →* core::Null? optional_closure = ([core::List<core::int*>* x = #C1]) → core::Null? {};
+ ({x: core::List<core::int*>*}) →* core::Null? name_closure = ({core::List<core::int*>* x = #C1}) → core::Null? {};
}
constants {
diff --git a/pkg/front_end/testcases/inference/parameter_defaults_upwards.dart b/pkg/front_end/testcases/inference/parameter_defaults_upwards.dart
index 067eba9..ce97e95 100644
--- a/pkg/front_end/testcases/inference/parameter_defaults_upwards.dart
+++ b/pkg/front_end/testcases/inference/parameter_defaults_upwards.dart
@@ -26,9 +26,9 @@
var /*@ type=C<dynamic>* */ c_named_local =
new /*@ typeArgs=dynamic */ C.named(named_local);
var /*@ type=C<dynamic>* */ c_optional_closure =
- new /*@ typeArgs=dynamic */ C.optional(/*@ returnType=Null* */ (
+ new /*@ typeArgs=dynamic */ C.optional(/*@ returnType=Null? */ (
[/*@ type=dynamic */ x = /*@ typeArgs=int* */ const [0]]) {});
var /*@ type=C<dynamic>* */ c_named_closure = new /*@ typeArgs=dynamic */ C.named(
- /*@ returnType=Null* */ (
+ /*@ returnType=Null? */ (
{/*@ type=dynamic */ x: /*@ typeArgs=int* */ const [0]}) {});
}
diff --git a/pkg/front_end/testcases/inference/parameter_defaults_upwards.dart.strong.expect b/pkg/front_end/testcases/inference/parameter_defaults_upwards.dart.strong.expect
index 163f232..f26bb4a 100644
--- a/pkg/front_end/testcases/inference/parameter_defaults_upwards.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/parameter_defaults_upwards.dart.strong.expect
@@ -17,8 +17,8 @@
self::C<dynamic>* c_named_toplevel = new self::C::named<dynamic>(#C4);
self::C<dynamic>* c_optional_local = new self::C::optional<dynamic>(optional_local);
self::C<dynamic>* c_named_local = new self::C::named<dynamic>(named_local);
- self::C<dynamic>* c_optional_closure = new self::C::optional<dynamic>(([dynamic x = #C2]) → core::Null* {});
- self::C<dynamic>* c_named_closure = new self::C::named<dynamic>(({dynamic x = #C2}) → core::Null* {});
+ self::C<dynamic>* c_optional_closure = new self::C::optional<dynamic>(([dynamic x = #C2]) → core::Null? {});
+ self::C<dynamic>* c_named_closure = new self::C::named<dynamic>(({dynamic x = #C2}) → core::Null? {});
}
constants {
diff --git a/pkg/front_end/testcases/inference/parameter_defaults_upwards.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/parameter_defaults_upwards.dart.strong.transformed.expect
index 163f232..f26bb4a 100644
--- a/pkg/front_end/testcases/inference/parameter_defaults_upwards.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/parameter_defaults_upwards.dart.strong.transformed.expect
@@ -17,8 +17,8 @@
self::C<dynamic>* c_named_toplevel = new self::C::named<dynamic>(#C4);
self::C<dynamic>* c_optional_local = new self::C::optional<dynamic>(optional_local);
self::C<dynamic>* c_named_local = new self::C::named<dynamic>(named_local);
- self::C<dynamic>* c_optional_closure = new self::C::optional<dynamic>(([dynamic x = #C2]) → core::Null* {});
- self::C<dynamic>* c_named_closure = new self::C::named<dynamic>(({dynamic x = #C2}) → core::Null* {});
+ self::C<dynamic>* c_optional_closure = new self::C::optional<dynamic>(([dynamic x = #C2]) → core::Null? {});
+ self::C<dynamic>* c_named_closure = new self::C::named<dynamic>(({dynamic x = #C2}) → core::Null? {});
}
constants {
diff --git a/pkg/front_end/testcases/inference/type_promotion_stopped_by_access_in_a_closure.dart b/pkg/front_end/testcases/inference/type_promotion_stopped_by_access_in_a_closure.dart
index f8fdf0b..747ad06 100644
--- a/pkg/front_end/testcases/inference/type_promotion_stopped_by_access_in_a_closure.dart
+++ b/pkg/front_end/testcases/inference/type_promotion_stopped_by_access_in_a_closure.dart
@@ -9,7 +9,7 @@
num n = null;
if (n is int) {
var /*@ type=num* */ i = n;
- /*@ returnType=Null* */ () {
+ /*@ returnType=Null? */ () {
n;
};
}
diff --git a/pkg/front_end/testcases/inference/type_promotion_stopped_by_access_in_a_closure.dart.strong.expect b/pkg/front_end/testcases/inference/type_promotion_stopped_by_access_in_a_closure.dart.strong.expect
index ae61a78..830f06e 100644
--- a/pkg/front_end/testcases/inference/type_promotion_stopped_by_access_in_a_closure.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/type_promotion_stopped_by_access_in_a_closure.dart.strong.expect
@@ -6,7 +6,7 @@
core::num* n = null;
if(n is core::int*) {
core::num* i = n;
- () → core::Null* {
+ () → core::Null? {
n;
};
}
diff --git a/pkg/front_end/testcases/inference/type_promotion_stopped_by_access_in_a_closure.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/type_promotion_stopped_by_access_in_a_closure.dart.strong.transformed.expect
index ae61a78..830f06e 100644
--- a/pkg/front_end/testcases/inference/type_promotion_stopped_by_access_in_a_closure.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/type_promotion_stopped_by_access_in_a_closure.dart.strong.transformed.expect
@@ -6,7 +6,7 @@
core::num* n = null;
if(n is core::int*) {
core::num* i = n;
- () → core::Null* {
+ () → core::Null? {
n;
};
}
diff --git a/pkg/front_end/testcases/inference/type_promotion_stopped_by_mutation_in_a_closure.dart b/pkg/front_end/testcases/inference/type_promotion_stopped_by_mutation_in_a_closure.dart
index 17ce8b7..dbbc0b1 100644
--- a/pkg/front_end/testcases/inference/type_promotion_stopped_by_mutation_in_a_closure.dart
+++ b/pkg/front_end/testcases/inference/type_promotion_stopped_by_mutation_in_a_closure.dart
@@ -10,7 +10,7 @@
if (n is int) {
var /*@ type=num* */ i = n;
}
- /*@ returnType=Null* */ () {
+ /*@ returnType=Null? */ () {
n = null;
};
}
diff --git a/pkg/front_end/testcases/inference/type_promotion_stopped_by_mutation_in_a_closure.dart.strong.expect b/pkg/front_end/testcases/inference/type_promotion_stopped_by_mutation_in_a_closure.dart.strong.expect
index 9cf4976..41ec7b8 100644
--- a/pkg/front_end/testcases/inference/type_promotion_stopped_by_mutation_in_a_closure.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/type_promotion_stopped_by_mutation_in_a_closure.dart.strong.expect
@@ -7,7 +7,7 @@
if(n is core::int*) {
core::num* i = n;
}
- () → core::Null* {
+ () → core::Null? {
n = null;
};
}
diff --git a/pkg/front_end/testcases/inference/type_promotion_stopped_by_mutation_in_a_closure.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/type_promotion_stopped_by_mutation_in_a_closure.dart.strong.transformed.expect
index 9cf4976..41ec7b8 100644
--- a/pkg/front_end/testcases/inference/type_promotion_stopped_by_mutation_in_a_closure.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/type_promotion_stopped_by_mutation_in_a_closure.dart.strong.transformed.expect
@@ -7,7 +7,7 @@
if(n is core::int*) {
core::num* i = n;
}
- () → core::Null* {
+ () → core::Null? {
n = null;
};
}
diff --git a/pkg/front_end/testcases/inference_new/const_invocation.dart b/pkg/front_end/testcases/inference_new/const_invocation.dart
index c707af5..8525174 100644
--- a/pkg/front_end/testcases/inference_new/const_invocation.dart
+++ b/pkg/front_end/testcases/inference_new/const_invocation.dart
@@ -8,16 +8,16 @@
typedef V F<U, V>(U u);
class Foo<T> {
- Bar<T> get v1 => const /*@ typeArgs=Null* */ Bar();
- Bar<List<T>> get v2 => const /*@ typeArgs=List<Null*>* */ Bar();
- Bar<F<T, T>> get v3 => const /*@ typeArgs=(Object*) ->* Null* */ Bar();
+ Bar<T> get v1 => const /*@ typeArgs=Null? */ Bar();
+ Bar<List<T>> get v2 => const /*@ typeArgs=List<Null?>* */ Bar();
+ Bar<F<T, T>> get v3 => const /*@ typeArgs=(Object*) ->* Null? */ Bar();
Bar<F<F<T, T>, T>> get v4 =>
- const /*@ typeArgs=((Null*) ->* Object*) ->* Null* */ Bar();
- List<T> get v5 => /*@ typeArgs=Null* */ const [];
- List<F<T, T>> get v6 => /*@ typeArgs=(Object*) ->* Null* */ const [];
- Map<T, T> get v7 => /*@ typeArgs=Null*, Null* */ const {};
- Map<F<T, T>, T> get v8 => /*@ typeArgs=(Object*) ->* Null*, Null* */ const {};
- Map<T, F<T, T>> get v9 => /*@ typeArgs=Null*, (Object*) ->* Null* */ const {};
+ const /*@ typeArgs=((Null?) ->* Object*) ->* Null? */ Bar();
+ List<T> get v5 => /*@ typeArgs=Null? */ const [];
+ List<F<T, T>> get v6 => /*@ typeArgs=(Object*) ->* Null? */ const [];
+ Map<T, T> get v7 => /*@ typeArgs=Null?, Null? */ const {};
+ Map<F<T, T>, T> get v8 => /*@ typeArgs=(Object*) ->* Null?, Null? */ const {};
+ Map<T, F<T, T>> get v9 => /*@ typeArgs=Null?, (Object*) ->* Null? */ const {};
}
class Bar<T> {
diff --git a/pkg/front_end/testcases/inference_new/const_invocation.dart.strong.expect b/pkg/front_end/testcases/inference_new/const_invocation.dart.strong.expect
index 6d0c538..c1f792b 100644
--- a/pkg/front_end/testcases/inference_new/const_invocation.dart.strong.expect
+++ b/pkg/front_end/testcases/inference_new/const_invocation.dart.strong.expect
@@ -34,14 +34,14 @@
static method main() → dynamic {}
constants {
- #C1 = self::Bar<core::Null*> {}
- #C2 = self::Bar<core::List<core::Null*>*> {}
- #C3 = self::Bar<(core::Object*) →* core::Null*> {}
- #C4 = self::Bar<((core::Null*) →* core::Object*) →* core::Null*> {}
- #C5 = <core::Null*>[]
- #C6 = <(core::Object*) →* core::Null*>[]
+ #C1 = self::Bar<core::Null?> {}
+ #C2 = self::Bar<core::List<core::Null?>*> {}
+ #C3 = self::Bar<(core::Object*) →* core::Null?> {}
+ #C4 = self::Bar<((core::Null?) →* core::Object*) →* core::Null?> {}
+ #C5 = <core::Null?>[]
+ #C6 = <(core::Object*) →* core::Null?>[]
#C7 = <dynamic>[]
- #C8 = core::_ImmutableMap<core::Null*, core::Null*> {_kvPairs:#C7}
- #C9 = core::_ImmutableMap<(core::Object*) →* core::Null*, core::Null*> {_kvPairs:#C7}
- #C10 = core::_ImmutableMap<core::Null*, (core::Object*) →* core::Null*> {_kvPairs:#C7}
+ #C8 = core::_ImmutableMap<core::Null?, core::Null?> {_kvPairs:#C7}
+ #C9 = core::_ImmutableMap<(core::Object*) →* core::Null?, core::Null?> {_kvPairs:#C7}
+ #C10 = core::_ImmutableMap<core::Null?, (core::Object*) →* core::Null?> {_kvPairs:#C7}
}
diff --git a/pkg/front_end/testcases/inference_new/const_invocation.dart.strong.transformed.expect b/pkg/front_end/testcases/inference_new/const_invocation.dart.strong.transformed.expect
index 6d0c538..c1f792b 100644
--- a/pkg/front_end/testcases/inference_new/const_invocation.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference_new/const_invocation.dart.strong.transformed.expect
@@ -34,14 +34,14 @@
static method main() → dynamic {}
constants {
- #C1 = self::Bar<core::Null*> {}
- #C2 = self::Bar<core::List<core::Null*>*> {}
- #C3 = self::Bar<(core::Object*) →* core::Null*> {}
- #C4 = self::Bar<((core::Null*) →* core::Object*) →* core::Null*> {}
- #C5 = <core::Null*>[]
- #C6 = <(core::Object*) →* core::Null*>[]
+ #C1 = self::Bar<core::Null?> {}
+ #C2 = self::Bar<core::List<core::Null?>*> {}
+ #C3 = self::Bar<(core::Object*) →* core::Null?> {}
+ #C4 = self::Bar<((core::Null?) →* core::Object*) →* core::Null?> {}
+ #C5 = <core::Null?>[]
+ #C6 = <(core::Object*) →* core::Null?>[]
#C7 = <dynamic>[]
- #C8 = core::_ImmutableMap<core::Null*, core::Null*> {_kvPairs:#C7}
- #C9 = core::_ImmutableMap<(core::Object*) →* core::Null*, core::Null*> {_kvPairs:#C7}
- #C10 = core::_ImmutableMap<core::Null*, (core::Object*) →* core::Null*> {_kvPairs:#C7}
+ #C8 = core::_ImmutableMap<core::Null?, core::Null?> {_kvPairs:#C7}
+ #C9 = core::_ImmutableMap<(core::Object*) →* core::Null?, core::Null?> {_kvPairs:#C7}
+ #C10 = core::_ImmutableMap<core::Null?, (core::Object*) →* core::Null?> {_kvPairs:#C7}
}
diff --git a/pkg/front_end/testcases/inference_new/for_each_identifier_downwards.dart b/pkg/front_end/testcases/inference_new/for_each_identifier_downwards.dart
index 1f79cf3..968995d 100644
--- a/pkg/front_end/testcases/inference_new/for_each_identifier_downwards.dart
+++ b/pkg/front_end/testcases/inference_new/for_each_identifier_downwards.dart
@@ -18,9 +18,15 @@
void test() {
A aLocal;
for (aLocal in /*@ typeArgs=Iterable<A*>* */ f()) {}
- for (/*@target=C::aField*/ aField in /*@ typeArgs=Iterable<A*>* */ f()) {}
- for (/*@target=C::aSetter*/ aSetter in /*@ typeArgs=Iterable<A*>* */ f()) {}
+
+ for (/*@target=C::aField*/ /*@target=C::aField*/ aField
+ in /*@ typeArgs=Iterable<A*>* */ f()) {}
+
+ for (/*@target=C::aSetter*/ /*@target=C::aSetter*/ aSetter
+ in /*@ typeArgs=Iterable<A*>* */ f()) {}
+
for (aTopLevel in /*@ typeArgs=Iterable<A*>* */ f()) {}
+
for (aTopLevelSetter in /*@ typeArgs=Iterable<A*>* */ f()) {}
}
}
diff --git a/pkg/front_end/testcases/inference_new/indexed_assign_combiner.dart b/pkg/front_end/testcases/inference_new/indexed_assign_combiner.dart
index f3ca5eb..6b8a751 100644
--- a/pkg/front_end/testcases/inference_new/indexed_assign_combiner.dart
+++ b/pkg/front_end/testcases/inference_new/indexed_assign_combiner.dart
@@ -32,18 +32,23 @@
}
void test1(G g) {
- g /*@target=G::[]=*/ [0] *= /*@ typeArgs=dynamic */ f();
- var /*@ type=C* */ x = g /*@target=G::[]=*/ [0] *= /*@ typeArgs=dynamic */ f();
+ g /*@target=G::[]*/ /*@target=G::[]=*/ [
+ 0] /*@ target=A::* */ *= /*@ typeArgs=D* */ f();
+ var /*@ type=C* */ x = g /*@target=G::[]*/ /*@target=G::[]=*/ [0]
+ /*@ target=A::* */
+ *= /*@ typeArgs=D* */ f();
}
void test2(G g) {
- ++g /*@target=G::[]=*/ [0];
- var /*@ type=C* */ x = ++g /*@target=G::[]=*/ [0];
+ /*@ target=A::+ */ ++g /*@target=G::[]*/ /*@target=G::[]=*/ [0];
+ var /*@ type=C* */ x = /*@ target=A::+ */ ++g /*@target=G::[]*/ /*@target=G::[]=*/ [
+ 0];
}
void test3(G g) {
- g /*@target=G::[]=*/ [0]++;
- var /*@ type=A* */ x = g /*@target=G::[]=*/ [0]++;
+ g /*@target=G::[] */ /*@target=G::[]=*/ [0] /*@ target=A::+ */ ++;
+ var /*@ type=A* */ x =
+ g /*@target=G::[]*/ /*@target=G::[]=*/ [0] /*@ target=A::+ */ ++;
}
main() {}
diff --git a/pkg/front_end/testcases/inference_new/indexed_assign_combiner.dart.strong.expect b/pkg/front_end/testcases/inference_new/indexed_assign_combiner.dart.strong.expect
index be01111..0d07bfd 100644
--- a/pkg/front_end/testcases/inference_new/indexed_assign_combiner.dart.strong.expect
+++ b/pkg/front_end/testcases/inference_new/indexed_assign_combiner.dart.strong.expect
@@ -51,8 +51,8 @@
static method f<T extends core::Object* = dynamic>() → self::f::T*
return null;
static method test1(self::G* g) → void {
- let final self::G* #t1 = g in let final core::int* #t2 = 0 in #t1.{self::G::[]=}(#t2, #t1.{self::G::[]}(#t2).{self::A::*}(self::f<dynamic>() as{TypeError} self::D*));
- self::C* x = let final self::G* #t3 = g in let final core::int* #t4 = 0 in let final self::C* #t5 = #t3.{self::G::[]}(#t4).{self::A::*}(self::f<dynamic>() as{TypeError} self::D*) in let final void #t6 = #t3.{self::G::[]=}(#t4, #t5) in #t5;
+ let final self::G* #t1 = g in let final core::int* #t2 = 0 in #t1.{self::G::[]=}(#t2, #t1.{self::G::[]}(#t2).{self::A::*}(self::f<self::D*>()));
+ self::C* x = let final self::G* #t3 = g in let final core::int* #t4 = 0 in let final self::C* #t5 = #t3.{self::G::[]}(#t4).{self::A::*}(self::f<self::D*>()) in let final void #t6 = #t3.{self::G::[]=}(#t4, #t5) in #t5;
}
static method test2(self::G* g) → void {
let final self::G* #t7 = g in let final core::int* #t8 = 0 in let final self::C* #t9 = #t7.{self::G::[]}(#t8).{self::A::+}(1) in let final void #t10 = #t7.{self::G::[]=}(#t8, #t9) in #t9;
diff --git a/pkg/front_end/testcases/inference_new/indexed_assign_combiner.dart.strong.transformed.expect b/pkg/front_end/testcases/inference_new/indexed_assign_combiner.dart.strong.transformed.expect
index be01111..0d07bfd 100644
--- a/pkg/front_end/testcases/inference_new/indexed_assign_combiner.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference_new/indexed_assign_combiner.dart.strong.transformed.expect
@@ -51,8 +51,8 @@
static method f<T extends core::Object* = dynamic>() → self::f::T*
return null;
static method test1(self::G* g) → void {
- let final self::G* #t1 = g in let final core::int* #t2 = 0 in #t1.{self::G::[]=}(#t2, #t1.{self::G::[]}(#t2).{self::A::*}(self::f<dynamic>() as{TypeError} self::D*));
- self::C* x = let final self::G* #t3 = g in let final core::int* #t4 = 0 in let final self::C* #t5 = #t3.{self::G::[]}(#t4).{self::A::*}(self::f<dynamic>() as{TypeError} self::D*) in let final void #t6 = #t3.{self::G::[]=}(#t4, #t5) in #t5;
+ let final self::G* #t1 = g in let final core::int* #t2 = 0 in #t1.{self::G::[]=}(#t2, #t1.{self::G::[]}(#t2).{self::A::*}(self::f<self::D*>()));
+ self::C* x = let final self::G* #t3 = g in let final core::int* #t4 = 0 in let final self::C* #t5 = #t3.{self::G::[]}(#t4).{self::A::*}(self::f<self::D*>()) in let final void #t6 = #t3.{self::G::[]=}(#t4, #t5) in #t5;
}
static method test2(self::G* g) → void {
let final self::G* #t7 = g in let final core::int* #t8 = 0 in let final self::C* #t9 = #t7.{self::G::[]}(#t8).{self::A::+}(1) in let final void #t10 = #t7.{self::G::[]=}(#t8, #t9) in #t9;
diff --git a/pkg/front_end/testcases/inference_new/infer_assign_to_implicit_this.dart b/pkg/front_end/testcases/inference_new/infer_assign_to_implicit_this.dart
index 024d1cc..f1f28c4 100644
--- a/pkg/front_end/testcases/inference_new/infer_assign_to_implicit_this.dart
+++ b/pkg/front_end/testcases/inference_new/infer_assign_to_implicit_this.dart
@@ -23,18 +23,38 @@
void test() {
/*@target=Test::member*/ member = /*@ typeArgs=B* */ f();
- /*@target=Test::member*/ member ??= /*@ typeArgs=B* */ f();
+
+ /*@target=Test::member*/ /*@target=Test::member*/ member
+ /*@ target=Object::== */ ??= /*@ typeArgs=B* */ f();
+
/*@target=Test::member*/ member += /*@ typeArgs=dynamic */ f();
+
/*@target=Test::member*/ member *= /*@ typeArgs=dynamic */ f();
+
/*@target=Test::member*/ member &= /*@ typeArgs=dynamic */ f();
+
-- /*@target=Test::member*/ member;
+
/*@target=Test::member*/ member--;
- var /*@ type=B* */ v1 = /*@target=Test::member*/ member = /*@ typeArgs=B* */ f();
- var /*@ type=B* */ v2 = /*@target=Test::member*/ member ??= /*@ typeArgs=B* */ f();
- var /*@ type=A* */ v3 = /*@target=Test::member*/ member += /*@ typeArgs=dynamic */ f();
- var /*@ type=B* */ v4 = /*@target=Test::member*/ member *= /*@ typeArgs=dynamic */ f();
- var /*@ type=C* */ v5 = /*@target=Test::member*/ member &= /*@ typeArgs=dynamic */ f();
+
+ var /*@ type=B* */ v1 = /*@target=Test::member*/ member =
+ /*@ typeArgs=B* */ f();
+
+ var /*@ type=B* */ v2 = /*@target=Test::member*/ /*@target=Test::member*/
+ member
+ /*@ target=Object::== */ ??= /*@ typeArgs=B* */ f();
+
+ var /*@ type=A* */ v3 = /*@target=Test::member*/ member +=
+ /*@ typeArgs=dynamic */ f();
+
+ var /*@ type=B* */ v4 = /*@target=Test::member*/ member *=
+ /*@ typeArgs=dynamic */ f();
+
+ var /*@ type=C* */ v5 = /*@target=Test::member*/ member &=
+ /*@ typeArgs=dynamic */ f();
+
var /*@ type=B* */ v6 = -- /*@target=Test::member*/ member;
+
var /*@ type=B* */ v7 = /*@target=Test::member*/ member--;
}
}
diff --git a/pkg/front_end/testcases/inference_new/infer_assign_to_implicit_this_upwards.dart b/pkg/front_end/testcases/inference_new/infer_assign_to_implicit_this_upwards.dart
index 51356c8..cfabd2b 100644
--- a/pkg/front_end/testcases/inference_new/infer_assign_to_implicit_this_upwards.dart
+++ b/pkg/front_end/testcases/inference_new/infer_assign_to_implicit_this_upwards.dart
@@ -14,12 +14,21 @@
void test() {
var /*@ type=int* */ v1 = /*@target=Test1::t*/ t = getInt();
+
var /*@ type=num* */ v2 = /*@target=Test1::t*/ t = getNum();
- var /*@ type=int* */ v4 = /*@target=Test1::t*/ t ??= getInt();
- var /*@ type=num* */ v5 = /*@target=Test1::t*/ t ??= getNum();
+
+ var /*@ type=int* */ v4 = /*@target=Test1::t*/ /*@target=Test1::t*/ t
+ /*@ target=num::== */ ??= getInt();
+
+ var /*@ type=num* */ v5 = /*@target=Test1::t*/ /*@target=Test1::t*/ t
+ /*@ target=num::== */ ??= getNum();
+
var /*@ type=int* */ v7 = /*@target=Test1::t*/ t += getInt();
+
var /*@ type=num* */ v8 = /*@target=Test1::t*/ t += getNum();
+
var /*@ type=int* */ v10 = ++ /*@target=Test1::t*/ t;
+
var /*@ type=int* */ v11 = /*@target=Test1::t*/ t++;
}
}
@@ -29,15 +38,28 @@
void test() {
var /*@ type=int* */ v1 = /*@target=Test2::t*/ t = getInt();
+
var /*@ type=num* */ v2 = /*@target=Test2::t*/ t = getNum();
+
var /*@ type=double* */ v3 = /*@target=Test2::t*/ t = getDouble();
- var /*@ type=num* */ v4 = /*@target=Test2::t*/ t ??= getInt();
- var /*@ type=num* */ v5 = /*@target=Test2::t*/ t ??= getNum();
- var /*@ type=num* */ v6 = /*@target=Test2::t*/ t ??= getDouble();
+
+ var /*@ type=num* */ v4 = /*@target=Test2::t*/ /*@target=Test2::t*/ t
+ /*@ target=num::== */ ??= getInt();
+
+ var /*@ type=num* */ v5 = /*@target=Test2::t*/ /*@target=Test2::t*/ t
+ /*@ target=num::== */ ??= getNum();
+
+ var /*@ type=num* */ v6 = /*@target=Test2::t*/ /*@target=Test2::t*/ t
+ /*@ target=num::== */ ??= getDouble();
+
var /*@ type=num* */ v7 = /*@target=Test2::t*/ t += getInt();
+
var /*@ type=num* */ v8 = /*@target=Test2::t*/ t += getNum();
+
var /*@ type=num* */ v9 = /*@target=Test2::t*/ t += getDouble();
+
var /*@ type=num* */ v10 = ++ /*@target=Test2::t*/ t;
+
var /*@ type=num* */ v11 = /*@target=Test2::t*/ t++;
}
}
@@ -47,13 +69,23 @@
void test3() {
var /*@ type=num* */ v2 = /*@target=Test3::t*/ t = getNum();
+
var /*@ type=double* */ v3 = /*@target=Test3::t*/ t = getDouble();
- var /*@ type=num* */ v5 = /*@target=Test3::t*/ t ??= getNum();
- var /*@ type=double* */ v6 = /*@target=Test3::t*/ t ??= getDouble();
+
+ var /*@ type=num* */ v5 = /*@target=Test3::t*/ /*@target=Test3::t*/ t
+ /*@ target=num::== */ ??= getNum();
+
+ var /*@ type=double* */ v6 = /*@target=Test3::t*/ /*@target=Test3::t*/ t
+ /*@ target=num::== */ ??= getDouble();
+
var /*@ type=double* */ v7 = /*@target=Test3::t*/ t += getInt();
+
var /*@ type=double* */ v8 = /*@target=Test3::t*/ t += getNum();
+
var /*@ type=double* */ v9 = /*@target=Test3::t*/ t += getDouble();
+
var /*@ type=double* */ v10 = ++ /*@target=Test3::t*/ t;
+
var /*@ type=double* */ v11 = /*@target=Test3::t*/ t++;
}
}
diff --git a/pkg/front_end/testcases/inference_new/infer_assign_to_index_full.dart b/pkg/front_end/testcases/inference_new/infer_assign_to_index_full.dart
index 8271a08..4d3a249 100644
--- a/pkg/front_end/testcases/inference_new/infer_assign_to_index_full.dart
+++ b/pkg/front_end/testcases/inference_new/infer_assign_to_index_full.dart
@@ -26,28 +26,60 @@
void test() {
Test t = /*@ typeArgs=Test* */ f();
- t /*@target=Test::[]=*/ [/*@ typeArgs=dynamic */ f()] = /*@ typeArgs=B* */ f();
- t /*@target=Test::[]=*/ [/*@ typeArgs=dynamic */ f()] ??= /*@ typeArgs=B* */ f();
+
t /*@target=Test::[]=*/ [
- /*@ typeArgs=dynamic */ f()] += /*@ typeArgs=dynamic */ f();
- t /*@target=Test::[]=*/ [
- /*@ typeArgs=dynamic */ f()] *= /*@ typeArgs=dynamic */ f();
- t /*@target=Test::[]=*/ [
- /*@ typeArgs=dynamic */ f()] &= /*@ typeArgs=dynamic */ f();
- --t /*@target=Test::[]=*/ [/*@ typeArgs=dynamic */ f()];
- t /*@target=Test::[]=*/ [/*@ typeArgs=dynamic */ f()]--;
+ /*@ typeArgs=Index* */ f()] = /*@ typeArgs=B* */ f();
+
+ t /*@target=Test::[]*/ [
+ /*@ typeArgs=Index* */ f()]
+ /*@target=Object::==*/ /*@target=Test::[]=*/ ??= /*@ typeArgs=B* */ f();
+
+ t /*@target=Test::[]*/ /*@target=Test::[]=*/ [/*@ typeArgs=Index* */ f()]
+ /*@ target=B::+ */ += /*@ typeArgs=C* */ f();
+
+ t /*@target=Test::[]*/ /*@target=Test::[]=*/ [/*@ typeArgs=Index* */ f()]
+ /*@ target=B::* */ *= /*@ typeArgs=B* */ f();
+
+ t /*@target=Test::[]*/ /*@target=Test::[]=*/ [/*@ typeArgs=Index* */ f()]
+ /*@ target=B::& */ &= /*@ typeArgs=A* */ f();
+
+ t /*@target=Test::[]*/ [/*@ typeArgs=Index* */ f()];
+
+ /*@ target=B::- */ --t
+ /*@target=Test::[]*/ /*@target=Test::[]=*/ [
+ /*@ typeArgs=Index* */ f()];
+
+ t /*@target=Test::[]*/ /*@target=Test::[]=*/ [
+ /*@ typeArgs=Index* */ f()] /*@ target=B::- */ --;
+
var /*@ type=B* */ v1 = t /*@target=Test::[]=*/ [
- /*@ typeArgs=dynamic */ f()] = /*@ typeArgs=B* */ f();
- var /*@ type=B* */ v2 = t /*@target=Test::[]=*/ [
- /*@ typeArgs=dynamic */ f()] ??= /*@ typeArgs=B* */ f();
- var /*@ type=A* */ v3 = t /*@target=Test::[]=*/ [
- /*@ typeArgs=dynamic */ f()] += /*@ typeArgs=dynamic */ f();
- var /*@ type=B* */ v4 = t /*@target=Test::[]=*/ [
- /*@ typeArgs=dynamic */ f()] *= /*@ typeArgs=dynamic */ f();
- var /*@ type=C* */ v5 = t /*@target=Test::[]=*/ [
- /*@ typeArgs=dynamic */ f()] &= /*@ typeArgs=dynamic */ f();
- var /*@ type=B* */ v6 = --t /*@target=Test::[]=*/ [/*@ typeArgs=dynamic */ f()];
- var /*@ type=B* */ v7 = t /*@target=Test::[]=*/ [/*@ typeArgs=dynamic */ f()]--;
+ /*@ typeArgs=Index* */ f()] = /*@ typeArgs=B* */ f();
+
+ var /*@ type=B* */ v2 = t /*@target=Test::[]*/ [
+ /*@ typeArgs=Index* */ f()]
+ /*@target=Object::==*/ /*@target=Test::[]=*/ ??= /*@ typeArgs=B* */ f();
+
+ var /*@ type=A* */ v3 = t /*@target=Test::[]*/ /*@target=Test::[]=*/ [
+ /*@ typeArgs=Index* */ f()]
+ /*@ target=B::+ */ += /*@ typeArgs=C* */ f();
+
+ var /*@ type=B* */ v4 = t /*@target=Test::[]*/ /*@target=Test::[]=*/ [
+ /*@ typeArgs=Index* */ f()]
+ /*@ target=B::* */ *= /*@ typeArgs=B* */ f();
+
+ var /*@ type=C* */ v5 = t /*@target=Test::[]*/ /*@target=Test::[]=*/ [
+ /*@ typeArgs=Index* */ f()]
+ /*@ target=B::& */ &= /*@ typeArgs=A* */ f();
+
+ var /*@ type=B* */ v6 = t /*@target=Test::[]*/ [/*@ typeArgs=Index* */ f()];
+
+ var /*@ type=B* */ v7 =
+ /*@ target=B::- */ --t
+ /*@target=Test::[]*/ /*@target=Test::[]=*/ [
+ /*@ typeArgs=Index* */ f()];
+
+ var /*@ type=B* */ v8 = t /*@target=Test::[]*/ /*@target=Test::[]=*/ [
+ /*@ typeArgs=Index* */ f()] /*@ target=B::- */ --;
}
}
diff --git a/pkg/front_end/testcases/inference_new/infer_assign_to_index_full.dart.strong.expect b/pkg/front_end/testcases/inference_new/infer_assign_to_index_full.dart.strong.expect
index a86cc01..79ba7a1 100644
--- a/pkg/front_end/testcases/inference_new/infer_assign_to_index_full.dart.strong.expect
+++ b/pkg/front_end/testcases/inference_new/infer_assign_to_index_full.dart.strong.expect
@@ -39,20 +39,22 @@
operator []=(self::Index* i, self::B* v) → void {}
method test() → void {
self::Test* t = self::f<self::Test*>();
- t.{self::Test::[]=}(self::f<dynamic>() as{TypeError} self::Index*, self::f<self::B*>());
- let final self::Test* #t1 = t in let final dynamic #t2 = self::f<dynamic>() in #t1.{self::Test::[]}(#t2 as{TypeError} self::Index*).{core::Object::==}(null) ?{self::B*} let final self::B* #t3 = self::f<self::B*>() in let final void #t4 = #t1.{self::Test::[]=}(#t2 as{TypeError} self::Index*, #t3) in #t3 : null;
- let final self::Test* #t5 = t in let final dynamic #t6 = self::f<dynamic>() in #t5.{self::Test::[]=}(#t6 as{TypeError} self::Index*, #t5.{self::Test::[]}(#t6 as{TypeError} self::Index*).{self::B::+}(self::f<dynamic>() as{TypeError} self::C*) as{TypeError} self::B*);
- let final self::Test* #t7 = t in let final dynamic #t8 = self::f<dynamic>() in #t7.{self::Test::[]=}(#t8 as{TypeError} self::Index*, #t7.{self::Test::[]}(#t8 as{TypeError} self::Index*).{self::B::*}(self::f<dynamic>() as{TypeError} self::B*));
- let final self::Test* #t9 = t in let final dynamic #t10 = self::f<dynamic>() in #t9.{self::Test::[]=}(#t10 as{TypeError} self::Index*, #t9.{self::Test::[]}(#t10 as{TypeError} self::Index*).{self::B::&}(self::f<dynamic>() as{TypeError} self::A*));
- let final self::Test* #t11 = t in let final dynamic #t12 = self::f<dynamic>() in let final self::B* #t13 = #t11.{self::Test::[]}(#t12 as{TypeError} self::Index*).{self::B::-}(1) in let final void #t14 = #t11.{self::Test::[]=}(#t12 as{TypeError} self::Index*, #t13) in #t13;
- let final self::Test* #t15 = t in let final dynamic #t16 = self::f<dynamic>() in #t15.{self::Test::[]=}(#t16 as{TypeError} self::Index*, #t15.{self::Test::[]}(#t16 as{TypeError} self::Index*).{self::B::-}(1));
- self::B* v1 = let final self::Test* #t17 = t in let final dynamic #t18 = self::f<dynamic>() in let final self::B* #t19 = self::f<self::B*>() in let final void #t20 = #t17.{self::Test::[]=}(#t18 as{TypeError} self::Index*, #t19) in #t19;
- self::B* v2 = let final self::Test* #t21 = t in let final dynamic #t22 = self::f<dynamic>() in let final self::B* #t23 = #t21.{self::Test::[]}(#t22 as{TypeError} self::Index*) in #t23.{core::Object::==}(null) ?{self::B*} let final self::B* #t24 = self::f<self::B*>() in let final void #t25 = #t21.{self::Test::[]=}(#t22 as{TypeError} self::Index*, #t24) in #t24 : #t23;
- self::A* v3 = let final self::Test* #t26 = t in let final dynamic #t27 = self::f<dynamic>() in let final self::A* #t28 = #t26.{self::Test::[]}(#t27 as{TypeError} self::Index*).{self::B::+}(self::f<dynamic>() as{TypeError} self::C*) as{TypeError} self::B* in let final void #t29 = #t26.{self::Test::[]=}(#t27 as{TypeError} self::Index*, #t28) in #t28;
- self::B* v4 = let final self::Test* #t30 = t in let final dynamic #t31 = self::f<dynamic>() in let final self::B* #t32 = #t30.{self::Test::[]}(#t31 as{TypeError} self::Index*).{self::B::*}(self::f<dynamic>() as{TypeError} self::B*) in let final void #t33 = #t30.{self::Test::[]=}(#t31 as{TypeError} self::Index*, #t32) in #t32;
- self::C* v5 = let final self::Test* #t34 = t in let final dynamic #t35 = self::f<dynamic>() in let final self::C* #t36 = #t34.{self::Test::[]}(#t35 as{TypeError} self::Index*).{self::B::&}(self::f<dynamic>() as{TypeError} self::A*) in let final void #t37 = #t34.{self::Test::[]=}(#t35 as{TypeError} self::Index*, #t36) in #t36;
- self::B* v6 = let final self::Test* #t38 = t in let final dynamic #t39 = self::f<dynamic>() in let final self::B* #t40 = #t38.{self::Test::[]}(#t39 as{TypeError} self::Index*).{self::B::-}(1) in let final void #t41 = #t38.{self::Test::[]=}(#t39 as{TypeError} self::Index*, #t40) in #t40;
- self::B* v7 = let final self::Test* #t42 = t in let final dynamic #t43 = self::f<dynamic>() in let final self::B* #t44 = #t42.{self::Test::[]}(#t43 as{TypeError} self::Index*) in let final void #t45 = #t42.{self::Test::[]=}(#t43 as{TypeError} self::Index*, #t44.{self::B::-}(1)) in #t44;
+ t.{self::Test::[]=}(self::f<self::Index*>(), self::f<self::B*>());
+ let final self::Test* #t1 = t in let final self::Index* #t2 = self::f<self::Index*>() in #t1.{self::Test::[]}(#t2).{core::Object::==}(null) ?{self::B*} #t1.{self::Test::[]=}(#t2, self::f<self::B*>()) : null;
+ let final self::Test* #t3 = t in let final self::Index* #t4 = self::f<self::Index*>() in #t3.{self::Test::[]=}(#t4, #t3.{self::Test::[]}(#t4).{self::B::+}(self::f<self::C*>()) as{TypeError} self::B*);
+ let final self::Test* #t5 = t in let final self::Index* #t6 = self::f<self::Index*>() in #t5.{self::Test::[]=}(#t6, #t5.{self::Test::[]}(#t6).{self::B::*}(self::f<self::B*>()));
+ let final self::Test* #t7 = t in let final self::Index* #t8 = self::f<self::Index*>() in #t7.{self::Test::[]=}(#t8, #t7.{self::Test::[]}(#t8).{self::B::&}(self::f<self::A*>()));
+ t.{self::Test::[]}(self::f<self::Index*>());
+ let final self::Test* #t9 = t in let final self::Index* #t10 = self::f<self::Index*>() in let final self::B* #t11 = #t9.{self::Test::[]}(#t10).{self::B::-}(1) in let final void #t12 = #t9.{self::Test::[]=}(#t10, #t11) in #t11;
+ let final self::Test* #t13 = t in let final self::Index* #t14 = self::f<self::Index*>() in #t13.{self::Test::[]=}(#t14, #t13.{self::Test::[]}(#t14).{self::B::-}(1));
+ self::B* v1 = let final self::Test* #t15 = t in let final self::Index* #t16 = self::f<self::Index*>() in let final self::B* #t17 = self::f<self::B*>() in let final void #t18 = #t15.{self::Test::[]=}(#t16, #t17) in #t17;
+ self::B* v2 = let final self::Test* #t19 = t in let final self::Index* #t20 = self::f<self::Index*>() in let final self::B* #t21 = #t19.{self::Test::[]}(#t20) in #t21.{core::Object::==}(null) ?{self::B*} let final self::B* #t22 = self::f<self::B*>() in let final void #t23 = #t19.{self::Test::[]=}(#t20, #t22) in #t22 : #t21;
+ self::A* v3 = let final self::Test* #t24 = t in let final self::Index* #t25 = self::f<self::Index*>() in let final self::A* #t26 = #t24.{self::Test::[]}(#t25).{self::B::+}(self::f<self::C*>()) as{TypeError} self::B* in let final void #t27 = #t24.{self::Test::[]=}(#t25, #t26) in #t26;
+ self::B* v4 = let final self::Test* #t28 = t in let final self::Index* #t29 = self::f<self::Index*>() in let final self::B* #t30 = #t28.{self::Test::[]}(#t29).{self::B::*}(self::f<self::B*>()) in let final void #t31 = #t28.{self::Test::[]=}(#t29, #t30) in #t30;
+ self::C* v5 = let final self::Test* #t32 = t in let final self::Index* #t33 = self::f<self::Index*>() in let final self::C* #t34 = #t32.{self::Test::[]}(#t33).{self::B::&}(self::f<self::A*>()) in let final void #t35 = #t32.{self::Test::[]=}(#t33, #t34) in #t34;
+ self::B* v6 = t.{self::Test::[]}(self::f<self::Index*>());
+ self::B* v7 = let final self::Test* #t36 = t in let final self::Index* #t37 = self::f<self::Index*>() in let final self::B* #t38 = #t36.{self::Test::[]}(#t37).{self::B::-}(1) in let final void #t39 = #t36.{self::Test::[]=}(#t37, #t38) in #t38;
+ self::B* v8 = let final self::Test* #t40 = t in let final self::Index* #t41 = self::f<self::Index*>() in let final self::B* #t42 = #t40.{self::Test::[]}(#t41) in let final void #t43 = #t40.{self::Test::[]=}(#t41, #t42.{self::B::-}(1)) in #t42;
}
}
static method f<T extends core::Object* = dynamic>() → self::f::T*
diff --git a/pkg/front_end/testcases/inference_new/infer_assign_to_index_full.dart.strong.transformed.expect b/pkg/front_end/testcases/inference_new/infer_assign_to_index_full.dart.strong.transformed.expect
index a86cc01..79ba7a1 100644
--- a/pkg/front_end/testcases/inference_new/infer_assign_to_index_full.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference_new/infer_assign_to_index_full.dart.strong.transformed.expect
@@ -39,20 +39,22 @@
operator []=(self::Index* i, self::B* v) → void {}
method test() → void {
self::Test* t = self::f<self::Test*>();
- t.{self::Test::[]=}(self::f<dynamic>() as{TypeError} self::Index*, self::f<self::B*>());
- let final self::Test* #t1 = t in let final dynamic #t2 = self::f<dynamic>() in #t1.{self::Test::[]}(#t2 as{TypeError} self::Index*).{core::Object::==}(null) ?{self::B*} let final self::B* #t3 = self::f<self::B*>() in let final void #t4 = #t1.{self::Test::[]=}(#t2 as{TypeError} self::Index*, #t3) in #t3 : null;
- let final self::Test* #t5 = t in let final dynamic #t6 = self::f<dynamic>() in #t5.{self::Test::[]=}(#t6 as{TypeError} self::Index*, #t5.{self::Test::[]}(#t6 as{TypeError} self::Index*).{self::B::+}(self::f<dynamic>() as{TypeError} self::C*) as{TypeError} self::B*);
- let final self::Test* #t7 = t in let final dynamic #t8 = self::f<dynamic>() in #t7.{self::Test::[]=}(#t8 as{TypeError} self::Index*, #t7.{self::Test::[]}(#t8 as{TypeError} self::Index*).{self::B::*}(self::f<dynamic>() as{TypeError} self::B*));
- let final self::Test* #t9 = t in let final dynamic #t10 = self::f<dynamic>() in #t9.{self::Test::[]=}(#t10 as{TypeError} self::Index*, #t9.{self::Test::[]}(#t10 as{TypeError} self::Index*).{self::B::&}(self::f<dynamic>() as{TypeError} self::A*));
- let final self::Test* #t11 = t in let final dynamic #t12 = self::f<dynamic>() in let final self::B* #t13 = #t11.{self::Test::[]}(#t12 as{TypeError} self::Index*).{self::B::-}(1) in let final void #t14 = #t11.{self::Test::[]=}(#t12 as{TypeError} self::Index*, #t13) in #t13;
- let final self::Test* #t15 = t in let final dynamic #t16 = self::f<dynamic>() in #t15.{self::Test::[]=}(#t16 as{TypeError} self::Index*, #t15.{self::Test::[]}(#t16 as{TypeError} self::Index*).{self::B::-}(1));
- self::B* v1 = let final self::Test* #t17 = t in let final dynamic #t18 = self::f<dynamic>() in let final self::B* #t19 = self::f<self::B*>() in let final void #t20 = #t17.{self::Test::[]=}(#t18 as{TypeError} self::Index*, #t19) in #t19;
- self::B* v2 = let final self::Test* #t21 = t in let final dynamic #t22 = self::f<dynamic>() in let final self::B* #t23 = #t21.{self::Test::[]}(#t22 as{TypeError} self::Index*) in #t23.{core::Object::==}(null) ?{self::B*} let final self::B* #t24 = self::f<self::B*>() in let final void #t25 = #t21.{self::Test::[]=}(#t22 as{TypeError} self::Index*, #t24) in #t24 : #t23;
- self::A* v3 = let final self::Test* #t26 = t in let final dynamic #t27 = self::f<dynamic>() in let final self::A* #t28 = #t26.{self::Test::[]}(#t27 as{TypeError} self::Index*).{self::B::+}(self::f<dynamic>() as{TypeError} self::C*) as{TypeError} self::B* in let final void #t29 = #t26.{self::Test::[]=}(#t27 as{TypeError} self::Index*, #t28) in #t28;
- self::B* v4 = let final self::Test* #t30 = t in let final dynamic #t31 = self::f<dynamic>() in let final self::B* #t32 = #t30.{self::Test::[]}(#t31 as{TypeError} self::Index*).{self::B::*}(self::f<dynamic>() as{TypeError} self::B*) in let final void #t33 = #t30.{self::Test::[]=}(#t31 as{TypeError} self::Index*, #t32) in #t32;
- self::C* v5 = let final self::Test* #t34 = t in let final dynamic #t35 = self::f<dynamic>() in let final self::C* #t36 = #t34.{self::Test::[]}(#t35 as{TypeError} self::Index*).{self::B::&}(self::f<dynamic>() as{TypeError} self::A*) in let final void #t37 = #t34.{self::Test::[]=}(#t35 as{TypeError} self::Index*, #t36) in #t36;
- self::B* v6 = let final self::Test* #t38 = t in let final dynamic #t39 = self::f<dynamic>() in let final self::B* #t40 = #t38.{self::Test::[]}(#t39 as{TypeError} self::Index*).{self::B::-}(1) in let final void #t41 = #t38.{self::Test::[]=}(#t39 as{TypeError} self::Index*, #t40) in #t40;
- self::B* v7 = let final self::Test* #t42 = t in let final dynamic #t43 = self::f<dynamic>() in let final self::B* #t44 = #t42.{self::Test::[]}(#t43 as{TypeError} self::Index*) in let final void #t45 = #t42.{self::Test::[]=}(#t43 as{TypeError} self::Index*, #t44.{self::B::-}(1)) in #t44;
+ t.{self::Test::[]=}(self::f<self::Index*>(), self::f<self::B*>());
+ let final self::Test* #t1 = t in let final self::Index* #t2 = self::f<self::Index*>() in #t1.{self::Test::[]}(#t2).{core::Object::==}(null) ?{self::B*} #t1.{self::Test::[]=}(#t2, self::f<self::B*>()) : null;
+ let final self::Test* #t3 = t in let final self::Index* #t4 = self::f<self::Index*>() in #t3.{self::Test::[]=}(#t4, #t3.{self::Test::[]}(#t4).{self::B::+}(self::f<self::C*>()) as{TypeError} self::B*);
+ let final self::Test* #t5 = t in let final self::Index* #t6 = self::f<self::Index*>() in #t5.{self::Test::[]=}(#t6, #t5.{self::Test::[]}(#t6).{self::B::*}(self::f<self::B*>()));
+ let final self::Test* #t7 = t in let final self::Index* #t8 = self::f<self::Index*>() in #t7.{self::Test::[]=}(#t8, #t7.{self::Test::[]}(#t8).{self::B::&}(self::f<self::A*>()));
+ t.{self::Test::[]}(self::f<self::Index*>());
+ let final self::Test* #t9 = t in let final self::Index* #t10 = self::f<self::Index*>() in let final self::B* #t11 = #t9.{self::Test::[]}(#t10).{self::B::-}(1) in let final void #t12 = #t9.{self::Test::[]=}(#t10, #t11) in #t11;
+ let final self::Test* #t13 = t in let final self::Index* #t14 = self::f<self::Index*>() in #t13.{self::Test::[]=}(#t14, #t13.{self::Test::[]}(#t14).{self::B::-}(1));
+ self::B* v1 = let final self::Test* #t15 = t in let final self::Index* #t16 = self::f<self::Index*>() in let final self::B* #t17 = self::f<self::B*>() in let final void #t18 = #t15.{self::Test::[]=}(#t16, #t17) in #t17;
+ self::B* v2 = let final self::Test* #t19 = t in let final self::Index* #t20 = self::f<self::Index*>() in let final self::B* #t21 = #t19.{self::Test::[]}(#t20) in #t21.{core::Object::==}(null) ?{self::B*} let final self::B* #t22 = self::f<self::B*>() in let final void #t23 = #t19.{self::Test::[]=}(#t20, #t22) in #t22 : #t21;
+ self::A* v3 = let final self::Test* #t24 = t in let final self::Index* #t25 = self::f<self::Index*>() in let final self::A* #t26 = #t24.{self::Test::[]}(#t25).{self::B::+}(self::f<self::C*>()) as{TypeError} self::B* in let final void #t27 = #t24.{self::Test::[]=}(#t25, #t26) in #t26;
+ self::B* v4 = let final self::Test* #t28 = t in let final self::Index* #t29 = self::f<self::Index*>() in let final self::B* #t30 = #t28.{self::Test::[]}(#t29).{self::B::*}(self::f<self::B*>()) in let final void #t31 = #t28.{self::Test::[]=}(#t29, #t30) in #t30;
+ self::C* v5 = let final self::Test* #t32 = t in let final self::Index* #t33 = self::f<self::Index*>() in let final self::C* #t34 = #t32.{self::Test::[]}(#t33).{self::B::&}(self::f<self::A*>()) in let final void #t35 = #t32.{self::Test::[]=}(#t33, #t34) in #t34;
+ self::B* v6 = t.{self::Test::[]}(self::f<self::Index*>());
+ self::B* v7 = let final self::Test* #t36 = t in let final self::Index* #t37 = self::f<self::Index*>() in let final self::B* #t38 = #t36.{self::Test::[]}(#t37).{self::B::-}(1) in let final void #t39 = #t36.{self::Test::[]=}(#t37, #t38) in #t38;
+ self::B* v8 = let final self::Test* #t40 = t in let final self::Index* #t41 = self::f<self::Index*>() in let final self::B* #t42 = #t40.{self::Test::[]}(#t41) in let final void #t43 = #t40.{self::Test::[]=}(#t41, #t42.{self::B::-}(1)) in #t42;
}
}
static method f<T extends core::Object* = dynamic>() → self::f::T*
diff --git a/pkg/front_end/testcases/inference_new/infer_assign_to_index_set_vs_get.dart b/pkg/front_end/testcases/inference_new/infer_assign_to_index_set_vs_get.dart
index 6857ea2..4f4b0ba 100644
--- a/pkg/front_end/testcases/inference_new/infer_assign_to_index_set_vs_get.dart
+++ b/pkg/front_end/testcases/inference_new/infer_assign_to_index_set_vs_get.dart
@@ -33,20 +33,40 @@
void test() {
Test t = /*@ typeArgs=Test* */ f();
- t /*@target=Test::[]=*/ [/*@ typeArgs=dynamic */ f()] = /*@ typeArgs=A* */ f();
- t /*@target=Test::[]=*/ [/*@ typeArgs=dynamic */ f()] ??= /*@ typeArgs=A* */ f();
+
t /*@target=Test::[]=*/ [
- /*@ typeArgs=dynamic */ f()] += /*@ typeArgs=dynamic */ f();
- --t /*@target=Test::[]=*/ [/*@ typeArgs=dynamic */ f()];
- t /*@target=Test::[]=*/ [/*@ typeArgs=dynamic */ f()]--;
+ /*@ typeArgs=Index* */ f()] = /*@ typeArgs=A* */ f();
+
+ t /*@target=Test::[]*/ [
+ /*@ typeArgs=Index* */ f()]
+ /*@target=Object::==*/ /*@target=Test::[]=*/ ??= /*@ typeArgs=A* */ f();
+
+ t /*@target=Test::[]*/ /*@target=Test::[]=*/ [/*@ typeArgs=Index* */ f()]
+ /*@ target=B::+ */ += /*@ typeArgs=E* */ f();
+
+ /*@ target=B::- */ --t /*@target=Test::[]*/ /*@target=Test::[]=*/ [
+ /*@ typeArgs=Index* */ f()];
+
+ t /*@target=Test::[]*/ /*@target=Test::[]=*/ [
+ /*@ typeArgs=Index* */ f()] /*@ target=B::- */ --;
+
var /*@ type=A* */ v1 = t /*@target=Test::[]=*/ [
- /*@ typeArgs=dynamic */ f()] = /*@ typeArgs=A* */ f();
- var /*@ type=A* */ v2 = t /*@target=Test::[]=*/ [
- /*@ typeArgs=dynamic */ f()] ??= /*@ typeArgs=A* */ f();
- var /*@ type=D* */ v3 = t /*@target=Test::[]=*/ [
- /*@ typeArgs=dynamic */ f()] += /*@ typeArgs=dynamic */ f();
- var /*@ type=D* */ v4 = --t /*@target=Test::[]=*/ [/*@ typeArgs=dynamic */ f()];
- var /*@ type=B* */ v5 = t /*@target=Test::[]=*/ [/*@ typeArgs=dynamic */ f()]--;
+ /*@ typeArgs=Index* */ f()] = /*@ typeArgs=A* */ f();
+
+ var /*@ type=A* */ v2 = t /*@target=Test::[]*/ [
+ /*@ typeArgs=Index* */ f()]
+ /*@target=Object::==*/ /*@target=Test::[]=*/ ??= /*@ typeArgs=A* */ f();
+
+ var /*@ type=D* */ v3 = t /*@target=Test::[]*/ /*@target=Test::[]=*/ [
+ /*@ typeArgs=Index* */ f()]
+ /*@ target=B::+ */ += /*@ typeArgs=E* */ f();
+
+ var /*@ type=D* */ v4 =
+ /*@ target=B::- */ --t /*@target=Test::[]*/ /*@target=Test::[]=*/ [
+ /*@ typeArgs=Index* */ f()];
+
+ var /*@ type=B* */ v5 = t /*@target=Test::[]*/ /*@target=Test::[]=*/ [
+ /*@ typeArgs=Index* */ f()] /*@ target=B::- */ --;
}
}
diff --git a/pkg/front_end/testcases/inference_new/infer_assign_to_index_set_vs_get.dart.strong.expect b/pkg/front_end/testcases/inference_new/infer_assign_to_index_set_vs_get.dart.strong.expect
index cde8b4e..9bba684 100644
--- a/pkg/front_end/testcases/inference_new/infer_assign_to_index_set_vs_get.dart.strong.expect
+++ b/pkg/front_end/testcases/inference_new/infer_assign_to_index_set_vs_get.dart.strong.expect
@@ -54,16 +54,16 @@
operator []=(self::Index* i, self::A* v) → void {}
method test() → void {
self::Test* t = self::f<self::Test*>();
- t.{self::Test::[]=}(self::f<dynamic>() as{TypeError} self::Index*, self::f<self::A*>());
- let final self::Test* #t1 = t in let final dynamic #t2 = self::f<dynamic>() in #t1.{self::Test::[]}(#t2 as{TypeError} self::Index*).{core::Object::==}(null) ?{self::A*} let final self::A* #t3 = self::f<self::A*>() in let final void #t4 = #t1.{self::Test::[]=}(#t2 as{TypeError} self::Index*, #t3) in #t3 : null;
- let final self::Test* #t5 = t in let final dynamic #t6 = self::f<dynamic>() in #t5.{self::Test::[]=}(#t6 as{TypeError} self::Index*, #t5.{self::Test::[]}(#t6 as{TypeError} self::Index*).{self::B::+}(self::f<dynamic>() as{TypeError} self::E*));
- let final self::Test* #t7 = t in let final dynamic #t8 = self::f<dynamic>() in let final self::D* #t9 = #t7.{self::Test::[]}(#t8 as{TypeError} self::Index*).{self::B::-}(1) in let final void #t10 = #t7.{self::Test::[]=}(#t8 as{TypeError} self::Index*, #t9) in #t9;
- let final self::Test* #t11 = t in let final dynamic #t12 = self::f<dynamic>() in #t11.{self::Test::[]=}(#t12 as{TypeError} self::Index*, #t11.{self::Test::[]}(#t12 as{TypeError} self::Index*).{self::B::-}(1));
- self::A* v1 = let final self::Test* #t13 = t in let final dynamic #t14 = self::f<dynamic>() in let final self::A* #t15 = self::f<self::A*>() in let final void #t16 = #t13.{self::Test::[]=}(#t14 as{TypeError} self::Index*, #t15) in #t15;
- self::A* v2 = let final self::Test* #t17 = t in let final dynamic #t18 = self::f<dynamic>() in let final self::B* #t19 = #t17.{self::Test::[]}(#t18 as{TypeError} self::Index*) in #t19.{core::Object::==}(null) ?{self::A*} let final self::A* #t20 = self::f<self::A*>() in let final void #t21 = #t17.{self::Test::[]=}(#t18 as{TypeError} self::Index*, #t20) in #t20 : #t19;
- self::D* v3 = let final self::Test* #t22 = t in let final dynamic #t23 = self::f<dynamic>() in let final self::D* #t24 = #t22.{self::Test::[]}(#t23 as{TypeError} self::Index*).{self::B::+}(self::f<dynamic>() as{TypeError} self::E*) in let final void #t25 = #t22.{self::Test::[]=}(#t23 as{TypeError} self::Index*, #t24) in #t24;
- self::D* v4 = let final self::Test* #t26 = t in let final dynamic #t27 = self::f<dynamic>() in let final self::D* #t28 = #t26.{self::Test::[]}(#t27 as{TypeError} self::Index*).{self::B::-}(1) in let final void #t29 = #t26.{self::Test::[]=}(#t27 as{TypeError} self::Index*, #t28) in #t28;
- self::B* v5 = let final self::Test* #t30 = t in let final dynamic #t31 = self::f<dynamic>() in let final self::B* #t32 = #t30.{self::Test::[]}(#t31 as{TypeError} self::Index*) in let final void #t33 = #t30.{self::Test::[]=}(#t31 as{TypeError} self::Index*, #t32.{self::B::-}(1)) in #t32;
+ t.{self::Test::[]=}(self::f<self::Index*>(), self::f<self::A*>());
+ let final self::Test* #t1 = t in let final self::Index* #t2 = self::f<self::Index*>() in #t1.{self::Test::[]}(#t2).{core::Object::==}(null) ?{self::A*} #t1.{self::Test::[]=}(#t2, self::f<self::A*>()) : null;
+ let final self::Test* #t3 = t in let final self::Index* #t4 = self::f<self::Index*>() in #t3.{self::Test::[]=}(#t4, #t3.{self::Test::[]}(#t4).{self::B::+}(self::f<self::E*>()));
+ let final self::Test* #t5 = t in let final self::Index* #t6 = self::f<self::Index*>() in let final self::D* #t7 = #t5.{self::Test::[]}(#t6).{self::B::-}(1) in let final void #t8 = #t5.{self::Test::[]=}(#t6, #t7) in #t7;
+ let final self::Test* #t9 = t in let final self::Index* #t10 = self::f<self::Index*>() in #t9.{self::Test::[]=}(#t10, #t9.{self::Test::[]}(#t10).{self::B::-}(1));
+ self::A* v1 = let final self::Test* #t11 = t in let final self::Index* #t12 = self::f<self::Index*>() in let final self::A* #t13 = self::f<self::A*>() in let final void #t14 = #t11.{self::Test::[]=}(#t12, #t13) in #t13;
+ self::A* v2 = let final self::Test* #t15 = t in let final self::Index* #t16 = self::f<self::Index*>() in let final self::B* #t17 = #t15.{self::Test::[]}(#t16) in #t17.{core::Object::==}(null) ?{self::A*} let final self::A* #t18 = self::f<self::A*>() in let final void #t19 = #t15.{self::Test::[]=}(#t16, #t18) in #t18 : #t17;
+ self::D* v3 = let final self::Test* #t20 = t in let final self::Index* #t21 = self::f<self::Index*>() in let final self::D* #t22 = #t20.{self::Test::[]}(#t21).{self::B::+}(self::f<self::E*>()) in let final void #t23 = #t20.{self::Test::[]=}(#t21, #t22) in #t22;
+ self::D* v4 = let final self::Test* #t24 = t in let final self::Index* #t25 = self::f<self::Index*>() in let final self::D* #t26 = #t24.{self::Test::[]}(#t25).{self::B::-}(1) in let final void #t27 = #t24.{self::Test::[]=}(#t25, #t26) in #t26;
+ self::B* v5 = let final self::Test* #t28 = t in let final self::Index* #t29 = self::f<self::Index*>() in let final self::B* #t30 = #t28.{self::Test::[]}(#t29) in let final void #t31 = #t28.{self::Test::[]=}(#t29, #t30.{self::B::-}(1)) in #t30;
}
}
static method f<T extends core::Object* = dynamic>() → self::f::T*
diff --git a/pkg/front_end/testcases/inference_new/infer_assign_to_index_set_vs_get.dart.strong.transformed.expect b/pkg/front_end/testcases/inference_new/infer_assign_to_index_set_vs_get.dart.strong.transformed.expect
index cde8b4e..9bba684 100644
--- a/pkg/front_end/testcases/inference_new/infer_assign_to_index_set_vs_get.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference_new/infer_assign_to_index_set_vs_get.dart.strong.transformed.expect
@@ -54,16 +54,16 @@
operator []=(self::Index* i, self::A* v) → void {}
method test() → void {
self::Test* t = self::f<self::Test*>();
- t.{self::Test::[]=}(self::f<dynamic>() as{TypeError} self::Index*, self::f<self::A*>());
- let final self::Test* #t1 = t in let final dynamic #t2 = self::f<dynamic>() in #t1.{self::Test::[]}(#t2 as{TypeError} self::Index*).{core::Object::==}(null) ?{self::A*} let final self::A* #t3 = self::f<self::A*>() in let final void #t4 = #t1.{self::Test::[]=}(#t2 as{TypeError} self::Index*, #t3) in #t3 : null;
- let final self::Test* #t5 = t in let final dynamic #t6 = self::f<dynamic>() in #t5.{self::Test::[]=}(#t6 as{TypeError} self::Index*, #t5.{self::Test::[]}(#t6 as{TypeError} self::Index*).{self::B::+}(self::f<dynamic>() as{TypeError} self::E*));
- let final self::Test* #t7 = t in let final dynamic #t8 = self::f<dynamic>() in let final self::D* #t9 = #t7.{self::Test::[]}(#t8 as{TypeError} self::Index*).{self::B::-}(1) in let final void #t10 = #t7.{self::Test::[]=}(#t8 as{TypeError} self::Index*, #t9) in #t9;
- let final self::Test* #t11 = t in let final dynamic #t12 = self::f<dynamic>() in #t11.{self::Test::[]=}(#t12 as{TypeError} self::Index*, #t11.{self::Test::[]}(#t12 as{TypeError} self::Index*).{self::B::-}(1));
- self::A* v1 = let final self::Test* #t13 = t in let final dynamic #t14 = self::f<dynamic>() in let final self::A* #t15 = self::f<self::A*>() in let final void #t16 = #t13.{self::Test::[]=}(#t14 as{TypeError} self::Index*, #t15) in #t15;
- self::A* v2 = let final self::Test* #t17 = t in let final dynamic #t18 = self::f<dynamic>() in let final self::B* #t19 = #t17.{self::Test::[]}(#t18 as{TypeError} self::Index*) in #t19.{core::Object::==}(null) ?{self::A*} let final self::A* #t20 = self::f<self::A*>() in let final void #t21 = #t17.{self::Test::[]=}(#t18 as{TypeError} self::Index*, #t20) in #t20 : #t19;
- self::D* v3 = let final self::Test* #t22 = t in let final dynamic #t23 = self::f<dynamic>() in let final self::D* #t24 = #t22.{self::Test::[]}(#t23 as{TypeError} self::Index*).{self::B::+}(self::f<dynamic>() as{TypeError} self::E*) in let final void #t25 = #t22.{self::Test::[]=}(#t23 as{TypeError} self::Index*, #t24) in #t24;
- self::D* v4 = let final self::Test* #t26 = t in let final dynamic #t27 = self::f<dynamic>() in let final self::D* #t28 = #t26.{self::Test::[]}(#t27 as{TypeError} self::Index*).{self::B::-}(1) in let final void #t29 = #t26.{self::Test::[]=}(#t27 as{TypeError} self::Index*, #t28) in #t28;
- self::B* v5 = let final self::Test* #t30 = t in let final dynamic #t31 = self::f<dynamic>() in let final self::B* #t32 = #t30.{self::Test::[]}(#t31 as{TypeError} self::Index*) in let final void #t33 = #t30.{self::Test::[]=}(#t31 as{TypeError} self::Index*, #t32.{self::B::-}(1)) in #t32;
+ t.{self::Test::[]=}(self::f<self::Index*>(), self::f<self::A*>());
+ let final self::Test* #t1 = t in let final self::Index* #t2 = self::f<self::Index*>() in #t1.{self::Test::[]}(#t2).{core::Object::==}(null) ?{self::A*} #t1.{self::Test::[]=}(#t2, self::f<self::A*>()) : null;
+ let final self::Test* #t3 = t in let final self::Index* #t4 = self::f<self::Index*>() in #t3.{self::Test::[]=}(#t4, #t3.{self::Test::[]}(#t4).{self::B::+}(self::f<self::E*>()));
+ let final self::Test* #t5 = t in let final self::Index* #t6 = self::f<self::Index*>() in let final self::D* #t7 = #t5.{self::Test::[]}(#t6).{self::B::-}(1) in let final void #t8 = #t5.{self::Test::[]=}(#t6, #t7) in #t7;
+ let final self::Test* #t9 = t in let final self::Index* #t10 = self::f<self::Index*>() in #t9.{self::Test::[]=}(#t10, #t9.{self::Test::[]}(#t10).{self::B::-}(1));
+ self::A* v1 = let final self::Test* #t11 = t in let final self::Index* #t12 = self::f<self::Index*>() in let final self::A* #t13 = self::f<self::A*>() in let final void #t14 = #t11.{self::Test::[]=}(#t12, #t13) in #t13;
+ self::A* v2 = let final self::Test* #t15 = t in let final self::Index* #t16 = self::f<self::Index*>() in let final self::B* #t17 = #t15.{self::Test::[]}(#t16) in #t17.{core::Object::==}(null) ?{self::A*} let final self::A* #t18 = self::f<self::A*>() in let final void #t19 = #t15.{self::Test::[]=}(#t16, #t18) in #t18 : #t17;
+ self::D* v3 = let final self::Test* #t20 = t in let final self::Index* #t21 = self::f<self::Index*>() in let final self::D* #t22 = #t20.{self::Test::[]}(#t21).{self::B::+}(self::f<self::E*>()) in let final void #t23 = #t20.{self::Test::[]=}(#t21, #t22) in #t22;
+ self::D* v4 = let final self::Test* #t24 = t in let final self::Index* #t25 = self::f<self::Index*>() in let final self::D* #t26 = #t24.{self::Test::[]}(#t25).{self::B::-}(1) in let final void #t27 = #t24.{self::Test::[]=}(#t25, #t26) in #t26;
+ self::B* v5 = let final self::Test* #t28 = t in let final self::Index* #t29 = self::f<self::Index*>() in let final self::B* #t30 = #t28.{self::Test::[]}(#t29) in let final void #t31 = #t28.{self::Test::[]=}(#t29, #t30.{self::B::-}(1)) in #t30;
}
}
static method f<T extends core::Object* = dynamic>() → self::f::T*
diff --git a/pkg/front_end/testcases/inference_new/infer_assign_to_index_upwards.dart b/pkg/front_end/testcases/inference_new/infer_assign_to_index_upwards.dart
index 27c4248..dee0c7d 100644
--- a/pkg/front_end/testcases/inference_new/infer_assign_to_index_upwards.dart
+++ b/pkg/front_end/testcases/inference_new/infer_assign_to_index_upwards.dart
@@ -16,113 +16,291 @@
void test1(Test<int, int> t) {
var /*@ type=int* */ v1 = t /*@target=Test::[]=*/ ['x'] = getInt();
+
var /*@ type=num* */ v2 = t /*@target=Test::[]=*/ ['x'] = getNum();
- var /*@ type=int* */ v4 = t /*@target=Test::[]=*/ ['x'] ??= getInt();
- var /*@ type=num* */ v5 = t /*@target=Test::[]=*/ ['x'] ??= getNum();
- var /*@ type=int* */ v7 = t /*@target=Test::[]=*/ ['x'] += getInt();
- var /*@ type=num* */ v8 = t /*@target=Test::[]=*/ ['x'] += getNum();
- var /*@ type=int* */ v10 = ++t /*@target=Test::[]=*/ ['x'];
- var /*@ type=int* */ v11 = t /*@target=Test::[]=*/ ['x']++;
+
+ var /*@ type=int* */ v4 =
+ t /*@target=Test::[]*/ ['x'] /*@target=num::==*/ /*@target=Test::[]=*/ ??=
+ getInt();
+
+ var /*@ type=num* */ v5 =
+ t /*@target=Test::[]*/ ['x'] /*@target=num::==*/ /*@target=Test::[]=*/ ??=
+ getNum();
+
+ var /*@ type=int* */ v7 =
+ t /*@target=Test::[]*/ /*@target=Test::[]=*/ ['x'] /*@ target=num::+ */ +=
+ getInt();
+
+ var /*@ type=num* */ v8 =
+ t /*@target=Test::[]*/ /*@target=Test::[]=*/ ['x'] /*@ target=num::+ */ +=
+ getNum();
+
+ var /*@ type=int* */ v10 =
+ /*@ target=num::+ */ ++t /*@target=Test::[]*/ /*@target=Test::[]=*/ ['x'];
+
+ var /*@ type=int* */ v11 = t /*@target=Test::[]*/ /*@target=Test::[]=*/ [
+ 'x'] /*@ target=num::+ */ ++;
}
void test2(Test<int, num> t) {
var /*@ type=int* */ v1 = t /*@target=Test::[]=*/ ['x'] = getInt();
+
var /*@ type=num* */ v2 = t /*@target=Test::[]=*/ ['x'] = getNum();
+
var /*@ type=double* */ v3 = t /*@target=Test::[]=*/ ['x'] = getDouble();
- var /*@ type=int* */ v4 = t /*@target=Test::[]=*/ ['x'] ??= getInt();
- var /*@ type=num* */ v5 = t /*@target=Test::[]=*/ ['x'] ??= getNum();
- var /*@ type=num* */ v6 = t /*@target=Test::[]=*/ ['x'] ??= getDouble();
- var /*@ type=int* */ v7 = t /*@target=Test::[]=*/ ['x'] += getInt();
- var /*@ type=num* */ v8 = t /*@target=Test::[]=*/ ['x'] += getNum();
- var /*@ type=double* */ v9 = t /*@target=Test::[]=*/ ['x'] += getDouble();
- var /*@ type=int* */ v10 = ++t /*@target=Test::[]=*/ ['x'];
- var /*@ type=int* */ v11 = t /*@target=Test::[]=*/ ['x']++;
+
+ var /*@ type=int* */ v4 =
+ t /*@target=Test::[]*/ ['x'] /*@target=num::==*/ /*@target=Test::[]=*/ ??=
+ getInt();
+
+ var /*@ type=num* */ v5 =
+ t /*@target=Test::[]*/ ['x'] /*@target=num::==*/ /*@target=Test::[]=*/ ??=
+ getNum();
+
+ var /*@ type=num* */ v6 =
+ t /*@target=Test::[]*/ ['x'] /*@target=num::==*/ /*@target=Test::[]=*/ ??=
+ getDouble();
+
+ var /*@ type=int* */ v7 =
+ t /*@target=Test::[]*/ /*@target=Test::[]=*/ ['x'] /*@ target=num::+ */ +=
+ getInt();
+
+ var /*@ type=num* */ v8 =
+ t /*@target=Test::[]*/ /*@target=Test::[]=*/ ['x'] /*@ target=num::+ */ +=
+ getNum();
+
+ var /*@ type=double* */ v9 =
+ t /*@target=Test::[]*/ /*@target=Test::[]=*/ ['x'] /*@ target=num::+ */ +=
+ getDouble();
+
+ var /*@ type=int* */ v10 =
+ /*@ target=num::+ */ ++t /*@target=Test::[]*/ /*@target=Test::[]=*/ ['x'];
+
+ var /*@ type=int* */ v11 = t /*@target=Test::[]*/ /*@target=Test::[]=*/ [
+ 'x'] /*@ target=num::+ */ ++;
}
void test3(Test<int, double> t) {
var /*@ type=num* */ v2 = t /*@target=Test::[]=*/ ['x'] = getNum();
+
var /*@ type=double* */ v3 = t /*@target=Test::[]=*/ ['x'] = getDouble();
- var /*@ type=num* */ v5 = t /*@target=Test::[]=*/ ['x'] ??= getNum();
- var /*@ type=num* */ v6 = t /*@target=Test::[]=*/ ['x'] ??= getDouble();
- var /*@ type=int* */ v7 = t /*@target=Test::[]=*/ ['x'] += getInt();
- var /*@ type=num* */ v8 = t /*@target=Test::[]=*/ ['x'] += getNum();
- var /*@ type=double* */ v9 = t /*@target=Test::[]=*/ ['x'] += getDouble();
- var /*@ type=int* */ v10 = ++t /*@target=Test::[]=*/ ['x'];
- var /*@ type=int* */ v11 = t /*@target=Test::[]=*/ ['x']++;
+
+ var /*@ type=num* */ v5 =
+ t /*@target=Test::[]*/ ['x'] /*@target=num::==*/ /*@target=Test::[]=*/ ??=
+ getNum();
+
+ var /*@ type=num* */ v6 =
+ t /*@target=Test::[]*/ ['x'] /*@target=num::==*/ /*@target=Test::[]=*/ ??=
+ getDouble();
+
+ var /*@ type=int* */ v7 =
+ t /*@target=Test::[]*/ /*@target=Test::[]=*/ ['x'] /*@ target=num::+ */ +=
+ getInt();
+
+ var /*@ type=num* */ v8 =
+ t /*@target=Test::[]*/ /*@target=Test::[]=*/ ['x'] /*@ target=num::+ */ +=
+ getNum();
+
+ var /*@ type=double* */ v9 =
+ t /*@target=Test::[]*/ /*@target=Test::[]=*/ ['x'] /*@ target=num::+ */ +=
+ getDouble();
+
+ var /*@ type=int* */ v10 =
+ /*@ target=num::+ */ ++t /*@target=Test::[]*/ /*@target=Test::[]=*/ ['x'];
+
+ var /*@ type=int* */ v11 = t /*@target=Test::[]*/ /*@target=Test::[]=*/ [
+ 'x'] /*@ target=num::+ */ ++;
}
void test4(Test<num, int> t) {
var /*@ type=int* */ v1 = t /*@target=Test::[]=*/ ['x'] = getInt();
+
var /*@ type=num* */ v2 = t /*@target=Test::[]=*/ ['x'] = getNum();
- var /*@ type=num* */ v4 = t /*@target=Test::[]=*/ ['x'] ??= getInt();
- var /*@ type=num* */ v5 = t /*@target=Test::[]=*/ ['x'] ??= getNum();
- var /*@ type=num* */ v7 = t /*@target=Test::[]=*/ ['x'] += getInt();
- var /*@ type=num* */ v8 = t /*@target=Test::[]=*/ ['x'] += getNum();
- var /*@ type=num* */ v10 = ++t /*@target=Test::[]=*/ ['x'];
- var /*@ type=num* */ v11 = t /*@target=Test::[]=*/ ['x']++;
+
+ var /*@ type=num* */ v4 =
+ t /*@target=Test::[]*/ ['x'] /*@target=num::==*/ /*@target=Test::[]=*/ ??=
+ getInt();
+
+ var /*@ type=num* */ v5 =
+ t /*@target=Test::[]*/ ['x'] /*@target=num::==*/ /*@target=Test::[]=*/ ??=
+ getNum();
+
+ var /*@ type=num* */ v7 =
+ t /*@target=Test::[]*/ /*@target=Test::[]=*/ ['x'] /*@ target=num::+ */ +=
+ getInt();
+
+ var /*@ type=num* */ v8 =
+ t /*@target=Test::[]*/ /*@target=Test::[]=*/ ['x'] /*@ target=num::+ */ +=
+ getNum();
+
+ var /*@ type=num* */ v10 =
+ /*@ target=num::+ */ ++t /*@target=Test::[]*/ /*@target=Test::[]=*/ ['x'];
+
+ var /*@ type=num* */ v11 = t /*@target=Test::[]*/ /*@target=Test::[]=*/ [
+ 'x'] /*@ target=num::+ */ ++;
}
void test5(Test<num, num> t) {
var /*@ type=int* */ v1 = t /*@target=Test::[]=*/ ['x'] = getInt();
+
var /*@ type=num* */ v2 = t /*@target=Test::[]=*/ ['x'] = getNum();
+
var /*@ type=double* */ v3 = t /*@target=Test::[]=*/ ['x'] = getDouble();
- var /*@ type=num* */ v4 = t /*@target=Test::[]=*/ ['x'] ??= getInt();
- var /*@ type=num* */ v5 = t /*@target=Test::[]=*/ ['x'] ??= getNum();
- var /*@ type=num* */ v6 = t /*@target=Test::[]=*/ ['x'] ??= getDouble();
- var /*@ type=num* */ v7 = t /*@target=Test::[]=*/ ['x'] += getInt();
- var /*@ type=num* */ v8 = t /*@target=Test::[]=*/ ['x'] += getNum();
- var /*@ type=num* */ v9 = t /*@target=Test::[]=*/ ['x'] += getDouble();
- var /*@ type=num* */ v10 = ++t /*@target=Test::[]=*/ ['x'];
- var /*@ type=num* */ v11 = t /*@target=Test::[]=*/ ['x']++;
+
+ var /*@ type=num* */ v4 =
+ t /*@target=Test::[]*/ ['x'] /*@target=num::==*/ /*@target=Test::[]=*/ ??=
+ getInt();
+
+ var /*@ type=num* */ v5 =
+ t /*@target=Test::[]*/ ['x'] /*@target=num::==*/ /*@target=Test::[]=*/ ??=
+ getNum();
+
+ var /*@ type=num* */ v6 =
+ t /*@target=Test::[]*/ ['x'] /*@target=num::==*/ /*@target=Test::[]=*/ ??=
+ getDouble();
+
+ var /*@ type=num* */ v7 =
+ t /*@target=Test::[]*/ /*@target=Test::[]=*/ ['x'] /*@ target=num::+ */ +=
+ getInt();
+
+ var /*@ type=num* */ v8 =
+ t /*@target=Test::[]*/ /*@target=Test::[]=*/ ['x'] /*@ target=num::+ */ +=
+ getNum();
+
+ var /*@ type=num* */ v9 =
+ t /*@target=Test::[]*/ /*@target=Test::[]=*/ ['x'] /*@ target=num::+ */ +=
+ getDouble();
+
+ var /*@ type=num* */ v10 =
+ /*@ target=num::+ */ ++t /*@target=Test::[]*/ /*@target=Test::[]=*/ ['x'];
+
+ var /*@ type=num* */ v11 = t /*@target=Test::[]*/ /*@target=Test::[]=*/ [
+ 'x'] /*@ target=num::+ */ ++;
}
void test6(Test<num, double> t) {
var /*@ type=num* */ v2 = t /*@target=Test::[]=*/ ['x'] = getNum();
+
var /*@ type=double* */ v3 = t /*@target=Test::[]=*/ ['x'] = getDouble();
- var /*@ type=num* */ v5 = t /*@target=Test::[]=*/ ['x'] ??= getNum();
- var /*@ type=num* */ v6 = t /*@target=Test::[]=*/ ['x'] ??= getDouble();
- var /*@ type=num* */ v7 = t /*@target=Test::[]=*/ ['x'] += getInt();
- var /*@ type=num* */ v8 = t /*@target=Test::[]=*/ ['x'] += getNum();
- var /*@ type=num* */ v9 = t /*@target=Test::[]=*/ ['x'] += getDouble();
- var /*@ type=num* */ v10 = ++t /*@target=Test::[]=*/ ['x'];
- var /*@ type=num* */ v11 = t /*@target=Test::[]=*/ ['x']++;
+
+ var /*@ type=num* */ v5 =
+ t /*@target=Test::[]*/ ['x'] /*@target=num::==*/ /*@target=Test::[]=*/ ??=
+ getNum();
+
+ var /*@ type=num* */ v6 =
+ t /*@target=Test::[]*/ ['x'] /*@target=num::==*/ /*@target=Test::[]=*/ ??=
+ getDouble();
+
+ var /*@ type=num* */ v7 =
+ t /*@target=Test::[]*/ /*@target=Test::[]=*/ ['x'] /*@ target=num::+ */ +=
+ getInt();
+
+ var /*@ type=num* */ v8 =
+ t /*@target=Test::[]*/ /*@target=Test::[]=*/ ['x'] /*@ target=num::+ */ +=
+ getNum();
+
+ var /*@ type=num* */ v9 =
+ t /*@target=Test::[]*/ /*@target=Test::[]=*/ ['x'] /*@ target=num::+ */ +=
+ getDouble();
+
+ var /*@ type=num* */ v10 =
+ /*@ target=num::+ */ ++t /*@target=Test::[]*/ /*@target=Test::[]=*/ ['x'];
+
+ var /*@ type=num* */ v11 = t /*@target=Test::[]*/ /*@target=Test::[]=*/ [
+ 'x'] /*@ target=num::+ */ ++;
}
void test7(Test<double, int> t) {
var /*@ type=int* */ v1 = t /*@target=Test::[]=*/ ['x'] = getInt();
+
var /*@ type=num* */ v2 = t /*@target=Test::[]=*/ ['x'] = getNum();
- var /*@ type=num* */ v4 = t /*@target=Test::[]=*/ ['x'] ??= getInt();
- var /*@ type=num* */ v5 = t /*@target=Test::[]=*/ ['x'] ??= getNum();
- var /*@ type=double* */ v7 = t /*@target=Test::[]=*/ ['x'] += getInt();
- var /*@ type=double* */ v8 = t /*@target=Test::[]=*/ ['x'] += getNum();
- var /*@ type=double* */ v10 = ++t /*@target=Test::[]=*/ ['x'];
- var /*@ type=double* */ v11 = t /*@target=Test::[]=*/ ['x']++;
+
+ var /*@ type=num* */ v4 =
+ t /*@target=Test::[]*/ ['x'] /*@target=num::==*/ /*@target=Test::[]=*/ ??=
+ getInt();
+
+ var /*@ type=num* */ v5 =
+ t /*@target=Test::[]*/ ['x'] /*@target=num::==*/ /*@target=Test::[]=*/ ??=
+ getNum();
+
+ var /*@ type=double* */ v7 = t /*@target=Test::[]*/ /*@target=Test::[]=*/ [
+ 'x'] /*@ target=double::+ */ += getInt();
+
+ var /*@ type=double* */ v8 = t /*@target=Test::[]*/ /*@target=Test::[]=*/ [
+ 'x'] /*@ target=double::+ */ += getNum();
+
+ var /*@ type=double* */ v10 =
+ /*@ target=double::+ */ ++t
+ /*@target=Test::[]*/ /*@target=Test::[]=*/ ['x'];
+
+ var /*@ type=double* */ v11 = t /*@target=Test::[]*/ /*@target=Test::[]=*/ [
+ 'x'] /*@ target=double::+ */ ++;
}
void test8(Test<double, num> t) {
var /*@ type=int* */ v1 = t /*@target=Test::[]=*/ ['x'] = getInt();
+
var /*@ type=num* */ v2 = t /*@target=Test::[]=*/ ['x'] = getNum();
+
var /*@ type=double* */ v3 = t /*@target=Test::[]=*/ ['x'] = getDouble();
- var /*@ type=num* */ v4 = t /*@target=Test::[]=*/ ['x'] ??= getInt();
- var /*@ type=num* */ v5 = t /*@target=Test::[]=*/ ['x'] ??= getNum();
- var /*@ type=double* */ v6 = t /*@target=Test::[]=*/ ['x'] ??= getDouble();
- var /*@ type=double* */ v7 = t /*@target=Test::[]=*/ ['x'] += getInt();
- var /*@ type=double* */ v8 = t /*@target=Test::[]=*/ ['x'] += getNum();
- var /*@ type=double* */ v9 = t /*@target=Test::[]=*/ ['x'] += getDouble();
- var /*@ type=double* */ v10 = ++t /*@target=Test::[]=*/ ['x'];
- var /*@ type=double* */ v11 = t /*@target=Test::[]=*/ ['x']++;
+
+ var /*@ type=num* */ v4 =
+ t /*@target=Test::[]*/ ['x'] /*@target=num::==*/ /*@target=Test::[]=*/ ??=
+ getInt();
+
+ var /*@ type=num* */ v5 =
+ t /*@target=Test::[]*/ ['x'] /*@target=num::==*/ /*@target=Test::[]=*/ ??=
+ getNum();
+
+ var /*@ type=double* */ v6 =
+ t /*@target=Test::[]*/ ['x'] /*@target=num::==*/ /*@target=Test::[]=*/ ??=
+ getDouble();
+
+ var /*@ type=double* */ v7 = t /*@target=Test::[]*/ /*@target=Test::[]=*/ [
+ 'x'] /*@ target=double::+ */ += getInt();
+
+ var /*@ type=double* */ v8 = t /*@target=Test::[]*/ /*@target=Test::[]=*/ [
+ 'x'] /*@ target=double::+ */ += getNum();
+
+ var /*@ type=double* */ v9 = t /*@target=Test::[]*/ /*@target=Test::[]=*/ [
+ 'x'] /*@ target=double::+ */ += getDouble();
+
+ var /*@ type=double* */ v10 =
+ /*@ target=double::+ */ ++t
+ /*@target=Test::[]*/ /*@target=Test::[]=*/ ['x'];
+
+ var /*@ type=double* */ v11 = t /*@target=Test::[]*/ /*@target=Test::[]=*/ [
+ 'x'] /*@ target=double::+ */ ++;
}
void test9(Test<double, double> t) {
var /*@ type=num* */ v2 = t /*@target=Test::[]=*/ ['x'] = getNum();
+
var /*@ type=double* */ v3 = t /*@target=Test::[]=*/ ['x'] = getDouble();
- var /*@ type=num* */ v5 = t /*@target=Test::[]=*/ ['x'] ??= getNum();
- var /*@ type=double* */ v6 = t /*@target=Test::[]=*/ ['x'] ??= getDouble();
- var /*@ type=double* */ v7 = t /*@target=Test::[]=*/ ['x'] += getInt();
- var /*@ type=double* */ v8 = t /*@target=Test::[]=*/ ['x'] += getNum();
- var /*@ type=double* */ v9 = t /*@target=Test::[]=*/ ['x'] += getDouble();
- var /*@ type=double* */ v10 = ++t /*@target=Test::[]=*/ ['x'];
- var /*@ type=double* */ v11 = t /*@target=Test::[]=*/ ['x']++;
+
+ var /*@ type=num* */ v5 =
+ t /*@target=Test::[]*/ ['x'] /*@target=num::==*/ /*@target=Test::[]=*/ ??=
+ getNum();
+
+ var /*@ type=double* */ v6 =
+ t /*@target=Test::[]*/ ['x'] /*@target=num::==*/ /*@target=Test::[]=*/ ??=
+ getDouble();
+
+ var /*@ type=double* */ v7 = t /*@target=Test::[]*/ /*@target=Test::[]=*/ [
+ 'x'] /*@ target=double::+ */ += getInt();
+
+ var /*@ type=double* */ v8 = t /*@target=Test::[]*/ /*@target=Test::[]=*/ [
+ 'x'] /*@ target=double::+ */ += getNum();
+
+ var /*@ type=double* */ v9 = t /*@target=Test::[]*/ /*@target=Test::[]=*/ [
+ 'x'] /*@ target=double::+ */ += getDouble();
+
+ var /*@ type=double* */ v10 =
+ /*@ target=double::+ */ ++t
+ /*@target=Test::[]*/ /*@target=Test::[]=*/ ['x'];
+
+ var /*@ type=double* */ v11 = t /*@target=Test::[]*/ /*@target=Test::[]=*/ [
+ 'x'] /*@ target=double::+ */ ++;
}
main() {}
diff --git a/pkg/front_end/testcases/inference_new/infer_assign_to_index_upwards.dart.strong.expect b/pkg/front_end/testcases/inference_new/infer_assign_to_index_upwards.dart.strong.expect
index 4b07b83..6e5b788 100644
--- a/pkg/front_end/testcases/inference_new/infer_assign_to_index_upwards.dart.strong.expect
+++ b/pkg/front_end/testcases/inference_new/infer_assign_to_index_upwards.dart.strong.expect
@@ -2,40 +2,40 @@
//
// Problems in library:
//
-// pkg/front_end/testcases/inference_new/infer_assign_to_index_upwards.dart:47:59: Error: A value of type 'int' can't be assigned to a variable of type 'double'.
+// pkg/front_end/testcases/inference_new/infer_assign_to_index_upwards.dart:97:79: Error: A value of type 'int' can't be assigned to a variable of type 'double'.
// Try changing the type of the left hand side, or casting the right hand side to 'double'.
-// var /*@ type=int* */ v7 = t /*@target=Test::[]=*/ ['x'] += getInt();
-// ^
+// t /*@target=Test::[]*/ /*@target=Test::[]=*/ ['x'] /*@ target=num::+ */ +=
+// ^
//
-// pkg/front_end/testcases/inference_new/infer_assign_to_index_upwards.dart:50:30: Error: A value of type 'int' can't be assigned to a variable of type 'double'.
+// pkg/front_end/testcases/inference_new/infer_assign_to_index_upwards.dart:109:28: Error: A value of type 'int' can't be assigned to a variable of type 'double'.
// Try changing the type of the left hand side, or casting the right hand side to 'double'.
-// var /*@ type=int* */ v10 = ++t /*@target=Test::[]=*/ ['x'];
-// ^
+// /*@ target=num::+ */ ++t /*@target=Test::[]*/ /*@target=Test::[]=*/ ['x'];
+// ^
//
-// pkg/front_end/testcases/inference_new/infer_assign_to_index_upwards.dart:51:59: Error: A value of type 'int' can't be assigned to a variable of type 'double'.
+// pkg/front_end/testcases/inference_new/infer_assign_to_index_upwards.dart:112:33: Error: A value of type 'int' can't be assigned to a variable of type 'double'.
// Try changing the type of the left hand side, or casting the right hand side to 'double'.
-// var /*@ type=int* */ v11 = t /*@target=Test::[]=*/ ['x']++;
-// ^
-//
-// pkg/front_end/testcases/inference_new/infer_assign_to_index_upwards.dart:96:62: Error: A value of type 'double' can't be assigned to a variable of type 'int'.
-// Try changing the type of the left hand side, or casting the right hand side to 'int'.
-// var /*@ type=double* */ v7 = t /*@target=Test::[]=*/ ['x'] += getInt();
-// ^
-//
-// pkg/front_end/testcases/inference_new/infer_assign_to_index_upwards.dart:97:62: Error: A value of type 'double' can't be assigned to a variable of type 'int'.
-// Try changing the type of the left hand side, or casting the right hand side to 'int'.
-// var /*@ type=double* */ v8 = t /*@target=Test::[]=*/ ['x'] += getNum();
-// ^
-//
-// pkg/front_end/testcases/inference_new/infer_assign_to_index_upwards.dart:98:33: Error: A value of type 'double' can't be assigned to a variable of type 'int'.
-// Try changing the type of the left hand side, or casting the right hand side to 'int'.
-// var /*@ type=double* */ v10 = ++t /*@target=Test::[]=*/ ['x'];
+// 'x'] /*@ target=num::+ */ ++;
// ^
//
-// pkg/front_end/testcases/inference_new/infer_assign_to_index_upwards.dart:99:62: Error: A value of type 'double' can't be assigned to a variable of type 'int'.
+// pkg/front_end/testcases/inference_new/infer_assign_to_index_upwards.dart:227:36: Error: A value of type 'double' can't be assigned to a variable of type 'int'.
// Try changing the type of the left hand side, or casting the right hand side to 'int'.
-// var /*@ type=double* */ v11 = t /*@target=Test::[]=*/ ['x']++;
-// ^
+// 'x'] /*@ target=double::+ */ += getInt();
+// ^
+//
+// pkg/front_end/testcases/inference_new/infer_assign_to_index_upwards.dart:230:36: Error: A value of type 'double' can't be assigned to a variable of type 'int'.
+// Try changing the type of the left hand side, or casting the right hand side to 'int'.
+// 'x'] /*@ target=double::+ */ += getNum();
+// ^
+//
+// pkg/front_end/testcases/inference_new/infer_assign_to_index_upwards.dart:233:31: Error: A value of type 'double' can't be assigned to a variable of type 'int'.
+// Try changing the type of the left hand side, or casting the right hand side to 'int'.
+// /*@ target=double::+ */ ++t
+// ^
+//
+// pkg/front_end/testcases/inference_new/infer_assign_to_index_upwards.dart:237:36: Error: A value of type 'double' can't be assigned to a variable of type 'int'.
+// Try changing the type of the left hand side, or casting the right hand side to 'int'.
+// 'x'] /*@ target=double::+ */ ++;
+// ^
//
import self as self;
import "dart:core" as core;
@@ -81,20 +81,20 @@
core::double* v3 = let final self::Test<core::int*, core::double*>* #t86 = t in let final core::String* #t87 = "x" in let final core::double* #t88 = self::getDouble() in let final void #t89 = #t86.{self::Test::[]=}(#t87, #t88) in #t88;
core::num* v5 = let final self::Test<core::int*, core::double*>* #t90 = t in let final core::String* #t91 = "x" in let final core::int* #t92 = #t90.{self::Test::[]}(#t91) in #t92.{core::num::==}(null) ?{core::num*} let final core::num* #t93 = self::getNum() as{TypeError} core::double* in let final void #t94 = #t90.{self::Test::[]=}(#t91, #t93) in #t93 : #t92;
core::num* v6 = let final self::Test<core::int*, core::double*>* #t95 = t in let final core::String* #t96 = "x" in let final core::int* #t97 = #t95.{self::Test::[]}(#t96) in #t97.{core::num::==}(null) ?{core::num*} let final core::double* #t98 = self::getDouble() in let final void #t99 = #t95.{self::Test::[]=}(#t96, #t98) in #t98 : #t97;
- core::int* v7 = let final self::Test<core::int*, core::double*>* #t100 = t in let final core::String* #t101 = "x" in let final core::int* #t102 = let final<BottomType> #t103 = invalid-expression "pkg/front_end/testcases/inference_new/infer_assign_to_index_upwards.dart:47:59: Error: A value of type 'int' can't be assigned to a variable of type 'double'.
+ core::int* v7 = let final self::Test<core::int*, core::double*>* #t100 = t in let final core::String* #t101 = "x" in let final core::int* #t102 = let final<BottomType> #t103 = invalid-expression "pkg/front_end/testcases/inference_new/infer_assign_to_index_upwards.dart:97:79: Error: A value of type 'int' can't be assigned to a variable of type 'double'.
Try changing the type of the left hand side, or casting the right hand side to 'double'.
- var /*@ type=int* */ v7 = t /*@target=Test::[]=*/ ['x'] += getInt();
- ^" in #t100.{self::Test::[]}(#t101).{core::num::+}(self::getInt()) as{TypeError} core::double* in let final void #t104 = #t100.{self::Test::[]=}(#t101, #t102) in #t102;
+ t /*@target=Test::[]*/ /*@target=Test::[]=*/ ['x'] /*@ target=num::+ */ +=
+ ^" in #t100.{self::Test::[]}(#t101).{core::num::+}(self::getInt()) as{TypeError} core::double* in let final void #t104 = #t100.{self::Test::[]=}(#t101, #t102) in #t102;
core::num* v8 = let final self::Test<core::int*, core::double*>* #t105 = t in let final core::String* #t106 = "x" in let final core::num* #t107 = #t105.{self::Test::[]}(#t106).{core::num::+}(self::getNum()) as{TypeError} core::double* in let final void #t108 = #t105.{self::Test::[]=}(#t106, #t107) in #t107;
core::double* v9 = let final self::Test<core::int*, core::double*>* #t109 = t in let final core::String* #t110 = "x" in let final core::double* #t111 = #t109.{self::Test::[]}(#t110).{core::num::+}(self::getDouble()) in let final void #t112 = #t109.{self::Test::[]=}(#t110, #t111) in #t111;
- core::int* v10 = let final self::Test<core::int*, core::double*>* #t113 = t in let final core::String* #t114 = "x" in let final core::int* #t115 = let final<BottomType> #t116 = invalid-expression "pkg/front_end/testcases/inference_new/infer_assign_to_index_upwards.dart:50:30: Error: A value of type 'int' can't be assigned to a variable of type 'double'.
+ core::int* v10 = let final self::Test<core::int*, core::double*>* #t113 = t in let final core::String* #t114 = "x" in let final core::int* #t115 = let final<BottomType> #t116 = invalid-expression "pkg/front_end/testcases/inference_new/infer_assign_to_index_upwards.dart:109:28: Error: A value of type 'int' can't be assigned to a variable of type 'double'.
Try changing the type of the left hand side, or casting the right hand side to 'double'.
- var /*@ type=int* */ v10 = ++t /*@target=Test::[]=*/ ['x'];
- ^" in #t113.{self::Test::[]}(#t114).{core::num::+}(1) as{TypeError} core::double* in let final void #t117 = #t113.{self::Test::[]=}(#t114, #t115) in #t115;
- core::int* v11 = let final self::Test<core::int*, core::double*>* #t118 = t in let final core::String* #t119 = "x" in let final core::int* #t120 = #t118.{self::Test::[]}(#t119) in let final void #t121 = #t118.{self::Test::[]=}(#t119, let final<BottomType> #t122 = invalid-expression "pkg/front_end/testcases/inference_new/infer_assign_to_index_upwards.dart:51:59: Error: A value of type 'int' can't be assigned to a variable of type 'double'.
+ /*@ target=num::+ */ ++t /*@target=Test::[]*/ /*@target=Test::[]=*/ ['x'];
+ ^" in #t113.{self::Test::[]}(#t114).{core::num::+}(1) as{TypeError} core::double* in let final void #t117 = #t113.{self::Test::[]=}(#t114, #t115) in #t115;
+ core::int* v11 = let final self::Test<core::int*, core::double*>* #t118 = t in let final core::String* #t119 = "x" in let final core::int* #t120 = #t118.{self::Test::[]}(#t119) in let final void #t121 = #t118.{self::Test::[]=}(#t119, let final<BottomType> #t122 = invalid-expression "pkg/front_end/testcases/inference_new/infer_assign_to_index_upwards.dart:112:33: Error: A value of type 'int' can't be assigned to a variable of type 'double'.
Try changing the type of the left hand side, or casting the right hand side to 'double'.
- var /*@ type=int* */ v11 = t /*@target=Test::[]=*/ ['x']++;
- ^" in #t120.{core::num::+}(1) as{TypeError} core::double*) in #t120;
+ 'x'] /*@ target=num::+ */ ++;
+ ^" in #t120.{core::num::+}(1) as{TypeError} core::double*) in #t120;
}
static method test4(self::Test<core::num*, core::int*>* t) → void {
core::int* v1 = let final self::Test<core::num*, core::int*>* #t123 = t in let final core::String* #t124 = "x" in let final core::int* #t125 = self::getInt() in let final void #t126 = #t123.{self::Test::[]=}(#t124, #t125) in #t125;
@@ -135,22 +135,22 @@
core::num* v2 = let final self::Test<core::double*, core::int*>* #t246 = t in let final core::String* #t247 = "x" in let final core::num* #t248 = self::getNum() as{TypeError} core::int* in let final void #t249 = #t246.{self::Test::[]=}(#t247, #t248) in #t248;
core::num* v4 = let final self::Test<core::double*, core::int*>* #t250 = t in let final core::String* #t251 = "x" in let final core::double* #t252 = #t250.{self::Test::[]}(#t251) in #t252.{core::num::==}(null) ?{core::num*} let final core::int* #t253 = self::getInt() in let final void #t254 = #t250.{self::Test::[]=}(#t251, #t253) in #t253 : #t252;
core::num* v5 = let final self::Test<core::double*, core::int*>* #t255 = t in let final core::String* #t256 = "x" in let final core::double* #t257 = #t255.{self::Test::[]}(#t256) in #t257.{core::num::==}(null) ?{core::num*} let final core::num* #t258 = self::getNum() as{TypeError} core::int* in let final void #t259 = #t255.{self::Test::[]=}(#t256, #t258) in #t258 : #t257;
- core::double* v7 = let final self::Test<core::double*, core::int*>* #t260 = t in let final core::String* #t261 = "x" in let final core::double* #t262 = let final<BottomType> #t263 = invalid-expression "pkg/front_end/testcases/inference_new/infer_assign_to_index_upwards.dart:96:62: Error: A value of type 'double' can't be assigned to a variable of type 'int'.
+ core::double* v7 = let final self::Test<core::double*, core::int*>* #t260 = t in let final core::String* #t261 = "x" in let final core::double* #t262 = let final<BottomType> #t263 = invalid-expression "pkg/front_end/testcases/inference_new/infer_assign_to_index_upwards.dart:227:36: Error: A value of type 'double' can't be assigned to a variable of type 'int'.
Try changing the type of the left hand side, or casting the right hand side to 'int'.
- var /*@ type=double* */ v7 = t /*@target=Test::[]=*/ ['x'] += getInt();
- ^" in #t260.{self::Test::[]}(#t261).{core::double::+}(self::getInt()) as{TypeError} core::int* in let final void #t264 = #t260.{self::Test::[]=}(#t261, #t262) in #t262;
- core::double* v8 = let final self::Test<core::double*, core::int*>* #t265 = t in let final core::String* #t266 = "x" in let final core::double* #t267 = let final<BottomType> #t268 = invalid-expression "pkg/front_end/testcases/inference_new/infer_assign_to_index_upwards.dart:97:62: Error: A value of type 'double' can't be assigned to a variable of type 'int'.
+ 'x'] /*@ target=double::+ */ += getInt();
+ ^" in #t260.{self::Test::[]}(#t261).{core::double::+}(self::getInt()) as{TypeError} core::int* in let final void #t264 = #t260.{self::Test::[]=}(#t261, #t262) in #t262;
+ core::double* v8 = let final self::Test<core::double*, core::int*>* #t265 = t in let final core::String* #t266 = "x" in let final core::double* #t267 = let final<BottomType> #t268 = invalid-expression "pkg/front_end/testcases/inference_new/infer_assign_to_index_upwards.dart:230:36: Error: A value of type 'double' can't be assigned to a variable of type 'int'.
Try changing the type of the left hand side, or casting the right hand side to 'int'.
- var /*@ type=double* */ v8 = t /*@target=Test::[]=*/ ['x'] += getNum();
- ^" in #t265.{self::Test::[]}(#t266).{core::double::+}(self::getNum()) as{TypeError} core::int* in let final void #t269 = #t265.{self::Test::[]=}(#t266, #t267) in #t267;
- core::double* v10 = let final self::Test<core::double*, core::int*>* #t270 = t in let final core::String* #t271 = "x" in let final core::double* #t272 = let final<BottomType> #t273 = invalid-expression "pkg/front_end/testcases/inference_new/infer_assign_to_index_upwards.dart:98:33: Error: A value of type 'double' can't be assigned to a variable of type 'int'.
+ 'x'] /*@ target=double::+ */ += getNum();
+ ^" in #t265.{self::Test::[]}(#t266).{core::double::+}(self::getNum()) as{TypeError} core::int* in let final void #t269 = #t265.{self::Test::[]=}(#t266, #t267) in #t267;
+ core::double* v10 = let final self::Test<core::double*, core::int*>* #t270 = t in let final core::String* #t271 = "x" in let final core::double* #t272 = let final<BottomType> #t273 = invalid-expression "pkg/front_end/testcases/inference_new/infer_assign_to_index_upwards.dart:233:31: Error: A value of type 'double' can't be assigned to a variable of type 'int'.
Try changing the type of the left hand side, or casting the right hand side to 'int'.
- var /*@ type=double* */ v10 = ++t /*@target=Test::[]=*/ ['x'];
- ^" in #t270.{self::Test::[]}(#t271).{core::double::+}(1) as{TypeError} core::int* in let final void #t274 = #t270.{self::Test::[]=}(#t271, #t272) in #t272;
- core::double* v11 = let final self::Test<core::double*, core::int*>* #t275 = t in let final core::String* #t276 = "x" in let final core::double* #t277 = #t275.{self::Test::[]}(#t276) in let final void #t278 = #t275.{self::Test::[]=}(#t276, let final<BottomType> #t279 = invalid-expression "pkg/front_end/testcases/inference_new/infer_assign_to_index_upwards.dart:99:62: Error: A value of type 'double' can't be assigned to a variable of type 'int'.
+ /*@ target=double::+ */ ++t
+ ^" in #t270.{self::Test::[]}(#t271).{core::double::+}(1) as{TypeError} core::int* in let final void #t274 = #t270.{self::Test::[]=}(#t271, #t272) in #t272;
+ core::double* v11 = let final self::Test<core::double*, core::int*>* #t275 = t in let final core::String* #t276 = "x" in let final core::double* #t277 = #t275.{self::Test::[]}(#t276) in let final void #t278 = #t275.{self::Test::[]=}(#t276, let final<BottomType> #t279 = invalid-expression "pkg/front_end/testcases/inference_new/infer_assign_to_index_upwards.dart:237:36: Error: A value of type 'double' can't be assigned to a variable of type 'int'.
Try changing the type of the left hand side, or casting the right hand side to 'int'.
- var /*@ type=double* */ v11 = t /*@target=Test::[]=*/ ['x']++;
- ^" in #t277.{core::double::+}(1) as{TypeError} core::int*) in #t277;
+ 'x'] /*@ target=double::+ */ ++;
+ ^" in #t277.{core::double::+}(1) as{TypeError} core::int*) in #t277;
}
static method test8(self::Test<core::double*, core::num*>* t) → void {
core::int* v1 = let final self::Test<core::double*, core::num*>* #t280 = t in let final core::String* #t281 = "x" in let final core::int* #t282 = self::getInt() in let final void #t283 = #t280.{self::Test::[]=}(#t281, #t282) in #t282;
diff --git a/pkg/front_end/testcases/inference_new/infer_assign_to_local.dart b/pkg/front_end/testcases/inference_new/infer_assign_to_local.dart
index ab2cac0..05354e5 100644
--- a/pkg/front_end/testcases/inference_new/infer_assign_to_local.dart
+++ b/pkg/front_end/testcases/inference_new/infer_assign_to_local.dart
@@ -22,18 +22,22 @@
B local;
local = /*@ typeArgs=B* */ f();
local ??= /*@ typeArgs=B* */ f();
- local += /*@ typeArgs=dynamic */ f();
- local *= /*@ typeArgs=dynamic */ f();
- local &= /*@ typeArgs=dynamic */ f();
- --local;
- local--;
+ local /*@ target=B::+ */ += /*@ typeArgs=C* */ f();
+ local /*@ target=B::* */ *= /*@ typeArgs=B* */ f();
+ local /*@ target=B::& */ &= /*@ typeArgs=A* */ f();
+ /*@ target=B::- */ --local;
+ local /*@ target=B::- */ --;
var /*@ type=B* */ v1 = local = /*@ typeArgs=B* */ f();
var /*@ type=B* */ v2 = local ??= /*@ typeArgs=B* */ f();
- var /*@ type=A* */ v3 = local += /*@ typeArgs=dynamic */ f();
- var /*@ type=B* */ v4 = local *= /*@ typeArgs=dynamic */ f();
- var /*@ type=C* */ v5 = local &= /*@ typeArgs=dynamic */ f();
- var /*@ type=B* */ v6 = --local;
- var /*@ type=B* */ v7 = local--;
+ var /*@ type=A* */ v3 = local
+ /*@ target=B::+ */ += /*@ typeArgs=C* */ f();
+ var /*@ type=B* */ v4 = local
+ /*@ target=B::* */ *= /*@ typeArgs=B* */ f();
+ var /*@ type=C* */ v5 = local
+ /*@ target=B::& */ &= /*@ typeArgs=A* */ f();
+ var /*@ type=B* */ v6 = /*@ target=B::- */ --local;
+ var /*@ type=B* */ v7 = /*@ type=B* */ local
+ /*@ type=B* */ /*@ target=B::- */ --;
}
main() {}
diff --git a/pkg/front_end/testcases/inference_new/infer_assign_to_local.dart.strong.expect b/pkg/front_end/testcases/inference_new/infer_assign_to_local.dart.strong.expect
index 0330af0..35c6164 100644
--- a/pkg/front_end/testcases/inference_new/infer_assign_to_local.dart.strong.expect
+++ b/pkg/front_end/testcases/inference_new/infer_assign_to_local.dart.strong.expect
@@ -31,16 +31,16 @@
self::B* local;
local = self::f<self::B*>();
local.{core::Object::==}(null) ?{self::B*} local = self::f<self::B*>() : null;
- local = local.{self::B::+}(self::f<dynamic>() as{TypeError} self::C*) as{TypeError} self::B*;
- local = local.{self::B::*}(self::f<dynamic>() as{TypeError} self::B*);
- local = local.{self::B::&}(self::f<dynamic>() as{TypeError} self::A*);
+ local = local.{self::B::+}(self::f<self::C*>()) as{TypeError} self::B*;
+ local = local.{self::B::*}(self::f<self::B*>());
+ local = local.{self::B::&}(self::f<self::A*>());
local = local.{self::B::-}(1);
local = local.{self::B::-}(1);
self::B* v1 = local = self::f<self::B*>();
self::B* v2 = let final self::B* #t1 = local in #t1.{core::Object::==}(null) ?{self::B*} local = self::f<self::B*>() : #t1;
- self::A* v3 = local = local.{self::B::+}(self::f<dynamic>() as{TypeError} self::C*) as{TypeError} self::B*;
- self::B* v4 = local = local.{self::B::*}(self::f<dynamic>() as{TypeError} self::B*);
- self::C* v5 = local = local.{self::B::&}(self::f<dynamic>() as{TypeError} self::A*);
+ self::A* v3 = local = local.{self::B::+}(self::f<self::C*>()) as{TypeError} self::B*;
+ self::B* v4 = local = local.{self::B::*}(self::f<self::B*>());
+ self::C* v5 = local = local.{self::B::&}(self::f<self::A*>());
self::B* v6 = local = local.{self::B::-}(1);
self::B* v7 = let final self::B* #t2 = local in let final self::B* #t3 = local = #t2.{self::B::-}(1) in #t2;
}
diff --git a/pkg/front_end/testcases/inference_new/infer_assign_to_local.dart.strong.transformed.expect b/pkg/front_end/testcases/inference_new/infer_assign_to_local.dart.strong.transformed.expect
index 0330af0..35c6164 100644
--- a/pkg/front_end/testcases/inference_new/infer_assign_to_local.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference_new/infer_assign_to_local.dart.strong.transformed.expect
@@ -31,16 +31,16 @@
self::B* local;
local = self::f<self::B*>();
local.{core::Object::==}(null) ?{self::B*} local = self::f<self::B*>() : null;
- local = local.{self::B::+}(self::f<dynamic>() as{TypeError} self::C*) as{TypeError} self::B*;
- local = local.{self::B::*}(self::f<dynamic>() as{TypeError} self::B*);
- local = local.{self::B::&}(self::f<dynamic>() as{TypeError} self::A*);
+ local = local.{self::B::+}(self::f<self::C*>()) as{TypeError} self::B*;
+ local = local.{self::B::*}(self::f<self::B*>());
+ local = local.{self::B::&}(self::f<self::A*>());
local = local.{self::B::-}(1);
local = local.{self::B::-}(1);
self::B* v1 = local = self::f<self::B*>();
self::B* v2 = let final self::B* #t1 = local in #t1.{core::Object::==}(null) ?{self::B*} local = self::f<self::B*>() : #t1;
- self::A* v3 = local = local.{self::B::+}(self::f<dynamic>() as{TypeError} self::C*) as{TypeError} self::B*;
- self::B* v4 = local = local.{self::B::*}(self::f<dynamic>() as{TypeError} self::B*);
- self::C* v5 = local = local.{self::B::&}(self::f<dynamic>() as{TypeError} self::A*);
+ self::A* v3 = local = local.{self::B::+}(self::f<self::C*>()) as{TypeError} self::B*;
+ self::B* v4 = local = local.{self::B::*}(self::f<self::B*>());
+ self::C* v5 = local = local.{self::B::&}(self::f<self::A*>());
self::B* v6 = local = local.{self::B::-}(1);
self::B* v7 = let final self::B* #t2 = local in let final self::B* #t3 = local = #t2.{self::B::-}(1) in #t2;
}
diff --git a/pkg/front_end/testcases/inference_new/infer_assign_to_local.dart.type_promotion.expect b/pkg/front_end/testcases/inference_new/infer_assign_to_local.dart.type_promotion.expect
index aa57cf4..7113cbf 100644
--- a/pkg/front_end/testcases/inference_new/infer_assign_to_local.dart.type_promotion.expect
+++ b/pkg/front_end/testcases/inference_new/infer_assign_to_local.dart.type_promotion.expect
@@ -4,39 +4,39 @@
pkg/front_end/testcases/inference_new/infer_assign_to_local.dart:24:9: Context: Write to local@474
local ??= /*@ typeArgs=B* */ f();
^^^
-pkg/front_end/testcases/inference_new/infer_assign_to_local.dart:25:9: Context: Write to local@474
- local += /*@ typeArgs=dynamic */ f();
- ^^
-pkg/front_end/testcases/inference_new/infer_assign_to_local.dart:26:9: Context: Write to local@474
- local *= /*@ typeArgs=dynamic */ f();
- ^^
-pkg/front_end/testcases/inference_new/infer_assign_to_local.dart:27:9: Context: Write to local@474
- local &= /*@ typeArgs=dynamic */ f();
- ^^
-pkg/front_end/testcases/inference_new/infer_assign_to_local.dart:28:3: Context: Write to local@474
- --local;
- ^^
-pkg/front_end/testcases/inference_new/infer_assign_to_local.dart:29:8: Context: Write to local@474
- local--;
- ^^
+pkg/front_end/testcases/inference_new/infer_assign_to_local.dart:25:28: Context: Write to local@474
+ local /*@ target=B::+ */ += /*@ typeArgs=C* */ f();
+ ^^
+pkg/front_end/testcases/inference_new/infer_assign_to_local.dart:26:28: Context: Write to local@474
+ local /*@ target=B::* */ *= /*@ typeArgs=B* */ f();
+ ^^
+pkg/front_end/testcases/inference_new/infer_assign_to_local.dart:27:28: Context: Write to local@474
+ local /*@ target=B::& */ &= /*@ typeArgs=A* */ f();
+ ^^
+pkg/front_end/testcases/inference_new/infer_assign_to_local.dart:28:22: Context: Write to local@474
+ /*@ target=B::- */ --local;
+ ^^
+pkg/front_end/testcases/inference_new/infer_assign_to_local.dart:29:28: Context: Write to local@474
+ local /*@ target=B::- */ --;
+ ^^
pkg/front_end/testcases/inference_new/infer_assign_to_local.dart:30:33: Context: Write to local@474
var /*@ type=B* */ v1 = local = /*@ typeArgs=B* */ f();
^
pkg/front_end/testcases/inference_new/infer_assign_to_local.dart:31:33: Context: Write to local@474
var /*@ type=B* */ v2 = local ??= /*@ typeArgs=B* */ f();
^^^
-pkg/front_end/testcases/inference_new/infer_assign_to_local.dart:32:33: Context: Write to local@474
- var /*@ type=A* */ v3 = local += /*@ typeArgs=dynamic */ f();
- ^^
-pkg/front_end/testcases/inference_new/infer_assign_to_local.dart:33:33: Context: Write to local@474
- var /*@ type=B* */ v4 = local *= /*@ typeArgs=dynamic */ f();
- ^^
-pkg/front_end/testcases/inference_new/infer_assign_to_local.dart:34:33: Context: Write to local@474
- var /*@ type=C* */ v5 = local &= /*@ typeArgs=dynamic */ f();
- ^^
-pkg/front_end/testcases/inference_new/infer_assign_to_local.dart:35:27: Context: Write to local@474
- var /*@ type=B* */ v6 = --local;
- ^^
-pkg/front_end/testcases/inference_new/infer_assign_to_local.dart:36:32: Context: Write to local@474
- var /*@ type=B* */ v7 = local--;
- ^^
+pkg/front_end/testcases/inference_new/infer_assign_to_local.dart:33:26: Context: Write to local@474
+ /*@ target=B::+ */ += /*@ typeArgs=C* */ f();
+ ^^
+pkg/front_end/testcases/inference_new/infer_assign_to_local.dart:35:26: Context: Write to local@474
+ /*@ target=B::* */ *= /*@ typeArgs=B* */ f();
+ ^^
+pkg/front_end/testcases/inference_new/infer_assign_to_local.dart:37:26: Context: Write to local@474
+ /*@ target=B::& */ &= /*@ typeArgs=A* */ f();
+ ^^
+pkg/front_end/testcases/inference_new/infer_assign_to_local.dart:38:46: Context: Write to local@474
+ var /*@ type=B* */ v6 = /*@ target=B::- */ --local;
+ ^^
+pkg/front_end/testcases/inference_new/infer_assign_to_local.dart:40:41: Context: Write to local@474
+ /*@ type=B* */ /*@ target=B::- */ --;
+ ^^
diff --git a/pkg/front_end/testcases/inference_new/infer_assign_to_local_upwards.dart b/pkg/front_end/testcases/inference_new/infer_assign_to_local_upwards.dart
index 62bba51..b88af64 100644
--- a/pkg/front_end/testcases/inference_new/infer_assign_to_local_upwards.dart
+++ b/pkg/front_end/testcases/inference_new/infer_assign_to_local_upwards.dart
@@ -14,10 +14,11 @@
var /*@ type=num* */ v2 = t = getNum();
var /*@ type=int* */ v4 = t ??= getInt();
var /*@ type=num* */ v5 = t ??= getNum();
- var /*@ type=int* */ v7 = t += getInt();
- var /*@ type=num* */ v8 = t += getNum();
- var /*@ type=int* */ v10 = ++t;
- var /*@ type=int* */ v11 = t++;
+ var /*@ type=int* */ v7 = t /*@ target=num::+ */ += getInt();
+ var /*@ type=num* */ v8 = t /*@ target=num::+ */ += getNum();
+ var /*@ type=int* */ v10 = /*@ target=num::+ */ ++t;
+ var /*@ type=int* */ v11 =
+ /*@ type=int* */ t /*@ type=int* */ /*@ target=num::+ */ ++;
}
void test2(num t) {
@@ -27,11 +28,12 @@
var /*@ type=num* */ v4 = t ??= getInt();
var /*@ type=num* */ v5 = t ??= getNum();
var /*@ type=num* */ v6 = t ??= getDouble();
- var /*@ type=num* */ v7 = t += getInt();
- var /*@ type=num* */ v8 = t += getNum();
- var /*@ type=num* */ v9 = t += getDouble();
- var /*@ type=num* */ v10 = ++t;
- var /*@ type=num* */ v11 = t++;
+ var /*@ type=num* */ v7 = t /*@ target=num::+ */ += getInt();
+ var /*@ type=num* */ v8 = t /*@ target=num::+ */ += getNum();
+ var /*@ type=num* */ v9 = t /*@ target=num::+ */ += getDouble();
+ var /*@ type=num* */ v10 = /*@ target=num::+ */ ++t;
+ var /*@ type=num* */ v11 =
+ /*@ type=num* */ t /*@ type=num* */ /*@ target=num::+ */ ++;
}
void test3(double t) {
@@ -39,11 +41,12 @@
var /*@ type=double* */ v3 = t = getDouble();
var /*@ type=num* */ v5 = t ??= getNum();
var /*@ type=double* */ v6 = t ??= getDouble();
- var /*@ type=double* */ v7 = t += getInt();
- var /*@ type=double* */ v8 = t += getNum();
- var /*@ type=double* */ v9 = t += getDouble();
- var /*@ type=double* */ v10 = ++t;
- var /*@ type=double* */ v11 = t++;
+ var /*@ type=double* */ v7 = t /*@ target=double::+ */ += getInt();
+ var /*@ type=double* */ v8 = t /*@ target=double::+ */ += getNum();
+ var /*@ type=double* */ v9 = t /*@ target=double::+ */ += getDouble();
+ var /*@ type=double* */ v10 = /*@ target=double::+ */ ++t;
+ var /*@ type=double* */ v11 =
+ /*@ type=double* */ t /*@ type=double* */ /*@ target=double::+ */ ++;
}
main() {}
diff --git a/pkg/front_end/testcases/inference_new/infer_assign_to_local_upwards.dart.type_promotion.expect b/pkg/front_end/testcases/inference_new/infer_assign_to_local_upwards.dart.type_promotion.expect
index 54a1aba..e076b03 100644
--- a/pkg/front_end/testcases/inference_new/infer_assign_to_local_upwards.dart.type_promotion.expect
+++ b/pkg/front_end/testcases/inference_new/infer_assign_to_local_upwards.dart.type_promotion.expect
@@ -10,75 +10,75 @@
pkg/front_end/testcases/inference_new/infer_assign_to_local_upwards.dart:16:31: Context: Write to t@343
var /*@ type=num* */ v5 = t ??= getNum();
^^^
-pkg/front_end/testcases/inference_new/infer_assign_to_local_upwards.dart:17:31: Context: Write to t@343
- var /*@ type=int* */ v7 = t += getInt();
- ^^
-pkg/front_end/testcases/inference_new/infer_assign_to_local_upwards.dart:18:31: Context: Write to t@343
- var /*@ type=num* */ v8 = t += getNum();
- ^^
-pkg/front_end/testcases/inference_new/infer_assign_to_local_upwards.dart:19:30: Context: Write to t@343
- var /*@ type=int* */ v10 = ++t;
- ^^
-pkg/front_end/testcases/inference_new/infer_assign_to_local_upwards.dart:20:31: Context: Write to t@343
- var /*@ type=int* */ v11 = t++;
- ^^
-pkg/front_end/testcases/inference_new/infer_assign_to_local_upwards.dart:24:31: Context: Write to t@343
+pkg/front_end/testcases/inference_new/infer_assign_to_local_upwards.dart:17:52: Context: Write to t@343
+ var /*@ type=int* */ v7 = t /*@ target=num::+ */ += getInt();
+ ^^
+pkg/front_end/testcases/inference_new/infer_assign_to_local_upwards.dart:18:52: Context: Write to t@343
+ var /*@ type=num* */ v8 = t /*@ target=num::+ */ += getNum();
+ ^^
+pkg/front_end/testcases/inference_new/infer_assign_to_local_upwards.dart:19:51: Context: Write to t@343
+ var /*@ type=int* */ v10 = /*@ target=num::+ */ ++t;
+ ^^
+pkg/front_end/testcases/inference_new/infer_assign_to_local_upwards.dart:21:64: Context: Write to t@343
+ /*@ type=int* */ t /*@ type=int* */ /*@ target=num::+ */ ++;
+ ^^
+pkg/front_end/testcases/inference_new/infer_assign_to_local_upwards.dart:25:31: Context: Write to t@343
var /*@ type=int* */ v1 = t = getInt();
^
-pkg/front_end/testcases/inference_new/infer_assign_to_local_upwards.dart:25:31: Context: Write to t@343
+pkg/front_end/testcases/inference_new/infer_assign_to_local_upwards.dart:26:31: Context: Write to t@343
var /*@ type=num* */ v2 = t = getNum();
^
-pkg/front_end/testcases/inference_new/infer_assign_to_local_upwards.dart:26:34: Context: Write to t@343
+pkg/front_end/testcases/inference_new/infer_assign_to_local_upwards.dart:27:34: Context: Write to t@343
var /*@ type=double* */ v3 = t = getDouble();
^
-pkg/front_end/testcases/inference_new/infer_assign_to_local_upwards.dart:27:31: Context: Write to t@343
+pkg/front_end/testcases/inference_new/infer_assign_to_local_upwards.dart:28:31: Context: Write to t@343
var /*@ type=num* */ v4 = t ??= getInt();
^^^
-pkg/front_end/testcases/inference_new/infer_assign_to_local_upwards.dart:28:31: Context: Write to t@343
- var /*@ type=num* */ v5 = t ??= getNum();
- ^^^
pkg/front_end/testcases/inference_new/infer_assign_to_local_upwards.dart:29:31: Context: Write to t@343
- var /*@ type=num* */ v6 = t ??= getDouble();
+ var /*@ type=num* */ v5 = t ??= getNum();
^^^
pkg/front_end/testcases/inference_new/infer_assign_to_local_upwards.dart:30:31: Context: Write to t@343
- var /*@ type=num* */ v7 = t += getInt();
- ^^
-pkg/front_end/testcases/inference_new/infer_assign_to_local_upwards.dart:31:31: Context: Write to t@343
- var /*@ type=num* */ v8 = t += getNum();
- ^^
-pkg/front_end/testcases/inference_new/infer_assign_to_local_upwards.dart:32:31: Context: Write to t@343
- var /*@ type=num* */ v9 = t += getDouble();
- ^^
-pkg/front_end/testcases/inference_new/infer_assign_to_local_upwards.dart:33:30: Context: Write to t@343
- var /*@ type=num* */ v10 = ++t;
- ^^
-pkg/front_end/testcases/inference_new/infer_assign_to_local_upwards.dart:34:31: Context: Write to t@343
- var /*@ type=num* */ v11 = t++;
- ^^
-pkg/front_end/testcases/inference_new/infer_assign_to_local_upwards.dart:38:31: Context: Write to t@343
+ var /*@ type=num* */ v6 = t ??= getDouble();
+ ^^^
+pkg/front_end/testcases/inference_new/infer_assign_to_local_upwards.dart:31:52: Context: Write to t@343
+ var /*@ type=num* */ v7 = t /*@ target=num::+ */ += getInt();
+ ^^
+pkg/front_end/testcases/inference_new/infer_assign_to_local_upwards.dart:32:52: Context: Write to t@343
+ var /*@ type=num* */ v8 = t /*@ target=num::+ */ += getNum();
+ ^^
+pkg/front_end/testcases/inference_new/infer_assign_to_local_upwards.dart:33:52: Context: Write to t@343
+ var /*@ type=num* */ v9 = t /*@ target=num::+ */ += getDouble();
+ ^^
+pkg/front_end/testcases/inference_new/infer_assign_to_local_upwards.dart:34:51: Context: Write to t@343
+ var /*@ type=num* */ v10 = /*@ target=num::+ */ ++t;
+ ^^
+pkg/front_end/testcases/inference_new/infer_assign_to_local_upwards.dart:36:64: Context: Write to t@343
+ /*@ type=num* */ t /*@ type=num* */ /*@ target=num::+ */ ++;
+ ^^
+pkg/front_end/testcases/inference_new/infer_assign_to_local_upwards.dart:40:31: Context: Write to t@343
var /*@ type=num* */ v2 = t = getNum();
^
-pkg/front_end/testcases/inference_new/infer_assign_to_local_upwards.dart:39:34: Context: Write to t@343
+pkg/front_end/testcases/inference_new/infer_assign_to_local_upwards.dart:41:34: Context: Write to t@343
var /*@ type=double* */ v3 = t = getDouble();
^
-pkg/front_end/testcases/inference_new/infer_assign_to_local_upwards.dart:40:31: Context: Write to t@343
+pkg/front_end/testcases/inference_new/infer_assign_to_local_upwards.dart:42:31: Context: Write to t@343
var /*@ type=num* */ v5 = t ??= getNum();
^^^
-pkg/front_end/testcases/inference_new/infer_assign_to_local_upwards.dart:41:34: Context: Write to t@343
+pkg/front_end/testcases/inference_new/infer_assign_to_local_upwards.dart:43:34: Context: Write to t@343
var /*@ type=double* */ v6 = t ??= getDouble();
^^^
-pkg/front_end/testcases/inference_new/infer_assign_to_local_upwards.dart:42:34: Context: Write to t@343
- var /*@ type=double* */ v7 = t += getInt();
- ^^
-pkg/front_end/testcases/inference_new/infer_assign_to_local_upwards.dart:43:34: Context: Write to t@343
- var /*@ type=double* */ v8 = t += getNum();
- ^^
-pkg/front_end/testcases/inference_new/infer_assign_to_local_upwards.dart:44:34: Context: Write to t@343
- var /*@ type=double* */ v9 = t += getDouble();
- ^^
-pkg/front_end/testcases/inference_new/infer_assign_to_local_upwards.dart:45:33: Context: Write to t@343
- var /*@ type=double* */ v10 = ++t;
- ^^
-pkg/front_end/testcases/inference_new/infer_assign_to_local_upwards.dart:46:34: Context: Write to t@343
- var /*@ type=double* */ v11 = t++;
- ^^
+pkg/front_end/testcases/inference_new/infer_assign_to_local_upwards.dart:44:58: Context: Write to t@343
+ var /*@ type=double* */ v7 = t /*@ target=double::+ */ += getInt();
+ ^^
+pkg/front_end/testcases/inference_new/infer_assign_to_local_upwards.dart:45:58: Context: Write to t@343
+ var /*@ type=double* */ v8 = t /*@ target=double::+ */ += getNum();
+ ^^
+pkg/front_end/testcases/inference_new/infer_assign_to_local_upwards.dart:46:58: Context: Write to t@343
+ var /*@ type=double* */ v9 = t /*@ target=double::+ */ += getDouble();
+ ^^
+pkg/front_end/testcases/inference_new/infer_assign_to_local_upwards.dart:47:57: Context: Write to t@343
+ var /*@ type=double* */ v10 = /*@ target=double::+ */ ++t;
+ ^^
+pkg/front_end/testcases/inference_new/infer_assign_to_local_upwards.dart:49:73: Context: Write to t@343
+ /*@ type=double* */ t /*@ type=double* */ /*@ target=double::+ */ ++;
+ ^^
diff --git a/pkg/front_end/testcases/inference_new/infer_assign_to_property.dart b/pkg/front_end/testcases/inference_new/infer_assign_to_property.dart
index 7b7d80f..18e21f8 100644
--- a/pkg/front_end/testcases/inference_new/infer_assign_to_property.dart
+++ b/pkg/front_end/testcases/inference_new/infer_assign_to_property.dart
@@ -10,12 +10,21 @@
}
var v_assign = (new A(). /*@target=A::f*/ f = 1);
-var v_plus = (new A(). /*@target=A::f*/ f += 1);
-var v_minus = (new A(). /*@target=A::f*/ f -= 1);
-var v_multiply = (new A(). /*@target=A::f*/ f *= 1);
-var v_prefix_pp = (++new A(). /*@target=A::f*/ f);
-var v_prefix_mm = (--new A(). /*@target=A::f*/ f);
-var v_postfix_pp = (new A(). /*@target=A::f*/ f++);
-var v_postfix_mm = (new A(). /*@target=A::f*/ f--);
+var v_plus = (new /*@ type=A* */ A()
+ . /*@target=A::f*/ /*@target=A::f*/ f /*@ target=num::+ */ += 1);
+var v_minus = (new /*@ type=A* */ A()
+ . /*@target=A::f*/ /*@target=A::f*/ f /*@ target=num::- */ -= 1);
+var v_multiply = (new /*@ type=A* */ A()
+ . /*@target=A::f*/ /*@target=A::f*/ f /*@ target=num::* */ *= 1);
+var v_prefix_pp = (/*@ target=num::+ */ ++new /*@ type=A* */ A()
+ . /*@target=A::f*/ /*@target=A::f*/ f);
+var v_prefix_mm = (/*@ target=num::- */ --new /*@ type=A* */ A()
+ . /*@target=A::f*/ /*@target=A::f*/ f);
+var v_postfix_pp = (new /*@ type=A* */ A()
+ . /*@ type=int* */ /*@target=A::f*/ /*@target=A::f*/
+ f /*@ type=int* */ /*@ target=num::+ */ ++);
+var v_postfix_mm = (new /*@ type=A* */ A()
+ . /*@ type=int* */ /*@target=A::f*/ /*@target=A::f*/
+ f /*@ type=int* */ /*@ target=num::- */ --);
main() {}
diff --git a/pkg/front_end/testcases/inference_new/infer_assign_to_property_custom.dart b/pkg/front_end/testcases/inference_new/infer_assign_to_property_custom.dart
index 0a7493d..1878c4d 100644
--- a/pkg/front_end/testcases/inference_new/infer_assign_to_property_custom.dart
+++ b/pkg/front_end/testcases/inference_new/infer_assign_to_property_custom.dart
@@ -14,9 +14,15 @@
A a;
}
-var v_prefix_pp = (++new B(). /*@target=B::a*/ a);
-var v_prefix_mm = (--new B(). /*@target=B::a*/ a);
-var v_postfix_pp = (new B(). /*@target=B::a*/ a++);
-var v_postfix_mm = (new B(). /*@target=B::a*/ a--);
+var v_prefix_pp = (/*@ target=A::+ */ ++new /*@ type=B* */ B()
+ . /*@target=B::a*/ /*@target=B::a*/ a);
+var v_prefix_mm = (/*@ target=A::- */ --new /*@ type=B* */ B()
+ . /*@target=B::a*/ /*@target=B::a*/ a);
+var v_postfix_pp =
+ (new /*@ type=B* */ B(). /*@ type=A* */ /*@target=B::a*/ /*@target=B::a*/ a
+ /*@ type=int* */ /*@ target=A::+ */ ++);
+var v_postfix_mm =
+ (new /*@ type=B* */ B(). /*@ type=A* */ /*@target=B::a*/ /*@target=B::a*/ a
+ /*@ type=double* */ /*@ target=A::- */ --);
main() {}
diff --git a/pkg/front_end/testcases/inference_new/infer_assign_to_property_custom.dart.strong.expect b/pkg/front_end/testcases/inference_new/infer_assign_to_property_custom.dart.strong.expect
index dd9255e..9749d80 100644
--- a/pkg/front_end/testcases/inference_new/infer_assign_to_property_custom.dart.strong.expect
+++ b/pkg/front_end/testcases/inference_new/infer_assign_to_property_custom.dart.strong.expect
@@ -2,28 +2,28 @@
//
// Problems in library:
//
-// pkg/front_end/testcases/inference_new/infer_assign_to_property_custom.dart:17:20: Error: A value of type 'int' can't be assigned to a variable of type 'A'.
+// pkg/front_end/testcases/inference_new/infer_assign_to_property_custom.dart:17:39: Error: A value of type 'int' can't be assigned to a variable of type 'A'.
// - 'A' is from 'pkg/front_end/testcases/inference_new/infer_assign_to_property_custom.dart'.
// Try changing the type of the left hand side, or casting the right hand side to 'A'.
-// var v_prefix_pp = (++new B(). /*@target=B::a*/ a);
-// ^
+// var v_prefix_pp = (/*@ target=A::+ */ ++new /*@ type=B* */ B()
+// ^
//
-// pkg/front_end/testcases/inference_new/infer_assign_to_property_custom.dart:18:20: Error: A value of type 'double' can't be assigned to a variable of type 'A'.
+// pkg/front_end/testcases/inference_new/infer_assign_to_property_custom.dart:19:39: Error: A value of type 'double' can't be assigned to a variable of type 'A'.
// - 'A' is from 'pkg/front_end/testcases/inference_new/infer_assign_to_property_custom.dart'.
// Try changing the type of the left hand side, or casting the right hand side to 'A'.
-// var v_prefix_mm = (--new B(). /*@target=B::a*/ a);
-// ^
+// var v_prefix_mm = (/*@ target=A::- */ --new /*@ type=B* */ B()
+// ^
//
-// pkg/front_end/testcases/inference_new/infer_assign_to_property_custom.dart:19:48: Error: A value of type 'int' can't be assigned to a variable of type 'A'.
+// pkg/front_end/testcases/inference_new/infer_assign_to_property_custom.dart:23:45: Error: A value of type 'int' can't be assigned to a variable of type 'A'.
// - 'A' is from 'pkg/front_end/testcases/inference_new/infer_assign_to_property_custom.dart'.
// Try changing the type of the left hand side, or casting the right hand side to 'A'.
-// var v_postfix_pp = (new B(). /*@target=B::a*/ a++);
-// ^
+// /*@ type=int* */ /*@ target=A::+ */ ++);
+// ^
//
-// pkg/front_end/testcases/inference_new/infer_assign_to_property_custom.dart:20:48: Error: A value of type 'double' can't be assigned to a variable of type 'A'.
+// pkg/front_end/testcases/inference_new/infer_assign_to_property_custom.dart:26:48: Error: A value of type 'double' can't be assigned to a variable of type 'A'.
// - 'A' is from 'pkg/front_end/testcases/inference_new/infer_assign_to_property_custom.dart'.
// Try changing the type of the left hand side, or casting the right hand side to 'A'.
-// var v_postfix_mm = (new B(). /*@target=B::a*/ a--);
+// /*@ type=double* */ /*@ target=A::- */ --);
// ^
//
import self as self;
@@ -44,24 +44,24 @@
: super core::Object::•()
;
}
-static field core::int* v_prefix_pp = let final self::B* #t1 = new self::B::•() in #t1.{self::B::a} = let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/inference_new/infer_assign_to_property_custom.dart:17:20: Error: A value of type 'int' can't be assigned to a variable of type 'A'.
+static field core::int* v_prefix_pp = let final self::B* #t1 = new self::B::•() in #t1.{self::B::a} = let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/inference_new/infer_assign_to_property_custom.dart:17:39: Error: A value of type 'int' can't be assigned to a variable of type 'A'.
- 'A' is from 'pkg/front_end/testcases/inference_new/infer_assign_to_property_custom.dart'.
Try changing the type of the left hand side, or casting the right hand side to 'A'.
-var v_prefix_pp = (++new B(). /*@target=B::a*/ a);
- ^" in #t1.{self::B::a}.{self::A::+}(1) as{TypeError} self::A*;
-static field core::double* v_prefix_mm = let final self::B* #t3 = new self::B::•() in #t3.{self::B::a} = let final<BottomType> #t4 = invalid-expression "pkg/front_end/testcases/inference_new/infer_assign_to_property_custom.dart:18:20: Error: A value of type 'double' can't be assigned to a variable of type 'A'.
+var v_prefix_pp = (/*@ target=A::+ */ ++new /*@ type=B* */ B()
+ ^" in #t1.{self::B::a}.{self::A::+}(1) as{TypeError} self::A*;
+static field core::double* v_prefix_mm = let final self::B* #t3 = new self::B::•() in #t3.{self::B::a} = let final<BottomType> #t4 = invalid-expression "pkg/front_end/testcases/inference_new/infer_assign_to_property_custom.dart:19:39: Error: A value of type 'double' can't be assigned to a variable of type 'A'.
- 'A' is from 'pkg/front_end/testcases/inference_new/infer_assign_to_property_custom.dart'.
Try changing the type of the left hand side, or casting the right hand side to 'A'.
-var v_prefix_mm = (--new B(). /*@target=B::a*/ a);
- ^" in #t3.{self::B::a}.{self::A::-}(1) as{TypeError} self::A*;
-static field self::A* v_postfix_pp = let final self::B* #t5 = new self::B::•() in let final self::A* #t6 = #t5.{self::B::a} in let final core::int* #t7 = #t5.{self::B::a} = let final<BottomType> #t8 = invalid-expression "pkg/front_end/testcases/inference_new/infer_assign_to_property_custom.dart:19:48: Error: A value of type 'int' can't be assigned to a variable of type 'A'.
+var v_prefix_mm = (/*@ target=A::- */ --new /*@ type=B* */ B()
+ ^" in #t3.{self::B::a}.{self::A::-}(1) as{TypeError} self::A*;
+static field self::A* v_postfix_pp = let final self::B* #t5 = new self::B::•() in let final self::A* #t6 = #t5.{self::B::a} in let final core::int* #t7 = #t5.{self::B::a} = let final<BottomType> #t8 = invalid-expression "pkg/front_end/testcases/inference_new/infer_assign_to_property_custom.dart:23:45: Error: A value of type 'int' can't be assigned to a variable of type 'A'.
- 'A' is from 'pkg/front_end/testcases/inference_new/infer_assign_to_property_custom.dart'.
Try changing the type of the left hand side, or casting the right hand side to 'A'.
-var v_postfix_pp = (new B(). /*@target=B::a*/ a++);
- ^" in #t6.{self::A::+}(1) as{TypeError} self::A* in #t6;
-static field self::A* v_postfix_mm = let final self::B* #t9 = new self::B::•() in let final self::A* #t10 = #t9.{self::B::a} in let final core::double* #t11 = #t9.{self::B::a} = let final<BottomType> #t12 = invalid-expression "pkg/front_end/testcases/inference_new/infer_assign_to_property_custom.dart:20:48: Error: A value of type 'double' can't be assigned to a variable of type 'A'.
+ /*@ type=int* */ /*@ target=A::+ */ ++);
+ ^" in #t6.{self::A::+}(1) as{TypeError} self::A* in #t6;
+static field self::A* v_postfix_mm = let final self::B* #t9 = new self::B::•() in let final self::A* #t10 = #t9.{self::B::a} in let final core::double* #t11 = #t9.{self::B::a} = let final<BottomType> #t12 = invalid-expression "pkg/front_end/testcases/inference_new/infer_assign_to_property_custom.dart:26:48: Error: A value of type 'double' can't be assigned to a variable of type 'A'.
- 'A' is from 'pkg/front_end/testcases/inference_new/infer_assign_to_property_custom.dart'.
Try changing the type of the left hand side, or casting the right hand side to 'A'.
-var v_postfix_mm = (new B(). /*@target=B::a*/ a--);
+ /*@ type=double* */ /*@ target=A::- */ --);
^" in #t10.{self::A::-}(1) as{TypeError} self::A* in #t10;
static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference_new/infer_assign_to_property_full.dart b/pkg/front_end/testcases/inference_new/infer_assign_to_property_full.dart
index 6a0d229..0fc74d0 100644
--- a/pkg/front_end/testcases/inference_new/infer_assign_to_property_full.dart
+++ b/pkg/front_end/testcases/inference_new/infer_assign_to_property_full.dart
@@ -23,24 +23,46 @@
static void test(Test t) {
t. /*@target=Test::member*/ member = /*@ typeArgs=B* */ f();
- t. /*@target=Test::member*/ member ??= /*@ typeArgs=B* */ f();
- t. /*@target=Test::member*/ member += /*@ typeArgs=dynamic */ f();
- t. /*@target=Test::member*/ member *= /*@ typeArgs=dynamic */ f();
- t. /*@target=Test::member*/ member &= /*@ typeArgs=dynamic */ f();
- --t. /*@target=Test::member*/ member;
- t. /*@target=Test::member*/ member--;
+ /*@ type=Test* */ t
+ . /*@target=Test::member*/ /*@target=Test::member*/ member
+ /*@target=Object::==*/ ??= /*@ typeArgs=B* */ f();
+ /*@ type=Test* */ t
+ . /*@target=Test::member*/ /*@target=Test::member*/ member
+ /*@ target=B::+ */ += /*@ typeArgs=C* */ f();
+ /*@ type=Test* */ t
+ . /*@target=Test::member*/ /*@target=Test::member*/ member
+ /*@ target=B::* */ *= /*@ typeArgs=B* */ f();
+ /*@ type=Test* */ t
+ . /*@target=Test::member*/ /*@target=Test::member*/ member
+ /*@ target=B::& */ &= /*@ typeArgs=A* */ f();
+ /*@ target=B::- */ -- /*@ type=Test* */ t
+ . /*@target=Test::member*/ /*@target=Test::member*/ member;
+ /*@ type=Test* */ t
+ . /*@target=Test::member*/ /*@target=Test::member*/ member
+ /*@ target=B::- */ --;
var /*@ type=B* */ v1 =
t. /*@target=Test::member*/ member = /*@ typeArgs=B* */ f();
var /*@ type=B* */ v2 =
- t. /*@target=Test::member*/ member ??= /*@ typeArgs=B* */ f();
+ /*@ type=Test* */ t
+ . /*@target=Test::member*/ /*@target=Test::member*/ member
+ /*@target=Object::==*/ ??= /*@ typeArgs=B* */ f();
var /*@ type=A* */ v3 =
- t. /*@target=Test::member*/ member += /*@ typeArgs=dynamic */ f();
+ /*@ type=Test* */ t
+ . /*@target=Test::member*/ /*@target=Test::member*/ member
+ /*@ target=B::+ */ += /*@ typeArgs=C* */ f();
var /*@ type=B* */ v4 =
- t. /*@target=Test::member*/ member *= /*@ typeArgs=dynamic */ f();
+ /*@ type=Test* */ t
+ . /*@target=Test::member*/ /*@target=Test::member*/ member
+ /*@ target=B::* */ *= /*@ typeArgs=B* */ f();
var /*@ type=C* */ v5 =
- t. /*@target=Test::member*/ member &= /*@ typeArgs=dynamic */ f();
- var /*@ type=B* */ v6 = --t. /*@target=Test::member*/ member;
- var /*@ type=B* */ v7 = t. /*@target=Test::member*/ member--;
+ /*@ type=Test* */ t
+ . /*@target=Test::member*/ /*@target=Test::member*/ member
+ /*@ target=B::& */ &= /*@ typeArgs=A* */ f();
+ var /*@ type=B* */ v6 = /*@ target=B::- */ -- /*@ type=Test* */ t
+ . /*@target=Test::member*/ /*@target=Test::member*/ member;
+ var /*@ type=B* */ v7 = /*@ type=Test* */ t
+ . /*@ type=B* */ /*@target=Test::member*/ /*@target=Test::member*/
+ member /*@ type=B* */ /*@ target=B::- */ --;
}
}
diff --git a/pkg/front_end/testcases/inference_new/infer_assign_to_property_full.dart.strong.expect b/pkg/front_end/testcases/inference_new/infer_assign_to_property_full.dart.strong.expect
index 74778b8..5809936 100644
--- a/pkg/front_end/testcases/inference_new/infer_assign_to_property_full.dart.strong.expect
+++ b/pkg/front_end/testcases/inference_new/infer_assign_to_property_full.dart.strong.expect
@@ -33,16 +33,16 @@
static method test(self::Test* t) → void {
t.{self::Test::member} = self::f<self::B*>();
let final self::Test* #t1 = t in #t1.{self::Test::member}.{core::Object::==}(null) ?{self::B*} #t1.{self::Test::member} = self::f<self::B*>() : null;
- let final self::Test* #t2 = t in #t2.{self::Test::member} = #t2.{self::Test::member}.{self::B::+}(self::f<dynamic>() as{TypeError} self::C*) as{TypeError} self::B*;
- let final self::Test* #t3 = t in #t3.{self::Test::member} = #t3.{self::Test::member}.{self::B::*}(self::f<dynamic>() as{TypeError} self::B*);
- let final self::Test* #t4 = t in #t4.{self::Test::member} = #t4.{self::Test::member}.{self::B::&}(self::f<dynamic>() as{TypeError} self::A*);
+ let final self::Test* #t2 = t in #t2.{self::Test::member} = #t2.{self::Test::member}.{self::B::+}(self::f<self::C*>()) as{TypeError} self::B*;
+ let final self::Test* #t3 = t in #t3.{self::Test::member} = #t3.{self::Test::member}.{self::B::*}(self::f<self::B*>());
+ let final self::Test* #t4 = t in #t4.{self::Test::member} = #t4.{self::Test::member}.{self::B::&}(self::f<self::A*>());
let final self::Test* #t5 = t in #t5.{self::Test::member} = #t5.{self::Test::member}.{self::B::-}(1);
let final self::Test* #t6 = t in #t6.{self::Test::member} = #t6.{self::Test::member}.{self::B::-}(1);
self::B* v1 = t.{self::Test::member} = self::f<self::B*>();
self::B* v2 = let final self::Test* #t7 = t in let final self::B* #t8 = #t7.{self::Test::member} in #t8.{core::Object::==}(null) ?{self::B*} #t7.{self::Test::member} = self::f<self::B*>() : #t8;
- self::A* v3 = let final self::Test* #t9 = t in #t9.{self::Test::member} = #t9.{self::Test::member}.{self::B::+}(self::f<dynamic>() as{TypeError} self::C*) as{TypeError} self::B*;
- self::B* v4 = let final self::Test* #t10 = t in #t10.{self::Test::member} = #t10.{self::Test::member}.{self::B::*}(self::f<dynamic>() as{TypeError} self::B*);
- self::C* v5 = let final self::Test* #t11 = t in #t11.{self::Test::member} = #t11.{self::Test::member}.{self::B::&}(self::f<dynamic>() as{TypeError} self::A*);
+ self::A* v3 = let final self::Test* #t9 = t in #t9.{self::Test::member} = #t9.{self::Test::member}.{self::B::+}(self::f<self::C*>()) as{TypeError} self::B*;
+ self::B* v4 = let final self::Test* #t10 = t in #t10.{self::Test::member} = #t10.{self::Test::member}.{self::B::*}(self::f<self::B*>());
+ self::C* v5 = let final self::Test* #t11 = t in #t11.{self::Test::member} = #t11.{self::Test::member}.{self::B::&}(self::f<self::A*>());
self::B* v6 = let final self::Test* #t12 = t in #t12.{self::Test::member} = #t12.{self::Test::member}.{self::B::-}(1);
self::B* v7 = let final self::Test* #t13 = t in let final self::B* #t14 = #t13.{self::Test::member} in let final self::B* #t15 = #t13.{self::Test::member} = #t14.{self::B::-}(1) in #t14;
}
diff --git a/pkg/front_end/testcases/inference_new/infer_assign_to_property_full.dart.strong.transformed.expect b/pkg/front_end/testcases/inference_new/infer_assign_to_property_full.dart.strong.transformed.expect
index 74778b8..5809936 100644
--- a/pkg/front_end/testcases/inference_new/infer_assign_to_property_full.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference_new/infer_assign_to_property_full.dart.strong.transformed.expect
@@ -33,16 +33,16 @@
static method test(self::Test* t) → void {
t.{self::Test::member} = self::f<self::B*>();
let final self::Test* #t1 = t in #t1.{self::Test::member}.{core::Object::==}(null) ?{self::B*} #t1.{self::Test::member} = self::f<self::B*>() : null;
- let final self::Test* #t2 = t in #t2.{self::Test::member} = #t2.{self::Test::member}.{self::B::+}(self::f<dynamic>() as{TypeError} self::C*) as{TypeError} self::B*;
- let final self::Test* #t3 = t in #t3.{self::Test::member} = #t3.{self::Test::member}.{self::B::*}(self::f<dynamic>() as{TypeError} self::B*);
- let final self::Test* #t4 = t in #t4.{self::Test::member} = #t4.{self::Test::member}.{self::B::&}(self::f<dynamic>() as{TypeError} self::A*);
+ let final self::Test* #t2 = t in #t2.{self::Test::member} = #t2.{self::Test::member}.{self::B::+}(self::f<self::C*>()) as{TypeError} self::B*;
+ let final self::Test* #t3 = t in #t3.{self::Test::member} = #t3.{self::Test::member}.{self::B::*}(self::f<self::B*>());
+ let final self::Test* #t4 = t in #t4.{self::Test::member} = #t4.{self::Test::member}.{self::B::&}(self::f<self::A*>());
let final self::Test* #t5 = t in #t5.{self::Test::member} = #t5.{self::Test::member}.{self::B::-}(1);
let final self::Test* #t6 = t in #t6.{self::Test::member} = #t6.{self::Test::member}.{self::B::-}(1);
self::B* v1 = t.{self::Test::member} = self::f<self::B*>();
self::B* v2 = let final self::Test* #t7 = t in let final self::B* #t8 = #t7.{self::Test::member} in #t8.{core::Object::==}(null) ?{self::B*} #t7.{self::Test::member} = self::f<self::B*>() : #t8;
- self::A* v3 = let final self::Test* #t9 = t in #t9.{self::Test::member} = #t9.{self::Test::member}.{self::B::+}(self::f<dynamic>() as{TypeError} self::C*) as{TypeError} self::B*;
- self::B* v4 = let final self::Test* #t10 = t in #t10.{self::Test::member} = #t10.{self::Test::member}.{self::B::*}(self::f<dynamic>() as{TypeError} self::B*);
- self::C* v5 = let final self::Test* #t11 = t in #t11.{self::Test::member} = #t11.{self::Test::member}.{self::B::&}(self::f<dynamic>() as{TypeError} self::A*);
+ self::A* v3 = let final self::Test* #t9 = t in #t9.{self::Test::member} = #t9.{self::Test::member}.{self::B::+}(self::f<self::C*>()) as{TypeError} self::B*;
+ self::B* v4 = let final self::Test* #t10 = t in #t10.{self::Test::member} = #t10.{self::Test::member}.{self::B::*}(self::f<self::B*>());
+ self::C* v5 = let final self::Test* #t11 = t in #t11.{self::Test::member} = #t11.{self::Test::member}.{self::B::&}(self::f<self::A*>());
self::B* v6 = let final self::Test* #t12 = t in #t12.{self::Test::member} = #t12.{self::Test::member}.{self::B::-}(1);
self::B* v7 = let final self::Test* #t13 = t in let final self::B* #t14 = #t13.{self::Test::member} in let final self::B* #t15 = #t13.{self::Test::member} = #t14.{self::B::-}(1) in #t14;
}
diff --git a/pkg/front_end/testcases/inference_new/infer_assign_to_property_null_aware.dart b/pkg/front_end/testcases/inference_new/infer_assign_to_property_null_aware.dart
index 45300f9..b2b1f77 100644
--- a/pkg/front_end/testcases/inference_new/infer_assign_to_property_null_aware.dart
+++ b/pkg/front_end/testcases/inference_new/infer_assign_to_property_null_aware.dart
@@ -22,7 +22,8 @@
B member;
static void test(Test t) {
- t?. /*@target=Test::member*/ member = /*@ typeArgs=B* */ f();
+ /*@ type=Test* */ /*@target=Object::==*/ t
+ ?. /*@target=Test::member*/ member = /*@ typeArgs=B* */ f();
t?. /*@target=Test::member*/ member ??= /*@ typeArgs=B* */ f();
t?. /*@target=Test::member*/ member += /*@ typeArgs=dynamic */ f();
t?. /*@target=Test::member*/ member *= /*@ typeArgs=dynamic */ f();
@@ -30,7 +31,8 @@
--t?. /*@target=Test::member*/ member;
t?. /*@target=Test::member*/ member--;
var /*@ type=B* */ v1 =
- t?. /*@target=Test::member*/ member = /*@ typeArgs=B* */ f();
+ /*@ type=Test* */ /*@target=Object::==*/ t
+ ?. /*@target=Test::member*/ member = /*@ typeArgs=B* */ f();
var /*@ type=B* */ v2 =
t?. /*@target=Test::member*/ member ??= /*@ typeArgs=B* */ f();
var /*@ type=A* */ v3 =
diff --git a/pkg/front_end/testcases/inference_new/infer_assign_to_property_null_aware.dart.strong.expect b/pkg/front_end/testcases/inference_new/infer_assign_to_property_null_aware.dart.strong.expect
index fdee8a4..52f7978 100644
--- a/pkg/front_end/testcases/inference_new/infer_assign_to_property_null_aware.dart.strong.expect
+++ b/pkg/front_end/testcases/inference_new/infer_assign_to_property_null_aware.dart.strong.expect
@@ -31,14 +31,14 @@
: super core::Object::•()
;
static method test(self::Test* t) → void {
- let final self::Test* #t1 = t in #t1.==(null) ?{self::B*} null : #t1.{self::Test::member} = self::f<self::B*>();
+ let final self::Test* #t1 = t in #t1.{core::Object::==}(null) ?{self::B*} null : #t1.{self::Test::member} = self::f<self::B*>();
let final self::Test* #t2 = t in #t2.==(null) ?{self::B*} null : #t2.{self::Test::member}.{core::Object::==}(null) ?{self::B*} #t2.{self::Test::member} = self::f<self::B*>() : null;
let final self::Test* #t3 = t in #t3.==(null) ?{self::A*} null : #t3.{self::Test::member} = #t3.{self::Test::member}.{self::B::+}(self::f<dynamic>() as{TypeError} self::C*) as{TypeError} self::B*;
let final self::Test* #t4 = t in #t4.==(null) ?{self::B*} null : #t4.{self::Test::member} = #t4.{self::Test::member}.{self::B::*}(self::f<dynamic>() as{TypeError} self::B*);
let final self::Test* #t5 = t in #t5.==(null) ?{self::C*} null : #t5.{self::Test::member} = #t5.{self::Test::member}.{self::B::&}(self::f<dynamic>() as{TypeError} self::A*);
let final self::Test* #t6 = t in #t6.==(null) ?{self::B*} null : #t6.{self::Test::member} = #t6.{self::Test::member}.{self::B::-}(1);
let final self::Test* #t7 = t in #t7.==(null) ?{self::B*} null : #t7.{self::Test::member} = #t7.{self::Test::member}.{self::B::-}(1);
- self::B* v1 = let final self::Test* #t8 = t in #t8.==(null) ?{self::B*} null : #t8.{self::Test::member} = self::f<self::B*>();
+ self::B* v1 = let final self::Test* #t8 = t in #t8.{core::Object::==}(null) ?{self::B*} null : #t8.{self::Test::member} = self::f<self::B*>();
self::B* v2 = let final self::Test* #t9 = t in #t9.==(null) ?{self::B*} null : let final self::B* #t10 = #t9.{self::Test::member} in #t10.{core::Object::==}(null) ?{self::B*} #t9.{self::Test::member} = self::f<self::B*>() : #t10;
self::A* v3 = let final self::Test* #t11 = t in #t11.==(null) ?{self::A*} null : #t11.{self::Test::member} = #t11.{self::Test::member}.{self::B::+}(self::f<dynamic>() as{TypeError} self::C*) as{TypeError} self::B*;
self::B* v4 = let final self::Test* #t12 = t in #t12.==(null) ?{self::B*} null : #t12.{self::Test::member} = #t12.{self::Test::member}.{self::B::*}(self::f<dynamic>() as{TypeError} self::B*);
diff --git a/pkg/front_end/testcases/inference_new/infer_assign_to_property_null_aware.dart.strong.transformed.expect b/pkg/front_end/testcases/inference_new/infer_assign_to_property_null_aware.dart.strong.transformed.expect
index fdee8a4..52f7978 100644
--- a/pkg/front_end/testcases/inference_new/infer_assign_to_property_null_aware.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference_new/infer_assign_to_property_null_aware.dart.strong.transformed.expect
@@ -31,14 +31,14 @@
: super core::Object::•()
;
static method test(self::Test* t) → void {
- let final self::Test* #t1 = t in #t1.==(null) ?{self::B*} null : #t1.{self::Test::member} = self::f<self::B*>();
+ let final self::Test* #t1 = t in #t1.{core::Object::==}(null) ?{self::B*} null : #t1.{self::Test::member} = self::f<self::B*>();
let final self::Test* #t2 = t in #t2.==(null) ?{self::B*} null : #t2.{self::Test::member}.{core::Object::==}(null) ?{self::B*} #t2.{self::Test::member} = self::f<self::B*>() : null;
let final self::Test* #t3 = t in #t3.==(null) ?{self::A*} null : #t3.{self::Test::member} = #t3.{self::Test::member}.{self::B::+}(self::f<dynamic>() as{TypeError} self::C*) as{TypeError} self::B*;
let final self::Test* #t4 = t in #t4.==(null) ?{self::B*} null : #t4.{self::Test::member} = #t4.{self::Test::member}.{self::B::*}(self::f<dynamic>() as{TypeError} self::B*);
let final self::Test* #t5 = t in #t5.==(null) ?{self::C*} null : #t5.{self::Test::member} = #t5.{self::Test::member}.{self::B::&}(self::f<dynamic>() as{TypeError} self::A*);
let final self::Test* #t6 = t in #t6.==(null) ?{self::B*} null : #t6.{self::Test::member} = #t6.{self::Test::member}.{self::B::-}(1);
let final self::Test* #t7 = t in #t7.==(null) ?{self::B*} null : #t7.{self::Test::member} = #t7.{self::Test::member}.{self::B::-}(1);
- self::B* v1 = let final self::Test* #t8 = t in #t8.==(null) ?{self::B*} null : #t8.{self::Test::member} = self::f<self::B*>();
+ self::B* v1 = let final self::Test* #t8 = t in #t8.{core::Object::==}(null) ?{self::B*} null : #t8.{self::Test::member} = self::f<self::B*>();
self::B* v2 = let final self::Test* #t9 = t in #t9.==(null) ?{self::B*} null : let final self::B* #t10 = #t9.{self::Test::member} in #t10.{core::Object::==}(null) ?{self::B*} #t9.{self::Test::member} = self::f<self::B*>() : #t10;
self::A* v3 = let final self::Test* #t11 = t in #t11.==(null) ?{self::A*} null : #t11.{self::Test::member} = #t11.{self::Test::member}.{self::B::+}(self::f<dynamic>() as{TypeError} self::C*) as{TypeError} self::B*;
self::B* v4 = let final self::Test* #t12 = t in #t12.==(null) ?{self::B*} null : #t12.{self::Test::member} = #t12.{self::Test::member}.{self::B::*}(self::f<dynamic>() as{TypeError} self::B*);
diff --git a/pkg/front_end/testcases/inference_new/infer_assign_to_property_null_aware_upwards.dart b/pkg/front_end/testcases/inference_new/infer_assign_to_property_null_aware_upwards.dart
index 664ca78..a8d4387 100644
--- a/pkg/front_end/testcases/inference_new/infer_assign_to_property_null_aware_upwards.dart
+++ b/pkg/front_end/testcases/inference_new/infer_assign_to_property_null_aware_upwards.dart
@@ -13,8 +13,10 @@
int prop;
static void test(Test1 t) {
- var /*@ type=int* */ v1 = t?. /*@target=Test1::prop*/ prop = getInt();
- var /*@ type=num* */ v2 = t?. /*@target=Test1::prop*/ prop = getNum();
+ var /*@ type=int* */ v1 = /*@ type=Test1* */ /*@target=Object::==*/ t
+ ?. /*@target=Test1::prop*/ prop = getInt();
+ var /*@ type=num* */ v2 = /*@ type=Test1* */ /*@target=Object::==*/ t
+ ?. /*@target=Test1::prop*/ prop = getNum();
var /*@ type=int* */ v4 = t?. /*@target=Test1::prop*/ prop ??= getInt();
var /*@ type=num* */ v5 = t?. /*@target=Test1::prop*/ prop ??= getNum();
var /*@ type=int* */ v7 = t?. /*@target=Test1::prop*/ prop += getInt();
@@ -28,9 +30,12 @@
num prop;
static void test(Test2 t) {
- var /*@ type=int* */ v1 = t?. /*@target=Test2::prop*/ prop = getInt();
- var /*@ type=num* */ v2 = t?. /*@target=Test2::prop*/ prop = getNum();
- var /*@ type=double* */ v3 = t?. /*@target=Test2::prop*/ prop = getDouble();
+ var /*@ type=int* */ v1 = /*@ type=Test2* */ /*@target=Object::==*/ t
+ ?. /*@target=Test2::prop*/ prop = getInt();
+ var /*@ type=num* */ v2 = /*@ type=Test2* */ /*@target=Object::==*/ t
+ ?. /*@target=Test2::prop*/ prop = getNum();
+ var /*@ type=double* */ v3 = /*@ type=Test2* */ /*@target=Object::==*/ t
+ ?. /*@target=Test2::prop*/ prop = getDouble();
var /*@ type=num* */ v4 = t?. /*@target=Test2::prop*/ prop ??= getInt();
var /*@ type=num* */ v5 = t?. /*@target=Test2::prop*/ prop ??= getNum();
var /*@ type=num* */ v6 = t?. /*@target=Test2::prop*/ prop ??= getDouble();
@@ -46,13 +51,17 @@
double prop;
static void test3(Test3 t) {
- var /*@ type=num* */ v2 = t?. /*@target=Test3::prop*/ prop = getNum();
- var /*@ type=double* */ v3 = t?. /*@target=Test3::prop*/ prop = getDouble();
+ var /*@ type=num* */ v2 = /*@ type=Test3* */ /*@target=Object::==*/ t
+ ?. /*@target=Test3::prop*/ prop = getNum();
+ var /*@ type=double* */ v3 = /*@ type=Test3* */ /*@target=Object::==*/ t
+ ?. /*@target=Test3::prop*/ prop = getDouble();
var /*@ type=num* */ v5 = t?. /*@target=Test3::prop*/ prop ??= getNum();
- var /*@ type=double* */ v6 = t?. /*@target=Test3::prop*/ prop ??= getDouble();
+ var /*@ type=double* */ v6 =
+ t?. /*@target=Test3::prop*/ prop ??= getDouble();
var /*@ type=double* */ v7 = t?. /*@target=Test3::prop*/ prop += getInt();
var /*@ type=double* */ v8 = t?. /*@target=Test3::prop*/ prop += getNum();
- var /*@ type=double* */ v9 = t?. /*@target=Test3::prop*/ prop += getDouble();
+ var /*@ type=double* */ v9 =
+ t?. /*@target=Test3::prop*/ prop += getDouble();
var /*@ type=double* */ v10 = ++t?. /*@target=Test3::prop*/ prop;
var /*@ type=double* */ v11 = t?. /*@target=Test3::prop*/ prop++;
}
diff --git a/pkg/front_end/testcases/inference_new/infer_assign_to_property_null_aware_upwards.dart.strong.expect b/pkg/front_end/testcases/inference_new/infer_assign_to_property_null_aware_upwards.dart.strong.expect
index 35c7161..da54b4b 100644
--- a/pkg/front_end/testcases/inference_new/infer_assign_to_property_null_aware_upwards.dart.strong.expect
+++ b/pkg/front_end/testcases/inference_new/infer_assign_to_property_null_aware_upwards.dart.strong.expect
@@ -8,8 +8,8 @@
: super core::Object::•()
;
static method test(self::Test1* t) → void {
- core::int* v1 = let final self::Test1* #t1 = t in #t1.==(null) ?{core::int*} null : #t1.{self::Test1::prop} = self::getInt();
- core::num* v2 = let final self::Test1* #t2 = t in #t2.==(null) ?{core::num*} null : #t2.{self::Test1::prop} = self::getNum() as{TypeError} core::int*;
+ core::int* v1 = let final self::Test1* #t1 = t in #t1.{core::Object::==}(null) ?{core::int*} null : #t1.{self::Test1::prop} = self::getInt();
+ core::num* v2 = let final self::Test1* #t2 = t in #t2.{core::Object::==}(null) ?{core::num*} null : #t2.{self::Test1::prop} = self::getNum() as{TypeError} core::int*;
core::int* v4 = let final self::Test1* #t3 = t in #t3.==(null) ?{core::int*} null : let final core::int* #t4 = #t3.{self::Test1::prop} in #t4.{core::num::==}(null) ?{core::int*} #t3.{self::Test1::prop} = self::getInt() : #t4;
core::num* v5 = let final self::Test1* #t5 = t in #t5.==(null) ?{core::num*} null : let final core::int* #t6 = #t5.{self::Test1::prop} in #t6.{core::num::==}(null) ?{core::num*} #t5.{self::Test1::prop} = self::getNum() as{TypeError} core::int* : #t6;
core::int* v7 = let final self::Test1* #t7 = t in #t7.==(null) ?{core::int*} null : #t7.{self::Test1::prop} = #t7.{self::Test1::prop}.{core::num::+}(self::getInt());
@@ -24,9 +24,9 @@
: super core::Object::•()
;
static method test(self::Test2* t) → void {
- core::int* v1 = let final self::Test2* #t13 = t in #t13.==(null) ?{core::int*} null : #t13.{self::Test2::prop} = self::getInt();
- core::num* v2 = let final self::Test2* #t14 = t in #t14.==(null) ?{core::num*} null : #t14.{self::Test2::prop} = self::getNum();
- core::double* v3 = let final self::Test2* #t15 = t in #t15.==(null) ?{core::double*} null : #t15.{self::Test2::prop} = self::getDouble();
+ core::int* v1 = let final self::Test2* #t13 = t in #t13.{core::Object::==}(null) ?{core::int*} null : #t13.{self::Test2::prop} = self::getInt();
+ core::num* v2 = let final self::Test2* #t14 = t in #t14.{core::Object::==}(null) ?{core::num*} null : #t14.{self::Test2::prop} = self::getNum();
+ core::double* v3 = let final self::Test2* #t15 = t in #t15.{core::Object::==}(null) ?{core::double*} null : #t15.{self::Test2::prop} = self::getDouble();
core::num* v4 = let final self::Test2* #t16 = t in #t16.==(null) ?{core::num*} null : let final core::num* #t17 = #t16.{self::Test2::prop} in #t17.{core::num::==}(null) ?{core::num*} #t16.{self::Test2::prop} = self::getInt() : #t17;
core::num* v5 = let final self::Test2* #t18 = t in #t18.==(null) ?{core::num*} null : let final core::num* #t19 = #t18.{self::Test2::prop} in #t19.{core::num::==}(null) ?{core::num*} #t18.{self::Test2::prop} = self::getNum() : #t19;
core::num* v6 = let final self::Test2* #t20 = t in #t20.==(null) ?{core::num*} null : let final core::num* #t21 = #t20.{self::Test2::prop} in #t21.{core::num::==}(null) ?{core::num*} #t20.{self::Test2::prop} = self::getDouble() : #t21;
@@ -43,8 +43,8 @@
: super core::Object::•()
;
static method test3(self::Test3* t) → void {
- core::num* v2 = let final self::Test3* #t29 = t in #t29.==(null) ?{core::num*} null : #t29.{self::Test3::prop} = self::getNum() as{TypeError} core::double*;
- core::double* v3 = let final self::Test3* #t30 = t in #t30.==(null) ?{core::double*} null : #t30.{self::Test3::prop} = self::getDouble();
+ core::num* v2 = let final self::Test3* #t29 = t in #t29.{core::Object::==}(null) ?{core::num*} null : #t29.{self::Test3::prop} = self::getNum() as{TypeError} core::double*;
+ core::double* v3 = let final self::Test3* #t30 = t in #t30.{core::Object::==}(null) ?{core::double*} null : #t30.{self::Test3::prop} = self::getDouble();
core::num* v5 = let final self::Test3* #t31 = t in #t31.==(null) ?{core::num*} null : let final core::double* #t32 = #t31.{self::Test3::prop} in #t32.{core::num::==}(null) ?{core::num*} #t31.{self::Test3::prop} = self::getNum() as{TypeError} core::double* : #t32;
core::double* v6 = let final self::Test3* #t33 = t in #t33.==(null) ?{core::double*} null : let final core::double* #t34 = #t33.{self::Test3::prop} in #t34.{core::num::==}(null) ?{core::double*} #t33.{self::Test3::prop} = self::getDouble() : #t34;
core::double* v7 = let final self::Test3* #t35 = t in #t35.==(null) ?{core::double*} null : #t35.{self::Test3::prop} = #t35.{self::Test3::prop}.{core::double::+}(self::getInt());
diff --git a/pkg/front_end/testcases/inference_new/infer_assign_to_property_null_aware_upwards.dart.strong.transformed.expect b/pkg/front_end/testcases/inference_new/infer_assign_to_property_null_aware_upwards.dart.strong.transformed.expect
index 35c7161..da54b4b 100644
--- a/pkg/front_end/testcases/inference_new/infer_assign_to_property_null_aware_upwards.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference_new/infer_assign_to_property_null_aware_upwards.dart.strong.transformed.expect
@@ -8,8 +8,8 @@
: super core::Object::•()
;
static method test(self::Test1* t) → void {
- core::int* v1 = let final self::Test1* #t1 = t in #t1.==(null) ?{core::int*} null : #t1.{self::Test1::prop} = self::getInt();
- core::num* v2 = let final self::Test1* #t2 = t in #t2.==(null) ?{core::num*} null : #t2.{self::Test1::prop} = self::getNum() as{TypeError} core::int*;
+ core::int* v1 = let final self::Test1* #t1 = t in #t1.{core::Object::==}(null) ?{core::int*} null : #t1.{self::Test1::prop} = self::getInt();
+ core::num* v2 = let final self::Test1* #t2 = t in #t2.{core::Object::==}(null) ?{core::num*} null : #t2.{self::Test1::prop} = self::getNum() as{TypeError} core::int*;
core::int* v4 = let final self::Test1* #t3 = t in #t3.==(null) ?{core::int*} null : let final core::int* #t4 = #t3.{self::Test1::prop} in #t4.{core::num::==}(null) ?{core::int*} #t3.{self::Test1::prop} = self::getInt() : #t4;
core::num* v5 = let final self::Test1* #t5 = t in #t5.==(null) ?{core::num*} null : let final core::int* #t6 = #t5.{self::Test1::prop} in #t6.{core::num::==}(null) ?{core::num*} #t5.{self::Test1::prop} = self::getNum() as{TypeError} core::int* : #t6;
core::int* v7 = let final self::Test1* #t7 = t in #t7.==(null) ?{core::int*} null : #t7.{self::Test1::prop} = #t7.{self::Test1::prop}.{core::num::+}(self::getInt());
@@ -24,9 +24,9 @@
: super core::Object::•()
;
static method test(self::Test2* t) → void {
- core::int* v1 = let final self::Test2* #t13 = t in #t13.==(null) ?{core::int*} null : #t13.{self::Test2::prop} = self::getInt();
- core::num* v2 = let final self::Test2* #t14 = t in #t14.==(null) ?{core::num*} null : #t14.{self::Test2::prop} = self::getNum();
- core::double* v3 = let final self::Test2* #t15 = t in #t15.==(null) ?{core::double*} null : #t15.{self::Test2::prop} = self::getDouble();
+ core::int* v1 = let final self::Test2* #t13 = t in #t13.{core::Object::==}(null) ?{core::int*} null : #t13.{self::Test2::prop} = self::getInt();
+ core::num* v2 = let final self::Test2* #t14 = t in #t14.{core::Object::==}(null) ?{core::num*} null : #t14.{self::Test2::prop} = self::getNum();
+ core::double* v3 = let final self::Test2* #t15 = t in #t15.{core::Object::==}(null) ?{core::double*} null : #t15.{self::Test2::prop} = self::getDouble();
core::num* v4 = let final self::Test2* #t16 = t in #t16.==(null) ?{core::num*} null : let final core::num* #t17 = #t16.{self::Test2::prop} in #t17.{core::num::==}(null) ?{core::num*} #t16.{self::Test2::prop} = self::getInt() : #t17;
core::num* v5 = let final self::Test2* #t18 = t in #t18.==(null) ?{core::num*} null : let final core::num* #t19 = #t18.{self::Test2::prop} in #t19.{core::num::==}(null) ?{core::num*} #t18.{self::Test2::prop} = self::getNum() : #t19;
core::num* v6 = let final self::Test2* #t20 = t in #t20.==(null) ?{core::num*} null : let final core::num* #t21 = #t20.{self::Test2::prop} in #t21.{core::num::==}(null) ?{core::num*} #t20.{self::Test2::prop} = self::getDouble() : #t21;
@@ -43,8 +43,8 @@
: super core::Object::•()
;
static method test3(self::Test3* t) → void {
- core::num* v2 = let final self::Test3* #t29 = t in #t29.==(null) ?{core::num*} null : #t29.{self::Test3::prop} = self::getNum() as{TypeError} core::double*;
- core::double* v3 = let final self::Test3* #t30 = t in #t30.==(null) ?{core::double*} null : #t30.{self::Test3::prop} = self::getDouble();
+ core::num* v2 = let final self::Test3* #t29 = t in #t29.{core::Object::==}(null) ?{core::num*} null : #t29.{self::Test3::prop} = self::getNum() as{TypeError} core::double*;
+ core::double* v3 = let final self::Test3* #t30 = t in #t30.{core::Object::==}(null) ?{core::double*} null : #t30.{self::Test3::prop} = self::getDouble();
core::num* v5 = let final self::Test3* #t31 = t in #t31.==(null) ?{core::num*} null : let final core::double* #t32 = #t31.{self::Test3::prop} in #t32.{core::num::==}(null) ?{core::num*} #t31.{self::Test3::prop} = self::getNum() as{TypeError} core::double* : #t32;
core::double* v6 = let final self::Test3* #t33 = t in #t33.==(null) ?{core::double*} null : let final core::double* #t34 = #t33.{self::Test3::prop} in #t34.{core::num::==}(null) ?{core::double*} #t33.{self::Test3::prop} = self::getDouble() : #t34;
core::double* v7 = let final self::Test3* #t35 = t in #t35.==(null) ?{core::double*} null : #t35.{self::Test3::prop} = #t35.{self::Test3::prop}.{core::double::+}(self::getInt());
diff --git a/pkg/front_end/testcases/inference_new/infer_assign_to_property_super.dart b/pkg/front_end/testcases/inference_new/infer_assign_to_property_super.dart
index 607cd37..428268a 100644
--- a/pkg/front_end/testcases/inference_new/infer_assign_to_property_super.dart
+++ b/pkg/front_end/testcases/inference_new/infer_assign_to_property_super.dart
@@ -25,24 +25,53 @@
class Test extends Base {
void test() {
super. /*@target=Base::member*/ member = /*@ typeArgs=B* */ f();
- super. /*@target=Base::member*/ member ??= /*@ typeArgs=B* */ f();
- super. /*@target=Base::member*/ member += /*@ typeArgs=dynamic */ f();
- super. /*@target=Base::member*/ member *= /*@ typeArgs=dynamic */ f();
- super. /*@target=Base::member*/ member &= /*@ typeArgs=dynamic */ f();
- --super. /*@target=Base::member*/ member;
- super. /*@target=Base::member*/ member--;
+
+ super. /*@target=Base::member*/ /*@target=Base::member*/ member
+ /*@ target=Object::== */ ??= /*@ typeArgs=B* */ f();
+
+ super. /*@target=Base::member*/ /*@target=Base::member*/ member
+ /*@ target=B::+ */ += /*@ typeArgs=C* */ f();
+
+ super. /*@target=Base::member*/ /*@target=Base::member*/ member
+ /*@ target=B::* */ *= /*@ typeArgs=B* */ f();
+
+ super. /*@target=Base::member*/ /*@target=Base::member*/ member
+ /*@ target=B::& */ &= /*@ typeArgs=A* */ f();
+
+ /*@ target=B::- */ --super
+ . /*@target=Base::member*/ /*@target=Base::member*/ member;
+
+ super. /*@target=Base::member*/ /*@target=Base::member*/ member
+ /*@ target=B::- */ --;
+
var /*@ type=B* */ v1 =
super. /*@target=Base::member*/ member = /*@ typeArgs=B* */ f();
+
var /*@ type=B* */ v2 =
- super. /*@target=Base::member*/ member ??= /*@ typeArgs=B* */ f();
+ super. /*@target=Base::member*/ /*@target=Base::member*/ member
+ /*@ target=Object::== */ ??= /*@ typeArgs=B* */ f();
+
var /*@ type=A* */ v3 =
- super. /*@target=Base::member*/ member += /*@ typeArgs=dynamic */ f();
+ super. /*@target=Base::member*/ /*@target=Base::member*/ member
+ /*@ target=B::+ */ += /*@ typeArgs=C* */ f();
+
var /*@ type=B* */ v4 =
- super. /*@target=Base::member*/ member *= /*@ typeArgs=dynamic */ f();
+ super. /*@target=Base::member*/ /*@target=Base::member*/ member
+ /*@ target=B::* */ *= /*@ typeArgs=B* */ f();
+
var /*@ type=C* */ v5 =
- super. /*@target=Base::member*/ member &= /*@ typeArgs=dynamic */ f();
- var /*@ type=B* */ v6 = --super. /*@target=Base::member*/ member;
- var /*@ type=B* */ v7 = super. /*@target=Base::member*/ member--;
+ super. /*@target=Base::member*/ /*@target=Base::member*/ member
+ /*@ target=B::& */ &= /*@ typeArgs=A* */ f();
+
+ var /*@ type=B* */ v6 = /*@ target=B::- */ --super
+ .
+ /*@target=Base::member*/ /*@target=Base::member*/ member;
+
+ var /*@ type=B* */ v7 = super
+ .
+ /*@ type=B* */ /*@target=Base::member*/ /*@target=Base::member*/
+ member
+ /*@ type=B* */ /*@ target=B::- */ --;
}
}
diff --git a/pkg/front_end/testcases/inference_new/infer_assign_to_property_super.dart.strong.expect b/pkg/front_end/testcases/inference_new/infer_assign_to_property_super.dart.strong.expect
index 18c1122..eb317ce 100644
--- a/pkg/front_end/testcases/inference_new/infer_assign_to_property_super.dart.strong.expect
+++ b/pkg/front_end/testcases/inference_new/infer_assign_to_property_super.dart.strong.expect
@@ -38,16 +38,16 @@
method test() → void {
super.{self::Base::member} = self::f<self::B*>();
super.{self::Base::member}.{core::Object::==}(null) ?{self::B*} super.{self::Base::member} = self::f<self::B*>() : null;
- super.{self::Base::member} = super.{self::Base::member}.{self::B::+}(self::f<dynamic>() as{TypeError} self::C*) as{TypeError} self::B*;
- super.{self::Base::member} = super.{self::Base::member}.{self::B::*}(self::f<dynamic>() as{TypeError} self::B*);
- super.{self::Base::member} = super.{self::Base::member}.{self::B::&}(self::f<dynamic>() as{TypeError} self::A*);
+ super.{self::Base::member} = super.{self::Base::member}.{self::B::+}(self::f<self::C*>()) as{TypeError} self::B*;
+ super.{self::Base::member} = super.{self::Base::member}.{self::B::*}(self::f<self::B*>());
+ super.{self::Base::member} = super.{self::Base::member}.{self::B::&}(self::f<self::A*>());
super.{self::Base::member} = super.{self::Base::member}.{self::B::-}(1);
super.{self::Base::member} = super.{self::Base::member}.{self::B::-}(1);
self::B* v1 = super.{self::Base::member} = self::f<self::B*>();
self::B* v2 = let final self::B* #t1 = super.{self::Base::member} in #t1.{core::Object::==}(null) ?{self::B*} super.{self::Base::member} = self::f<self::B*>() : #t1;
- self::A* v3 = super.{self::Base::member} = super.{self::Base::member}.{self::B::+}(self::f<dynamic>() as{TypeError} self::C*) as{TypeError} self::B*;
- self::B* v4 = super.{self::Base::member} = super.{self::Base::member}.{self::B::*}(self::f<dynamic>() as{TypeError} self::B*);
- self::C* v5 = super.{self::Base::member} = super.{self::Base::member}.{self::B::&}(self::f<dynamic>() as{TypeError} self::A*);
+ self::A* v3 = super.{self::Base::member} = super.{self::Base::member}.{self::B::+}(self::f<self::C*>()) as{TypeError} self::B*;
+ self::B* v4 = super.{self::Base::member} = super.{self::Base::member}.{self::B::*}(self::f<self::B*>());
+ self::C* v5 = super.{self::Base::member} = super.{self::Base::member}.{self::B::&}(self::f<self::A*>());
self::B* v6 = super.{self::Base::member} = super.{self::Base::member}.{self::B::-}(1);
self::B* v7 = let final self::B* #t2 = super.{self::Base::member} in let final self::B* #t3 = super.{self::Base::member} = #t2.{self::B::-}(1) in #t2;
}
diff --git a/pkg/front_end/testcases/inference_new/infer_assign_to_property_super.dart.strong.transformed.expect b/pkg/front_end/testcases/inference_new/infer_assign_to_property_super.dart.strong.transformed.expect
index 18c1122..eb317ce 100644
--- a/pkg/front_end/testcases/inference_new/infer_assign_to_property_super.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference_new/infer_assign_to_property_super.dart.strong.transformed.expect
@@ -38,16 +38,16 @@
method test() → void {
super.{self::Base::member} = self::f<self::B*>();
super.{self::Base::member}.{core::Object::==}(null) ?{self::B*} super.{self::Base::member} = self::f<self::B*>() : null;
- super.{self::Base::member} = super.{self::Base::member}.{self::B::+}(self::f<dynamic>() as{TypeError} self::C*) as{TypeError} self::B*;
- super.{self::Base::member} = super.{self::Base::member}.{self::B::*}(self::f<dynamic>() as{TypeError} self::B*);
- super.{self::Base::member} = super.{self::Base::member}.{self::B::&}(self::f<dynamic>() as{TypeError} self::A*);
+ super.{self::Base::member} = super.{self::Base::member}.{self::B::+}(self::f<self::C*>()) as{TypeError} self::B*;
+ super.{self::Base::member} = super.{self::Base::member}.{self::B::*}(self::f<self::B*>());
+ super.{self::Base::member} = super.{self::Base::member}.{self::B::&}(self::f<self::A*>());
super.{self::Base::member} = super.{self::Base::member}.{self::B::-}(1);
super.{self::Base::member} = super.{self::Base::member}.{self::B::-}(1);
self::B* v1 = super.{self::Base::member} = self::f<self::B*>();
self::B* v2 = let final self::B* #t1 = super.{self::Base::member} in #t1.{core::Object::==}(null) ?{self::B*} super.{self::Base::member} = self::f<self::B*>() : #t1;
- self::A* v3 = super.{self::Base::member} = super.{self::Base::member}.{self::B::+}(self::f<dynamic>() as{TypeError} self::C*) as{TypeError} self::B*;
- self::B* v4 = super.{self::Base::member} = super.{self::Base::member}.{self::B::*}(self::f<dynamic>() as{TypeError} self::B*);
- self::C* v5 = super.{self::Base::member} = super.{self::Base::member}.{self::B::&}(self::f<dynamic>() as{TypeError} self::A*);
+ self::A* v3 = super.{self::Base::member} = super.{self::Base::member}.{self::B::+}(self::f<self::C*>()) as{TypeError} self::B*;
+ self::B* v4 = super.{self::Base::member} = super.{self::Base::member}.{self::B::*}(self::f<self::B*>());
+ self::C* v5 = super.{self::Base::member} = super.{self::Base::member}.{self::B::&}(self::f<self::A*>());
self::B* v6 = super.{self::Base::member} = super.{self::Base::member}.{self::B::-}(1);
self::B* v7 = let final self::B* #t2 = super.{self::Base::member} in let final self::B* #t3 = super.{self::Base::member} = #t2.{self::B::-}(1) in #t2;
}
diff --git a/pkg/front_end/testcases/inference_new/infer_assign_to_property_super_upwards.dart b/pkg/front_end/testcases/inference_new/infer_assign_to_property_super_upwards.dart
index 470276a..d236e96 100644
--- a/pkg/front_end/testcases/inference_new/infer_assign_to_property_super_upwards.dart
+++ b/pkg/front_end/testcases/inference_new/infer_assign_to_property_super_upwards.dart
@@ -17,37 +17,79 @@
class Test1 extends Base {
void test() {
- var /*@ type=int* */ v1 = super. /*@target=Base::intProp*/ intProp = getInt();
- var /*@ type=num* */ v2 = super. /*@target=Base::intProp*/ intProp = getNum();
+ var /*@ type=int* */ v1 =
+ super. /*@target=Base::intProp*/ intProp = getInt();
+
+ var /*@ type=num* */ v2 =
+ super. /*@target=Base::intProp*/ intProp = getNum();
+
var /*@ type=int* */ v4 =
- super. /*@target=Base::intProp*/ intProp ??= getInt();
+ super. /*@target=Base::intProp*/ /*@target=Base::intProp*/ intProp
+ /*@ target=num::== */ ??= getInt();
+
var /*@ type=num* */ v5 =
- super. /*@target=Base::intProp*/ intProp ??= getNum();
- var /*@ type=int* */ v7 = super. /*@target=Base::intProp*/ intProp += getInt();
- var /*@ type=num* */ v8 = super. /*@target=Base::intProp*/ intProp += getNum();
- var /*@ type=int* */ v10 = ++super. /*@target=Base::intProp*/ intProp;
- var /*@ type=int* */ v11 = super. /*@target=Base::intProp*/ intProp++;
+ super. /*@target=Base::intProp*/ /*@target=Base::intProp*/ intProp
+ /*@ target=num::== */ ??= getNum();
+
+ var /*@ type=int* */ v7 =
+ super. /*@target=Base::intProp*/ /*@target=Base::intProp*/ intProp
+ /*@ target=num::+ */ += getInt();
+
+ var /*@ type=num* */ v8 =
+ super. /*@target=Base::intProp*/ /*@target=Base::intProp*/ intProp
+ /*@ target=num::+ */ += getNum();
+
+ var /*@ type=int* */ v10 = /*@ target=num::+ */ ++super
+ . /*@target=Base::intProp*/ /*@target=Base::intProp*/ intProp;
+
+ var /*@ type=int* */ v11 = super
+ . /*@ type=int* */ /*@target=Base::intProp*/ /*@target=Base::intProp*/
+ intProp
+ /*@ type=int* */ /*@ target=num::+ */ ++;
}
}
class Test2 extends Base {
void test() {
- var /*@ type=int* */ v1 = super. /*@target=Base::numProp*/ numProp = getInt();
- var /*@ type=num* */ v2 = super. /*@target=Base::numProp*/ numProp = getNum();
+ var /*@ type=int* */ v1 =
+ super. /*@target=Base::numProp*/ numProp = getInt();
+
+ var /*@ type=num* */ v2 =
+ super. /*@target=Base::numProp*/ numProp = getNum();
+
var /*@ type=double* */ v3 =
super. /*@target=Base::numProp*/ numProp = getDouble();
+
var /*@ type=num* */ v4 =
- super. /*@target=Base::numProp*/ numProp ??= getInt();
+ super. /*@target=Base::numProp*/ /*@target=Base::numProp*/ numProp
+ /*@ target=num::== */ ??= getInt();
+
var /*@ type=num* */ v5 =
- super. /*@target=Base::numProp*/ numProp ??= getNum();
+ super. /*@target=Base::numProp*/ /*@target=Base::numProp*/ numProp
+ /*@ target=num::== */ ??= getNum();
+
var /*@ type=num* */ v6 =
- super. /*@target=Base::numProp*/ numProp ??= getDouble();
- var /*@ type=num* */ v7 = super. /*@target=Base::numProp*/ numProp += getInt();
- var /*@ type=num* */ v8 = super. /*@target=Base::numProp*/ numProp += getNum();
+ super. /*@target=Base::numProp*/ /*@target=Base::numProp*/ numProp
+ /*@ target=num::== */ ??= getDouble();
+
+ var /*@ type=num* */ v7 =
+ super. /*@target=Base::numProp*/ /*@target=Base::numProp*/ numProp
+ /*@ target=num::+ */ += getInt();
+
+ var /*@ type=num* */ v8 =
+ super. /*@target=Base::numProp*/ /*@target=Base::numProp*/ numProp
+ /*@ target=num::+ */ += getNum();
+
var /*@ type=num* */ v9 =
- super. /*@target=Base::numProp*/ numProp += getDouble();
- var /*@ type=num* */ v10 = ++super. /*@target=Base::numProp*/ numProp;
- var /*@ type=num* */ v11 = super. /*@target=Base::numProp*/ numProp++;
+ super. /*@target=Base::numProp*/ /*@target=Base::numProp*/ numProp
+ /*@ target=num::+ */ += getDouble();
+
+ var /*@ type=num* */ v10 = /*@ target=num::+ */ ++super
+ . /*@target=Base::numProp*/ /*@target=Base::numProp*/ numProp;
+
+ var /*@ type=num* */ v11 = super
+ . /*@ type=num* */ /*@target=Base::numProp*/ /*@target=Base::numProp*/
+ numProp /*@ type=num* */ /*@ target=num::+ */ ++;
}
}
@@ -55,20 +97,38 @@
void test3() {
var /*@ type=num* */ v2 =
super. /*@target=Base::doubleProp*/ doubleProp = getNum();
+
var /*@ type=double* */ v3 =
super. /*@target=Base::doubleProp*/ doubleProp = getDouble();
- var /*@ type=num* */ v5 =
- super. /*@target=Base::doubleProp*/ doubleProp ??= getNum();
- var /*@ type=double* */ v6 =
- super. /*@target=Base::doubleProp*/ doubleProp ??= getDouble();
- var /*@ type=double* */ v7 =
- super. /*@target=Base::doubleProp*/ doubleProp += getInt();
- var /*@ type=double* */ v8 =
- super. /*@target=Base::doubleProp*/ doubleProp += getNum();
- var /*@ type=double* */ v9 =
- super. /*@target=Base::doubleProp*/ doubleProp += getDouble();
- var /*@ type=double* */ v10 = ++super. /*@target=Base::doubleProp*/ doubleProp;
- var /*@ type=double* */ v11 = super. /*@target=Base::doubleProp*/ doubleProp++;
+
+ var /*@ type=num* */ v5 = super
+ . /*@target=Base::doubleProp*/ /*@target=Base::doubleProp*/ doubleProp
+ /*@ target=num::== */ ??= getNum();
+
+ var /*@ type=double* */ v6 = super
+ . /*@target=Base::doubleProp*/ /*@target=Base::doubleProp*/ doubleProp
+ /*@ target=num::== */ ??= getDouble();
+
+ var /*@ type=double* */ v7 = super
+ . /*@target=Base::doubleProp*/ /*@target=Base::doubleProp*/
+ doubleProp /*@ target=double::+ */ += getInt();
+
+ var /*@ type=double* */ v8 = super
+ . /*@target=Base::doubleProp*/ /*@target=Base::doubleProp*/
+ doubleProp /*@ target=double::+ */ += getNum();
+
+ var /*@ type=double* */ v9 = super
+ . /*@target=Base::doubleProp*/ /*@target=Base::doubleProp*/
+ doubleProp /*@ target=double::+ */ += getDouble();
+
+ var /*@ type=double* */ v10 =
+ /*@ target=double::+ */ ++super
+ . /*@target=Base::doubleProp*/ /*@target=Base::doubleProp*/
+ doubleProp;
+
+ var /*@ type=double* */ v11 = super
+ . /*@ type=double* */ /*@target=Base::doubleProp*/ /*@target=Base::doubleProp*/
+ doubleProp /*@ type=double* */ /*@ target=double::+ */ ++;
}
}
diff --git a/pkg/front_end/testcases/inference_new/infer_assign_to_property_upwards.dart b/pkg/front_end/testcases/inference_new/infer_assign_to_property_upwards.dart
index 5ade9c5..502a144 100644
--- a/pkg/front_end/testcases/inference_new/infer_assign_to_property_upwards.dart
+++ b/pkg/front_end/testcases/inference_new/infer_assign_to_property_upwards.dart
@@ -15,12 +15,24 @@
static void test(Test1 t) {
var /*@ type=int* */ v1 = t. /*@target=Test1::prop*/ prop = getInt();
var /*@ type=num* */ v2 = t. /*@target=Test1::prop*/ prop = getNum();
- var /*@ type=int* */ v4 = t. /*@target=Test1::prop*/ prop ??= getInt();
- var /*@ type=num* */ v5 = t. /*@target=Test1::prop*/ prop ??= getNum();
- var /*@ type=int* */ v7 = t. /*@target=Test1::prop*/ prop += getInt();
- var /*@ type=num* */ v8 = t. /*@target=Test1::prop*/ prop += getNum();
- var /*@ type=int* */ v10 = ++t. /*@target=Test1::prop*/ prop;
- var /*@ type=int* */ v11 = t. /*@target=Test1::prop*/ prop++;
+ var /*@ type=int* */ v4 = /*@ type=Test1* */ t
+ . /*@target=Test1::prop*/ /*@target=Test1::prop*/ prop
+ /*@target=num::==*/ ??= getInt();
+ var /*@ type=num* */ v5 = /*@ type=Test1* */ t
+ . /*@target=Test1::prop*/ /*@target=Test1::prop*/ prop
+ /*@target=num::==*/ ??= getNum();
+ var /*@ type=int* */ v7 = /*@ type=Test1* */ t
+ . /*@target=Test1::prop*/ /*@target=Test1::prop*/ prop
+ /*@ target=num::+ */ += getInt();
+ var /*@ type=num* */ v8 = /*@ type=Test1* */ t
+ . /*@target=Test1::prop*/ /*@target=Test1::prop*/ prop
+ /*@ target=num::+ */ += getNum();
+ var /*@ type=int* */ v10 = /*@ target=num::+ */ ++ /*@ type=Test1* */ t
+ . /*@target=Test1::prop*/ /*@target=Test1::prop*/ prop;
+ var /*@ type=int* */ v11 =
+ /*@ type=Test1* */ t
+ . /*@ type=int* */ /*@target=Test1::prop*/ /*@target=Test1::prop*/
+ prop /*@ type=int* */ /*@ target=num::+ */ ++;
}
}
@@ -31,14 +43,30 @@
var /*@ type=int* */ v1 = t. /*@target=Test2::prop*/ prop = getInt();
var /*@ type=num* */ v2 = t. /*@target=Test2::prop*/ prop = getNum();
var /*@ type=double* */ v3 = t. /*@target=Test2::prop*/ prop = getDouble();
- var /*@ type=num* */ v4 = t. /*@target=Test2::prop*/ prop ??= getInt();
- var /*@ type=num* */ v5 = t. /*@target=Test2::prop*/ prop ??= getNum();
- var /*@ type=num* */ v6 = t. /*@target=Test2::prop*/ prop ??= getDouble();
- var /*@ type=num* */ v7 = t. /*@target=Test2::prop*/ prop += getInt();
- var /*@ type=num* */ v8 = t. /*@target=Test2::prop*/ prop += getNum();
- var /*@ type=num* */ v9 = t. /*@target=Test2::prop*/ prop += getDouble();
- var /*@ type=num* */ v10 = ++t. /*@target=Test2::prop*/ prop;
- var /*@ type=num* */ v11 = t. /*@target=Test2::prop*/ prop++;
+ var /*@ type=num* */ v4 = /*@ type=Test2* */ t
+ . /*@target=Test2::prop*/ /*@target=Test2::prop*/ prop
+ /*@target=num::==*/ ??= getInt();
+ var /*@ type=num* */ v5 = /*@ type=Test2* */ t
+ . /*@target=Test2::prop*/ /*@target=Test2::prop*/ prop
+ /*@target=num::==*/ ??= getNum();
+ var /*@ type=num* */ v6 = /*@ type=Test2* */ t
+ . /*@target=Test2::prop*/ /*@target=Test2::prop*/ prop
+ /*@target=num::==*/ ??= getDouble();
+ var /*@ type=num* */ v7 = /*@ type=Test2* */ t
+ . /*@target=Test2::prop*/ /*@target=Test2::prop*/ prop
+ /*@ target=num::+ */ += getInt();
+ var /*@ type=num* */ v8 = /*@ type=Test2* */ t
+ . /*@target=Test2::prop*/ /*@target=Test2::prop*/ prop
+ /*@ target=num::+ */ += getNum();
+ var /*@ type=num* */ v9 = /*@ type=Test2* */ t
+ . /*@target=Test2::prop*/ /*@target=Test2::prop*/ prop
+ /*@ target=num::+ */ += getDouble();
+ var /*@ type=num* */ v10 = /*@ target=num::+ */ ++ /*@ type=Test2* */ t
+ . /*@target=Test2::prop*/ /*@target=Test2::prop*/ prop;
+ var /*@ type=num* */ v11 =
+ /*@ type=Test2* */ t
+ . /*@ type=num* */ /*@target=Test2::prop*/ /*@target=Test2::prop*/
+ prop /*@ type=num* */ /*@ target=num::+ */ ++;
}
}
@@ -48,13 +76,27 @@
static void test3(Test3 t) {
var /*@ type=num* */ v2 = t. /*@target=Test3::prop*/ prop = getNum();
var /*@ type=double* */ v3 = t. /*@target=Test3::prop*/ prop = getDouble();
- var /*@ type=num* */ v5 = t. /*@target=Test3::prop*/ prop ??= getNum();
- var /*@ type=double* */ v6 = t. /*@target=Test3::prop*/ prop ??= getDouble();
- var /*@ type=double* */ v7 = t. /*@target=Test3::prop*/ prop += getInt();
- var /*@ type=double* */ v8 = t. /*@target=Test3::prop*/ prop += getNum();
- var /*@ type=double* */ v9 = t. /*@target=Test3::prop*/ prop += getDouble();
- var /*@ type=double* */ v10 = ++t. /*@target=Test3::prop*/ prop;
- var /*@ type=double* */ v11 = t. /*@target=Test3::prop*/ prop++;
+ var /*@ type=num* */ v5 = /*@ type=Test3* */ t
+ . /*@target=Test3::prop*/ /*@target=Test3::prop*/ prop
+ /*@target=num::==*/ ??= getNum();
+ var /*@ type=double* */ v6 = /*@ type=Test3* */ t
+ . /*@target=Test3::prop*/ /*@target=Test3::prop*/ prop
+ /*@target=num::==*/ ??= getDouble();
+ var /*@ type=double* */ v7 = /*@ type=Test3* */ t
+ . /*@target=Test3::prop*/ /*@target=Test3::prop*/ prop
+ /*@ target=double::+ */ += getInt();
+ var /*@ type=double* */ v8 = /*@ type=Test3* */ t
+ . /*@target=Test3::prop*/ /*@target=Test3::prop*/ prop
+ /*@ target=double::+ */ += getNum();
+ var /*@ type=double* */ v9 = /*@ type=Test3* */ t
+ . /*@target=Test3::prop*/ /*@target=Test3::prop*/ prop
+ /*@ target=double::+ */ += getDouble();
+ var /*@ type=double* */ v10 = /*@ target=double::+ */ ++ /*@ type=Test3* */ t
+ . /*@target=Test3::prop*/ /*@target=Test3::prop*/ prop;
+ var /*@ type=double* */ v11 =
+ /*@ type=Test3* */ t
+ . /*@ type=double* */ /*@target=Test3::prop*/ /*@target=Test3::prop*/
+ prop /*@ type=double* */ /*@ target=double::+ */ ++;
}
}
diff --git a/pkg/front_end/testcases/inference_new/infer_assign_to_static.dart b/pkg/front_end/testcases/inference_new/infer_assign_to_static.dart
index 1a832b3..33bd5fe 100644
--- a/pkg/front_end/testcases/inference_new/infer_assign_to_static.dart
+++ b/pkg/front_end/testcases/inference_new/infer_assign_to_static.dart
@@ -24,36 +24,72 @@
void test_topLevelVariable() {
topLevelVariable = /*@ typeArgs=B* */ f();
- topLevelVariable ??= /*@ typeArgs=B* */ f();
- topLevelVariable += /*@ typeArgs=dynamic */ f();
- topLevelVariable *= /*@ typeArgs=dynamic */ f();
- topLevelVariable &= /*@ typeArgs=dynamic */ f();
- --topLevelVariable;
- topLevelVariable--;
+
+ topLevelVariable /*@ target=Object::== */ ??= /*@ typeArgs=B* */ f();
+
+ topLevelVariable /*@ target=B::+ */ += /*@ typeArgs=C* */ f();
+
+ topLevelVariable /*@ target=B::* */ *= /*@ typeArgs=B* */ f();
+
+ topLevelVariable /*@ target=B::& */ &= /*@ typeArgs=A* */ f();
+
+ /*@ target=B::- */ --topLevelVariable;
+
+ topLevelVariable /*@ target=B::- */ --;
+
var /*@ type=B* */ v1 = topLevelVariable = /*@ typeArgs=B* */ f();
- var /*@ type=B* */ v2 = topLevelVariable ??= /*@ typeArgs=B* */ f();
- var /*@ type=A* */ v3 = topLevelVariable += /*@ typeArgs=dynamic */ f();
- var /*@ type=B* */ v4 = topLevelVariable *= /*@ typeArgs=dynamic */ f();
- var /*@ type=C* */ v5 = topLevelVariable &= /*@ typeArgs=dynamic */ f();
- var /*@ type=B* */ v6 = --topLevelVariable;
- var /*@ type=B* */ v7 = topLevelVariable--;
+
+ var /*@ type=B* */ v2 =
+ topLevelVariable /*@ target=Object::== */ ??= /*@ typeArgs=B* */ f();
+
+ var /*@ type=A* */ v3 =
+ topLevelVariable /*@ target=B::+ */ += /*@ typeArgs=C* */ f();
+
+ var /*@ type=B* */ v4 =
+ topLevelVariable /*@ target=B::* */ *= /*@ typeArgs=B* */ f();
+
+ var /*@ type=C* */ v5 =
+ topLevelVariable /*@ target=B::& */ &= /*@ typeArgs=A* */ f();
+
+ var /*@ type=B* */ v6 = /*@ target=B::- */ --topLevelVariable;
+
+ var /*@ type=B* */ v7 = /*@ type=B* */ topLevelVariable
+ /*@ type=B* */ /*@ target=B::- */ --;
}
void test_staticVariable() {
B.staticVariable = /*@ typeArgs=B* */ f();
- B.staticVariable ??= /*@ typeArgs=B* */ f();
- B.staticVariable += /*@ typeArgs=dynamic */ f();
- B.staticVariable *= /*@ typeArgs=dynamic */ f();
- B.staticVariable &= /*@ typeArgs=dynamic */ f();
- --B.staticVariable;
- B.staticVariable--;
+
+ B.staticVariable /*@ target=Object::== */ ??= /*@ typeArgs=B* */ f();
+
+ B.staticVariable /*@ target=B::+ */ += /*@ typeArgs=C* */ f();
+
+ B.staticVariable /*@ target=B::* */ *= /*@ typeArgs=B* */ f();
+
+ B.staticVariable /*@ target=B::& */ &= /*@ typeArgs=A* */ f();
+
+ /*@ target=B::- */ --B.staticVariable;
+
+ B.staticVariable /*@ target=B::- */ --;
+
var /*@ type=B* */ v1 = B.staticVariable = /*@ typeArgs=B* */ f();
- var /*@ type=B* */ v2 = B.staticVariable ??= /*@ typeArgs=B* */ f();
- var /*@ type=A* */ v3 = B.staticVariable += /*@ typeArgs=dynamic */ f();
- var /*@ type=B* */ v4 = B.staticVariable *= /*@ typeArgs=dynamic */ f();
- var /*@ type=C* */ v5 = B.staticVariable &= /*@ typeArgs=dynamic */ f();
- var /*@ type=B* */ v6 = --B.staticVariable;
- var /*@ type=B* */ v7 = B.staticVariable--;
+
+ var /*@ type=B* */ v2 =
+ B.staticVariable /*@ target=Object::== */ ??= /*@ typeArgs=B* */ f();
+
+ var /*@ type=A* */ v3 =
+ B.staticVariable /*@ target=B::+ */ += /*@ typeArgs=C* */ f();
+
+ var /*@ type=B* */ v4 =
+ B.staticVariable /*@ target=B::* */ *= /*@ typeArgs=B* */ f();
+
+ var /*@ type=C* */ v5 =
+ B.staticVariable /*@ target=B::& */ &= /*@ typeArgs=A* */ f();
+
+ var /*@ type=B* */ v6 = /*@ target=B::- */ --B.staticVariable;
+
+ var /*@ type=B* */ v7 =
+ B. /*@ type=B* */ staticVariable /*@ type=B* */ /*@ target=B::- */ --;
}
main() {}
diff --git a/pkg/front_end/testcases/inference_new/infer_assign_to_static.dart.strong.expect b/pkg/front_end/testcases/inference_new/infer_assign_to_static.dart.strong.expect
index 00189a5..2c07ffd 100644
--- a/pkg/front_end/testcases/inference_new/infer_assign_to_static.dart.strong.expect
+++ b/pkg/front_end/testcases/inference_new/infer_assign_to_static.dart.strong.expect
@@ -32,32 +32,32 @@
static method test_topLevelVariable() → void {
self::topLevelVariable = self::f<self::B*>();
self::topLevelVariable.{core::Object::==}(null) ?{self::B*} self::topLevelVariable = self::f<self::B*>() : null;
- self::topLevelVariable = self::topLevelVariable.{self::B::+}(self::f<dynamic>() as{TypeError} self::C*) as{TypeError} self::B*;
- self::topLevelVariable = self::topLevelVariable.{self::B::*}(self::f<dynamic>() as{TypeError} self::B*);
- self::topLevelVariable = self::topLevelVariable.{self::B::&}(self::f<dynamic>() as{TypeError} self::A*);
+ self::topLevelVariable = self::topLevelVariable.{self::B::+}(self::f<self::C*>()) as{TypeError} self::B*;
+ self::topLevelVariable = self::topLevelVariable.{self::B::*}(self::f<self::B*>());
+ self::topLevelVariable = self::topLevelVariable.{self::B::&}(self::f<self::A*>());
self::topLevelVariable = self::topLevelVariable.{self::B::-}(1);
self::topLevelVariable = self::topLevelVariable.{self::B::-}(1);
self::B* v1 = self::topLevelVariable = self::f<self::B*>();
self::B* v2 = let final self::B* #t1 = self::topLevelVariable in #t1.{core::Object::==}(null) ?{self::B*} self::topLevelVariable = self::f<self::B*>() : #t1;
- self::A* v3 = self::topLevelVariable = self::topLevelVariable.{self::B::+}(self::f<dynamic>() as{TypeError} self::C*) as{TypeError} self::B*;
- self::B* v4 = self::topLevelVariable = self::topLevelVariable.{self::B::*}(self::f<dynamic>() as{TypeError} self::B*);
- self::C* v5 = self::topLevelVariable = self::topLevelVariable.{self::B::&}(self::f<dynamic>() as{TypeError} self::A*);
+ self::A* v3 = self::topLevelVariable = self::topLevelVariable.{self::B::+}(self::f<self::C*>()) as{TypeError} self::B*;
+ self::B* v4 = self::topLevelVariable = self::topLevelVariable.{self::B::*}(self::f<self::B*>());
+ self::C* v5 = self::topLevelVariable = self::topLevelVariable.{self::B::&}(self::f<self::A*>());
self::B* v6 = self::topLevelVariable = self::topLevelVariable.{self::B::-}(1);
self::B* v7 = let final self::B* #t2 = self::topLevelVariable in let final self::B* #t3 = self::topLevelVariable = #t2.{self::B::-}(1) in #t2;
}
static method test_staticVariable() → void {
self::B::staticVariable = self::f<self::B*>();
self::B::staticVariable.{core::Object::==}(null) ?{self::B*} self::B::staticVariable = self::f<self::B*>() : null;
- self::B::staticVariable = self::B::staticVariable.{self::B::+}(self::f<dynamic>() as{TypeError} self::C*) as{TypeError} self::B*;
- self::B::staticVariable = self::B::staticVariable.{self::B::*}(self::f<dynamic>() as{TypeError} self::B*);
- self::B::staticVariable = self::B::staticVariable.{self::B::&}(self::f<dynamic>() as{TypeError} self::A*);
+ self::B::staticVariable = self::B::staticVariable.{self::B::+}(self::f<self::C*>()) as{TypeError} self::B*;
+ self::B::staticVariable = self::B::staticVariable.{self::B::*}(self::f<self::B*>());
+ self::B::staticVariable = self::B::staticVariable.{self::B::&}(self::f<self::A*>());
self::B::staticVariable = self::B::staticVariable.{self::B::-}(1);
self::B::staticVariable = self::B::staticVariable.{self::B::-}(1);
self::B* v1 = self::B::staticVariable = self::f<self::B*>();
self::B* v2 = let final self::B* #t4 = self::B::staticVariable in #t4.{core::Object::==}(null) ?{self::B*} self::B::staticVariable = self::f<self::B*>() : #t4;
- self::A* v3 = self::B::staticVariable = self::B::staticVariable.{self::B::+}(self::f<dynamic>() as{TypeError} self::C*) as{TypeError} self::B*;
- self::B* v4 = self::B::staticVariable = self::B::staticVariable.{self::B::*}(self::f<dynamic>() as{TypeError} self::B*);
- self::C* v5 = self::B::staticVariable = self::B::staticVariable.{self::B::&}(self::f<dynamic>() as{TypeError} self::A*);
+ self::A* v3 = self::B::staticVariable = self::B::staticVariable.{self::B::+}(self::f<self::C*>()) as{TypeError} self::B*;
+ self::B* v4 = self::B::staticVariable = self::B::staticVariable.{self::B::*}(self::f<self::B*>());
+ self::C* v5 = self::B::staticVariable = self::B::staticVariable.{self::B::&}(self::f<self::A*>());
self::B* v6 = self::B::staticVariable = self::B::staticVariable.{self::B::-}(1);
self::B* v7 = let final self::B* #t5 = self::B::staticVariable in let final self::B* #t6 = self::B::staticVariable = #t5.{self::B::-}(1) in #t5;
}
diff --git a/pkg/front_end/testcases/inference_new/infer_assign_to_static.dart.strong.transformed.expect b/pkg/front_end/testcases/inference_new/infer_assign_to_static.dart.strong.transformed.expect
index 00189a5..2c07ffd 100644
--- a/pkg/front_end/testcases/inference_new/infer_assign_to_static.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference_new/infer_assign_to_static.dart.strong.transformed.expect
@@ -32,32 +32,32 @@
static method test_topLevelVariable() → void {
self::topLevelVariable = self::f<self::B*>();
self::topLevelVariable.{core::Object::==}(null) ?{self::B*} self::topLevelVariable = self::f<self::B*>() : null;
- self::topLevelVariable = self::topLevelVariable.{self::B::+}(self::f<dynamic>() as{TypeError} self::C*) as{TypeError} self::B*;
- self::topLevelVariable = self::topLevelVariable.{self::B::*}(self::f<dynamic>() as{TypeError} self::B*);
- self::topLevelVariable = self::topLevelVariable.{self::B::&}(self::f<dynamic>() as{TypeError} self::A*);
+ self::topLevelVariable = self::topLevelVariable.{self::B::+}(self::f<self::C*>()) as{TypeError} self::B*;
+ self::topLevelVariable = self::topLevelVariable.{self::B::*}(self::f<self::B*>());
+ self::topLevelVariable = self::topLevelVariable.{self::B::&}(self::f<self::A*>());
self::topLevelVariable = self::topLevelVariable.{self::B::-}(1);
self::topLevelVariable = self::topLevelVariable.{self::B::-}(1);
self::B* v1 = self::topLevelVariable = self::f<self::B*>();
self::B* v2 = let final self::B* #t1 = self::topLevelVariable in #t1.{core::Object::==}(null) ?{self::B*} self::topLevelVariable = self::f<self::B*>() : #t1;
- self::A* v3 = self::topLevelVariable = self::topLevelVariable.{self::B::+}(self::f<dynamic>() as{TypeError} self::C*) as{TypeError} self::B*;
- self::B* v4 = self::topLevelVariable = self::topLevelVariable.{self::B::*}(self::f<dynamic>() as{TypeError} self::B*);
- self::C* v5 = self::topLevelVariable = self::topLevelVariable.{self::B::&}(self::f<dynamic>() as{TypeError} self::A*);
+ self::A* v3 = self::topLevelVariable = self::topLevelVariable.{self::B::+}(self::f<self::C*>()) as{TypeError} self::B*;
+ self::B* v4 = self::topLevelVariable = self::topLevelVariable.{self::B::*}(self::f<self::B*>());
+ self::C* v5 = self::topLevelVariable = self::topLevelVariable.{self::B::&}(self::f<self::A*>());
self::B* v6 = self::topLevelVariable = self::topLevelVariable.{self::B::-}(1);
self::B* v7 = let final self::B* #t2 = self::topLevelVariable in let final self::B* #t3 = self::topLevelVariable = #t2.{self::B::-}(1) in #t2;
}
static method test_staticVariable() → void {
self::B::staticVariable = self::f<self::B*>();
self::B::staticVariable.{core::Object::==}(null) ?{self::B*} self::B::staticVariable = self::f<self::B*>() : null;
- self::B::staticVariable = self::B::staticVariable.{self::B::+}(self::f<dynamic>() as{TypeError} self::C*) as{TypeError} self::B*;
- self::B::staticVariable = self::B::staticVariable.{self::B::*}(self::f<dynamic>() as{TypeError} self::B*);
- self::B::staticVariable = self::B::staticVariable.{self::B::&}(self::f<dynamic>() as{TypeError} self::A*);
+ self::B::staticVariable = self::B::staticVariable.{self::B::+}(self::f<self::C*>()) as{TypeError} self::B*;
+ self::B::staticVariable = self::B::staticVariable.{self::B::*}(self::f<self::B*>());
+ self::B::staticVariable = self::B::staticVariable.{self::B::&}(self::f<self::A*>());
self::B::staticVariable = self::B::staticVariable.{self::B::-}(1);
self::B::staticVariable = self::B::staticVariable.{self::B::-}(1);
self::B* v1 = self::B::staticVariable = self::f<self::B*>();
self::B* v2 = let final self::B* #t4 = self::B::staticVariable in #t4.{core::Object::==}(null) ?{self::B*} self::B::staticVariable = self::f<self::B*>() : #t4;
- self::A* v3 = self::B::staticVariable = self::B::staticVariable.{self::B::+}(self::f<dynamic>() as{TypeError} self::C*) as{TypeError} self::B*;
- self::B* v4 = self::B::staticVariable = self::B::staticVariable.{self::B::*}(self::f<dynamic>() as{TypeError} self::B*);
- self::C* v5 = self::B::staticVariable = self::B::staticVariable.{self::B::&}(self::f<dynamic>() as{TypeError} self::A*);
+ self::A* v3 = self::B::staticVariable = self::B::staticVariable.{self::B::+}(self::f<self::C*>()) as{TypeError} self::B*;
+ self::B* v4 = self::B::staticVariable = self::B::staticVariable.{self::B::*}(self::f<self::B*>());
+ self::C* v5 = self::B::staticVariable = self::B::staticVariable.{self::B::&}(self::f<self::A*>());
self::B* v6 = self::B::staticVariable = self::B::staticVariable.{self::B::-}(1);
self::B* v7 = let final self::B* #t5 = self::B::staticVariable in let final self::B* #t6 = self::B::staticVariable = #t5.{self::B::-}(1) in #t5;
}
diff --git a/pkg/front_end/testcases/inference_new/infer_assign_to_static_upwards.dart b/pkg/front_end/testcases/inference_new/infer_assign_to_static_upwards.dart
index 93419da..4f08b48 100644
--- a/pkg/front_end/testcases/inference_new/infer_assign_to_static_upwards.dart
+++ b/pkg/front_end/testcases/inference_new/infer_assign_to_static_upwards.dart
@@ -15,39 +15,71 @@
void test1() {
var /*@ type=int* */ v1 = topLevelInt = getInt();
+
var /*@ type=num* */ v2 = topLevelInt = getNum();
- var /*@ type=int* */ v4 = topLevelInt ??= getInt();
- var /*@ type=num* */ v5 = topLevelInt ??= getNum();
- var /*@ type=int* */ v7 = topLevelInt += getInt();
- var /*@ type=num* */ v8 = topLevelInt += getNum();
- var /*@ type=int* */ v10 = ++topLevelInt;
- var /*@ type=int* */ v11 = topLevelInt++;
+
+ var /*@ type=int* */ v4 = topLevelInt /*@ target=num::== */ ??= getInt();
+
+ var /*@ type=num* */ v5 = topLevelInt /*@ target=num::== */ ??= getNum();
+
+ var /*@ type=int* */ v7 = topLevelInt /*@ target=num::+ */ += getInt();
+
+ var /*@ type=num* */ v8 = topLevelInt /*@ target=num::+ */ += getNum();
+
+ var /*@ type=int* */ v10 = /*@ target=num::+ */ ++topLevelInt;
+
+ var /*@ type=int* */ v11 = /*@ type=int* */ topLevelInt
+ /*@ type=int* */ /*@ target=num::+ */ ++;
}
void test2() {
var /*@ type=int* */ v1 = topLevelNum = getInt();
+
var /*@ type=num* */ v2 = topLevelNum = getNum();
+
var /*@ type=double* */ v3 = topLevelNum = getDouble();
- var /*@ type=num* */ v4 = topLevelNum ??= getInt();
- var /*@ type=num* */ v5 = topLevelNum ??= getNum();
- var /*@ type=num* */ v6 = topLevelNum ??= getDouble();
- var /*@ type=num* */ v7 = topLevelNum += getInt();
- var /*@ type=num* */ v8 = topLevelNum += getNum();
- var /*@ type=num* */ v9 = topLevelNum += getDouble();
- var /*@ type=num* */ v10 = ++topLevelNum;
- var /*@ type=num* */ v11 = topLevelNum++;
+
+ var /*@ type=num* */ v4 = topLevelNum /*@ target=num::== */ ??= getInt();
+
+ var /*@ type=num* */ v5 = topLevelNum /*@ target=num::== */ ??= getNum();
+
+ var /*@ type=num* */ v6 = topLevelNum /*@ target=num::== */ ??= getDouble();
+
+ var /*@ type=num* */ v7 = topLevelNum /*@ target=num::+ */ += getInt();
+
+ var /*@ type=num* */ v8 = topLevelNum /*@ target=num::+ */ += getNum();
+
+ var /*@ type=num* */ v9 = topLevelNum /*@ target=num::+ */ += getDouble();
+
+ var /*@ type=num* */ v10 = /*@ target=num::+ */ ++topLevelNum;
+
+ var /*@ type=num* */ v11 = /*@ type=num* */ topLevelNum
+ /*@ type=num* */ /*@ target=num::+ */ ++;
}
void test3() {
var /*@ type=num* */ v2 = topLevelDouble = getNum();
+
var /*@ type=double* */ v3 = topLevelDouble = getDouble();
- var /*@ type=num* */ v5 = topLevelDouble ??= getNum();
- var /*@ type=double* */ v6 = topLevelDouble ??= getDouble();
- var /*@ type=double* */ v7 = topLevelDouble += getInt();
- var /*@ type=double* */ v8 = topLevelDouble += getNum();
- var /*@ type=double* */ v9 = topLevelDouble += getDouble();
- var /*@ type=double* */ v10 = ++topLevelDouble;
- var /*@ type=double* */ v11 = topLevelDouble++;
+
+ var /*@ type=num* */ v5 = topLevelDouble /*@ target=num::== */ ??= getNum();
+
+ var /*@ type=double* */ v6 =
+ topLevelDouble /*@ target=num::== */ ??= getDouble();
+
+ var /*@ type=double* */ v7 =
+ topLevelDouble /*@ target=double::+ */ += getInt();
+
+ var /*@ type=double* */ v8 =
+ topLevelDouble /*@ target=double::+ */ += getNum();
+
+ var /*@ type=double* */ v9 =
+ topLevelDouble /*@ target=double::+ */ += getDouble();
+
+ var /*@ type=double* */ v10 = /*@ target=double::+ */ ++topLevelDouble;
+
+ var /*@ type=double* */ v11 = /*@ type=double* */ topLevelDouble
+ /*@ type=double* */ /*@ target=double::+ */ ++;
}
main() {}
diff --git a/pkg/front_end/testcases/inference_new/infer_instance_accessor_ref.dart b/pkg/front_end/testcases/inference_new/infer_instance_accessor_ref.dart
index fd98fc2..af51b3b 100644
--- a/pkg/front_end/testcases/inference_new/infer_instance_accessor_ref.dart
+++ b/pkg/front_end/testcases/inference_new/infer_instance_accessor_ref.dart
@@ -20,6 +20,8 @@
var a = new A();
var x = a. /*@target=A::b*/ b. /*@target=B::c*/ c;
-var y = a. /*@target=A::b*/ b. /*@target=B::c*/ c ??= new D();
+var y =
+ a. /*@ type=B* */ /*@target=A::b*/ b. /*@target=B::c*/ /*@target=B::c*/ c
+ /*@target=Object::==*/ ??= new D();
main() {}
diff --git a/pkg/front_end/testcases/inference_new/infer_instance_field_ref.dart b/pkg/front_end/testcases/inference_new/infer_instance_field_ref.dart
index e649aab..ac3418c 100644
--- a/pkg/front_end/testcases/inference_new/infer_instance_field_ref.dart
+++ b/pkg/front_end/testcases/inference_new/infer_instance_field_ref.dart
@@ -19,6 +19,7 @@
var a = new A();
var x = a. /*@target=A::b*/ b. /*@target=B::c*/ c;
-var y = a. /*@target=A::b*/ b. /*@target=B::c*/ c ??= new D();
+var y = a. /*@ type=B* */ /*@target=A::b*/ b
+ . /*@target=B::c*/ /*@target=B::c*/ c /*@target=Object::==*/ ??= new D();
main() {}
diff --git a/pkg/front_end/testcases/inference_new/list_literals_can_infer_null_top_level.dart b/pkg/front_end/testcases/inference_new/list_literals_can_infer_null_top_level.dart
index 83fd2d8..f8811d5 100644
--- a/pkg/front_end/testcases/inference_new/list_literals_can_infer_null_top_level.dart
+++ b/pkg/front_end/testcases/inference_new/list_literals_can_infer_null_top_level.dart
@@ -5,7 +5,7 @@
/*@testedFeatures=inference*/
library test;
-var x = /*@ typeArgs=Null* */ [null];
+var x = /*@ typeArgs=Null? */ [null];
main() {
x;
diff --git a/pkg/front_end/testcases/inference_new/list_literals_can_infer_null_top_level.dart.outline.expect b/pkg/front_end/testcases/inference_new/list_literals_can_infer_null_top_level.dart.outline.expect
index efecb76..e4f67d0 100644
--- a/pkg/front_end/testcases/inference_new/list_literals_can_infer_null_top_level.dart.outline.expect
+++ b/pkg/front_end/testcases/inference_new/list_literals_can_infer_null_top_level.dart.outline.expect
@@ -2,6 +2,6 @@
import self as self;
import "dart:core" as core;
-static field core::List<core::Null*>* x;
+static field core::List<core::Null?>* x;
static method main() → dynamic
;
diff --git a/pkg/front_end/testcases/inference_new/list_literals_can_infer_null_top_level.dart.strong.expect b/pkg/front_end/testcases/inference_new/list_literals_can_infer_null_top_level.dart.strong.expect
index 1b33259..aa63d12 100644
--- a/pkg/front_end/testcases/inference_new/list_literals_can_infer_null_top_level.dart.strong.expect
+++ b/pkg/front_end/testcases/inference_new/list_literals_can_infer_null_top_level.dart.strong.expect
@@ -2,7 +2,7 @@
import self as self;
import "dart:core" as core;
-static field core::List<core::Null*>* x = <core::Null*>[null];
+static field core::List<core::Null?>* x = <core::Null?>[null];
static method main() → dynamic {
self::x;
}
diff --git a/pkg/front_end/testcases/inference_new/list_literals_can_infer_null_top_level.dart.strong.transformed.expect b/pkg/front_end/testcases/inference_new/list_literals_can_infer_null_top_level.dart.strong.transformed.expect
index 1b33259..aa63d12 100644
--- a/pkg/front_end/testcases/inference_new/list_literals_can_infer_null_top_level.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference_new/list_literals_can_infer_null_top_level.dart.strong.transformed.expect
@@ -2,7 +2,7 @@
import self as self;
import "dart:core" as core;
-static field core::List<core::Null*>* x = <core::Null*>[null];
+static field core::List<core::Null?>* x = <core::Null?>[null];
static method main() → dynamic {
self::x;
}
diff --git a/pkg/front_end/testcases/inference_new/map_literals_can_infer_null_top_level.dart b/pkg/front_end/testcases/inference_new/map_literals_can_infer_null_top_level.dart
index 17b5a27..03f228f 100644
--- a/pkg/front_end/testcases/inference_new/map_literals_can_infer_null_top_level.dart
+++ b/pkg/front_end/testcases/inference_new/map_literals_can_infer_null_top_level.dart
@@ -5,7 +5,7 @@
/*@testedFeatures=inference*/
library test;
-var x = /*@ typeArgs=Null*, Null* */ {null: null};
+var x = /*@ typeArgs=Null?, Null? */ {null: null};
main() {
x;
diff --git a/pkg/front_end/testcases/inference_new/map_literals_can_infer_null_top_level.dart.outline.expect b/pkg/front_end/testcases/inference_new/map_literals_can_infer_null_top_level.dart.outline.expect
index 0f28e73..f7f9db3 100644
--- a/pkg/front_end/testcases/inference_new/map_literals_can_infer_null_top_level.dart.outline.expect
+++ b/pkg/front_end/testcases/inference_new/map_literals_can_infer_null_top_level.dart.outline.expect
@@ -2,6 +2,6 @@
import self as self;
import "dart:core" as core;
-static field core::Map<core::Null*, core::Null*>* x;
+static field core::Map<core::Null?, core::Null?>* x;
static method main() → dynamic
;
diff --git a/pkg/front_end/testcases/inference_new/map_literals_can_infer_null_top_level.dart.strong.expect b/pkg/front_end/testcases/inference_new/map_literals_can_infer_null_top_level.dart.strong.expect
index 79c64f0..4f1d6de 100644
--- a/pkg/front_end/testcases/inference_new/map_literals_can_infer_null_top_level.dart.strong.expect
+++ b/pkg/front_end/testcases/inference_new/map_literals_can_infer_null_top_level.dart.strong.expect
@@ -2,7 +2,7 @@
import self as self;
import "dart:core" as core;
-static field core::Map<core::Null*, core::Null*>* x = <core::Null*, core::Null*>{null: null};
+static field core::Map<core::Null?, core::Null?>* x = <core::Null?, core::Null?>{null: null};
static method main() → dynamic {
self::x;
}
diff --git a/pkg/front_end/testcases/inference_new/map_literals_can_infer_null_top_level.dart.strong.transformed.expect b/pkg/front_end/testcases/inference_new/map_literals_can_infer_null_top_level.dart.strong.transformed.expect
index 79c64f0..4f1d6de 100644
--- a/pkg/front_end/testcases/inference_new/map_literals_can_infer_null_top_level.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference_new/map_literals_can_infer_null_top_level.dart.strong.transformed.expect
@@ -2,7 +2,7 @@
import self as self;
import "dart:core" as core;
-static field core::Map<core::Null*, core::Null*>* x = <core::Null*, core::Null*>{null: null};
+static field core::Map<core::Null?, core::Null?>* x = <core::Null?, core::Null?>{null: null};
static method main() → dynamic {
self::x;
}
diff --git a/pkg/front_end/testcases/inference_new/property_assign_combiner.dart b/pkg/front_end/testcases/inference_new/property_assign_combiner.dart
index b4c2286..c38f17d 100644
--- a/pkg/front_end/testcases/inference_new/property_assign_combiner.dart
+++ b/pkg/front_end/testcases/inference_new/property_assign_combiner.dart
@@ -32,19 +32,28 @@
}
void test1(G g) {
- g. /*@target=G::target*/ target *= /*@ typeArgs=dynamic */ f();
+ /*@ type=G* */ g. /*@target=G::target*/ /*@target=G::target*/ target
+ /*@ target=A::* */ *=
+ /*@ typeArgs=D* */ f();
var /*@ type=C* */ x =
- g. /*@target=G::target*/ target *= /*@ typeArgs=dynamic */ f();
+ /*@ type=G* */ g. /*@target=G::target*/ /*@target=G::target*/ target
+ /*@ target=A::* */ *=
+ /*@ typeArgs=D* */ f();
}
void test2(G g) {
- ++g. /*@target=G::target*/ target;
- var /*@ type=C* */ x = ++g. /*@target=G::target*/ target;
+ /*@ target=A::+ */ ++ /*@ type=G* */ g
+ . /*@target=G::target*/ /*@target=G::target*/ target;
+ var /*@ type=C* */ x = /*@ target=A::+ */ ++ /*@ type=G* */ g
+ . /*@target=G::target*/ /*@target=G::target*/ target;
}
void test3(G g) {
- g. /*@target=G::target*/ target++;
- var /*@ type=A* */ x = g. /*@target=G::target*/ target++;
+ /*@ type=G* */ g
+ . /*@target=G::target*/ /*@target=G::target*/ target /*@ target=A::+ */ ++;
+ var /*@ type=A* */ x = /*@ type=G* */ g
+ . /*@ type=A* */ /*@target=G::target*/ /*@target=G::target*/ target
+ /*@ type=C* */ /*@ target=A::+ */ ++;
}
main() {}
diff --git a/pkg/front_end/testcases/inference_new/property_assign_combiner.dart.strong.expect b/pkg/front_end/testcases/inference_new/property_assign_combiner.dart.strong.expect
index 572f472..85a7b60 100644
--- a/pkg/front_end/testcases/inference_new/property_assign_combiner.dart.strong.expect
+++ b/pkg/front_end/testcases/inference_new/property_assign_combiner.dart.strong.expect
@@ -51,8 +51,8 @@
static method f<T extends core::Object* = dynamic>() → self::f::T*
return null;
static method test1(self::G* g) → void {
- let final self::G* #t1 = g in #t1.{self::G::target} = #t1.{self::G::target}.{self::A::*}(self::f<dynamic>() as{TypeError} self::D*);
- self::C* x = let final self::G* #t2 = g in #t2.{self::G::target} = #t2.{self::G::target}.{self::A::*}(self::f<dynamic>() as{TypeError} self::D*);
+ let final self::G* #t1 = g in #t1.{self::G::target} = #t1.{self::G::target}.{self::A::*}(self::f<self::D*>());
+ self::C* x = let final self::G* #t2 = g in #t2.{self::G::target} = #t2.{self::G::target}.{self::A::*}(self::f<self::D*>());
}
static method test2(self::G* g) → void {
let final self::G* #t3 = g in #t3.{self::G::target} = #t3.{self::G::target}.{self::A::+}(1);
diff --git a/pkg/front_end/testcases/inference_new/property_assign_combiner.dart.strong.transformed.expect b/pkg/front_end/testcases/inference_new/property_assign_combiner.dart.strong.transformed.expect
index 572f472..85a7b60 100644
--- a/pkg/front_end/testcases/inference_new/property_assign_combiner.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference_new/property_assign_combiner.dart.strong.transformed.expect
@@ -51,8 +51,8 @@
static method f<T extends core::Object* = dynamic>() → self::f::T*
return null;
static method test1(self::G* g) → void {
- let final self::G* #t1 = g in #t1.{self::G::target} = #t1.{self::G::target}.{self::A::*}(self::f<dynamic>() as{TypeError} self::D*);
- self::C* x = let final self::G* #t2 = g in #t2.{self::G::target} = #t2.{self::G::target}.{self::A::*}(self::f<dynamic>() as{TypeError} self::D*);
+ let final self::G* #t1 = g in #t1.{self::G::target} = #t1.{self::G::target}.{self::A::*}(self::f<self::D*>());
+ self::C* x = let final self::G* #t2 = g in #t2.{self::G::target} = #t2.{self::G::target}.{self::A::*}(self::f<self::D*>());
}
static method test2(self::G* g) → void {
let final self::G* #t3 = g in #t3.{self::G::target} = #t3.{self::G::target}.{self::A::+}(1);
diff --git a/pkg/front_end/testcases/inference_new/static_assign_combiner.dart b/pkg/front_end/testcases/inference_new/static_assign_combiner.dart
index 2d57409..15084a1 100644
--- a/pkg/front_end/testcases/inference_new/static_assign_combiner.dart
+++ b/pkg/front_end/testcases/inference_new/static_assign_combiner.dart
@@ -30,18 +30,19 @@
void set target(B value) {}
void test1() {
- target *= /*@ typeArgs=dynamic */ f();
- var /*@ type=C* */ x = target *= /*@ typeArgs=dynamic */ f();
+ target /*@ target=A::* */ *= /*@ typeArgs=D* */ f();
+ var /*@ type=C* */ x = target /*@ target=A::* */ *= /*@ typeArgs=D* */ f();
}
void test2() {
- ++target;
- var /*@ type=C* */ x = ++target;
+ /*@ target=A::+ */ ++target;
+ var /*@ type=C* */ x = /*@ target=A::+ */ ++target;
}
void test3() {
- target++;
- var /*@ type=A* */ x = target++;
+ target /*@ target=A::+ */ ++;
+ var /*@ type=A* */ x = /*@ type=A* */ target
+ /*@ type=C* */ /*@ target=A::+ */ ++;
}
main() {}
diff --git a/pkg/front_end/testcases/inference_new/static_assign_combiner.dart.strong.expect b/pkg/front_end/testcases/inference_new/static_assign_combiner.dart.strong.expect
index c941a13..cc0f51e 100644
--- a/pkg/front_end/testcases/inference_new/static_assign_combiner.dart.strong.expect
+++ b/pkg/front_end/testcases/inference_new/static_assign_combiner.dart.strong.expect
@@ -46,8 +46,8 @@
return null;
static set target(self::B* value) → void {}
static method test1() → void {
- self::target = self::target.{self::A::*}(self::f<dynamic>() as{TypeError} self::D*);
- self::C* x = self::target = self::target.{self::A::*}(self::f<dynamic>() as{TypeError} self::D*);
+ self::target = self::target.{self::A::*}(self::f<self::D*>());
+ self::C* x = self::target = self::target.{self::A::*}(self::f<self::D*>());
}
static method test2() → void {
self::target = self::target.{self::A::+}(1);
diff --git a/pkg/front_end/testcases/inference_new/static_assign_combiner.dart.strong.transformed.expect b/pkg/front_end/testcases/inference_new/static_assign_combiner.dart.strong.transformed.expect
index c941a13..cc0f51e 100644
--- a/pkg/front_end/testcases/inference_new/static_assign_combiner.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference_new/static_assign_combiner.dart.strong.transformed.expect
@@ -46,8 +46,8 @@
return null;
static set target(self::B* value) → void {}
static method test1() → void {
- self::target = self::target.{self::A::*}(self::f<dynamic>() as{TypeError} self::D*);
- self::C* x = self::target = self::target.{self::A::*}(self::f<dynamic>() as{TypeError} self::D*);
+ self::target = self::target.{self::A::*}(self::f<self::D*>());
+ self::C* x = self::target = self::target.{self::A::*}(self::f<self::D*>());
}
static method test2() → void {
self::target = self::target.{self::A::+}(1);
diff --git a/pkg/front_end/testcases/nnbd/function_types.dart b/pkg/front_end/testcases/nnbd/function_types.dart
new file mode 100644
index 0000000..67c0108
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/function_types.dart
@@ -0,0 +1,28 @@
+// Copyright (c) 2019, 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.
+
+typedef F = void Function();
+
+void foo() {}
+F bar() => foo;
+F? baz() => foo;
+void Function() hest() => foo;
+void Function()? fisk() => foo;
+
+Function()? foobar(Function()? x) => null;
+
+class A<T> {}
+class B extends A<Function()?> {
+ Function()? method(Function()? x) => null;
+}
+
+main() {
+ void Function() g;
+ void Function()? f = g;
+
+ var fBar = bar();
+ var fBaz = baz();
+ var fHest = hest();
+ var fFisk = fisk();
+}
diff --git a/pkg/front_end/testcases/nnbd/function_types.dart.outline.expect b/pkg/front_end/testcases/nnbd/function_types.dart.outline.expect
new file mode 100644
index 0000000..eb8a0fd
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/function_types.dart.outline.expect
@@ -0,0 +1,29 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+typedef F = () → void;
+class A<T extends core::Object* = dynamic> extends core::Object {
+ synthetic constructor •() → self::A<self::A::T*>*
+ ;
+}
+class B extends self::A<() →? dynamic> {
+ synthetic constructor •() → self::B*
+ ;
+ method method(() →? dynamic x) → () →? dynamic
+ ;
+}
+static method foo() → void
+ ;
+static method bar() → () → void
+ ;
+static method baz() → () → void
+ ;
+static method hest() → () → void
+ ;
+static method fisk() → () →? void
+ ;
+static method foobar(() →? dynamic x) → () →? dynamic
+ ;
+static method main() → dynamic
+ ;
diff --git a/pkg/front_end/testcases/nnbd/function_types.dart.strong.expect b/pkg/front_end/testcases/nnbd/function_types.dart.strong.expect
new file mode 100644
index 0000000..a1e7b4a
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/function_types.dart.strong.expect
@@ -0,0 +1,40 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+typedef F = () → void;
+class A<T extends core::Object* = dynamic> extends core::Object {
+ synthetic constructor •() → self::A<self::A::T*>*
+ : super core::Object::•()
+ ;
+}
+class B extends self::A<() →? dynamic> {
+ synthetic constructor •() → self::B*
+ : super self::A::•()
+ ;
+ method method(() →? dynamic x) → () →? dynamic
+ return null;
+}
+static method foo() → void {}
+static method bar() → () → void
+ return #C1;
+static method baz() → () → void
+ return #C1;
+static method hest() → () → void
+ return #C1;
+static method fisk() → () →? void
+ return #C1;
+static method foobar(() →? dynamic x) → () →? dynamic
+ return null;
+static method main() → dynamic {
+ () → void g;
+ () →? void f = g;
+ () → void fBar = self::bar();
+ () → void fBaz = self::baz();
+ () → void fHest = self::hest();
+ () →? void fFisk = self::fisk();
+}
+
+constants {
+ #C1 = tearoff self::foo
+}
diff --git a/pkg/front_end/testcases/nnbd/function_types.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/function_types.dart.strong.transformed.expect
new file mode 100644
index 0000000..a1e7b4a
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/function_types.dart.strong.transformed.expect
@@ -0,0 +1,40 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+typedef F = () → void;
+class A<T extends core::Object* = dynamic> extends core::Object {
+ synthetic constructor •() → self::A<self::A::T*>*
+ : super core::Object::•()
+ ;
+}
+class B extends self::A<() →? dynamic> {
+ synthetic constructor •() → self::B*
+ : super self::A::•()
+ ;
+ method method(() →? dynamic x) → () →? dynamic
+ return null;
+}
+static method foo() → void {}
+static method bar() → () → void
+ return #C1;
+static method baz() → () → void
+ return #C1;
+static method hest() → () → void
+ return #C1;
+static method fisk() → () →? void
+ return #C1;
+static method foobar(() →? dynamic x) → () →? dynamic
+ return null;
+static method main() → dynamic {
+ () → void g;
+ () →? void f = g;
+ () → void fBar = self::bar();
+ () → void fBaz = self::baz();
+ () → void fHest = self::hest();
+ () →? void fFisk = self::fisk();
+}
+
+constants {
+ #C1 = tearoff self::foo
+}
diff --git a/pkg/front_end/testcases/nnbd/nullable_param.dart.outline.expect b/pkg/front_end/testcases/nnbd/nullable_param.dart.outline.expect
index 18fe203..a40317e 100644
--- a/pkg/front_end/testcases/nnbd/nullable_param.dart.outline.expect
+++ b/pkg/front_end/testcases/nnbd/nullable_param.dart.outline.expect
@@ -27,5 +27,5 @@
}
static method main() → dynamic
;
-static method test_nullable_function_type_formal_param({() →* core::int f}) → core::int
+static method test_nullable_function_type_formal_param({() →? core::int f}) → core::int
;
diff --git a/pkg/front_end/testcases/nnbd/nullable_param.dart.strong.expect b/pkg/front_end/testcases/nnbd/nullable_param.dart.strong.expect
index 977546a..d0af2e7 100644
--- a/pkg/front_end/testcases/nnbd/nullable_param.dart.strong.expect
+++ b/pkg/front_end/testcases/nnbd/nullable_param.dart.strong.expect
@@ -30,9 +30,9 @@
self::Foo foo = new self::Foo::•();
foo.{self::Foo::field} = 5;
foo.{self::Foo::bar}(6);
- self::test_nullable_function_type_formal_param(f: () → core::int* => 2);
+ self::test_nullable_function_type_formal_param(f: () → core::int => 2);
}
-static method test_nullable_function_type_formal_param({() →* core::int f = #C1}) → core::int {
+static method test_nullable_function_type_formal_param({() →? core::int f = #C1}) → core::int {
return let final core::int #t1 = f.call() in #t1.==(null) ?{core::int*} 1.{core::int::unary-}() : #t1;
}
diff --git a/pkg/front_end/testcases/nnbd/nullable_param.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/nullable_param.dart.strong.transformed.expect
index 977546a..d0af2e7 100644
--- a/pkg/front_end/testcases/nnbd/nullable_param.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/nullable_param.dart.strong.transformed.expect
@@ -30,9 +30,9 @@
self::Foo foo = new self::Foo::•();
foo.{self::Foo::field} = 5;
foo.{self::Foo::bar}(6);
- self::test_nullable_function_type_formal_param(f: () → core::int* => 2);
+ self::test_nullable_function_type_formal_param(f: () → core::int => 2);
}
-static method test_nullable_function_type_formal_param({() →* core::int f = #C1}) → core::int {
+static method test_nullable_function_type_formal_param({() →? core::int f = #C1}) → core::int {
return let final core::int #t1 = f.call() in #t1.==(null) ?{core::int*} 1.{core::int::unary-}() : #t1;
}
diff --git a/pkg/front_end/testcases/nnbd/required.dart.outline.expect b/pkg/front_end/testcases/nnbd/required.dart.outline.expect
index 044b885..d5dda81 100644
--- a/pkg/front_end/testcases/nnbd/required.dart.outline.expect
+++ b/pkg/front_end/testcases/nnbd/required.dart.outline.expect
@@ -2,15 +2,15 @@
import self as self;
import "dart:core" as core;
-typedef Typedef1 = ({a: core::int, required b: core::int}) →* dynamic;
-typedef Typedef2 = ({a: core::int, required b: core::int}) →* dynamic;
+typedef Typedef1 = ({a: core::int, required b: core::int}) → dynamic;
+typedef Typedef2 = ({a: core::int, required b: core::int}) → dynamic;
class Class extends core::Object {
synthetic constructor •() → self::Class*
;
method method({core::int a, required core::int b, required final core::int c, required covariant final core::int d}) → dynamic
;
}
-static field ({a: core::int, required b: core::int}) →* dynamic field;
+static field ({a: core::int, required b: core::int}) → dynamic field;
static method method({core::int a, required core::int b, required final core::int c}) → dynamic
;
static method main() → dynamic
diff --git a/pkg/front_end/testcases/nnbd/required.dart.strong.expect b/pkg/front_end/testcases/nnbd/required.dart.strong.expect
index a23a59d..4ce5b20 100644
--- a/pkg/front_end/testcases/nnbd/required.dart.strong.expect
+++ b/pkg/front_end/testcases/nnbd/required.dart.strong.expect
@@ -2,15 +2,15 @@
import self as self;
import "dart:core" as core;
-typedef Typedef1 = ({a: core::int, required b: core::int}) →* dynamic;
-typedef Typedef2 = ({a: core::int, required b: core::int}) →* dynamic;
+typedef Typedef1 = ({a: core::int, required b: core::int}) → dynamic;
+typedef Typedef2 = ({a: core::int, required b: core::int}) → dynamic;
class Class extends core::Object {
synthetic constructor •() → self::Class*
: super core::Object::•()
;
method method({core::int a = #C1, required core::int b = #C1, required final core::int c = #C1, required covariant final core::int d = #C1}) → dynamic {}
}
-static field ({a: core::int, required b: core::int}) →* dynamic field;
+static field ({a: core::int, required b: core::int}) → dynamic field;
static method method({core::int a = #C1, required core::int b = #C1, required final core::int c = #C1}) → dynamic {}
static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/nnbd/required.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/required.dart.strong.transformed.expect
index a23a59d..4ce5b20 100644
--- a/pkg/front_end/testcases/nnbd/required.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/required.dart.strong.transformed.expect
@@ -2,15 +2,15 @@
import self as self;
import "dart:core" as core;
-typedef Typedef1 = ({a: core::int, required b: core::int}) →* dynamic;
-typedef Typedef2 = ({a: core::int, required b: core::int}) →* dynamic;
+typedef Typedef1 = ({a: core::int, required b: core::int}) → dynamic;
+typedef Typedef2 = ({a: core::int, required b: core::int}) → dynamic;
class Class extends core::Object {
synthetic constructor •() → self::Class*
: super core::Object::•()
;
method method({core::int a = #C1, required core::int b = #C1, required final core::int c = #C1, required covariant final core::int d = #C1}) → dynamic {}
}
-static field ({a: core::int, required b: core::int}) →* dynamic field;
+static field ({a: core::int, required b: core::int}) → dynamic field;
static method method({core::int a = #C1, required core::int b = #C1, required final core::int c = #C1}) → dynamic {}
static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/old_dills/dart2js.version.32.compile.1.dill b/pkg/front_end/testcases/old_dills/dart2js.version.32.compile.1.dill
new file mode 100644
index 0000000..ce5e225
--- /dev/null
+++ b/pkg/front_end/testcases/old_dills/dart2js.version.32.compile.1.dill
Binary files differ
diff --git a/pkg/front_end/testcases/rasta/generic_factory.dart.strong.transformed.expect b/pkg/front_end/testcases/rasta/generic_factory.dart.strong.transformed.expect
index c8ebf36..d362a24 100644
--- a/pkg/front_end/testcases/rasta/generic_factory.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/rasta/generic_factory.dart.strong.transformed.expect
@@ -52,9 +52,9 @@
: super core::Object::•()
;
static factory a<T extends core::Object* = dynamic>() → self::A<self::A::a::T*>*
- let <S extends core::Object* = dynamic>() →* self::B<self::B::a::S*>* #redirecting_factory = self::B::a in let self::A::a::T* #typeArg0 = null in invalid-expression;
+ let <S extends core::Object* = dynamic>() →* self::B<S*>* #redirecting_factory = self::B::a in let self::A::a::T* #typeArg0 = null in invalid-expression;
static factory b<T extends core::Object* = dynamic>() → self::A<self::A::b::T*>*
- let <S extends core::Object* = dynamic>() →* self::B<self::B::a::S*>* #redirecting_factory = self::B::a in let self::C1* #typeArg0 = null in invalid-expression;
+ let <S extends core::Object* = dynamic>() →* self::B<S*>* #redirecting_factory = self::B::a in let self::C1* #typeArg0 = null in invalid-expression;
static factory c<T extends core::Object* = dynamic>() → self::A<self::A::c::T*>*
let core::String* #redirecting_factory = "Missing" in invalid-expression;
}
diff --git a/pkg/front_end/testcases/rasta/issue_000052.dart.strong.expect b/pkg/front_end/testcases/rasta/issue_000052.dart.strong.expect
index ed31e8d..2130845 100644
--- a/pkg/front_end/testcases/rasta/issue_000052.dart.strong.expect
+++ b/pkg/front_end/testcases/rasta/issue_000052.dart.strong.expect
@@ -3,7 +3,7 @@
import "dart:core" as core;
static method main() → dynamic {
- function f() → core::Null* {
+ function f() → core::Null? {
core::print("hello");
}
f.call();
diff --git a/pkg/front_end/testcases/rasta/issue_000052.dart.strong.transformed.expect b/pkg/front_end/testcases/rasta/issue_000052.dart.strong.transformed.expect
index ed31e8d..2130845 100644
--- a/pkg/front_end/testcases/rasta/issue_000052.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/rasta/issue_000052.dart.strong.transformed.expect
@@ -3,7 +3,7 @@
import "dart:core" as core;
static method main() → dynamic {
- function f() → core::Null* {
+ function f() → core::Null? {
core::print("hello");
}
f.call();
diff --git a/pkg/front_end/testcases/rasta/issue_000070.dart.outline.expect b/pkg/front_end/testcases/rasta/issue_000070.dart.outline.expect
index afa2636..c7a0e81 100644
--- a/pkg/front_end/testcases/rasta/issue_000070.dart.outline.expect
+++ b/pkg/front_end/testcases/rasta/issue_000070.dart.outline.expect
@@ -11,7 +11,7 @@
constructor empty() → self::A<self::A::N*, self::A::S*, self::A::U*>*
;
const constructor c(self::A::U* u, self::A::S* s) → self::A<self::A::N*, self::A::S*, self::A::U*>*
- : self::A::field = const <core::Null*>[null], super core::Object::•()
+ : self::A::field = const <core::Null?>[null], super core::Object::•()
;
static factory f<N extends core::Object* = dynamic, S extends core::Object* = dynamic, U extends core::Object* = dynamic>(self::A::f::S* s) → self::A<self::A::f::N*, self::A::f::S*, self::A::f::U*>*
;
diff --git a/pkg/front_end/testcases/rasta/issue_000070.dart.strong.expect b/pkg/front_end/testcases/rasta/issue_000070.dart.strong.expect
index c9aa9ff..8718610 100644
--- a/pkg/front_end/testcases/rasta/issue_000070.dart.strong.expect
+++ b/pkg/front_end/testcases/rasta/issue_000070.dart.strong.expect
@@ -46,6 +46,6 @@
constants {
#C1 = null
- #C2 = <core::Null*>[#C1]
+ #C2 = <core::Null?>[#C1]
#C3 = self::A<core::int*, core::int*, core::List<dynamic>*> {field:#C2}
}
diff --git a/pkg/front_end/testcases/rasta/issue_000070.dart.strong.transformed.expect b/pkg/front_end/testcases/rasta/issue_000070.dart.strong.transformed.expect
index 9a4571e..e5097ea 100644
--- a/pkg/front_end/testcases/rasta/issue_000070.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/rasta/issue_000070.dart.strong.transformed.expect
@@ -46,6 +46,6 @@
constants {
#C1 = null
- #C2 = <core::Null*>[#C1]
+ #C2 = <core::Null?>[#C1]
#C3 = self::A<core::int*, core::int*, core::List<dynamic>*> {field:#C2}
}
diff --git a/pkg/front_end/testcases/rasta/issue_000081.dart.strong.expect b/pkg/front_end/testcases/rasta/issue_000081.dart.strong.expect
index 17c277f..ecdd7b2 100644
--- a/pkg/front_end/testcases/rasta/issue_000081.dart.strong.expect
+++ b/pkg/front_end/testcases/rasta/issue_000081.dart.strong.expect
@@ -21,6 +21,6 @@
}
static method main() → dynamic {
core::print(new self::Sub::•().{self::Sub::hashCode});
- core::List<core::Null*>* l = <core::Null*>[null];
- let final core::List<core::Null*>* #t2 = l in let final core::int* #t3 = 0 in #t2.{core::List::[]}(#t3).{core::Object::==}(null) ?{core::String*} let final core::String* #t4 = "fisk" as{TypeError} core::Null* in let final void #t5 = #t2.{core::List::[]=}(#t3, #t4) in #t4 : null;
+ core::List<core::Null?>* l = <core::Null?>[null];
+ let final core::List<core::Null?>* #t2 = l in let final core::int* #t3 = 0 in #t2.{core::List::[]}(#t3).{core::Object::==}(null) ?{core::String*} #t2.{core::List::[]=}(#t3, "fisk" as{TypeError} core::Null?) : null;
}
diff --git a/pkg/front_end/testcases/rasta/issue_000081.dart.strong.transformed.expect b/pkg/front_end/testcases/rasta/issue_000081.dart.strong.transformed.expect
index 17c277f..ecdd7b2 100644
--- a/pkg/front_end/testcases/rasta/issue_000081.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/rasta/issue_000081.dart.strong.transformed.expect
@@ -21,6 +21,6 @@
}
static method main() → dynamic {
core::print(new self::Sub::•().{self::Sub::hashCode});
- core::List<core::Null*>* l = <core::Null*>[null];
- let final core::List<core::Null*>* #t2 = l in let final core::int* #t3 = 0 in #t2.{core::List::[]}(#t3).{core::Object::==}(null) ?{core::String*} let final core::String* #t4 = "fisk" as{TypeError} core::Null* in let final void #t5 = #t2.{core::List::[]=}(#t3, #t4) in #t4 : null;
+ core::List<core::Null?>* l = <core::Null?>[null];
+ let final core::List<core::Null?>* #t2 = l in let final core::int* #t3 = 0 in #t2.{core::List::[]}(#t3).{core::Object::==}(null) ?{core::String*} #t2.{core::List::[]=}(#t3, "fisk" as{TypeError} core::Null?) : null;
}
diff --git a/pkg/front_end/testcases/rasta/mandatory_parameter_initializer.dart.strong.expect b/pkg/front_end/testcases/rasta/mandatory_parameter_initializer.dart.strong.expect
index 391c477..9096c74 100644
--- a/pkg/front_end/testcases/rasta/mandatory_parameter_initializer.dart.strong.expect
+++ b/pkg/front_end/testcases/rasta/mandatory_parameter_initializer.dart.strong.expect
@@ -20,6 +20,11 @@
// main(arguments = [x]) {
// ^
//
+// pkg/front_end/testcases/rasta/mandatory_parameter_initializer.dart:5:18: Error: Constant expression expected.
+// Try inserting 'const'.
+// main(arguments = [x]) {
+// ^
+//
// pkg/front_end/testcases/rasta/mandatory_parameter_initializer.dart:5:19: Error: Getter not found: 'x'.
// main(arguments = [x]) {
// ^
diff --git a/pkg/front_end/testcases/rasta/mandatory_parameter_initializer.dart.strong.transformed.expect b/pkg/front_end/testcases/rasta/mandatory_parameter_initializer.dart.strong.transformed.expect
index 391c477..9096c74 100644
--- a/pkg/front_end/testcases/rasta/mandatory_parameter_initializer.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/rasta/mandatory_parameter_initializer.dart.strong.transformed.expect
@@ -20,6 +20,11 @@
// main(arguments = [x]) {
// ^
//
+// pkg/front_end/testcases/rasta/mandatory_parameter_initializer.dart:5:18: Error: Constant expression expected.
+// Try inserting 'const'.
+// main(arguments = [x]) {
+// ^
+//
// pkg/front_end/testcases/rasta/mandatory_parameter_initializer.dart:5:19: Error: Getter not found: 'x'.
// main(arguments = [x]) {
// ^
diff --git a/pkg/front_end/testcases/rasta/static.dart.strong.expect b/pkg/front_end/testcases/rasta/static.dart.strong.expect
index 30a8714..2cee8d5 100644
--- a/pkg/front_end/testcases/rasta/static.dart.strong.expect
+++ b/pkg/front_end/testcases/rasta/static.dart.strong.expect
@@ -138,26 +138,6 @@
// use(Foo.staticSetter ??= 87);
// ^^^^^^^^^^^^
//
-// pkg/front_end/testcases/rasta/static.dart:35:23: Error: The method '+' isn't defined for the class 'dynamic Function()'.
-// Try correcting the name to the name of an existing method, or defining a method named '+'.
-// Foo.staticFunction++;
-// ^
-//
-// pkg/front_end/testcases/rasta/static.dart:36:27: Error: The method '+' isn't defined for the class 'dynamic Function()'.
-// Try correcting the name to the name of an existing method, or defining a method named '+'.
-// use(Foo.staticFunction++);
-// ^
-//
-// pkg/front_end/testcases/rasta/static.dart:46:5: Error: The method '+' isn't defined for the class 'dynamic Function()'.
-// Try correcting the name to the name of an existing method, or defining a method named '+'.
-// ++Foo.staticFunction;
-// ^
-//
-// pkg/front_end/testcases/rasta/static.dart:47:9: Error: The method '+' isn't defined for the class 'dynamic Function()'.
-// Try correcting the name to the name of an existing method, or defining a method named '+'.
-// use(++Foo.staticFunction);
-// ^
-//
// pkg/front_end/testcases/rasta/static.dart:53:23: Error: The method 'call' isn't defined for the class 'int'.
// Try correcting the name to the name of an existing method, or defining a method named 'call'.
// Foo.staticConstant();
@@ -215,7 +195,7 @@
invalid-expression "pkg/front_end/testcases/rasta/static.dart:31:9: Error: Setter not found: 'staticConstant'.
Foo.staticConstant++;
^^^^^^^^^^^^^^";
- self::use(let final core::int* #t1 = #C1 in let final core::int* #t2 = invalid-expression "pkg/front_end/testcases/rasta/static.dart:32:13: Error: Setter not found: 'staticConstant'.
+ self::use(let final core::int* #t1 = #C1 in let final dynamic #t2 = invalid-expression "pkg/front_end/testcases/rasta/static.dart:32:13: Error: Setter not found: 'staticConstant'.
use(Foo.staticConstant++);
^^^^^^^^^^^^^^" in #t1);
self::Foo::staticField = self::Foo::staticField.{core::num::+}(1);
@@ -312,18 +292,18 @@
^^^^^^^^^^^^");
self::Foo::staticSetter = 87;
self::use(self::Foo::staticSetter = 87);
- (#C1).{core::Object::==}(null) ?{core::int*} invalid-expression "pkg/front_end/testcases/rasta/static.dart:75:9: Error: Setter not found: 'staticConstant'.
+ (#C1).{core::num::==}(null) ?{dynamic} invalid-expression "pkg/front_end/testcases/rasta/static.dart:75:9: Error: Setter not found: 'staticConstant'.
Foo.staticConstant ??= 87;
^^^^^^^^^^^^^^" : null;
- self::use(let final core::int* #t11 = #C1 in #t11.{core::Object::==}(null) ?{core::int*} invalid-expression "pkg/front_end/testcases/rasta/static.dart:76:13: Error: Setter not found: 'staticConstant'.
+ self::use(let final core::int* #t11 = #C1 in #t11.{core::num::==}(null) ?{dynamic} invalid-expression "pkg/front_end/testcases/rasta/static.dart:76:13: Error: Setter not found: 'staticConstant'.
use(Foo.staticConstant ??= 87);
^^^^^^^^^^^^^^" : #t11);
self::Foo::staticField.{core::num::==}(null) ?{core::int*} self::Foo::staticField = 87 : null;
self::use(let final core::int* #t12 = self::Foo::staticField in #t12.{core::num::==}(null) ?{core::int*} self::Foo::staticField = 87 : #t12);
- (#C2).{core::Object::==}(null) ?{core::Object*} invalid-expression "pkg/front_end/testcases/rasta/static.dart:79:9: Error: Setter not found: 'staticFunction'.
+ (#C2).{core::Object::==}(null) ?{dynamic} invalid-expression "pkg/front_end/testcases/rasta/static.dart:79:9: Error: Setter not found: 'staticFunction'.
Foo.staticFunction ??= 87;
^^^^^^^^^^^^^^" : null;
- self::use(let final () →* dynamic #t13 = #C2 in #t13.{core::Object::==}(null) ?{core::Object*} invalid-expression "pkg/front_end/testcases/rasta/static.dart:80:13: Error: Setter not found: 'staticFunction'.
+ self::use(let final () →* dynamic #t13 = #C2 in #t13.{core::Object::==}(null) ?{dynamic} invalid-expression "pkg/front_end/testcases/rasta/static.dart:80:13: Error: Setter not found: 'staticFunction'.
use(Foo.staticFunction ??= 87);
^^^^^^^^^^^^^^" : #t13);
self::Foo::staticGetter.{core::Object::==}(null) ?{dynamic} invalid-expression "pkg/front_end/testcases/rasta/static.dart:81:9: Error: Setter not found: 'staticGetter'.
diff --git a/pkg/front_end/testcases/rasta/static.dart.strong.transformed.expect b/pkg/front_end/testcases/rasta/static.dart.strong.transformed.expect
index 30a8714..2cee8d5 100644
--- a/pkg/front_end/testcases/rasta/static.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/rasta/static.dart.strong.transformed.expect
@@ -138,26 +138,6 @@
// use(Foo.staticSetter ??= 87);
// ^^^^^^^^^^^^
//
-// pkg/front_end/testcases/rasta/static.dart:35:23: Error: The method '+' isn't defined for the class 'dynamic Function()'.
-// Try correcting the name to the name of an existing method, or defining a method named '+'.
-// Foo.staticFunction++;
-// ^
-//
-// pkg/front_end/testcases/rasta/static.dart:36:27: Error: The method '+' isn't defined for the class 'dynamic Function()'.
-// Try correcting the name to the name of an existing method, or defining a method named '+'.
-// use(Foo.staticFunction++);
-// ^
-//
-// pkg/front_end/testcases/rasta/static.dart:46:5: Error: The method '+' isn't defined for the class 'dynamic Function()'.
-// Try correcting the name to the name of an existing method, or defining a method named '+'.
-// ++Foo.staticFunction;
-// ^
-//
-// pkg/front_end/testcases/rasta/static.dart:47:9: Error: The method '+' isn't defined for the class 'dynamic Function()'.
-// Try correcting the name to the name of an existing method, or defining a method named '+'.
-// use(++Foo.staticFunction);
-// ^
-//
// pkg/front_end/testcases/rasta/static.dart:53:23: Error: The method 'call' isn't defined for the class 'int'.
// Try correcting the name to the name of an existing method, or defining a method named 'call'.
// Foo.staticConstant();
@@ -215,7 +195,7 @@
invalid-expression "pkg/front_end/testcases/rasta/static.dart:31:9: Error: Setter not found: 'staticConstant'.
Foo.staticConstant++;
^^^^^^^^^^^^^^";
- self::use(let final core::int* #t1 = #C1 in let final core::int* #t2 = invalid-expression "pkg/front_end/testcases/rasta/static.dart:32:13: Error: Setter not found: 'staticConstant'.
+ self::use(let final core::int* #t1 = #C1 in let final dynamic #t2 = invalid-expression "pkg/front_end/testcases/rasta/static.dart:32:13: Error: Setter not found: 'staticConstant'.
use(Foo.staticConstant++);
^^^^^^^^^^^^^^" in #t1);
self::Foo::staticField = self::Foo::staticField.{core::num::+}(1);
@@ -312,18 +292,18 @@
^^^^^^^^^^^^");
self::Foo::staticSetter = 87;
self::use(self::Foo::staticSetter = 87);
- (#C1).{core::Object::==}(null) ?{core::int*} invalid-expression "pkg/front_end/testcases/rasta/static.dart:75:9: Error: Setter not found: 'staticConstant'.
+ (#C1).{core::num::==}(null) ?{dynamic} invalid-expression "pkg/front_end/testcases/rasta/static.dart:75:9: Error: Setter not found: 'staticConstant'.
Foo.staticConstant ??= 87;
^^^^^^^^^^^^^^" : null;
- self::use(let final core::int* #t11 = #C1 in #t11.{core::Object::==}(null) ?{core::int*} invalid-expression "pkg/front_end/testcases/rasta/static.dart:76:13: Error: Setter not found: 'staticConstant'.
+ self::use(let final core::int* #t11 = #C1 in #t11.{core::num::==}(null) ?{dynamic} invalid-expression "pkg/front_end/testcases/rasta/static.dart:76:13: Error: Setter not found: 'staticConstant'.
use(Foo.staticConstant ??= 87);
^^^^^^^^^^^^^^" : #t11);
self::Foo::staticField.{core::num::==}(null) ?{core::int*} self::Foo::staticField = 87 : null;
self::use(let final core::int* #t12 = self::Foo::staticField in #t12.{core::num::==}(null) ?{core::int*} self::Foo::staticField = 87 : #t12);
- (#C2).{core::Object::==}(null) ?{core::Object*} invalid-expression "pkg/front_end/testcases/rasta/static.dart:79:9: Error: Setter not found: 'staticFunction'.
+ (#C2).{core::Object::==}(null) ?{dynamic} invalid-expression "pkg/front_end/testcases/rasta/static.dart:79:9: Error: Setter not found: 'staticFunction'.
Foo.staticFunction ??= 87;
^^^^^^^^^^^^^^" : null;
- self::use(let final () →* dynamic #t13 = #C2 in #t13.{core::Object::==}(null) ?{core::Object*} invalid-expression "pkg/front_end/testcases/rasta/static.dart:80:13: Error: Setter not found: 'staticFunction'.
+ self::use(let final () →* dynamic #t13 = #C2 in #t13.{core::Object::==}(null) ?{dynamic} invalid-expression "pkg/front_end/testcases/rasta/static.dart:80:13: Error: Setter not found: 'staticFunction'.
use(Foo.staticFunction ??= 87);
^^^^^^^^^^^^^^" : #t13);
self::Foo::staticGetter.{core::Object::==}(null) ?{dynamic} invalid-expression "pkg/front_end/testcases/rasta/static.dart:81:9: Error: Setter not found: 'staticGetter'.
diff --git a/pkg/front_end/testcases/regress/issue_29937.dart.strong.expect b/pkg/front_end/testcases/regress/issue_29937.dart.strong.expect
index 976b248..c6c6d4d 100644
--- a/pkg/front_end/testcases/regress/issue_29937.dart.strong.expect
+++ b/pkg/front_end/testcases/regress/issue_29937.dart.strong.expect
@@ -10,5 +10,5 @@
import "dart:core" as core;
static method main() → dynamic {
- <() →* core::Null*>[let final () →* core::Null* f = () → core::Null* {} in f];
+ <() →* core::Null?>[let final () →* core::Null? f = () → core::Null? {} in f];
}
diff --git a/pkg/front_end/testcases/regress/issue_29937.dart.strong.transformed.expect b/pkg/front_end/testcases/regress/issue_29937.dart.strong.transformed.expect
index 976b248..c6c6d4d 100644
--- a/pkg/front_end/testcases/regress/issue_29937.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/regress/issue_29937.dart.strong.transformed.expect
@@ -10,5 +10,5 @@
import "dart:core" as core;
static method main() → dynamic {
- <() →* core::Null*>[let final () →* core::Null* f = () → core::Null* {} in f];
+ <() →* core::Null?>[let final () →* core::Null? f = () → core::Null? {} in f];
}
diff --git a/pkg/front_end/testcases/regress/issue_29942.dart.strong.expect b/pkg/front_end/testcases/regress/issue_29942.dart.strong.expect
index de81539..a052ac0 100644
--- a/pkg/front_end/testcases/regress/issue_29942.dart.strong.expect
+++ b/pkg/front_end/testcases/regress/issue_29942.dart.strong.expect
@@ -16,4 +16,4 @@
static method main() → dynamic {}
static method f() → dynamic
- return let final () →* core::Null* h = () → core::Null* => null in h;
+ return let final () →* core::Null? h = () → core::Null? => null in h;
diff --git a/pkg/front_end/testcases/regress/issue_29942.dart.strong.transformed.expect b/pkg/front_end/testcases/regress/issue_29942.dart.strong.transformed.expect
index de81539..a052ac0 100644
--- a/pkg/front_end/testcases/regress/issue_29942.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/regress/issue_29942.dart.strong.transformed.expect
@@ -16,4 +16,4 @@
static method main() → dynamic {}
static method f() → dynamic
- return let final () →* core::Null* h = () → core::Null* => null in h;
+ return let final () →* core::Null? h = () → core::Null? => null in h;
diff --git a/pkg/front_end/testcases/regress/issue_29978.dart.strong.expect b/pkg/front_end/testcases/regress/issue_29978.dart.strong.expect
index 01dbc9a..86dc966 100644
--- a/pkg/front_end/testcases/regress/issue_29978.dart.strong.expect
+++ b/pkg/front_end/testcases/regress/issue_29978.dart.strong.expect
@@ -12,5 +12,5 @@
static method foo(dynamic a, dynamic b) → dynamic
return null;
static method main() → dynamic {
- self::foo(null, let final () →* core::Null* f = () → core::Null* {} in f);
+ self::foo(null, let final () →* core::Null? f = () → core::Null? {} in f);
}
diff --git a/pkg/front_end/testcases/regress/issue_29978.dart.strong.transformed.expect b/pkg/front_end/testcases/regress/issue_29978.dart.strong.transformed.expect
index 01dbc9a..86dc966 100644
--- a/pkg/front_end/testcases/regress/issue_29978.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/regress/issue_29978.dart.strong.transformed.expect
@@ -12,5 +12,5 @@
static method foo(dynamic a, dynamic b) → dynamic
return null;
static method main() → dynamic {
- self::foo(null, let final () →* core::Null* f = () → core::Null* {} in f);
+ self::foo(null, let final () →* core::Null? f = () → core::Null? {} in f);
}
diff --git a/pkg/front_end/testcases/regress/issue_29979.dart.strong.expect b/pkg/front_end/testcases/regress/issue_29979.dart.strong.expect
index cdc5774..df04eff 100644
--- a/pkg/front_end/testcases/regress/issue_29979.dart.strong.expect
+++ b/pkg/front_end/testcases/regress/issue_29979.dart.strong.expect
@@ -10,5 +10,5 @@
import "dart:core" as core;
static method main() → dynamic {
- (let final () →* core::Null* f = () → core::Null* {} in f).call();
+ (let final () →* core::Null? f = () → core::Null? {} in f).call();
}
diff --git a/pkg/front_end/testcases/regress/issue_29979.dart.strong.transformed.expect b/pkg/front_end/testcases/regress/issue_29979.dart.strong.transformed.expect
index cdc5774..df04eff 100644
--- a/pkg/front_end/testcases/regress/issue_29979.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/regress/issue_29979.dart.strong.transformed.expect
@@ -10,5 +10,5 @@
import "dart:core" as core;
static method main() → dynamic {
- (let final () →* core::Null* f = () → core::Null* {} in f).call();
+ (let final () →* core::Null? f = () → core::Null? {} in f).call();
}
diff --git a/pkg/front_end/testcases/regress/issue_31766.dart.strong.expect b/pkg/front_end/testcases/regress/issue_31766.dart.strong.expect
index cf83ecf..fb78ee0 100644
--- a/pkg/front_end/testcases/regress/issue_31766.dart.strong.expect
+++ b/pkg/front_end/testcases/regress/issue_31766.dart.strong.expect
@@ -14,7 +14,7 @@
core::print("t.foo()=${t.{self::A::foo}()}");
}
bar.call<self::A*>(new self::A::•());
- (<S extends self::A* = self::A*>(S* s) → core::Null* {
+ (<S extends self::A* = self::A*>(S* s) → core::Null? {
core::print("s.foo()=${s.{self::A::foo}()}");
}).call<self::A*>(new self::A::•());
}
diff --git a/pkg/front_end/testcases/regress/issue_31766.dart.strong.transformed.expect b/pkg/front_end/testcases/regress/issue_31766.dart.strong.transformed.expect
index cf83ecf..fb78ee0 100644
--- a/pkg/front_end/testcases/regress/issue_31766.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/regress/issue_31766.dart.strong.transformed.expect
@@ -14,7 +14,7 @@
core::print("t.foo()=${t.{self::A::foo}()}");
}
bar.call<self::A*>(new self::A::•());
- (<S extends self::A* = self::A*>(S* s) → core::Null* {
+ (<S extends self::A* = self::A*>(S* s) → core::Null? {
core::print("s.foo()=${s.{self::A::foo}()}");
}).call<self::A*>(new self::A::•());
}
diff --git a/pkg/front_end/testcases/runtime_checks/contravariant_generic_method_type_parameter.dart.strong.expect b/pkg/front_end/testcases/runtime_checks/contravariant_generic_method_type_parameter.dart.strong.expect
index 1f1240e..ce550cf 100644
--- a/pkg/front_end/testcases/runtime_checks/contravariant_generic_method_type_parameter.dart.strong.expect
+++ b/pkg/front_end/testcases/runtime_checks/contravariant_generic_method_type_parameter.dart.strong.expect
@@ -10,7 +10,7 @@
method f<U extends (self::C::T*) →* void = (self::C::T*) →* void>(self::C::f::U* x) → void {}
}
static method g(self::C<core::num*>* c) → void {
- c.{self::C::f}<(core::Object*) →* void>((core::Object* o) → core::Null* {});
+ c.{self::C::f}<(core::Object*) →* void>((core::Object* o) → core::Null? {});
}
static method test() → void {
self::g(new self::C::•<core::int*>());
diff --git a/pkg/front_end/testcases/runtime_checks/contravariant_generic_method_type_parameter.dart.strong.transformed.expect b/pkg/front_end/testcases/runtime_checks/contravariant_generic_method_type_parameter.dart.strong.transformed.expect
index 1f1240e..ce550cf 100644
--- a/pkg/front_end/testcases/runtime_checks/contravariant_generic_method_type_parameter.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/runtime_checks/contravariant_generic_method_type_parameter.dart.strong.transformed.expect
@@ -10,7 +10,7 @@
method f<U extends (self::C::T*) →* void = (self::C::T*) →* void>(self::C::f::U* x) → void {}
}
static method g(self::C<core::num*>* c) → void {
- c.{self::C::f}<(core::Object*) →* void>((core::Object* o) → core::Null* {});
+ c.{self::C::f}<(core::Object*) →* void>((core::Object* o) → core::Null? {});
}
static method test() → void {
self::g(new self::C::•<core::int*>());
diff --git a/pkg/front_end/testcases/runtime_checks/contravariant_generic_return_null_aware.dart.strong.expect b/pkg/front_end/testcases/runtime_checks/contravariant_generic_return_null_aware.dart.strong.expect
index dd9a3f3..77140dc 100644
--- a/pkg/front_end/testcases/runtime_checks/contravariant_generic_return_null_aware.dart.strong.expect
+++ b/pkg/front_end/testcases/runtime_checks/contravariant_generic_return_null_aware.dart.strong.expect
@@ -13,15 +13,15 @@
}
}
static method g1(self::C<core::num*>* c) → void {
- (core::num*) →* void x = let final self::C<core::num*>* #t1 = c in #t1.==(null) ?{(core::num*) →* void} null : #t1.{self::C::f1}() as{TypeError} (core::num*) →* void;
+ (core::num*) →* void x = let final self::C<core::num*>* #t1 = c in #t1.{core::Object::==}(null) ?{(core::num*) →* void} null : #t1.{self::C::f1}() as{TypeError} (core::num*) →* void;
core::print("hello");
x.call(1.5);
}
static method g2(self::C<core::num*>* c) → void {
- (core::int*) →* void x = let final self::C<core::num*>* #t2 = c in #t2.==(null) ?{(core::num*) →* void} null : #t2.{self::C::f1}() as{TypeError} (core::num*) →* void;
+ (core::int*) →* void x = let final self::C<core::num*>* #t2 = c in #t2.{core::Object::==}(null) ?{(core::num*) →* void} null : #t2.{self::C::f1}() as{TypeError} (core::num*) →* void;
x.call(1);
}
static method g3(self::C<core::num*>* c) → void {
- core::List<(core::num*) →* void>* x = let final self::C<core::num*>* #t3 = c in #t3.==(null) ?{core::List<(core::num*) →* void>*} null : #t3.{self::C::f2}() as{TypeError} core::List<(core::num*) →* void>*;
+ core::List<(core::num*) →* void>* x = let final self::C<core::num*>* #t3 = c in #t3.{core::Object::==}(null) ?{core::List<(core::num*) →* void>*} null : #t3.{self::C::f2}() as{TypeError} core::List<(core::num*) →* void>*;
}
static method main() → void {}
diff --git a/pkg/front_end/testcases/runtime_checks/contravariant_generic_return_null_aware.dart.strong.transformed.expect b/pkg/front_end/testcases/runtime_checks/contravariant_generic_return_null_aware.dart.strong.transformed.expect
index dd9a3f3..77140dc 100644
--- a/pkg/front_end/testcases/runtime_checks/contravariant_generic_return_null_aware.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/runtime_checks/contravariant_generic_return_null_aware.dart.strong.transformed.expect
@@ -13,15 +13,15 @@
}
}
static method g1(self::C<core::num*>* c) → void {
- (core::num*) →* void x = let final self::C<core::num*>* #t1 = c in #t1.==(null) ?{(core::num*) →* void} null : #t1.{self::C::f1}() as{TypeError} (core::num*) →* void;
+ (core::num*) →* void x = let final self::C<core::num*>* #t1 = c in #t1.{core::Object::==}(null) ?{(core::num*) →* void} null : #t1.{self::C::f1}() as{TypeError} (core::num*) →* void;
core::print("hello");
x.call(1.5);
}
static method g2(self::C<core::num*>* c) → void {
- (core::int*) →* void x = let final self::C<core::num*>* #t2 = c in #t2.==(null) ?{(core::num*) →* void} null : #t2.{self::C::f1}() as{TypeError} (core::num*) →* void;
+ (core::int*) →* void x = let final self::C<core::num*>* #t2 = c in #t2.{core::Object::==}(null) ?{(core::num*) →* void} null : #t2.{self::C::f1}() as{TypeError} (core::num*) →* void;
x.call(1);
}
static method g3(self::C<core::num*>* c) → void {
- core::List<(core::num*) →* void>* x = let final self::C<core::num*>* #t3 = c in #t3.==(null) ?{core::List<(core::num*) →* void>*} null : #t3.{self::C::f2}() as{TypeError} core::List<(core::num*) →* void>*;
+ core::List<(core::num*) →* void>* x = let final self::C<core::num*>* #t3 = c in #t3.{core::Object::==}(null) ?{core::List<(core::num*) →* void>*} null : #t3.{self::C::f2}() as{TypeError} core::List<(core::num*) →* void>*;
}
static method main() → void {}
diff --git a/pkg/front_end/testcases/runtime_checks/contravariant_getter_return_null_aware.dart.strong.expect b/pkg/front_end/testcases/runtime_checks/contravariant_getter_return_null_aware.dart.strong.expect
index c4f2438..b534829 100644
--- a/pkg/front_end/testcases/runtime_checks/contravariant_getter_return_null_aware.dart.strong.expect
+++ b/pkg/front_end/testcases/runtime_checks/contravariant_getter_return_null_aware.dart.strong.expect
@@ -14,15 +14,15 @@
}
}
static method g1(self::C<core::num*>* c) → void {
- (core::num*) →* void x = let final self::C<core::num*>* #t1 = c in #t1.==(null) ?{(core::num*) →* void} null : #t1.{self::C::f1} as{TypeError} (core::num*) →* void;
+ (core::num*) →* void x = let final self::C<core::num*>* #t1 = c in #t1.{core::Object::==}(null) ?{(core::num*) →* void} null : #t1.{self::C::f1} as{TypeError} (core::num*) →* void;
core::print("hello");
x.call(1.5);
}
static method g2(self::C<core::num*>* c) → void {
- (core::int*) →* void x = let final self::C<core::num*>* #t2 = c in #t2.==(null) ?{(core::num*) →* void} null : #t2.{self::C::f1} as{TypeError} (core::num*) →* void;
+ (core::int*) →* void x = let final self::C<core::num*>* #t2 = c in #t2.{core::Object::==}(null) ?{(core::num*) →* void} null : #t2.{self::C::f1} as{TypeError} (core::num*) →* void;
x.call(1);
}
static method g3(self::C<core::num*>* c) → void {
- core::List<(core::num*) →* void>* x = let final self::C<core::num*>* #t3 = c in #t3.==(null) ?{core::List<(core::num*) →* void>*} null : #t3.{self::C::f2} as{TypeError} core::List<(core::num*) →* void>*;
+ core::List<(core::num*) →* void>* x = let final self::C<core::num*>* #t3 = c in #t3.{core::Object::==}(null) ?{core::List<(core::num*) →* void>*} null : #t3.{self::C::f2} as{TypeError} core::List<(core::num*) →* void>*;
}
static method main() → void {}
diff --git a/pkg/front_end/testcases/runtime_checks/contravariant_getter_return_null_aware.dart.strong.transformed.expect b/pkg/front_end/testcases/runtime_checks/contravariant_getter_return_null_aware.dart.strong.transformed.expect
index c4f2438..b534829 100644
--- a/pkg/front_end/testcases/runtime_checks/contravariant_getter_return_null_aware.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/runtime_checks/contravariant_getter_return_null_aware.dart.strong.transformed.expect
@@ -14,15 +14,15 @@
}
}
static method g1(self::C<core::num*>* c) → void {
- (core::num*) →* void x = let final self::C<core::num*>* #t1 = c in #t1.==(null) ?{(core::num*) →* void} null : #t1.{self::C::f1} as{TypeError} (core::num*) →* void;
+ (core::num*) →* void x = let final self::C<core::num*>* #t1 = c in #t1.{core::Object::==}(null) ?{(core::num*) →* void} null : #t1.{self::C::f1} as{TypeError} (core::num*) →* void;
core::print("hello");
x.call(1.5);
}
static method g2(self::C<core::num*>* c) → void {
- (core::int*) →* void x = let final self::C<core::num*>* #t2 = c in #t2.==(null) ?{(core::num*) →* void} null : #t2.{self::C::f1} as{TypeError} (core::num*) →* void;
+ (core::int*) →* void x = let final self::C<core::num*>* #t2 = c in #t2.{core::Object::==}(null) ?{(core::num*) →* void} null : #t2.{self::C::f1} as{TypeError} (core::num*) →* void;
x.call(1);
}
static method g3(self::C<core::num*>* c) → void {
- core::List<(core::num*) →* void>* x = let final self::C<core::num*>* #t3 = c in #t3.==(null) ?{core::List<(core::num*) →* void>*} null : #t3.{self::C::f2} as{TypeError} core::List<(core::num*) →* void>*;
+ core::List<(core::num*) →* void>* x = let final self::C<core::num*>* #t3 = c in #t3.{core::Object::==}(null) ?{core::List<(core::num*) →* void>*} null : #t3.{self::C::f2} as{TypeError} core::List<(core::num*) →* void>*;
}
static method main() → void {}
diff --git a/pkg/front_end/testcases/runtime_checks_new/contravariant_generic_return_with_compound_assign_implicit_downcast.dart.strong.expect b/pkg/front_end/testcases/runtime_checks_new/contravariant_generic_return_with_compound_assign_implicit_downcast.dart.strong.expect
index 6c00c8a..8d3508c 100644
--- a/pkg/front_end/testcases/runtime_checks_new/contravariant_generic_return_with_compound_assign_implicit_downcast.dart.strong.expect
+++ b/pkg/front_end/testcases/runtime_checks_new/contravariant_generic_return_with_compound_assign_implicit_downcast.dart.strong.expect
@@ -60,7 +60,7 @@
^" in (#t1.{self::D::value}.{self::C::+}(1) as{TypeError} (core::num*) →* core::num*) as{TypeError} (core::int*) →* core::int*;
self::expect(d.{self::D::setValue}(0), 1);
d = new self::D::•(new self::C::•<core::num*>(#C2));
- self::expectTypeError(() → core::Null* {
+ self::expectTypeError(() → core::Null? {
let final self::D* #t3 = d in #t3.{self::D::value} = let final<BottomType> #t4 = invalid-expression "pkg/front_end/testcases/runtime_checks_new/contravariant_generic_return_with_compound_assign_implicit_downcast.dart:53:48: Error: A value of type 'num Function(num)' can't be assigned to a variable of type 'int Function(int)'.
Try changing the type of the left hand side, or casting the right hand side to 'int Function(int)'.
d.value /*@ checkReturn=(num*) ->* num* */ += 1;
diff --git a/pkg/front_end/testcases/runtime_checks_new/contravariant_generic_return_with_compound_assign_implicit_downcast.dart.strong.transformed.expect b/pkg/front_end/testcases/runtime_checks_new/contravariant_generic_return_with_compound_assign_implicit_downcast.dart.strong.transformed.expect
index 6c00c8a..8d3508c 100644
--- a/pkg/front_end/testcases/runtime_checks_new/contravariant_generic_return_with_compound_assign_implicit_downcast.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/runtime_checks_new/contravariant_generic_return_with_compound_assign_implicit_downcast.dart.strong.transformed.expect
@@ -60,7 +60,7 @@
^" in (#t1.{self::D::value}.{self::C::+}(1) as{TypeError} (core::num*) →* core::num*) as{TypeError} (core::int*) →* core::int*;
self::expect(d.{self::D::setValue}(0), 1);
d = new self::D::•(new self::C::•<core::num*>(#C2));
- self::expectTypeError(() → core::Null* {
+ self::expectTypeError(() → core::Null? {
let final self::D* #t3 = d in #t3.{self::D::value} = let final<BottomType> #t4 = invalid-expression "pkg/front_end/testcases/runtime_checks_new/contravariant_generic_return_with_compound_assign_implicit_downcast.dart:53:48: Error: A value of type 'num Function(num)' can't be assigned to a variable of type 'int Function(int)'.
Try changing the type of the left hand side, or casting the right hand side to 'int Function(int)'.
d.value /*@ checkReturn=(num*) ->* num* */ += 1;
diff --git a/pkg/front_end/testcases/runtime_checks_new/contravariant_getter_return_compound_assign.dart.strong.expect b/pkg/front_end/testcases/runtime_checks_new/contravariant_getter_return_compound_assign.dart.strong.expect
index 09538b1..4a65ddd 100644
--- a/pkg/front_end/testcases/runtime_checks_new/contravariant_getter_return_compound_assign.dart.strong.expect
+++ b/pkg/front_end/testcases/runtime_checks_new/contravariant_getter_return_compound_assign.dart.strong.expect
@@ -2,15 +2,15 @@
//
// Problems in library:
//
-// pkg/front_end/testcases/runtime_checks_new/contravariant_getter_return_compound_assign.dart:20:54: Error: A value of type 'B<num>' can't be assigned to a variable of type 'B<void Function(num)>'.
+// pkg/front_end/testcases/runtime_checks_new/contravariant_getter_return_compound_assign.dart:20:54: Error: The argument type 'B<num>' can't be assigned to the parameter type 'B<void Function(num)>'.
// - 'B' is from 'pkg/front_end/testcases/runtime_checks_new/contravariant_getter_return_compound_assign.dart'.
-// Try changing the type of the left hand side, or casting the right hand side to 'B<void Function(num)>'.
+// Try changing the type of the parameter, or casting the argument to 'B<void Function(num)>'.
// c. /*@ checkReturn=B<(num*) ->* void>* */ x += new B<num>();
// ^
//
-// pkg/front_end/testcases/runtime_checks_new/contravariant_getter_return_compound_assign.dart:21:62: Error: A value of type 'B<num>' can't be assigned to a variable of type 'B<void Function(num)>'.
+// pkg/front_end/testcases/runtime_checks_new/contravariant_getter_return_compound_assign.dart:21:62: Error: The argument type 'B<num>' can't be assigned to the parameter type 'B<void Function(num)>'.
// - 'B' is from 'pkg/front_end/testcases/runtime_checks_new/contravariant_getter_return_compound_assign.dart'.
-// Try changing the type of the left hand side, or casting the right hand side to 'B<void Function(num)>'.
+// Try changing the type of the parameter, or casting the argument to 'B<void Function(num)>'.
// var y = c. /*@ checkReturn=B<(num*) ->* void>* */ x += new B<num>();
// ^
//
@@ -46,14 +46,14 @@
set x(self::B<(self::C::T*) →* void>* value) → void {}
}
static method test(self::C<core::num*>* c) → void {
- let final self::C<core::num*>* #t1 = c in #t1.{self::C::x} = (#t1.{self::C::x} as{TypeError} self::B<(core::num*) →* void>*).{self::B::+}(let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/runtime_checks_new/contravariant_getter_return_compound_assign.dart:20:54: Error: A value of type 'B<num>' can't be assigned to a variable of type 'B<void Function(num)>'.
+ let final self::C<core::num*>* #t1 = c in #t1.{self::C::x} = (#t1.{self::C::x} as{TypeError} self::B<(core::num*) →* void>*).{self::B::+}(let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/runtime_checks_new/contravariant_getter_return_compound_assign.dart:20:54: Error: The argument type 'B<num>' can't be assigned to the parameter type 'B<void Function(num)>'.
- 'B' is from 'pkg/front_end/testcases/runtime_checks_new/contravariant_getter_return_compound_assign.dart'.
-Try changing the type of the left hand side, or casting the right hand side to 'B<void Function(num)>'.
+Try changing the type of the parameter, or casting the argument to 'B<void Function(num)>'.
c. /*@ checkReturn=B<(num*) ->* void>* */ x += new B<num>();
^" in new self::B::•<core::num*>() as{TypeError} self::B<(core::num*) →* void>*);
- self::B<(core::num*) →* void>* y = let final self::C<core::num*>* #t3 = c in #t3.{self::C::x} = (#t3.{self::C::x} as{TypeError} self::B<(core::num*) →* void>*).{self::B::+}(let final<BottomType> #t4 = invalid-expression "pkg/front_end/testcases/runtime_checks_new/contravariant_getter_return_compound_assign.dart:21:62: Error: A value of type 'B<num>' can't be assigned to a variable of type 'B<void Function(num)>'.
+ self::B<(core::num*) →* void>* y = let final self::C<core::num*>* #t3 = c in #t3.{self::C::x} = (#t3.{self::C::x} as{TypeError} self::B<(core::num*) →* void>*).{self::B::+}(let final<BottomType> #t4 = invalid-expression "pkg/front_end/testcases/runtime_checks_new/contravariant_getter_return_compound_assign.dart:21:62: Error: The argument type 'B<num>' can't be assigned to the parameter type 'B<void Function(num)>'.
- 'B' is from 'pkg/front_end/testcases/runtime_checks_new/contravariant_getter_return_compound_assign.dart'.
-Try changing the type of the left hand side, or casting the right hand side to 'B<void Function(num)>'.
+Try changing the type of the parameter, or casting the argument to 'B<void Function(num)>'.
var y = c. /*@ checkReturn=B<(num*) ->* void>* */ x += new B<num>();
^" in new self::B::•<core::num*>() as{TypeError} self::B<(core::num*) →* void>*);
let final self::C<core::num*>* #t5 = c in (#t5.{self::C::x} as{TypeError} self::B<(core::num*) →* void>*).{core::Object::==}(null) ?{self::B<core::Object*>*} #t5.{self::C::x} = let final<BottomType> #t6 = invalid-expression "pkg/front_end/testcases/runtime_checks_new/contravariant_getter_return_compound_assign.dart:22:55: Error: A value of type 'B<num>' can't be assigned to a variable of type 'B<void Function(num)>'.
@@ -61,7 +61,7 @@
Try changing the type of the left hand side, or casting the right hand side to 'B<void Function(num)>'.
c. /*@ checkReturn=B<(num*) ->* void>* */ x ??= new B<num>();
^" in new self::B::•<core::num*>() as{TypeError} self::B<(core::num*) →* void>* : null;
- self::B<core::Object*>* z = let final self::C<core::num*>* #t7 = c in let final dynamic #t8 = #t7.{self::C::x} as{TypeError} self::B<(core::num*) →* void>* in #t8.{core::Object::==}(null) ?{self::B<core::Object*>*} #t7.{self::C::x} = let final<BottomType> #t9 = invalid-expression "pkg/front_end/testcases/runtime_checks_new/contravariant_getter_return_compound_assign.dart:23:63: Error: A value of type 'B<num>' can't be assigned to a variable of type 'B<void Function(num)>'.
+ self::B<core::Object*>* z = let final self::C<core::num*>* #t7 = c in let final self::B<(core::num*) →* void>* #t8 = #t7.{self::C::x} as{TypeError} self::B<(core::num*) →* void>* in #t8.{core::Object::==}(null) ?{self::B<core::Object*>*} #t7.{self::C::x} = let final<BottomType> #t9 = invalid-expression "pkg/front_end/testcases/runtime_checks_new/contravariant_getter_return_compound_assign.dart:23:63: Error: A value of type 'B<num>' can't be assigned to a variable of type 'B<void Function(num)>'.
- 'B' is from 'pkg/front_end/testcases/runtime_checks_new/contravariant_getter_return_compound_assign.dart'.
Try changing the type of the left hand side, or casting the right hand side to 'B<void Function(num)>'.
var z = c. /*@ checkReturn=B<(num*) ->* void>* */ x ??= new B<num>();
diff --git a/pkg/front_end/testcases/runtime_checks_new/contravariant_getter_return_compound_assign.dart.strong.transformed.expect b/pkg/front_end/testcases/runtime_checks_new/contravariant_getter_return_compound_assign.dart.strong.transformed.expect
index 3b5cd11..4a65ddd 100644
--- a/pkg/front_end/testcases/runtime_checks_new/contravariant_getter_return_compound_assign.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/runtime_checks_new/contravariant_getter_return_compound_assign.dart.strong.transformed.expect
@@ -2,15 +2,15 @@
//
// Problems in library:
//
-// pkg/front_end/testcases/runtime_checks_new/contravariant_getter_return_compound_assign.dart:20:54: Error: A value of type 'B<num>' can't be assigned to a variable of type 'B<void Function(num)>'.
+// pkg/front_end/testcases/runtime_checks_new/contravariant_getter_return_compound_assign.dart:20:54: Error: The argument type 'B<num>' can't be assigned to the parameter type 'B<void Function(num)>'.
// - 'B' is from 'pkg/front_end/testcases/runtime_checks_new/contravariant_getter_return_compound_assign.dart'.
-// Try changing the type of the left hand side, or casting the right hand side to 'B<void Function(num)>'.
+// Try changing the type of the parameter, or casting the argument to 'B<void Function(num)>'.
// c. /*@ checkReturn=B<(num*) ->* void>* */ x += new B<num>();
// ^
//
-// pkg/front_end/testcases/runtime_checks_new/contravariant_getter_return_compound_assign.dart:21:62: Error: A value of type 'B<num>' can't be assigned to a variable of type 'B<void Function(num)>'.
+// pkg/front_end/testcases/runtime_checks_new/contravariant_getter_return_compound_assign.dart:21:62: Error: The argument type 'B<num>' can't be assigned to the parameter type 'B<void Function(num)>'.
// - 'B' is from 'pkg/front_end/testcases/runtime_checks_new/contravariant_getter_return_compound_assign.dart'.
-// Try changing the type of the left hand side, or casting the right hand side to 'B<void Function(num)>'.
+// Try changing the type of the parameter, or casting the argument to 'B<void Function(num)>'.
// var y = c. /*@ checkReturn=B<(num*) ->* void>* */ x += new B<num>();
// ^
//
@@ -46,14 +46,14 @@
set x(self::B<(self::C::T*) →* void>* value) → void {}
}
static method test(self::C<core::num*>* c) → void {
- let final self::C<core::num*>* #t1 = c in #t1.{self::C::x} = (#t1.{self::C::x} as{TypeError} self::B<(core::num*) →* void>*).{self::B::+}(let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/runtime_checks_new/contravariant_getter_return_compound_assign.dart:20:54: Error: A value of type 'B<num>' can't be assigned to a variable of type 'B<void Function(num)>'.
+ let final self::C<core::num*>* #t1 = c in #t1.{self::C::x} = (#t1.{self::C::x} as{TypeError} self::B<(core::num*) →* void>*).{self::B::+}(let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/runtime_checks_new/contravariant_getter_return_compound_assign.dart:20:54: Error: The argument type 'B<num>' can't be assigned to the parameter type 'B<void Function(num)>'.
- 'B' is from 'pkg/front_end/testcases/runtime_checks_new/contravariant_getter_return_compound_assign.dart'.
-Try changing the type of the left hand side, or casting the right hand side to 'B<void Function(num)>'.
+Try changing the type of the parameter, or casting the argument to 'B<void Function(num)>'.
c. /*@ checkReturn=B<(num*) ->* void>* */ x += new B<num>();
^" in new self::B::•<core::num*>() as{TypeError} self::B<(core::num*) →* void>*);
- self::B<(core::num*) →* void>* y = let final self::C<core::num*>* #t3 = c in #t3.{self::C::x} = (#t3.{self::C::x} as{TypeError} self::B<(core::num*) →* void>*).{self::B::+}(let final<BottomType> #t4 = invalid-expression "pkg/front_end/testcases/runtime_checks_new/contravariant_getter_return_compound_assign.dart:21:62: Error: A value of type 'B<num>' can't be assigned to a variable of type 'B<void Function(num)>'.
+ self::B<(core::num*) →* void>* y = let final self::C<core::num*>* #t3 = c in #t3.{self::C::x} = (#t3.{self::C::x} as{TypeError} self::B<(core::num*) →* void>*).{self::B::+}(let final<BottomType> #t4 = invalid-expression "pkg/front_end/testcases/runtime_checks_new/contravariant_getter_return_compound_assign.dart:21:62: Error: The argument type 'B<num>' can't be assigned to the parameter type 'B<void Function(num)>'.
- 'B' is from 'pkg/front_end/testcases/runtime_checks_new/contravariant_getter_return_compound_assign.dart'.
-Try changing the type of the left hand side, or casting the right hand side to 'B<void Function(num)>'.
+Try changing the type of the parameter, or casting the argument to 'B<void Function(num)>'.
var y = c. /*@ checkReturn=B<(num*) ->* void>* */ x += new B<num>();
^" in new self::B::•<core::num*>() as{TypeError} self::B<(core::num*) →* void>*);
let final self::C<core::num*>* #t5 = c in (#t5.{self::C::x} as{TypeError} self::B<(core::num*) →* void>*).{core::Object::==}(null) ?{self::B<core::Object*>*} #t5.{self::C::x} = let final<BottomType> #t6 = invalid-expression "pkg/front_end/testcases/runtime_checks_new/contravariant_getter_return_compound_assign.dart:22:55: Error: A value of type 'B<num>' can't be assigned to a variable of type 'B<void Function(num)>'.
diff --git a/pkg/front_end/testcases/runtime_checks_new/contravariant_index_assign.dart.strong.expect b/pkg/front_end/testcases/runtime_checks_new/contravariant_index_assign.dart.strong.expect
index 1f89703..53d1c58 100644
--- a/pkg/front_end/testcases/runtime_checks_new/contravariant_index_assign.dart.strong.expect
+++ b/pkg/front_end/testcases/runtime_checks_new/contravariant_index_assign.dart.strong.expect
@@ -22,7 +22,7 @@
c.{self::C::[]=}(0, new self::B::•<(core::num*) →* void>());
let final self::C<core::num*>* #t1 = c in let final core::int* #t2 = 0 in #t1.{self::C::[]=}(#t2, (#t1.{self::C::[]}(#t2) as{TypeError} self::B<(core::num*) →* void>*).{self::B::+}(new self::B::•<(core::num*) →* void>()));
self::B<(core::num*) →* void>* x = let final self::C<core::num*>* #t3 = c in let final core::int* #t4 = 0 in let final self::B<(core::num*) →* void>* #t5 = (#t3.{self::C::[]}(#t4) as{TypeError} self::B<(core::num*) →* void>*).{self::B::+}(new self::B::•<(core::num*) →* void>()) in let final void #t6 = #t3.{self::C::[]=}(#t4, #t5) in #t5;
- let final self::C<core::num*>* #t7 = c in let final core::int* #t8 = 0 in (#t7.{self::C::[]}(#t8) as{TypeError} self::B<(core::num*) →* void>*).{core::Object::==}(null) ?{self::B<(core::num*) →* void>*} let final self::B<(core::num*) →* void>* #t9 = new self::B::•<(core::num*) →* void>() in let final void #t10 = #t7.{self::C::[]=}(#t8, #t9) in #t9 : null;
- self::B<(core::num*) →* void>* y = let final self::C<core::num*>* #t11 = c in let final core::int* #t12 = 0 in let final self::B<(core::num*) →* void>* #t13 = #t11.{self::C::[]}(#t12) as{TypeError} self::B<(core::num*) →* void>* in #t13.{core::Object::==}(null) ?{self::B<(core::num*) →* void>*} let final self::B<(core::num*) →* void>* #t14 = new self::B::•<(core::num*) →* void>() in let final void #t15 = #t11.{self::C::[]=}(#t12, #t14) in #t14 : #t13;
+ let final self::C<core::num*>* #t7 = c in let final core::int* #t8 = 0 in (#t7.{self::C::[]}(#t8) as{TypeError} self::B<(core::num*) →* void>*).{core::Object::==}(null) ?{self::B<(core::num*) →* void>*} #t7.{self::C::[]=}(#t8, new self::B::•<(core::num*) →* void>()) : null;
+ self::B<(core::num*) →* void>* y = let final self::C<core::num*>* #t9 = c in let final core::int* #t10 = 0 in let final self::B<(core::num*) →* void>* #t11 = #t9.{self::C::[]}(#t10) as{TypeError} self::B<(core::num*) →* void>* in #t11.{core::Object::==}(null) ?{self::B<(core::num*) →* void>*} let final self::B<(core::num*) →* void>* #t12 = new self::B::•<(core::num*) →* void>() in let final void #t13 = #t9.{self::C::[]=}(#t10, #t12) in #t12 : #t11;
}
static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/runtime_checks_new/contravariant_index_assign.dart.strong.transformed.expect b/pkg/front_end/testcases/runtime_checks_new/contravariant_index_assign.dart.strong.transformed.expect
index 1f89703..53d1c58 100644
--- a/pkg/front_end/testcases/runtime_checks_new/contravariant_index_assign.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/runtime_checks_new/contravariant_index_assign.dart.strong.transformed.expect
@@ -22,7 +22,7 @@
c.{self::C::[]=}(0, new self::B::•<(core::num*) →* void>());
let final self::C<core::num*>* #t1 = c in let final core::int* #t2 = 0 in #t1.{self::C::[]=}(#t2, (#t1.{self::C::[]}(#t2) as{TypeError} self::B<(core::num*) →* void>*).{self::B::+}(new self::B::•<(core::num*) →* void>()));
self::B<(core::num*) →* void>* x = let final self::C<core::num*>* #t3 = c in let final core::int* #t4 = 0 in let final self::B<(core::num*) →* void>* #t5 = (#t3.{self::C::[]}(#t4) as{TypeError} self::B<(core::num*) →* void>*).{self::B::+}(new self::B::•<(core::num*) →* void>()) in let final void #t6 = #t3.{self::C::[]=}(#t4, #t5) in #t5;
- let final self::C<core::num*>* #t7 = c in let final core::int* #t8 = 0 in (#t7.{self::C::[]}(#t8) as{TypeError} self::B<(core::num*) →* void>*).{core::Object::==}(null) ?{self::B<(core::num*) →* void>*} let final self::B<(core::num*) →* void>* #t9 = new self::B::•<(core::num*) →* void>() in let final void #t10 = #t7.{self::C::[]=}(#t8, #t9) in #t9 : null;
- self::B<(core::num*) →* void>* y = let final self::C<core::num*>* #t11 = c in let final core::int* #t12 = 0 in let final self::B<(core::num*) →* void>* #t13 = #t11.{self::C::[]}(#t12) as{TypeError} self::B<(core::num*) →* void>* in #t13.{core::Object::==}(null) ?{self::B<(core::num*) →* void>*} let final self::B<(core::num*) →* void>* #t14 = new self::B::•<(core::num*) →* void>() in let final void #t15 = #t11.{self::C::[]=}(#t12, #t14) in #t14 : #t13;
+ let final self::C<core::num*>* #t7 = c in let final core::int* #t8 = 0 in (#t7.{self::C::[]}(#t8) as{TypeError} self::B<(core::num*) →* void>*).{core::Object::==}(null) ?{self::B<(core::num*) →* void>*} #t7.{self::C::[]=}(#t8, new self::B::•<(core::num*) →* void>()) : null;
+ self::B<(core::num*) →* void>* y = let final self::C<core::num*>* #t9 = c in let final core::int* #t10 = 0 in let final self::B<(core::num*) →* void>* #t11 = #t9.{self::C::[]}(#t10) as{TypeError} self::B<(core::num*) →* void>* in #t11.{core::Object::==}(null) ?{self::B<(core::num*) →* void>*} let final self::B<(core::num*) →* void>* #t12 = new self::B::•<(core::num*) →* void>() in let final void #t13 = #t9.{self::C::[]=}(#t10, #t12) in #t12 : #t11;
}
static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/runtime_checks_new/mixin_forwarding_stub_field.dart.strong.expect b/pkg/front_end/testcases/runtime_checks_new/mixin_forwarding_stub_field.dart.strong.expect
index 2d52e9b..9587cd5 100644
--- a/pkg/front_end/testcases/runtime_checks_new/mixin_forwarding_stub_field.dart.strong.expect
+++ b/pkg/front_end/testcases/runtime_checks_new/mixin_forwarding_stub_field.dart.strong.expect
@@ -72,12 +72,12 @@
}
}
static method test(self::I<core::Object*>* i) → void {
- self::expectTypeError(() → core::Null* {
+ self::expectTypeError(() → core::Null? {
i.{self::I::x} = "hello";
});
i.{self::I::x} = 1;
self::expect(i.{self::I::x}, 1);
- self::expectTypeError(() → core::Null* {
+ self::expectTypeError(() → core::Null? {
i.{self::I::y} = "hello";
});
i.{self::I::y} = 2;
diff --git a/pkg/front_end/testcases/runtime_checks_new/mixin_forwarding_stub_setter.dart.strong.expect b/pkg/front_end/testcases/runtime_checks_new/mixin_forwarding_stub_setter.dart.strong.expect
index a3d75db..067ee48 100644
--- a/pkg/front_end/testcases/runtime_checks_new/mixin_forwarding_stub_setter.dart.strong.expect
+++ b/pkg/front_end/testcases/runtime_checks_new/mixin_forwarding_stub_setter.dart.strong.expect
@@ -81,12 +81,12 @@
}
}
static method test(self::I<core::Object*>* i) → void {
- self::expectTypeError(() → core::Null* {
+ self::expectTypeError(() → core::Null? {
i.{self::I::x} = "hello";
});
i.{self::I::x} = 2;
self::expect(i.{self::I::x}, 1);
- self::expectTypeError(() → core::Null* {
+ self::expectTypeError(() → core::Null? {
i.{self::I::y} = "hello";
});
i.{self::I::y} = 4;
diff --git a/pkg/front_end/testcases/runtime_checks_new/stub_checked_via_target.dart.strong.expect b/pkg/front_end/testcases/runtime_checks_new/stub_checked_via_target.dart.strong.expect
index c533269..ab4a68c 100644
--- a/pkg/front_end/testcases/runtime_checks_new/stub_checked_via_target.dart.strong.expect
+++ b/pkg/front_end/testcases/runtime_checks_new/stub_checked_via_target.dart.strong.expect
@@ -41,11 +41,11 @@
c.{self::C::f}("hello");
}
static method test(self::C* c, self::I* i) → void {
- self::expectTypeError(() → core::Null* {
+ self::expectTypeError(() → core::Null? {
i.{self::I::f}("hello");
});
self::expect(i.{self::I::f}(1), 2);
- self::expectTypeError(() → core::Null* {
+ self::expectTypeError(() → core::Null? {
c.{self::C::f}("hello");
});
self::expect(c.{self::C::f}(1), 2);
diff --git a/pkg/front_end/testcases/runtime_checks_new/stub_checked_via_target.dart.strong.transformed.expect b/pkg/front_end/testcases/runtime_checks_new/stub_checked_via_target.dart.strong.transformed.expect
index c533269..ab4a68c 100644
--- a/pkg/front_end/testcases/runtime_checks_new/stub_checked_via_target.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/runtime_checks_new/stub_checked_via_target.dart.strong.transformed.expect
@@ -41,11 +41,11 @@
c.{self::C::f}("hello");
}
static method test(self::C* c, self::I* i) → void {
- self::expectTypeError(() → core::Null* {
+ self::expectTypeError(() → core::Null? {
i.{self::I::f}("hello");
});
self::expect(i.{self::I::f}(1), 2);
- self::expectTypeError(() → core::Null* {
+ self::expectTypeError(() → core::Null? {
c.{self::C::f}("hello");
});
self::expect(c.{self::C::f}(1), 2);
diff --git a/pkg/front_end/testcases/strong.status b/pkg/front_end/testcases/strong.status
index df68cb5..c52e649 100644
--- a/pkg/front_end/testcases/strong.status
+++ b/pkg/front_end/testcases/strong.status
@@ -53,6 +53,7 @@
general/reject_generic_function_types_in_bounds: RuntimeError # Expected
general/spread_collection: RuntimeError
general/statements: Crash
+general/type_variable_bound_access: TypeCheckError
general/type_parameter_type_named_int: RuntimeError # Expected
general/type_variable_as_super: RuntimeError
general/unsound_promotion: RuntimeError
@@ -79,7 +80,6 @@
inference/generic_methods_infer_js_builtin: InstrumentationMismatch # Issue #30029
inference/inconsistent_overrides: TypeCheckError
inference/infer_field_override_multiple: TypeCheckError
-inference/infer_from_complex_expressions_if_outer_most_value_is_precise: TypeCheckError # Issue #35630
inference/infer_method_missing_params: ExpectationFileMismatch # Not supposed to be able to infer types if supertypes disagree on number of parameters. An error may be missing as C.f and B.f are not compatible at all.
inference/infer_method_missing_params: TypeCheckError
inference/infer_type_regardless_of_declaration_order_or_cycles: RuntimeError
diff --git a/pkg/front_end/testcases/text_serialization.status b/pkg/front_end/testcases/text_serialization.status
index 35ef84e..8d0e382 100644
--- a/pkg/front_end/testcases/text_serialization.status
+++ b/pkg/front_end/testcases/text_serialization.status
@@ -8,6 +8,7 @@
expression/eval: TextSerializationFailure # Was: Pass
expression/main: TextSerializationFailure # Was: Pass
+extensions/compounds: TextSerializationFailure
extensions/direct_instance_access: TextSerializationFailure
extensions/direct_static_access: TextSerializationFailure
extensions/explicit_extension_access: TextSerializationFailure
@@ -24,6 +25,7 @@
extensions/instance_tearoff: TextSerializationFailure
extensions/invalid_explicit_access: TextSerializationFailure
extensions/nested_on_types: TextSerializationFailure
+extensions/null_aware: TextSerializationFailure
extensions/on_type_inference: TextSerializationFailure
extensions/on_type_variable_inference: TextSerializationFailure
extensions/operators: TextSerializationFailure
@@ -31,6 +33,7 @@
extensions/static_access: TextSerializationFailure
extensions/static_access_of_instance: TextSerializationFailure
extensions/type_variables: TextSerializationFailure
+extensions/unnamed_extensions: TextSerializationFailure
extensions/use_this: TextSerializationFailure
general/error_locations/error_location_01: TextSerializationFailure
general/error_locations/error_location_02: TextSerializationFailure
@@ -94,6 +97,7 @@
general/closure: TextSerializationFailure # Was: Pass
general/co19_language_metadata_syntax_t04: TextSerializationFailure # Was: Pass
general/complex_class_hierarchy: TextSerializationFailure
+general/compound_binary_implicit_as: TextSerializationFailure
general/constructor_const_inference: TextSerializationFailure # Was: Pass
general/constructor_cycle: TextSerializationFailure # Was: Pass
general/constructor_function_types: TextSerializationFailure # Was: Pass
@@ -183,10 +187,13 @@
general/named_parameters: TextSerializationFailure # Was: Pass
general/native_as_name: TextSerializationFailure # Was: Pass
general/nested_implicit_const_with_env_var: TextSerializationFailure # Was: Pass
+general/nested_property_set: TextSerializationFailure
+general/nested_variable_set: TextSerializationFailure
general/no_such_method_private_setter: TextSerializationFailure # Was: Pass
general/no_such_method_private_setter_lib: TextSerializationFailure # Was: Pass
general/non_covariant_checks: TextSerializationFailure
general/null_aware: TextSerializationFailure # Was: Pass
+general/null_aware_for_in: TextSerializationFailure
general/operator_method_not_found: TextSerializationFailure
general/operators: TextSerializationFailure # Was: Pass
general/optional: TypeCheckError
@@ -247,6 +254,7 @@
general/top_level_accessors_part: TextSerializationFailure # Was: Pass
general/top_level_library_method: TextSerializationFailure # Was: Pass
general/type_of_null: TextSerializationFailure
+general/type_variable_bound_access: TypeCheckError
general/type_parameter_type_named_int: TextSerializationFailure
general/type_variable_as_super: TextSerializationFailure # Was: RuntimeError
general/type_variable_prefix: TextSerializationFailure # Was: RuntimeError
@@ -468,7 +476,7 @@
inference/infer_final_field_getter_and_setter: TextSerializationFailure # Was: Pass
inference/infer_final_field_getter_only: TextSerializationFailure # Was: Pass
inference/infer_final_field_setter_only: TextSerializationFailure # Was: Pass
-inference/infer_from_complex_expressions_if_outer_most_value_is_precise: TypeCheckError # Issue #35630
+inference/infer_from_complex_expressions_if_outer_most_value_is_precise: TextSerializationFailure
inference/infer_from_rhs_only_if_it_wont_conflict_with_overridden_fields2: TextSerializationFailure # Was: Pass
inference/infer_from_rhs_only_if_it_wont_conflict_with_overridden_fields: TextSerializationFailure # Was: Pass
inference/infer_from_variables_in_cycle_libs_when_flag_is_on2: TextSerializationFailure # Was: Pass
@@ -828,6 +836,7 @@
instantiate_to_bound/typedef_raw_in_bound: TextSerializationFailure # Was: Pass
instantiate_to_bound/typedef_super_bounded_type: TextSerializationFailure # Was: Pass
new_const_insertion/simple: TextSerializationFailure # Was: Pass
+nnbd/function_types: TextSerializationFailure
nnbd/late: TextSerializationFailure
nnbd/nullable_param: TextSerializationFailure
nnbd/required: TextSerializationFailure
diff --git a/pkg/front_end/tool/_fasta/command_line.dart b/pkg/front_end/tool/_fasta/command_line.dart
index 98ea35d..619c986 100644
--- a/pkg/front_end/tool/_fasta/command_line.dart
+++ b/pkg/front_end/tool/_fasta/command_line.dart
@@ -249,6 +249,8 @@
"--omit-platform": false,
"--fatal": ",",
"--help": false,
+ // TODO(johnniwinther): Remove legacy option flags. Legacy mode is no longer
+ // supported.
"--legacy": "--legacy-mode",
"--legacy-mode": false,
"--libraries-json": Uri,
@@ -299,11 +301,9 @@
"Can't specify both '--compile-sdk' and '--platform'.");
}
- final bool legacyMode = options["--legacy-mode"];
-
final String targetName = options["--target"] ?? "vm";
- final TargetFlags flags = new TargetFlags(legacyMode: legacyMode);
+ final TargetFlags flags = new TargetFlags();
final Target target = getTarget(targetName, flags);
if (target == null) {
@@ -377,7 +377,6 @@
..setExitCodeOnProblem = true
..fileSystem = fileSystem
..packagesFileUri = packages
- ..legacyMode = legacyMode
..target = target
..throwOnErrorsForDebugging = errorsAreFatal
..throwOnWarningsForDebugging = warningsAreFatal
@@ -410,7 +409,9 @@
case 'dart2js_server':
return 'dart2js_platform.dill';
case 'vm':
- return legacyMode ? 'vm_platform.dill' : "vm_platform_strong.dill";
+ // TODO(johnniwinther): Stop generating 'vm_platform.dill' and rename
+ // 'vm_platform_strong.dill' to 'vm_platform.dill'.
+ return "vm_platform_strong.dill";
case 'none':
return "vm_platform_strong.dill";
default:
@@ -432,7 +433,6 @@
..sdkRoot = sdk
..sdkSummary = platform
..packagesFileUri = packages
- ..legacyMode = legacyMode
..target = target
..throwOnErrorsForDebugging = errorsAreFatal
..throwOnWarningsForDebugging = warningsAreFatal
diff --git a/pkg/front_end/tool/compare_dill.dart b/pkg/front_end/tool/compare_dill.dart
new file mode 100644
index 0000000..1711ed5
--- /dev/null
+++ b/pkg/front_end/tool/compare_dill.dart
@@ -0,0 +1,46 @@
+import 'dart:io' show File;
+
+import '../test/binary_md_dill_reader.dart' show DillComparer;
+
+import '../test/utils/io_utils.dart' show computeRepoDir;
+
+main(List<String> args) {
+ if (args.length != 2) {
+ throw "Expects two arguments: The two files to compare";
+ }
+ File fileA = new File(args[0]);
+ File fileB = new File(args[1]);
+
+ List<int> a = fileA.readAsBytesSync();
+ List<int> b = fileB.readAsBytesSync();
+
+ bool shouldCompare = false;
+ if (a.length != b.length) {
+ print("Input lengths are different.");
+ shouldCompare = true;
+ } else {
+ for (int i = 0; i < a.length; ++i) {
+ if (a[i] != b[i]) {
+ print("Data differs at byte ${i + 1}.");
+ shouldCompare = true;
+ }
+ }
+ }
+
+ if (shouldCompare) {
+ StringBuffer message = new StringBuffer();
+ final String repoDir = computeRepoDir();
+ File binaryMd = new File("$repoDir/pkg/kernel/binary.md");
+ String binaryMdContent = binaryMd.readAsStringSync();
+
+ DillComparer dillComparer = new DillComparer();
+ if (dillComparer.compare(a, b, binaryMdContent, message)) {
+ message.writeln(
+ "Somehow the two different byte-lists compared to the same.");
+ }
+
+ print(message);
+ } else {
+ print("Inputs byte-equal!");
+ }
+}
diff --git a/pkg/front_end/tool/fasta_perf.dart b/pkg/front_end/tool/fasta_perf.dart
index 577d582..3ad1726 100644
--- a/pkg/front_end/tool/fasta_perf.dart
+++ b/pkg/front_end/tool/fasta_perf.dart
@@ -36,11 +36,10 @@
print(argParser.usage);
exit(1);
}
- bool legacyMode = options['legacy'];
var bench = options.rest[0];
var entryUri = Uri.base.resolve(options.rest[1]);
- await setup(entryUri, legacyMode: legacyMode);
+ await setup(entryUri);
Map<Uri, List<int>> files = await scanReachableFiles(entryUri);
var handlers = {
@@ -48,10 +47,10 @@
// TODO(sigmund): enable when we can run the ast-builder standalone.
// 'parse': () async => parseFiles(files),
'kernel_gen_e2e': () async {
- await generateKernel(entryUri, legacyMode: legacyMode);
+ await generateKernel(entryUri);
},
'kernel_gen_e2e_sum': () async {
- await generateKernel(entryUri, compileSdk: false, legacyMode: legacyMode);
+ await generateKernel(entryUri, compileSdk: false);
},
};
@@ -90,15 +89,15 @@
/// Preliminary set up to be able to correctly resolve URIs on the given
/// program.
-Future setup(Uri entryUri, {bool legacyMode: false}) async {
+Future setup(Uri entryUri) async {
var options = new CompilerOptions()
..sdkRoot = sdkRoot
// Because this is only used to create a uriResolver, we don't allow any
// whitelisting of error messages in the error handler.
- ..onDiagnostic = onDiagnosticMessageHandler(legacyMode: true)
+ ..onDiagnostic = onDiagnosticMessageHandler()
..compileSdk = true
..packagesFileUri = Uri.base.resolve('.packages')
- ..target = createTarget(isFlutter: false, legacyMode: legacyMode);
+ ..target = createTarget(isFlutter: false);
uriResolver = await new ProcessedOptions(options: options).getUriTranslator();
}
@@ -225,8 +224,7 @@
}
// Invoke the fasta kernel generator for the program starting in [entryUri]
-generateKernel(Uri entryUri,
- {bool compileSdk: true, bool legacyMode: false}) async {
+generateKernel(Uri entryUri, {bool compileSdk: true}) async {
// TODO(sigmund): this is here only to compute the input size,
// we should extract the input size from the frontend instead.
await scanReachableFiles(entryUri);
@@ -234,9 +232,8 @@
var timer = new Stopwatch()..start();
var options = new CompilerOptions()
..sdkRoot = sdkRoot
- ..onDiagnostic = onDiagnosticMessageHandler(legacyMode: legacyMode)
- ..legacyMode = legacyMode
- ..target = createTarget(isFlutter: false, legacyMode: legacyMode)
+ ..onDiagnostic = onDiagnosticMessageHandler()
+ ..target = createTarget(isFlutter: false)
..packagesFileUri = Uri.base.resolve('.packages')
..compileSdk = compileSdk
..environmentDefines = const {};
@@ -267,6 +264,8 @@
}
ArgParser argParser = new ArgParser()
+ // TODO(johnniwinther): Remove legacy option. Legacy mode is no longer
+ // supported.
..addFlag('legacy',
help: 'run the compiler in legacy-mode',
defaultsTo: false,
diff --git a/pkg/front_end/tool/incremental_perf.dart b/pkg/front_end/tool/incremental_perf.dart
index 1d1ddfd..7d87595 100644
--- a/pkg/front_end/tool/incremental_perf.dart
+++ b/pkg/front_end/tool/incremental_perf.dart
@@ -72,7 +72,6 @@
parse(jsonDecode(new File.fromUri(editsUri).readAsStringSync()));
bool verbose = options["verbose"];
bool verboseCompilation = options["verbose-compilation"];
- bool legacyMode = options["mode"] == "legacy";
bool isFlutter = options["target"] == "flutter";
bool useMinimalGenerator = options["implementation"] == "minimal";
TimingsCollector collector = new TimingsCollector(verbose);
@@ -81,7 +80,6 @@
await benchmark(
collector,
entryUri,
- legacyMode,
isFlutter,
useMinimalGenerator,
verbose,
@@ -98,7 +96,6 @@
Future benchmark(
TimingsCollector collector,
Uri entryUri,
- bool legacyMode,
bool isFlutter,
bool useMinimalGenerator,
bool verbose,
@@ -111,9 +108,8 @@
var compilerOptions = new CompilerOptions()
..verbose = verboseCompilation
..fileSystem = overlayFs
- ..legacyMode = legacyMode
- ..onDiagnostic = onDiagnosticMessageHandler(legacyMode: legacyMode)
- ..target = createTarget(isFlutter: isFlutter, legacyMode: legacyMode)
+ ..onDiagnostic = onDiagnosticMessageHandler()
+ ..target = createTarget(isFlutter: isFlutter)
..environmentDefines = const {};
if (sdkSummary != null) {
compilerOptions.sdkSummary = _resolveOverlayUri(sdkSummary);
@@ -301,6 +297,8 @@
help: 'caching policy used by the compiler',
defaultsTo: 'protected',
allowed: ['evicting', 'memory', 'protected'])
+ // TODO(johnniwinther): Remove mode option. Legacy mode is no longer
+ // supported.
..addOption('mode',
help: 'whether to run in strong or legacy mode',
defaultsTo: 'strong',
diff --git a/pkg/front_end/tool/perf_common.dart b/pkg/front_end/tool/perf_common.dart
index 67f93a9..5a8db5e 100644
--- a/pkg/front_end/tool/perf_common.dart
+++ b/pkg/front_end/tool/perf_common.dart
@@ -48,13 +48,12 @@
fastaCodes.codeUndefinedMethod,
]);
-DiagnosticMessageHandler onDiagnosticMessageHandler({bool legacyMode: false}) {
+DiagnosticMessageHandler onDiagnosticMessageHandler() {
bool messageReported = false;
return (DiagnosticMessage m) {
if (m.severity == Severity.internalProblem ||
m.severity == Severity.error) {
- if (legacyMode ||
- !whitelistMessageCode.contains(getMessageCodeObject(m))) {
+ if (!whitelistMessageCode.contains(getMessageCodeObject(m))) {
printDiagnosticMessage(m, stderr.writeln);
exitCode = 1;
} else if (!messageReported) {
@@ -70,8 +69,8 @@
// TODO(sigmund): delete as soon as the disableTypeInference flag and the
// legacyMode flag get merged, and we have a single way of specifying the
// legacy-mode flag to the FE.
-Target createTarget({bool isFlutter: false, bool legacyMode: false}) {
- var flags = new TargetFlags(legacyMode: legacyMode);
+Target createTarget({bool isFlutter: false}) {
+ TargetFlags flags = new TargetFlags();
if (isFlutter) {
return new FlutterTarget(flags);
} else {
diff --git a/pkg/kernel/binary.md b/pkg/kernel/binary.md
index cad20ee..337d47d 100644
--- a/pkg/kernel/binary.md
+++ b/pkg/kernel/binary.md
@@ -143,7 +143,7 @@
type ComponentFile {
UInt32 magic = 0x90ABCDEF;
- UInt32 formatVersion = 31;
+ UInt32 formatVersion = 32;
List<String> problemsAsJson; // Described in problems.md.
Library[] libraries;
UriSource sourceMap;
@@ -228,7 +228,7 @@
}
type Library {
- Byte flags (isExternal, isSynthetic);
+ Byte flags (isExternal, isSynthetic, isNonNullableByDefault);
UInt languageVersionMajor;
UInt languageVersionMinor;
CanonicalNameReference canonicalName;
diff --git a/pkg/kernel/lib/ast.dart b/pkg/kernel/lib/ast.dart
index 4f83479..ae961e9 100644
--- a/pkg/kernel/lib/ast.dart
+++ b/pkg/kernel/lib/ast.dart
@@ -64,6 +64,7 @@
///
library kernel.ast;
+import 'dart:collection' show ListBase;
import 'dart:convert' show utf8;
import 'visitor.dart';
@@ -116,7 +117,7 @@
R accept<R>(TreeVisitor<R> v);
void visitChildren(Visitor v);
- transformChildren(Transformer v);
+ void transformChildren(Transformer v);
/// Replaces [child] with [replacement].
///
@@ -200,7 +201,38 @@
class Reference {
CanonicalName canonicalName;
- NamedNode node;
+ NamedNode _node;
+
+ NamedNode get node {
+ if (_node == null) {
+ // Either this is an unbound reference or it belongs to a lazy-loaded
+ // (and not yet loaded) class. If it belongs to a lazy-loaded class,
+ // load the class.
+
+ CanonicalName canonicalNameParent = canonicalName?.parent;
+ while (canonicalNameParent != null) {
+ if (canonicalNameParent.name.startsWith("@")) {
+ break;
+ }
+ canonicalNameParent = canonicalNameParent.parent;
+ }
+ if (canonicalNameParent != null) {
+ NamedNode parentNamedNode =
+ canonicalNameParent?.parent?.reference?._node;
+ if (parentNamedNode is Class) {
+ Class parentClass = parentNamedNode;
+ if (parentClass.lazyBuilder != null) {
+ parentClass.ensureLoaded();
+ }
+ }
+ }
+ }
+ return _node;
+ }
+
+ void set node(NamedNode node) {
+ _node = node;
+ }
String toString() {
if (canonicalName != null) {
@@ -298,6 +330,7 @@
static const int ExternalFlag = 1 << 0;
static const int SyntheticFlag = 1 << 1;
+ static const int NonNullableByDefaultFlag = 1 << 2;
int flags = 0;
@@ -322,6 +355,13 @@
flags = value ? (flags | SyntheticFlag) : (flags & ~SyntheticFlag);
}
+ bool get isNonNullableByDefault => (flags & NonNullableByDefaultFlag) != 0;
+ void set isNonNullableByDefault(bool value) {
+ flags = value
+ ? (flags | NonNullableByDefaultFlag)
+ : (flags & ~NonNullableByDefaultFlag);
+ }
+
String name;
/// Problems in this [Library] encoded as json objects.
@@ -380,6 +420,23 @@
setParents(this.fields, this);
}
+ Nullability get nullable {
+ return isNonNullableByDefault ? Nullability.nullable : Nullability.legacy;
+ }
+
+ Nullability get nonNullable {
+ return isNonNullableByDefault
+ ? Nullability.nonNullable
+ : Nullability.legacy;
+ }
+
+ Nullability nullableIfTrue(bool isNullable) {
+ if (isNonNullableByDefault) {
+ return isNullable ? Nullability.nullable : Nullability.nonNullable;
+ }
+ return Nullability.legacy;
+ }
+
/// Returns the top-level fields and procedures defined in this library.
///
/// This getter is for convenience, not efficiency. Consider manually
@@ -745,6 +802,41 @@
Body,
}
+/// List-wrapper that marks the parent-class as dirty if the list is modified.
+///
+/// The idea being, that for non-dirty classes (classes just loaded from dill)
+/// the canonical names has already been calculated, and recalculating them is
+/// not needed. If, however, we change anything, recalculation of the canonical
+/// names can be needed.
+class DirtifyingList<E> extends ListBase<E> {
+ final Class dirtifyClass;
+ final List<E> wrapped;
+
+ DirtifyingList(this.dirtifyClass, this.wrapped);
+
+ @override
+ int get length {
+ return wrapped.length;
+ }
+
+ @override
+ void set length(int length) {
+ dirtifyClass.dirty = true;
+ wrapped.length = length;
+ }
+
+ @override
+ E operator [](int index) {
+ return wrapped[index];
+ }
+
+ @override
+ void operator []=(int index, E value) {
+ dirtifyClass.dirty = true;
+ wrapped[index] = value;
+ }
+}
+
/// Declaration of a regular class or a mixin application.
///
/// Mixin applications may not contain fields or procedures, as they implicitly
@@ -885,23 +977,92 @@
/// The types from the `implements` clause.
final List<Supertype> implementedTypes;
+ /// Internal. Should *ONLY* be used from within kernel.
+ ///
+ /// If non-null, the function that will have to be called to fill-out the
+ /// content of this class. Note that this should not be called directly though.
+ void Function() lazyBuilder;
+
+ /// Makes sure the class is loaded, i.e. the fields, procedures etc have been
+ /// loaded from the dill. Generally, one should not need to call this as it is
+ /// done automatically when accessing the lists.
+ void ensureLoaded() {
+ if (lazyBuilder != null) {
+ var lazyBuilderLocal = lazyBuilder;
+ lazyBuilder = null;
+ lazyBuilderLocal();
+ }
+ }
+
+ /// Internal. Should *ONLY* be used from within kernel.
+ ///
+ /// Used for adding fields when reading the dill file.
+ final List<Field> fieldsInternal;
+ DirtifyingList<Field> _fieldsView;
+
/// Fields declared in the class.
///
/// For mixin applications this should be empty.
- final List<Field> fields;
+ List<Field> get fields {
+ ensureLoaded();
+ // If already dirty the caller just might as well add stuff directly too.
+ if (dirty) return fieldsInternal;
+ _fieldsView ??= new DirtifyingList(this, fieldsInternal);
+ return _fieldsView;
+ }
+
+ /// Internal. Should *ONLY* be used from within kernel.
+ ///
+ /// Used for adding constructors when reading the dill file.
+ final List<Constructor> constructorsInternal;
+ DirtifyingList<Constructor> _constructorsView;
/// Constructors declared in the class.
- final List<Constructor> constructors;
+ List<Constructor> get constructors {
+ ensureLoaded();
+ // If already dirty the caller just might as well add stuff directly too.
+ if (dirty) return constructorsInternal;
+ _constructorsView ??= new DirtifyingList(this, constructorsInternal);
+ return _constructorsView;
+ }
+
+ /// Internal. Should *ONLY* be used from within kernel.
+ ///
+ /// Used for adding procedures when reading the dill file.
+ final List<Procedure> proceduresInternal;
+ DirtifyingList<Procedure> _proceduresView;
/// Procedures declared in the class.
///
/// For mixin applications this should only contain forwarding stubs.
- final List<Procedure> procedures;
+ List<Procedure> get procedures {
+ ensureLoaded();
+ // If already dirty the caller just might as well add stuff directly too.
+ if (dirty) return proceduresInternal;
+ _proceduresView ??= new DirtifyingList(this, proceduresInternal);
+ return _proceduresView;
+ }
+
+ /// Internal. Should *ONLY* be used from within kernel.
+ ///
+ /// Used for adding redirecting factory constructor when reading the dill
+ /// file.
+ final List<RedirectingFactoryConstructor>
+ redirectingFactoryConstructorsInternal;
+ DirtifyingList<RedirectingFactoryConstructor>
+ _redirectingFactoryConstructorsView;
/// Redirecting factory constructors declared in the class.
///
/// For mixin applications this should be empty.
- final List<RedirectingFactoryConstructor> redirectingFactoryConstructors;
+ List<RedirectingFactoryConstructor> get redirectingFactoryConstructors {
+ ensureLoaded();
+ // If already dirty the caller just might as well add stuff directly too.
+ if (dirty) return redirectingFactoryConstructorsInternal;
+ _redirectingFactoryConstructorsView ??=
+ new DirtifyingList(this, redirectingFactoryConstructorsInternal);
+ return _redirectingFactoryConstructorsView;
+ }
Class(
{this.name,
@@ -919,23 +1080,24 @@
Reference reference})
: this.typeParameters = typeParameters ?? <TypeParameter>[],
this.implementedTypes = implementedTypes ?? <Supertype>[],
- this.fields = fields ?? <Field>[],
- this.constructors = constructors ?? <Constructor>[],
- this.procedures = procedures ?? <Procedure>[],
- this.redirectingFactoryConstructors =
+ this.fieldsInternal = fields ?? <Field>[],
+ this.constructorsInternal = constructors ?? <Constructor>[],
+ this.proceduresInternal = procedures ?? <Procedure>[],
+ this.redirectingFactoryConstructorsInternal =
redirectingFactoryConstructors ?? <RedirectingFactoryConstructor>[],
super(reference) {
setParents(this.typeParameters, this);
- setParents(this.constructors, this);
- setParents(this.procedures, this);
- setParents(this.fields, this);
- setParents(this.redirectingFactoryConstructors, this);
+ setParents(this.constructorsInternal, this);
+ setParents(this.proceduresInternal, this);
+ setParents(this.fieldsInternal, this);
+ setParents(this.redirectingFactoryConstructorsInternal, this);
this.isAbstract = isAbstract;
this.isAnonymousMixin = isAnonymousMixin;
}
void computeCanonicalNames() {
assert(canonicalName != null);
+ if (!dirty) return;
for (int i = 0; i < fields.length; ++i) {
Field member = fields[i];
canonicalName.getChildFromMember(member).bindTo(member.reference);
@@ -952,6 +1114,7 @@
RedirectingFactoryConstructor member = redirectingFactoryConstructors[i];
canonicalName.getChildFromMember(member).bindTo(member.reference);
}
+ dirty = false;
}
/// The immediate super class, or `null` if this is the root class.
@@ -1008,20 +1171,27 @@
/// The library containing this class.
Library get enclosingLibrary => parent;
+ /// Internal. Should *ONLY* be used from within kernel.
+ ///
+ /// If true we have to compute canonical names for all children of this class.
+ /// if false we can skip it.
+ bool dirty = true;
+
/// Adds a member to this class.
///
/// Throws an error if attempting to add a field or procedure to a mixin
/// application.
void addMember(Member member) {
+ dirty = true;
member.parent = this;
if (member is Constructor) {
- constructors.add(member);
+ constructorsInternal.add(member);
} else if (member is Procedure) {
- procedures.add(member);
+ proceduresInternal.add(member);
} else if (member is Field) {
- fields.add(member);
+ fieldsInternal.add(member);
} else if (member is RedirectingFactoryConstructor) {
- redirectingFactoryConstructors.add(member);
+ redirectingFactoryConstructorsInternal.add(member);
} else {
throw new ArgumentError(member);
}
@@ -1054,9 +1224,6 @@
return new Supertype(this, _getAsTypeArguments(typeParameters));
}
- InterfaceType _rawType;
- InterfaceType get rawType => _rawType ??= new InterfaceType(this);
-
InterfaceType _thisType;
InterfaceType get thisType {
return _thisType ??=
@@ -2302,7 +2469,15 @@
return new NamedType(node.name, node.type, isRequired: node.isRequired);
}
- FunctionType get functionType {
+ /// Returns the function type of the node reusing its type parameters.
+ ///
+ /// This getter works similarly to [functionType], but reuses type parameters
+ /// of the function node (or the class enclosing it -- see the comment on
+ /// [functionType] about constructors of generic classes) in the result. It
+ /// is useful in some contexts, especially when reasoning about the function
+ /// type of the enclosing generic function and in combination with
+ /// [FunctionType.withoutTypeParameters].
+ FunctionType get thisFunctionType {
TreeNode parent = this.parent;
List<NamedType> named =
namedParameters.map(_getNamedTypeOfVariable).toList(growable: false);
@@ -2320,6 +2495,21 @@
requiredParameterCount: requiredParameterCount);
}
+ /// Returns the function type of the function node.
+ ///
+ /// If the function node describes a generic function, the resulting function
+ /// type will be generic. If the function node describes a constructor of a
+ /// generic class, the resulting function type will be generic with its type
+ /// parameters constructed after those of the class. In both cases, if the
+ /// resulting function type is generic, a fresh set of type parameters is used
+ /// in it.
+ FunctionType get functionType {
+ return typeParameters.isEmpty
+ ? thisFunctionType
+ : getFreshTypeParameters(typeParameters)
+ .applyToFunctionType(thisFunctionType);
+ }
+
R accept<R>(TreeVisitor<R> v) => v.visitFunctionNode(this);
visitChildren(Visitor v) {
@@ -2416,7 +2606,7 @@
// subtypes of Object (not just interface types), and function types are
// considered subtypes of Function.
if (superclass.typeParameters.isEmpty) {
- return superclass.rawType;
+ return types.coreTypes.legacyRawType(superclass);
}
var type = getStaticType(types);
while (type is TypeParameterType) {
@@ -2432,7 +2622,7 @@
return superclass.bottomType;
}
types.typeError(this, '$type is not a subtype of $superclass');
- return superclass.rawType;
+ return types.coreTypes.legacyRawType(superclass);
}
R accept<R>(ExpressionVisitor<R> v);
@@ -3229,8 +3419,9 @@
DartType getStaticType(TypeEnvironment types) {
return arguments.types.isEmpty
- ? target.enclosingClass.rawType
- : new InterfaceType(target.enclosingClass, arguments.types);
+ ? types.coreTypes.legacyRawType(target.enclosingClass)
+ : new InterfaceType(
+ target.enclosingClass, arguments.types, Nullability.legacy);
}
R accept<R>(ExpressionVisitor<R> v) => v.visitConstructorInvocation(this);
@@ -3249,10 +3440,16 @@
}
}
+ // TODO(dmitryas): Change the getter into a method that accepts a CoreTypes.
InterfaceType get constructedType {
+ Class enclosingClass = target.enclosingClass;
+ // TODO(dmitryas): Get raw type from a CoreTypes object if arguments is
+ // empty.
return arguments.types.isEmpty
- ? target.enclosingClass.rawType
- : new InterfaceType(target.enclosingClass, arguments.types);
+ ? new InterfaceType(
+ enclosingClass, const <DartType>[], Nullability.legacy)
+ : new InterfaceType(
+ enclosingClass, arguments.types, Nullability.legacy);
}
}
@@ -3561,7 +3758,7 @@
DartType getStaticType(TypeEnvironment types) {
return typeArguments.isEmpty
- ? classNode.rawType
+ ? types.coreTypes.legacyRawType(classNode)
: new InterfaceType(classNode, typeArguments);
}
@@ -4498,13 +4695,13 @@
R accept1<R, A>(StatementVisitor1<R, A> v, A arg) =>
v.visitForInStatement(this, arg);
- visitChildren(Visitor v) {
+ void visitChildren(Visitor v) {
variable?.accept(v);
iterable?.accept(v);
body?.accept(v);
}
- transformChildren(Transformer v) {
+ void transformChildren(Transformer v) {
if (variable != null) {
variable = variable.accept<TreeNode>(v);
variable?.parent = this;
@@ -5901,6 +6098,7 @@
DartType getType(TypeEnvironment types) => types.boolType;
}
+/// An integer constant on a non-JS target.
class IntConstant extends PrimitiveConstant<int> {
IntConstant(int value) : super(value);
@@ -5911,6 +6109,7 @@
DartType getType(TypeEnvironment types) => types.intType;
}
+/// A double constant on a non-JS target or any numeric constant on a JS target.
class DoubleConstant extends PrimitiveConstant<double> {
DoubleConstant(double value) : super(value);
@@ -6326,6 +6525,14 @@
}
void unbindCanonicalNames() {
+ // TODO(jensj): Get rid of this.
+ for (int i = 0; i < libraries.length; i++) {
+ Library lib = libraries[i];
+ for (int j = 0; j < lib.classes.length; j++) {
+ Class c = lib.classes[j];
+ c.dirty = true;
+ }
+ }
root.unbindAll();
}
diff --git a/pkg/kernel/lib/binary/ast_from_binary.dart b/pkg/kernel/lib/binary/ast_from_binary.dart
index 120d1bb..32f2210 100644
--- a/pkg/kernel/lib/binary/ast_from_binary.dart
+++ b/pkg/kernel/lib/binary/ast_from_binary.dart
@@ -87,11 +87,21 @@
/// will not be resolved correctly.
bool _disableLazyReading = false;
+ /// If binary contains metadata section with payloads referencing other nodes
+ /// such Kernel binary can't be read lazily because metadata cross references
+ /// will not be resolved correctly.
+ bool _disableLazyClassReading = false;
+
+ /// Note that [disableLazyClassReading] is incompatible
+ /// with checkCanonicalNames on readComponent.
BinaryBuilder(this._bytes,
{this.filename,
bool disableLazyReading = false,
+ bool disableLazyClassReading = false,
bool alwaysCreateNewNamedNodes})
: _disableLazyReading = disableLazyReading,
+ _disableLazyClassReading =
+ disableLazyReading || disableLazyClassReading,
this.alwaysCreateNewNamedNodes = alwaysCreateNewNamedNodes ?? false;
fail(String message) {
@@ -460,6 +470,7 @@
List<int> componentFileSizes = _indexComponents();
if (componentFileSizes.length > 1) {
_disableLazyReading = true;
+ _disableLazyClassReading = true;
}
int componentFileIndex = 0;
while (_byteOffset < _bytes.length) {
@@ -479,6 +490,7 @@
List<int> componentFileSizes = _indexComponents();
if (componentFileSizes.length > 1) {
_disableLazyReading = true;
+ _disableLazyClassReading = true;
}
int componentFileIndex = 0;
while (_byteOffset < _bytes.length) {
@@ -687,6 +699,8 @@
component.mainMethodName ??= mainMethod;
_byteOffset = _componentStartOffset + componentFileSize;
+
+ assert(typeParameterStack.isEmpty);
}
/// Read a list of strings. If the list is empty, [null] is returned.
@@ -1016,7 +1030,9 @@
}
bool shouldWriteData = node == null || _isReadingLibraryImplementation;
if (node == null) {
- node = new Class(reference: reference)..level = ClassLevel.Temporary;
+ node = new Class(reference: reference)
+ ..level = ClassLevel.Temporary
+ ..dirty = false;
}
var fileUri = readUriReference();
@@ -1036,6 +1052,9 @@
debugPath.add(node.name ?? 'normal-class');
return true;
}());
+
+ assert(typeParameterStack.length == 0);
+
readAndPushTypeParameterList(node.typeParameters, node);
var supertype = readSupertypeOption();
var mixedInType = readSupertypeOption();
@@ -1044,16 +1063,12 @@
} else {
_skipNodeList(readSupertype);
}
- _mergeNamedNodeList(node.fields, (index) => readField(), node);
- _mergeNamedNodeList(node.constructors, (index) => readConstructor(), node);
+ if (_disableLazyClassReading) {
+ readClassPartialContent(node, procedureOffsets);
+ } else {
+ _setLazyLoadClass(node, procedureOffsets);
+ }
- _mergeNamedNodeList(node.procedures, (index) {
- _byteOffset = procedureOffsets[index];
- return readProcedure(procedureOffsets[index + 1]);
- }, node);
- _byteOffset = procedureOffsets.last;
- _mergeNamedNodeList(node.redirectingFactoryConstructors,
- (index) => readRedirectingFactoryConstructor(), node);
typeParameterStack.length = 0;
assert(debugPath.removeLast() != null);
if (shouldWriteData) {
@@ -1120,6 +1135,39 @@
return node;
}
+ /// Reads the partial content of a class, namely fields, procedures,
+ /// constructors and redirecting factory constructors.
+ void readClassPartialContent(Class node, List<int> procedureOffsets) {
+ _mergeNamedNodeList(node.fieldsInternal, (index) => readField(), node);
+ _mergeNamedNodeList(
+ node.constructorsInternal, (index) => readConstructor(), node);
+
+ _mergeNamedNodeList(node.proceduresInternal, (index) {
+ _byteOffset = procedureOffsets[index];
+ return readProcedure(procedureOffsets[index + 1]);
+ }, node);
+ _byteOffset = procedureOffsets.last;
+ _mergeNamedNodeList(node.redirectingFactoryConstructorsInternal,
+ (index) => readRedirectingFactoryConstructor(), node);
+ }
+
+ /// Set the lazyBuilder on the class so it can be lazy loaded in the future.
+ void _setLazyLoadClass(Class node, List<int> procedureOffsets) {
+ final int savedByteOffset = _byteOffset;
+ final int componentStartOffset = _componentStartOffset;
+ final Library currentLibrary = _currentLibrary;
+ node.lazyBuilder = () {
+ _byteOffset = savedByteOffset;
+ _currentLibrary = currentLibrary;
+ assert(typeParameterStack.isEmpty);
+ _componentStartOffset = componentStartOffset;
+ typeParameterStack.addAll(node.typeParameters);
+
+ readClassPartialContent(node, procedureOffsets);
+ typeParameterStack.length = 0;
+ };
+ }
+
int getAndResetTransformerFlags() {
int flags = _transformerFlags;
_transformerFlags = 0;
@@ -1416,8 +1464,7 @@
..fileEndOffset = endOffset;
if (lazyLoadBody) {
- _setLazyLoadFunction(result, oldLabelStackBase, variableStackHeight,
- typeParameterStackHeight);
+ _setLazyLoadFunction(result, oldLabelStackBase, variableStackHeight);
}
labelStackBase = oldLabelStackBase;
@@ -1427,8 +1474,8 @@
return result;
}
- void _setLazyLoadFunction(FunctionNode result, int oldLabelStackBase,
- int variableStackHeight, int typeParameterStackHeight) {
+ void _setLazyLoadFunction(
+ FunctionNode result, int oldLabelStackBase, int variableStackHeight) {
final int savedByteOffset = _byteOffset;
final int componentStartOffset = _componentStartOffset;
final List<TypeParameter> typeParameters = typeParameterStack.toList();
@@ -1447,7 +1494,7 @@
result.body?.parent = result;
labelStackBase = oldLabelStackBase;
variableStack.length = variableStackHeight;
- typeParameterStack.length = typeParameterStackHeight;
+ typeParameterStack.clear();
if (result.parent is Procedure) {
Procedure parent = result.parent;
parent.transformerFlags |= getAndResetTransformerFlags();
diff --git a/pkg/kernel/lib/binary/tag.dart b/pkg/kernel/lib/binary/tag.dart
index dc93073..0645cb9 100644
--- a/pkg/kernel/lib/binary/tag.dart
+++ b/pkg/kernel/lib/binary/tag.dart
@@ -146,7 +146,7 @@
/// Internal version of kernel binary format.
/// Bump it when making incompatible changes in kernel binaries.
/// Keep in sync with runtime/vm/kernel_binary.h, pkg/kernel/binary.md.
- static const int BinaryFormatVersion = 31;
+ static const int BinaryFormatVersion = 32;
}
abstract class ConstantTag {
diff --git a/pkg/kernel/lib/canonical_name.dart b/pkg/kernel/lib/canonical_name.dart
index 29aeac4..71a42bf 100644
--- a/pkg/kernel/lib/canonical_name.dart
+++ b/pkg/kernel/lib/canonical_name.dart
@@ -179,6 +179,12 @@
void unbind() {
if (reference == null) return;
assert(reference.canonicalName == this);
+ if (reference.node is Class) {
+ // TODO(jensj): Get rid of this. This is only needed because pkg:vm does
+ // weird stuff in transformations. `unbind` should probably be private.
+ Class c = reference.node;
+ c.ensureLoaded();
+ }
reference.canonicalName = null;
reference = null;
}
diff --git a/pkg/kernel/lib/class_hierarchy.dart b/pkg/kernel/lib/class_hierarchy.dart
index 73cd12a..b2431be 100644
--- a/pkg/kernel/lib/class_hierarchy.dart
+++ b/pkg/kernel/lib/class_hierarchy.dart
@@ -8,6 +8,7 @@
import 'dart:typed_data';
import 'ast.dart';
+import 'core_types.dart';
import 'src/heap.dart';
import 'type_algebra.dart';
@@ -62,7 +63,7 @@
/// one type is a subtype of the other, or where both types are based on the
/// same class.
InterfaceType getLegacyLeastUpperBound(
- InterfaceType type1, InterfaceType type2);
+ InterfaceType type1, InterfaceType type2, CoreTypes coreTypes);
/// Returns the instantiation of [superclass] that is implemented by [class_],
/// or `null` if [class_] does not implement [superclass] at all.
@@ -540,7 +541,7 @@
@override
InterfaceType getLegacyLeastUpperBound(
- InterfaceType type1, InterfaceType type2) {
+ InterfaceType type1, InterfaceType type2, CoreTypes coreTypes) {
// The algorithm is: first we compute a list of superclasses for both types,
// ordered from greatest to least depth, and ordered by topological sort
// index within each depth. Due to the sort order, we can find the
@@ -614,7 +615,8 @@
// immediately. Since all interface types are subtypes of Object, this
// ensures the loop terminates.
if (next.classNode.typeParameters.isEmpty) {
- candidate = next.classNode.rawType;
+ // TODO(dmitryas): Update nullability as necessary for the LUB spec.
+ candidate = coreTypes.legacyRawType(next.classNode);
if (currentDepth == 0) return candidate;
++numCandidatesAtThisDepth;
} else {
@@ -660,16 +662,14 @@
@override
Member getDispatchTarget(Class class_, Name name, {bool setter: false}) {
- _ClassInfo info = infoFor(class_);
List<Member> list =
- setter ? info.implementedSetters : info.implementedGettersAndCalls;
+ _buildImplementedMembers(class_, infoFor(class_), setters: setter);
return ClassHierarchy.findMemberByName(list, name);
}
@override
List<Member> getDispatchTargets(Class class_, {bool setters: false}) {
- _ClassInfo info = infoFor(class_);
- return setters ? info.implementedSetters : info.implementedGettersAndCalls;
+ return _buildImplementedMembers(class_, infoFor(class_), setters: setters);
}
@override
@@ -685,8 +685,7 @@
@override
List<Member> getDeclaredMembers(Class class_, {bool setters: false}) {
- var info = infoFor(class_);
- return setters ? info.declaredSetters : info.declaredGettersAndCalls;
+ return _buildDeclaredMembers(class_, infoFor(class_), setters: setters);
}
@override
@@ -698,8 +697,10 @@
var superclass = supertype.classNode;
var superGetters = getInterfaceMembers(superclass);
var superSetters = getInterfaceMembers(superclass, setters: true);
- _reportOverrides(info.declaredGettersAndCalls, superGetters, callback);
- _reportOverrides(info.declaredSetters, superSetters, callback,
+ _reportOverrides(_buildDeclaredMembers(class_, info, setters: false),
+ superGetters, callback);
+ _reportOverrides(_buildDeclaredMembers(class_, info, setters: true),
+ superSetters, callback,
isSetter: true);
}
}
@@ -835,13 +836,12 @@
});
for (_ClassInfo info in infos) {
- Class class_ = info.classNode;
- _buildDeclaredMembers(class_, info);
- _buildImplementedMembers(class_, info);
- info.interfaceSetters = null;
- info.interfaceGettersAndCalls = null;
- _buildInterfaceMembers(class_, info, setters: true);
- _buildInterfaceMembers(class_, info, setters: false);
+ info.lazyDeclaredGettersAndCalls = null;
+ info.lazyDeclaredSetters = null;
+ info.lazyImplementedGettersAndCalls = null;
+ info.lazyImplementedSetters = null;
+ info.lazyInterfaceGettersAndCalls = null;
+ info.lazyInterfaceSetters = null;
}
assert(sanityCheckAlsoKnowsParentAndLibrary());
@@ -921,9 +921,6 @@
_recordSuperTypes(info, supertype);
}
- _buildInterfaceMembers(class_, info, setters: true);
- _buildInterfaceMembers(class_, info, setters: false);
-
if (info == null) {
throw "No info for ${class_.name} from ${class_.fileUri}.";
}
@@ -973,8 +970,7 @@
_topologicalSortVisit(supertype.classNode, beingVisited,
orderedList: orderedList));
}
- _buildDeclaredMembers(classNode, info);
- _buildImplementedMembers(classNode, info);
+
info.topologicalIndex = _topSortIndex++;
_infoMap[classNode] = info;
@@ -983,71 +979,92 @@
return info.depth = superDepth + 1;
}
- void _buildDeclaredMembers(Class classNode, _ClassInfo info) {
- if (classNode.mixedInType != null) {
- _ClassInfo mixedInfo = _infoMap[classNode.mixedInType.classNode];
+ List<Member> _buildImplementedMembers(Class classNode, _ClassInfo info,
+ {bool setters}) {
+ if (info == null) {
+ throw "${classNode.fileUri}: No class info for ${classNode.name}";
+ }
+ List<Member> members = setters
+ ? info.lazyImplementedSetters
+ : info.lazyImplementedGettersAndCalls;
+ if (members != null) return members;
- List<Member> declaredGettersAndCalls = <Member>[];
- for (Member mixinMember in mixedInfo.declaredGettersAndCalls) {
- if (mixinMember is! Procedure ||
- (mixinMember is Procedure &&
- !mixinMember.isNoSuchMethodForwarder)) {
- declaredGettersAndCalls.add(mixinMember);
- }
- }
-
- List<Member> declaredSetters = <Member>[];
- for (Member mixinMember in mixedInfo.declaredSetters) {
- if (mixinMember is! Procedure ||
- (mixinMember is Procedure &&
- !mixinMember.isNoSuchMethodForwarder)) {
- declaredSetters.add(mixinMember);
- }
- }
-
- info.declaredGettersAndCalls = declaredGettersAndCalls;
- info.declaredSetters = declaredSetters;
+ List<Member> inherited;
+ if (classNode.supertype == null) {
+ inherited = const <Member>[];
} else {
- var members = info.declaredGettersAndCalls = <Member>[];
- var setters = info.declaredSetters = <Member>[];
+ Class superClassNode = classNode.supertype.classNode;
+ _ClassInfo superInfo = _infoMap[superClassNode];
+ inherited =
+ _buildImplementedMembers(superClassNode, superInfo, setters: setters);
+ }
+ members = _inheritMembers(
+ _buildDeclaredMembers(classNode, info, setters: setters), inherited,
+ skipAbstractMembers: true);
+ if (setters) {
+ info.lazyImplementedSetters = members;
+ } else {
+ info.lazyImplementedGettersAndCalls = members;
+ }
+ return members;
+ }
+
+ List<Member> _buildDeclaredMembers(Class classNode, _ClassInfo info,
+ {bool setters}) {
+ if (info == null) {
+ throw "${classNode.fileUri}: No class info for ${classNode.name}";
+ }
+ List<Member> members =
+ setters ? info.lazyDeclaredSetters : info.lazyDeclaredGettersAndCalls;
+ if (members != null) return members;
+
+ if (classNode.mixedInType != null) {
+ Class mixedInClassNode = classNode.mixedInType.classNode;
+ _ClassInfo mixedInInfo = _infoMap[mixedInClassNode];
+
+ members = <Member>[];
+ for (Member mixinMember in _buildDeclaredMembers(
+ mixedInClassNode, mixedInInfo,
+ setters: setters)) {
+ if (mixinMember is! Procedure ||
+ (mixinMember is Procedure &&
+ !mixinMember.isNoSuchMethodForwarder)) {
+ members.add(mixinMember);
+ }
+ }
+ } else {
+ members = new List<Member>();
for (Procedure procedure in classNode.procedures) {
if (procedure.isStatic) continue;
if (procedure.kind == ProcedureKind.Setter) {
- setters.add(procedure);
+ if (setters) {
+ members.add(procedure);
+ }
} else {
- members.add(procedure);
+ if (!setters) {
+ members.add(procedure);
+ }
}
}
for (Field field in classNode.fields) {
if (field.isStatic) continue;
- if (field.hasImplicitGetter) {
+ if (!setters && field.hasImplicitGetter) {
members.add(field);
}
- if (field.hasImplicitSetter) {
- setters.add(field);
+ if (setters && field.hasImplicitSetter) {
+ members.add(field);
}
}
- members.sort(ClassHierarchy.compareMembers);
- setters.sort(ClassHierarchy.compareMembers);
- }
- }
- void _buildImplementedMembers(Class classNode, _ClassInfo info) {
- List<Member> inheritedMembers;
- List<Member> inheritedSetters;
- if (classNode.supertype == null) {
- inheritedMembers = inheritedSetters = const <Member>[];
- } else {
- _ClassInfo superInfo = _infoMap[classNode.supertype.classNode];
- inheritedMembers = superInfo.implementedGettersAndCalls;
- inheritedSetters = superInfo.implementedSetters;
+ members.sort(ClassHierarchy.compareMembers);
}
- info.implementedGettersAndCalls = _inheritMembers(
- info.declaredGettersAndCalls, inheritedMembers,
- skipAbstractMembers: true);
- info.implementedSetters = _inheritMembers(
- info.declaredSetters, inheritedSetters,
- skipAbstractMembers: true);
+
+ if (setters) {
+ info.lazyDeclaredSetters = members;
+ } else {
+ info.lazyDeclaredGettersAndCalls = members;
+ }
+ return members;
}
List<Member> _buildInterfaceMembers(Class classNode, _ClassInfo info,
@@ -1056,11 +1073,12 @@
throw "${classNode.fileUri}: No class info for ${classNode.name}";
}
List<Member> members =
- setters ? info.interfaceSetters : info.interfaceGettersAndCalls;
+ setters ? info.lazyInterfaceSetters : info.lazyInterfaceGettersAndCalls;
if (members != null) return members;
List<Member> allInheritedMembers = <Member>[];
List<Member> declared =
- setters ? info.declaredSetters : info.declaredGettersAndCalls;
+ _buildDeclaredMembers(classNode, info, setters: setters);
+
void inheritFrom(Supertype type) {
if (type == null) return;
List<Member> inherited = _buildInterfaceMembers(
@@ -1076,9 +1094,9 @@
classNode.implementedTypes.forEach(inheritFrom);
members = _inheritMembers(declared, allInheritedMembers);
if (setters) {
- info.interfaceSetters = members;
+ info.lazyInterfaceSetters = members;
} else {
- info.interfaceGettersAndCalls = members;
+ info.lazyInterfaceGettersAndCalls = members;
}
return members;
}
@@ -1399,22 +1417,22 @@
/// Instance fields, getters, methods, and operators declared in this class
/// or its mixed-in class, sorted according to [_compareMembers].
- List<Member> declaredGettersAndCalls;
+ List<Member> lazyDeclaredGettersAndCalls;
/// Non-final instance fields and setters declared in this class or its
/// mixed-in class, sorted according to [_compareMembers].
- List<Member> declaredSetters;
+ List<Member> lazyDeclaredSetters;
/// Instance fields, getters, methods, and operators implemented by this class
/// (declared or inherited).
- List<Member> implementedGettersAndCalls;
+ List<Member> lazyImplementedGettersAndCalls;
/// Non-final instance fields and setters implemented by this class
/// (declared or inherited).
- List<Member> implementedSetters;
+ List<Member> lazyImplementedSetters;
- List<Member> interfaceGettersAndCalls;
- List<Member> interfaceSetters;
+ List<Member> lazyInterfaceGettersAndCalls;
+ List<Member> lazyInterfaceSetters;
_ClassInfo(this.classNode);
diff --git a/pkg/kernel/lib/clone.dart b/pkg/kernel/lib/clone.dart
index e0dc4e7..f80716e 100644
--- a/pkg/kernel/lib/clone.dart
+++ b/pkg/kernel/lib/clone.dart
@@ -494,6 +494,7 @@
}
visitRedirectingFactoryConstructor(RedirectingFactoryConstructor node) {
+ prepareTypeParameters(node.typeParameters);
return new RedirectingFactoryConstructor(node.targetReference,
name: node.name,
isConst: node.isConst,
@@ -510,12 +511,19 @@
: const <Expression>[];
}
+ void prepareTypeParameters(List<TypeParameter> typeParameters) {
+ for (TypeParameter node in typeParameters) {
+ TypeParameter newNode = typeParams[node];
+ if (newNode == null) {
+ newNode = new TypeParameter(node.name);
+ typeParams[node] = newNode;
+ typeSubstitution[node] = new TypeParameterType(newNode);
+ }
+ }
+ }
+
visitTypeParameter(TypeParameter node) {
TypeParameter newNode = typeParams[node];
- if (newNode == null) {
- newNode = new TypeParameter(node.name);
- typeSubstitution[node] = new TypeParameterType(newNode);
- }
newNode.bound = visitType(node.bound);
if (node.defaultType != null) {
newNode.defaultType = visitType(node.defaultType);
@@ -538,6 +546,7 @@
}
visitFunctionNode(FunctionNode node) {
+ prepareTypeParameters(node.typeParameters);
var typeParameters = node.typeParameters.map(clone).toList();
var positional = node.positionalParameters.map(clone).toList();
var named = node.namedParameters.map(clone).toList();
diff --git a/pkg/kernel/lib/core_types.dart b/pkg/kernel/lib/core_types.dart
index aa8d0f7..9e3dea1 100644
--- a/pkg/kernel/lib/core_types.dart
+++ b/pkg/kernel/lib/core_types.dart
@@ -95,6 +95,80 @@
Field _pragmaOptions;
Constructor _pragmaConstructor;
+ InterfaceType _objectLegacyRawType;
+ InterfaceType _objectNullableRawType;
+ InterfaceType _objectNonNullableRawType;
+ InterfaceType _nullType;
+ InterfaceType _boolLegacyRawType;
+ InterfaceType _boolNullableRawType;
+ InterfaceType _boolNonNullableRawType;
+ InterfaceType _intLegacyRawType;
+ InterfaceType _intNullableRawType;
+ InterfaceType _intNonNullableRawType;
+ InterfaceType _numLegacyRawType;
+ InterfaceType _numNullableRawType;
+ InterfaceType _numNonNullableRawType;
+ InterfaceType _doubleLegacyRawType;
+ InterfaceType _doubleNullableRawType;
+ InterfaceType _doubleNonNullableRawType;
+ InterfaceType _stringLegacyRawType;
+ InterfaceType _stringNullableRawType;
+ InterfaceType _stringNonNullableRawType;
+ InterfaceType _listLegacyRawType;
+ InterfaceType _listNullableRawType;
+ InterfaceType _listNonNullableRawType;
+ InterfaceType _setLegacyRawType;
+ InterfaceType _setNullableRawType;
+ InterfaceType _setNonNullableRawType;
+ InterfaceType _mapLegacyRawType;
+ InterfaceType _mapNullableRawType;
+ InterfaceType _mapNonNullableRawType;
+ InterfaceType _iterableLegacyRawType;
+ InterfaceType _iterableNullableRawType;
+ InterfaceType _iterableNonNullableRawType;
+ InterfaceType _iteratorLegacyRawType;
+ InterfaceType _iteratorNullableRawType;
+ InterfaceType _iteratorNonNullableRawType;
+ InterfaceType _symbolLegacyRawType;
+ InterfaceType _symbolNullableRawType;
+ InterfaceType _symbolNonNullableRawType;
+ InterfaceType _typeLegacyRawType;
+ InterfaceType _typeNullableRawType;
+ InterfaceType _typeNonNullableRawType;
+ InterfaceType _functionLegacyRawType;
+ InterfaceType _functionNullableRawType;
+ InterfaceType _functionNonNullableRawType;
+ InterfaceType _invocationLegacyRawType;
+ InterfaceType _invocationNullableRawType;
+ InterfaceType _invocationNonNullableRawType;
+ InterfaceType _invocationMirrorLegacyRawType;
+ InterfaceType _invocationMirrorNullableRawType;
+ InterfaceType _invocationMirrorNonNullableRawType;
+ InterfaceType _futureLegacyRawType;
+ InterfaceType _futureNullableRawType;
+ InterfaceType _futureNonNullableRawType;
+ InterfaceType _stackTraceLegacyRawType;
+ InterfaceType _stackTraceNullableRawType;
+ InterfaceType _stackTraceNonNullableRawType;
+ InterfaceType _streamLegacyRawType;
+ InterfaceType _streamNullableRawType;
+ InterfaceType _streamNonNullableRawType;
+ InterfaceType _asyncAwaitCompleterLegacyRawType;
+ InterfaceType _asyncAwaitCompleterNullableRawType;
+ InterfaceType _asyncAwaitCompleterNonNullableRawType;
+ InterfaceType _futureOrLegacyRawType;
+ InterfaceType _futureOrNullableRawType;
+ InterfaceType _futureOrNonNullableRawType;
+ InterfaceType _pragmaLegacyRawType;
+ InterfaceType _pragmaNullableRawType;
+ InterfaceType _pragmaNonNullableRawType;
+ final Map<Class, InterfaceType> _legacyRawTypes =
+ new Map<Class, InterfaceType>.identity();
+ final Map<Class, InterfaceType> _nullableRawTypes =
+ new Map<Class, InterfaceType>.identity();
+ final Map<Class, InterfaceType> _nonNullableRawTypes =
+ new Map<Class, InterfaceType>.identity();
+
CoreTypes(Component component)
: index = new LibraryIndex.coreLibraries(component);
@@ -388,4 +462,777 @@
return _boolFromEnvironment ??=
index.getMember('dart:core', 'bool', 'fromEnvironment');
}
+
+ InterfaceType get objectLegacyRawType {
+ return _objectLegacyRawType ??= _legacyRawTypes[objectClass] ??=
+ new InterfaceType(objectClass, const <DartType>[], Nullability.legacy);
+ }
+
+ InterfaceType get objectNullableRawType {
+ return _objectNullableRawType ??= _nullableRawTypes[objectClass] ??=
+ new InterfaceType(
+ objectClass, const <DartType>[], Nullability.nullable);
+ }
+
+ InterfaceType get objectNonNullableRawType {
+ return _objectNonNullableRawType ??= _nonNullableRawTypes[objectClass] ??=
+ new InterfaceType(
+ objectClass, const <DartType>[], Nullability.nonNullable);
+ }
+
+ InterfaceType objectRawType(Nullability nullability) {
+ switch (nullability) {
+ case Nullability.legacy:
+ return objectLegacyRawType;
+ case Nullability.nullable:
+ return objectNullableRawType;
+ case Nullability.nonNullable:
+ return objectNonNullableRawType;
+ case Nullability.neither:
+ default:
+ throw new StateError(
+ "Unsupported nullability $nullability on an InterfaceType.");
+ }
+ }
+
+ /// Null is always nullable, so there's only one raw type for that class.
+ InterfaceType get nullType {
+ return _nullType ??= _nullableRawTypes[nullClass] ??=
+ new InterfaceType(nullClass, const <DartType>[], Nullability.nullable);
+ }
+
+ InterfaceType get boolLegacyRawType {
+ return _boolLegacyRawType ??= _legacyRawTypes[boolClass] ??=
+ new InterfaceType(boolClass, const <DartType>[], Nullability.legacy);
+ }
+
+ InterfaceType get boolNullableRawType {
+ return _boolNullableRawType ??= _nullableRawTypes[boolClass] ??=
+ new InterfaceType(boolClass, const <DartType>[], Nullability.nullable);
+ }
+
+ InterfaceType get boolNonNullableRawType {
+ return _boolNonNullableRawType ??= _nonNullableRawTypes[boolClass] ??=
+ new InterfaceType(
+ boolClass, const <DartType>[], Nullability.nonNullable);
+ }
+
+ InterfaceType boolRawType(Nullability nullability) {
+ switch (nullability) {
+ case Nullability.legacy:
+ return boolLegacyRawType;
+ case Nullability.nullable:
+ return boolNullableRawType;
+ case Nullability.nonNullable:
+ return boolNonNullableRawType;
+ case Nullability.neither:
+ default:
+ throw new StateError(
+ "Unsupported nullability $nullability on an InterfaceType.");
+ }
+ }
+
+ InterfaceType get intLegacyRawType {
+ return _intLegacyRawType ??= _legacyRawTypes[intClass] ??=
+ new InterfaceType(intClass, const <DartType>[], Nullability.legacy);
+ }
+
+ InterfaceType get intNullableRawType {
+ return _intNullableRawType ??= _nullableRawTypes[intClass] ??=
+ new InterfaceType(intClass, const <DartType>[], Nullability.nullable);
+ }
+
+ InterfaceType get intNonNullableRawType {
+ return _intNonNullableRawType ??= _nonNullableRawTypes[intClass] ??=
+ new InterfaceType(
+ intClass, const <DartType>[], Nullability.nonNullable);
+ }
+
+ InterfaceType intRawType(Nullability nullability) {
+ switch (nullability) {
+ case Nullability.legacy:
+ return intLegacyRawType;
+ case Nullability.nullable:
+ return intNullableRawType;
+ case Nullability.nonNullable:
+ return intNonNullableRawType;
+ case Nullability.neither:
+ default:
+ throw new StateError(
+ "Unsupported nullability $nullability on an InterfaceType.");
+ }
+ }
+
+ InterfaceType get numLegacyRawType {
+ return _numLegacyRawType ??= _legacyRawTypes[numClass] ??=
+ new InterfaceType(numClass, const <DartType>[], Nullability.legacy);
+ }
+
+ InterfaceType get numNullableRawType {
+ return _numNullableRawType ??= _nullableRawTypes[numClass] ??=
+ new InterfaceType(numClass, const <DartType>[], Nullability.nullable);
+ }
+
+ InterfaceType get numNonNullableRawType {
+ return _numNonNullableRawType ??= _nonNullableRawTypes[numClass] ??=
+ new InterfaceType(
+ numClass, const <DartType>[], Nullability.nonNullable);
+ }
+
+ InterfaceType numRawType(Nullability nullability) {
+ switch (nullability) {
+ case Nullability.legacy:
+ return numLegacyRawType;
+ case Nullability.nullable:
+ return numNullableRawType;
+ case Nullability.nonNullable:
+ return numNonNullableRawType;
+ case Nullability.neither:
+ default:
+ throw new StateError(
+ "Unsupported nullability $nullability on an InterfaceType.");
+ }
+ }
+
+ InterfaceType get doubleLegacyRawType {
+ return _doubleLegacyRawType ??= _legacyRawTypes[doubleClass] ??=
+ new InterfaceType(doubleClass, const <DartType>[], Nullability.legacy);
+ }
+
+ InterfaceType get doubleNullableRawType {
+ return _doubleNullableRawType ??= _nullableRawTypes[doubleClass] ??=
+ new InterfaceType(
+ doubleClass, const <DartType>[], Nullability.nullable);
+ }
+
+ InterfaceType get doubleNonNullableRawType {
+ return _doubleNonNullableRawType ??= _nonNullableRawTypes[doubleClass] ??=
+ new InterfaceType(
+ doubleClass, const <DartType>[], Nullability.nonNullable);
+ }
+
+ InterfaceType doubleRawType(Nullability nullability) {
+ switch (nullability) {
+ case Nullability.legacy:
+ return doubleLegacyRawType;
+ case Nullability.nullable:
+ return doubleNullableRawType;
+ case Nullability.nonNullable:
+ return doubleNonNullableRawType;
+ case Nullability.neither:
+ default:
+ throw new StateError(
+ "Unsupported nullability $nullability on an InterfaceType.");
+ }
+ }
+
+ InterfaceType get stringLegacyRawType {
+ return _stringLegacyRawType ??= _legacyRawTypes[stringClass] ??=
+ new InterfaceType(stringClass, const <DartType>[], Nullability.legacy);
+ }
+
+ InterfaceType get stringNullableRawType {
+ return _stringNullableRawType ??= _nullableRawTypes[stringClass] ??=
+ new InterfaceType(
+ stringClass, const <DartType>[], Nullability.nullable);
+ }
+
+ InterfaceType get stringNonNullableRawType {
+ return _stringNonNullableRawType ??= _nonNullableRawTypes[stringClass] ??=
+ new InterfaceType(
+ stringClass, const <DartType>[], Nullability.nonNullable);
+ }
+
+ InterfaceType stringRawType(Nullability nullability) {
+ switch (nullability) {
+ case Nullability.legacy:
+ return stringLegacyRawType;
+ case Nullability.nullable:
+ return stringNullableRawType;
+ case Nullability.nonNullable:
+ return stringNonNullableRawType;
+ case Nullability.neither:
+ default:
+ throw new StateError(
+ "Unsupported nullability $nullability on an InterfaceType.");
+ }
+ }
+
+ InterfaceType get listLegacyRawType {
+ return _listLegacyRawType ??= _legacyRawTypes[listClass] ??=
+ new InterfaceType(listClass, const <DartType>[const DynamicType()],
+ Nullability.legacy);
+ }
+
+ InterfaceType get listNullableRawType {
+ return _listNullableRawType ??= _nullableRawTypes[listClass] ??=
+ new InterfaceType(listClass, const <DartType>[const DynamicType()],
+ Nullability.nullable);
+ }
+
+ InterfaceType get listNonNullableRawType {
+ return _listNonNullableRawType ??= _nonNullableRawTypes[listClass] ??=
+ new InterfaceType(listClass, const <DartType>[const DynamicType()],
+ Nullability.nonNullable);
+ }
+
+ InterfaceType listRawType(Nullability nullability) {
+ switch (nullability) {
+ case Nullability.legacy:
+ return listLegacyRawType;
+ case Nullability.nullable:
+ return listNullableRawType;
+ case Nullability.nonNullable:
+ return listNonNullableRawType;
+ case Nullability.neither:
+ default:
+ throw new StateError(
+ "Unsupported nullability $nullability on an InterfaceType.");
+ }
+ }
+
+ InterfaceType get setLegacyRawType {
+ return _setLegacyRawType ??= _legacyRawTypes[setClass] ??=
+ new InterfaceType(setClass, const <DartType>[const DynamicType()],
+ Nullability.legacy);
+ }
+
+ InterfaceType get setNullableRawType {
+ return _setNullableRawType ??= _nullableRawTypes[setClass] ??=
+ new InterfaceType(setClass, const <DartType>[const DynamicType()],
+ Nullability.nullable);
+ }
+
+ InterfaceType get setNonNullableRawType {
+ return _setNonNullableRawType ??= _nonNullableRawTypes[setClass] ??=
+ new InterfaceType(setClass, const <DartType>[const DynamicType()],
+ Nullability.nonNullable);
+ }
+
+ InterfaceType setRawType(Nullability nullability) {
+ switch (nullability) {
+ case Nullability.legacy:
+ return setLegacyRawType;
+ case Nullability.nullable:
+ return setNullableRawType;
+ case Nullability.nonNullable:
+ return setNonNullableRawType;
+ case Nullability.neither:
+ default:
+ throw new StateError(
+ "Unsupported nullability $nullability on an InterfaceType.");
+ }
+ }
+
+ InterfaceType get mapLegacyRawType {
+ return _mapLegacyRawType ??= _legacyRawTypes[mapClass] ??=
+ new InterfaceType(
+ mapClass,
+ const <DartType>[const DynamicType(), const DynamicType()],
+ Nullability.legacy);
+ }
+
+ InterfaceType get mapNullableRawType {
+ return _mapNullableRawType ??= _nullableRawTypes[mapClass] ??=
+ new InterfaceType(
+ mapClass,
+ const <DartType>[const DynamicType(), const DynamicType()],
+ Nullability.nullable);
+ }
+
+ InterfaceType get mapNonNullableRawType {
+ return _mapNonNullableRawType ??= _nonNullableRawTypes[mapClass] ??=
+ new InterfaceType(
+ mapClass,
+ const <DartType>[const DynamicType(), const DynamicType()],
+ Nullability.nonNullable);
+ }
+
+ InterfaceType mapRawType(Nullability nullability) {
+ switch (nullability) {
+ case Nullability.legacy:
+ return mapLegacyRawType;
+ case Nullability.nullable:
+ return mapNullableRawType;
+ case Nullability.nonNullable:
+ return mapNonNullableRawType;
+ case Nullability.neither:
+ default:
+ throw new StateError(
+ "Unsupported nullability $nullability on an InterfaceType.");
+ }
+ }
+
+ InterfaceType get iterableLegacyRawType {
+ return _iterableLegacyRawType ??= _legacyRawTypes[iterableClass] ??=
+ new InterfaceType(iterableClass, const <DartType>[const DynamicType()],
+ Nullability.legacy);
+ }
+
+ InterfaceType get iterableNullableRawType {
+ return _iterableNullableRawType ??= _nullableRawTypes[iterableClass] ??=
+ new InterfaceType(iterableClass, const <DartType>[const DynamicType()],
+ Nullability.nullable);
+ }
+
+ InterfaceType get iterableNonNullableRawType {
+ return _iterableNonNullableRawType ??=
+ _nonNullableRawTypes[iterableClass] ??= new InterfaceType(iterableClass,
+ const <DartType>[const DynamicType()], Nullability.nonNullable);
+ }
+
+ InterfaceType iterableRawType(Nullability nullability) {
+ switch (nullability) {
+ case Nullability.legacy:
+ return iterableLegacyRawType;
+ case Nullability.nullable:
+ return iterableNullableRawType;
+ case Nullability.nonNullable:
+ return iterableNonNullableRawType;
+ case Nullability.neither:
+ default:
+ throw new StateError(
+ "Unsupported nullability $nullability on an InterfaceType.");
+ }
+ }
+
+ InterfaceType get iteratorLegacyRawType {
+ return _iteratorLegacyRawType ??= _legacyRawTypes[iteratorClass] ??=
+ new InterfaceType(iteratorClass, const <DartType>[const DynamicType()],
+ Nullability.legacy);
+ }
+
+ InterfaceType get iteratorNullableRawType {
+ return _iteratorNullableRawType ??= _nullableRawTypes[iteratorClass] ??=
+ new InterfaceType(iteratorClass, const <DartType>[const DynamicType()],
+ Nullability.nullable);
+ }
+
+ InterfaceType get iteratorNonNullableRawType {
+ return _iteratorNonNullableRawType ??=
+ _nonNullableRawTypes[iteratorClass] ??= new InterfaceType(iteratorClass,
+ const <DartType>[const DynamicType()], Nullability.nonNullable);
+ }
+
+ InterfaceType iteratorRawType(Nullability nullability) {
+ switch (nullability) {
+ case Nullability.legacy:
+ return iteratorLegacyRawType;
+ case Nullability.nullable:
+ return iteratorNullableRawType;
+ case Nullability.nonNullable:
+ return iteratorNonNullableRawType;
+ case Nullability.neither:
+ default:
+ throw new StateError(
+ "Unsupported nullability $nullability on an InterfaceType.");
+ }
+ }
+
+ InterfaceType get symbolLegacyRawType {
+ return _symbolLegacyRawType ??= _legacyRawTypes[symbolClass] ??=
+ new InterfaceType(symbolClass, const <DartType>[], Nullability.legacy);
+ }
+
+ InterfaceType get symbolNullableRawType {
+ return _symbolNullableRawType ??= _nullableRawTypes[symbolClass] ??=
+ new InterfaceType(
+ symbolClass, const <DartType>[], Nullability.nullable);
+ }
+
+ InterfaceType get symbolNonNullableRawType {
+ return _symbolNonNullableRawType ??= _nonNullableRawTypes[symbolClass] ??=
+ new InterfaceType(
+ symbolClass, const <DartType>[], Nullability.nonNullable);
+ }
+
+ InterfaceType symbolRawType(Nullability nullability) {
+ switch (nullability) {
+ case Nullability.legacy:
+ return symbolLegacyRawType;
+ case Nullability.nullable:
+ return symbolNullableRawType;
+ case Nullability.nonNullable:
+ return symbolNonNullableRawType;
+ case Nullability.neither:
+ default:
+ throw new StateError(
+ "Unsupported nullability $nullability on an InterfaceType.");
+ }
+ }
+
+ InterfaceType get typeLegacyRawType {
+ return _typeLegacyRawType ??= _legacyRawTypes[typeClass] ??=
+ new InterfaceType(typeClass, const <DartType>[], Nullability.legacy);
+ }
+
+ InterfaceType get typeNullableRawType {
+ return _typeNullableRawType ??= _nullableRawTypes[typeClass] ??=
+ new InterfaceType(typeClass, const <DartType>[], Nullability.nullable);
+ }
+
+ InterfaceType get typeNonNullableRawType {
+ return _typeNonNullableRawType ??= _nonNullableRawTypes[typeClass] ??=
+ new InterfaceType(
+ typeClass, const <DartType>[], Nullability.nonNullable);
+ }
+
+ InterfaceType typeRawType(Nullability nullability) {
+ switch (nullability) {
+ case Nullability.legacy:
+ return typeLegacyRawType;
+ case Nullability.nullable:
+ return typeNullableRawType;
+ case Nullability.nonNullable:
+ return typeNonNullableRawType;
+ case Nullability.neither:
+ default:
+ throw new StateError(
+ "Unsupported nullability $nullability on an InterfaceType.");
+ }
+ }
+
+ InterfaceType get functionLegacyRawType {
+ return _functionLegacyRawType ??= _legacyRawTypes[functionClass] ??=
+ new InterfaceType(
+ functionClass, const <DartType>[], Nullability.legacy);
+ }
+
+ InterfaceType get functionNullableRawType {
+ return _functionNullableRawType ??= _nullableRawTypes[functionClass] ??=
+ new InterfaceType(
+ functionClass, const <DartType>[], Nullability.nullable);
+ }
+
+ InterfaceType get functionNonNullableRawType {
+ return _functionNonNullableRawType ??=
+ _nonNullableRawTypes[functionClass] ??= new InterfaceType(
+ functionClass, const <DartType>[], Nullability.nonNullable);
+ }
+
+ InterfaceType functionRawType(Nullability nullability) {
+ switch (nullability) {
+ case Nullability.legacy:
+ return functionLegacyRawType;
+ case Nullability.nullable:
+ return functionNullableRawType;
+ case Nullability.nonNullable:
+ return functionNonNullableRawType;
+ case Nullability.neither:
+ default:
+ throw new StateError(
+ "Unsupported nullability $nullability on an InterfaceType.");
+ }
+ }
+
+ InterfaceType get invocationLegacyRawType {
+ return _invocationLegacyRawType ??= _legacyRawTypes[invocationClass] ??=
+ new InterfaceType(
+ invocationClass, const <DartType>[], Nullability.legacy);
+ }
+
+ InterfaceType get invocationNullableRawType {
+ return _invocationNullableRawType ??= _nullableRawTypes[invocationClass] ??=
+ new InterfaceType(
+ invocationClass, const <DartType>[], Nullability.nullable);
+ }
+
+ InterfaceType get invocationNonNullableRawType {
+ return _invocationNonNullableRawType ??=
+ _nonNullableRawTypes[invocationClass] ??= new InterfaceType(
+ invocationClass, const <DartType>[], Nullability.nonNullable);
+ }
+
+ InterfaceType invocationRawType(Nullability nullability) {
+ switch (nullability) {
+ case Nullability.legacy:
+ return invocationLegacyRawType;
+ case Nullability.nullable:
+ return invocationNullableRawType;
+ case Nullability.nonNullable:
+ return invocationNonNullableRawType;
+ case Nullability.neither:
+ default:
+ throw new StateError(
+ "Unsupported nullability $nullability on an InterfaceType.");
+ }
+ }
+
+ InterfaceType get invocationMirrorLegacyRawType {
+ return _invocationMirrorLegacyRawType ??=
+ _legacyRawTypes[invocationMirrorClass] ??= new InterfaceType(
+ invocationMirrorClass, const <DartType>[], Nullability.legacy);
+ }
+
+ InterfaceType get invocationMirrorNullableRawType {
+ return _invocationMirrorNullableRawType ??=
+ _nullableRawTypes[invocationMirrorClass] ??= new InterfaceType(
+ invocationMirrorClass, const <DartType>[], Nullability.nullable);
+ }
+
+ InterfaceType get invocationMirrorNonNullableRawType {
+ return _invocationMirrorNonNullableRawType ??=
+ _nonNullableRawTypes[invocationMirrorClass] ??= new InterfaceType(
+ invocationMirrorClass, const <DartType>[], Nullability.nonNullable);
+ }
+
+ InterfaceType invocationMirrorRawType(Nullability nullability) {
+ switch (nullability) {
+ case Nullability.legacy:
+ return invocationMirrorLegacyRawType;
+ case Nullability.nullable:
+ return invocationMirrorNullableRawType;
+ case Nullability.nonNullable:
+ return invocationMirrorNonNullableRawType;
+ case Nullability.neither:
+ default:
+ throw new StateError(
+ "Unsupported nullability $nullability on an InterfaceType.");
+ }
+ }
+
+ InterfaceType get futureLegacyRawType {
+ return _futureLegacyRawType ??= _legacyRawTypes[futureClass] ??=
+ new InterfaceType(futureClass, const <DartType>[const DynamicType()],
+ Nullability.legacy);
+ }
+
+ InterfaceType get futureNullableRawType {
+ return _futureNullableRawType ??= _nullableRawTypes[futureClass] ??=
+ new InterfaceType(futureClass, const <DartType>[const DynamicType()],
+ Nullability.nullable);
+ }
+
+ InterfaceType get futureNonNullableRawType {
+ return _futureNonNullableRawType ??= _nonNullableRawTypes[futureClass] ??=
+ new InterfaceType(futureClass, const <DartType>[const DynamicType()],
+ Nullability.nonNullable);
+ }
+
+ InterfaceType futureRawType(Nullability nullability) {
+ switch (nullability) {
+ case Nullability.legacy:
+ return futureLegacyRawType;
+ case Nullability.nullable:
+ return futureNullableRawType;
+ case Nullability.nonNullable:
+ return futureNonNullableRawType;
+ case Nullability.neither:
+ default:
+ throw new StateError(
+ "Unsupported nullability $nullability on an InterfaceType.");
+ }
+ }
+
+ InterfaceType get stackTraceLegacyRawType {
+ return _stackTraceLegacyRawType ??= _legacyRawTypes[stackTraceClass] ??=
+ new InterfaceType(
+ stackTraceClass, const <DartType>[], Nullability.legacy);
+ }
+
+ InterfaceType get stackTraceNullableRawType {
+ return _stackTraceNullableRawType ??= _nullableRawTypes[stackTraceClass] ??=
+ new InterfaceType(
+ stackTraceClass, const <DartType>[], Nullability.nullable);
+ }
+
+ InterfaceType get stackTraceNonNullableRawType {
+ return _stackTraceNonNullableRawType ??=
+ _nonNullableRawTypes[stackTraceClass] ??= new InterfaceType(
+ stackTraceClass, const <DartType>[], Nullability.nonNullable);
+ }
+
+ InterfaceType stackTraceRawType(Nullability nullability) {
+ switch (nullability) {
+ case Nullability.legacy:
+ return stackTraceLegacyRawType;
+ case Nullability.nullable:
+ return stackTraceNullableRawType;
+ case Nullability.nonNullable:
+ return stackTraceNonNullableRawType;
+ case Nullability.neither:
+ default:
+ throw new StateError(
+ "Unsupported nullability $nullability on an InterfaceType.");
+ }
+ }
+
+ InterfaceType get streamLegacyRawType {
+ return _streamLegacyRawType ??= _legacyRawTypes[streamClass] ??=
+ new InterfaceType(streamClass, const <DartType>[const DynamicType()],
+ Nullability.legacy);
+ }
+
+ InterfaceType get streamNullableRawType {
+ return _streamNullableRawType ??= _nullableRawTypes[streamClass] ??=
+ new InterfaceType(streamClass, const <DartType>[const DynamicType()],
+ Nullability.nullable);
+ }
+
+ InterfaceType get streamNonNullableRawType {
+ return _streamNonNullableRawType ??= _nonNullableRawTypes[streamClass] ??=
+ new InterfaceType(streamClass, const <DartType>[const DynamicType()],
+ Nullability.nonNullable);
+ }
+
+ InterfaceType streamRawType(Nullability nullability) {
+ switch (nullability) {
+ case Nullability.legacy:
+ return streamLegacyRawType;
+ case Nullability.nullable:
+ return streamNullableRawType;
+ case Nullability.nonNullable:
+ return streamNonNullableRawType;
+ case Nullability.neither:
+ default:
+ throw new StateError(
+ "Unsupported nullability $nullability on an InterfaceType.");
+ }
+ }
+
+ InterfaceType get asyncAwaitCompleterLegacyRawType {
+ return _asyncAwaitCompleterLegacyRawType ??=
+ _legacyRawTypes[asyncAwaitCompleterClass] ??= new InterfaceType(
+ asyncAwaitCompleterClass,
+ const <DartType>[const DynamicType()],
+ Nullability.legacy);
+ }
+
+ InterfaceType get asyncAwaitCompleterNullableRawType {
+ return _asyncAwaitCompleterNullableRawType ??=
+ _nullableRawTypes[asyncAwaitCompleterClass] ??= new InterfaceType(
+ asyncAwaitCompleterClass,
+ const <DartType>[const DynamicType()],
+ Nullability.nullable);
+ }
+
+ InterfaceType get asyncAwaitCompleterNonNullableRawType {
+ return _asyncAwaitCompleterNonNullableRawType ??=
+ _nonNullableRawTypes[asyncAwaitCompleterClass] ??= new InterfaceType(
+ asyncAwaitCompleterClass,
+ const <DartType>[const DynamicType()],
+ Nullability.nonNullable);
+ }
+
+ InterfaceType asyncAwaitCompleterRawType(Nullability nullability) {
+ switch (nullability) {
+ case Nullability.legacy:
+ return asyncAwaitCompleterLegacyRawType;
+ case Nullability.nullable:
+ return asyncAwaitCompleterNullableRawType;
+ case Nullability.nonNullable:
+ return asyncAwaitCompleterNonNullableRawType;
+ case Nullability.neither:
+ default:
+ throw new StateError(
+ "Unsupported nullability $nullability on an InterfaceType.");
+ }
+ }
+
+ InterfaceType get futureOrLegacyRawType {
+ return _futureOrLegacyRawType ??= _legacyRawTypes[futureOrClass] ??=
+ new InterfaceType(futureOrClass, const <DartType>[const DynamicType()],
+ Nullability.legacy);
+ }
+
+ InterfaceType get futureOrNullableRawType {
+ return _futureOrNullableRawType ??= _nullableRawTypes[futureOrClass] ??=
+ new InterfaceType(futureOrClass, const <DartType>[const DynamicType()],
+ Nullability.nullable);
+ }
+
+ InterfaceType get futureOrNonNullableRawType {
+ return _futureOrNonNullableRawType ??=
+ _nonNullableRawTypes[futureOrClass] ??= new InterfaceType(futureOrClass,
+ const <DartType>[const DynamicType()], Nullability.nonNullable);
+ }
+
+ InterfaceType futureOrRawType(Nullability nullability) {
+ switch (nullability) {
+ case Nullability.legacy:
+ return futureOrLegacyRawType;
+ case Nullability.nullable:
+ return futureOrNullableRawType;
+ case Nullability.nonNullable:
+ return futureOrNonNullableRawType;
+ case Nullability.neither:
+ default:
+ throw new StateError(
+ "Unsupported nullability $nullability on an InterfaceType.");
+ }
+ }
+
+ InterfaceType get pragmaLegacyRawType {
+ return _pragmaLegacyRawType ??= _legacyRawTypes[pragmaClass] ??=
+ new InterfaceType(pragmaClass, const <DartType>[], Nullability.legacy);
+ }
+
+ InterfaceType get pragmaNullableRawType {
+ return _pragmaNullableRawType ??= _nullableRawTypes[pragmaClass] ??=
+ new InterfaceType(
+ pragmaClass, const <DartType>[], Nullability.nullable);
+ }
+
+ InterfaceType get pragmaNonNullableRawType {
+ return _pragmaNonNullableRawType ??= _nonNullableRawTypes[pragmaClass] ??=
+ new InterfaceType(
+ pragmaClass, const <DartType>[], Nullability.nonNullable);
+ }
+
+ InterfaceType pragmaRawType(Nullability nullability) {
+ switch (nullability) {
+ case Nullability.legacy:
+ return pragmaLegacyRawType;
+ case Nullability.nullable:
+ return pragmaNullableRawType;
+ case Nullability.nonNullable:
+ return pragmaNonNullableRawType;
+ case Nullability.neither:
+ default:
+ throw new StateError(
+ "Unsupported nullability $nullability on an InterfaceType.");
+ }
+ }
+
+ InterfaceType legacyRawType(Class klass) {
+ // TODO(dmitryas): Consider using computeBounds instead of DynamicType here.
+ return _legacyRawTypes[klass] ??= new InterfaceType(
+ klass,
+ new List<DartType>.filled(
+ klass.typeParameters.length, const DynamicType()),
+ Nullability.legacy);
+ }
+
+ InterfaceType nullableRawType(Class klass) {
+ // TODO(dmitryas): Consider using computeBounds instead of DynamicType here.
+ return _nullableRawTypes[klass] ??= new InterfaceType(
+ klass,
+ new List<DartType>.filled(
+ klass.typeParameters.length, const DynamicType()),
+ Nullability.nullable);
+ }
+
+ InterfaceType nonNullableRawType(Class klass) {
+ // TODO(dmitryas): Consider using computeBounds instead of DynamicType here.
+ return _nonNullableRawTypes[klass] ??= new InterfaceType(
+ klass,
+ new List<DartType>.filled(
+ klass.typeParameters.length, const DynamicType()),
+ Nullability.nonNullable);
+ }
+
+ InterfaceType rawType(Class klass, Nullability nullability) {
+ switch (nullability) {
+ case Nullability.legacy:
+ return legacyRawType(klass);
+ case Nullability.nullable:
+ return nullableRawType(klass);
+ case Nullability.nonNullable:
+ return nonNullableRawType(klass);
+ case Nullability.neither:
+ default:
+ throw new StateError(
+ "Unsupported nullability $nullability on an InterfaceType.");
+ }
+ }
}
diff --git a/pkg/kernel/lib/target/targets.dart b/pkg/kernel/lib/target/targets.dart
index 64e3b5b..57673c6 100644
--- a/pkg/kernel/lib/target/targets.dart
+++ b/pkg/kernel/lib/target/targets.dart
@@ -10,10 +10,9 @@
final List<String> targetNames = targets.keys.toList();
class TargetFlags {
- final bool legacyMode;
final bool trackWidgetCreation;
- TargetFlags({this.legacyMode = false, this.trackWidgetCreation = false});
+ TargetFlags({this.trackWidgetCreation = false});
}
typedef Target _TargetBuilder(TargetFlags flags);
@@ -112,8 +111,6 @@
/// transformations.
Map<String, List<String>> get requiredSdkClasses => CoreTypes.requiredClasses;
- bool get legacyMode;
-
/// A derived class may change this to `true` to enable forwarders to
/// user-defined `noSuchMethod` that are generated for each abstract member
/// if such `noSuchMethod` is present.
@@ -274,7 +271,6 @@
NoneTarget(this.flags);
- bool get legacyMode => flags.legacyMode;
String get name => 'none';
List<String> get extraRequiredLibraries => <String>[];
void performModularTransformationsOnLibraries(
diff --git a/pkg/kernel/lib/testing/mock_sdk_component.dart b/pkg/kernel/lib/testing/mock_sdk_component.dart
index c85bdcf..17be30b 100644
--- a/pkg/kernel/lib/testing/mock_sdk_component.dart
+++ b/pkg/kernel/lib/testing/mock_sdk_component.dart
@@ -17,7 +17,7 @@
}
var objectClass = addClass(coreLib, new Class(name: 'Object'));
- var objectType = objectClass.rawType;
+ var objectType = new InterfaceType(objectClass);
TypeParameter typeParam(String name, [DartType bound]) {
return new TypeParameter(name, bound ?? objectType);
diff --git a/pkg/kernel/lib/transformations/continuation.dart b/pkg/kernel/lib/transformations/continuation.dart
index 3e87ef2..d6bf44f 100644
--- a/pkg/kernel/lib/transformations/continuation.dart
+++ b/pkg/kernel/lib/transformations/continuation.dart
@@ -208,7 +208,7 @@
dartAsyncMarker: AsyncMarker.Sync)
..fileOffset = enclosingFunction.fileOffset
..fileEndOffset = enclosingFunction.fileEndOffset
- ..returnType = helper.coreTypes.boolClass.rawType;
+ ..returnType = helper.coreTypes.boolLegacyRawType;
final closureFunction =
new FunctionDeclaration(nestedClosureVariable, function)
diff --git a/pkg/kernel/lib/type_algebra.dart b/pkg/kernel/lib/type_algebra.dart
index d368c2d..cfd4617 100644
--- a/pkg/kernel/lib/type_algebra.dart
+++ b/pkg/kernel/lib/type_algebra.dart
@@ -4,6 +4,7 @@
library kernel.type_algebra;
import 'ast.dart';
+import 'clone.dart';
/// Returns a type where all occurrences of the given type parameters have been
/// replaced with the corresponding types.
@@ -109,11 +110,25 @@
for (int i = 0; i < typeParameters.length; ++i) {
map[typeParameters[i]] = new TypeParameterType(freshParameters[i]);
}
+ CloneVisitor cloner;
for (int i = 0; i < typeParameters.length; ++i) {
- freshParameters[i].bound = substitute(typeParameters[i].bound, map);
- freshParameters[i].defaultType = typeParameters[i].defaultType != null
- ? substitute(typeParameters[i].defaultType, map)
+ TypeParameter typeParameter = typeParameters[i];
+ TypeParameter freshTypeParameter = freshParameters[i];
+
+ freshTypeParameter.bound = substitute(typeParameter.bound, map);
+ freshTypeParameter.defaultType = typeParameter.defaultType != null
+ ? substitute(typeParameter.defaultType, map)
: null;
+ if (typeParameter.annotations.isNotEmpty) {
+ // Annotations can't refer to type parameters, so the cloner shouldn't
+ // perform the substitution.
+ // TODO(dmitryas): Consider rewriting getFreshTypeParameters using cloner
+ // for copying typeParameters as well.
+ cloner ??= new CloneVisitor();
+ for (Expression annotation in typeParameter.annotations) {
+ freshTypeParameter.addAnnotation(cloner.clone(annotation));
+ }
+ }
}
return new FreshTypeParameters(freshParameters, Substitution.fromMap(map));
}
diff --git a/pkg/kernel/lib/type_checker.dart b/pkg/kernel/lib/type_checker.dart
index 6c9af84..90fff29 100644
--- a/pkg/kernel/lib/type_checker.dart
+++ b/pkg/kernel/lib/type_checker.dart
@@ -344,7 +344,7 @@
}
final enclosingFunction = parent as FunctionNode;
if (enclosingFunction.dartAsyncMarker == AsyncMarker.SyncStar) {
- return coreTypes.boolClass.rawType;
+ return coreTypes.boolLegacyRawType;
}
return null;
@@ -424,7 +424,7 @@
Constructor target = node.target;
Arguments arguments = node.arguments;
Class class_ = target.enclosingClass;
- handleCall(arguments, target.function.functionType,
+ handleCall(arguments, target.function.thisFunctionType,
typeParameters: class_.typeParameters);
return new InterfaceType(target.enclosingClass, arguments.types);
}
@@ -458,7 +458,7 @@
@override
DartType visitFunctionExpression(FunctionExpression node) {
handleNestedFunctionNode(node.function);
- return node.function.functionType;
+ return node.function.thisFunctionType;
}
@override
diff --git a/pkg/kernel/lib/type_environment.dart b/pkg/kernel/lib/type_environment.dart
index 795f9d4..98ef5f2 100644
--- a/pkg/kernel/lib/type_environment.dart
+++ b/pkg/kernel/lib/type_environment.dart
@@ -32,16 +32,18 @@
return new HierarchyBasedTypeEnvironment(coreTypes, hierarchy);
}
- InterfaceType get objectType => coreTypes.objectClass.rawType;
- InterfaceType get nullType => coreTypes.nullClass.rawType;
- InterfaceType get boolType => coreTypes.boolClass.rawType;
- InterfaceType get intType => coreTypes.intClass.rawType;
- InterfaceType get numType => coreTypes.numClass.rawType;
- InterfaceType get doubleType => coreTypes.doubleClass.rawType;
- InterfaceType get stringType => coreTypes.stringClass.rawType;
- InterfaceType get symbolType => coreTypes.symbolClass.rawType;
- InterfaceType get typeType => coreTypes.typeClass.rawType;
- InterfaceType get rawFunctionType => coreTypes.functionClass.rawType;
+ // TODO(dmitryas): Remove these getters, use the appropriate member of
+ // CoreTypes at the call sites instead.
+ InterfaceType get objectType => coreTypes.objectLegacyRawType;
+ InterfaceType get nullType => coreTypes.nullType;
+ InterfaceType get boolType => coreTypes.boolLegacyRawType;
+ InterfaceType get intType => coreTypes.intLegacyRawType;
+ InterfaceType get numType => coreTypes.numLegacyRawType;
+ InterfaceType get doubleType => coreTypes.doubleLegacyRawType;
+ InterfaceType get stringType => coreTypes.stringLegacyRawType;
+ InterfaceType get symbolType => coreTypes.symbolLegacyRawType;
+ InterfaceType get typeType => coreTypes.typeLegacyRawType;
+ InterfaceType get rawFunctionType => coreTypes.functionLegacyRawType;
Class get intClass => coreTypes.intClass;
Class get numClass => coreTypes.numClass;
diff --git a/pkg/kernel/lib/visitor.dart b/pkg/kernel/lib/visitor.dart
index d3dc88e..4f95e65 100644
--- a/pkg/kernel/lib/visitor.dart
+++ b/pkg/kernel/lib/visitor.dart
@@ -696,7 +696,7 @@
R visitTypeLiteral(TypeLiteral node, T arg) => defaultExpression(node, arg);
R visitThisExpression(ThisExpression node, T arg) =>
defaultExpression(node, arg);
- R visitConstantExpression(ConstantExpression node, arg) =>
+ R visitConstantExpression(ConstantExpression node, T arg) =>
defaultExpression(node, arg);
R visitRethrow(Rethrow node, T arg) => defaultExpression(node, arg);
R visitThrow(Throw node, T arg) => defaultExpression(node, arg);
diff --git a/pkg/kernel/pubspec.yaml b/pkg/kernel/pubspec.yaml
index d28cdb0..b0b05b0 100644
--- a/pkg/kernel/pubspec.yaml
+++ b/pkg/kernel/pubspec.yaml
@@ -1,7 +1,7 @@
name: kernel
# Currently, kernel API is not stable and users should
# not depend on semver semantics when depending on this package.
-version: 0.3.24
+version: 0.3.25
author: Dart Team <misc@dartlang.org>
description: Dart IR (Intermediate Representation)
homepage: https://github.com/dart-lang/sdk/tree/master/pkg/kernel
diff --git a/pkg/kernel/test/class_hierarchy_test.dart b/pkg/kernel/test/class_hierarchy_test.dart
index 6253f4d..c4bdcd8 100644
--- a/pkg/kernel/test/class_hierarchy_test.dart
+++ b/pkg/kernel/test/class_hierarchy_test.dart
@@ -306,7 +306,7 @@
{Supertype extends_(List<DartType> typeParameterTypes),
List<Supertype> implements_(List<DartType> typeParameterTypes)}) {
var typeParameters = typeParameterNames
- .map((name) => new TypeParameter(name, objectClass.rawType))
+ .map((name) => new TypeParameter(name, coreTypes.objectLegacyRawType))
.toList();
var typeParameterTypes = typeParameters
.map((parameter) => new TypeParameterType(parameter))
@@ -521,12 +521,12 @@
}
void test_getClassAsInstanceOf_generic_extends() {
- var int = coreTypes.intClass.rawType;
- var bool = coreTypes.boolClass.rawType;
+ var int = coreTypes.intLegacyRawType;
+ var bool = coreTypes.boolLegacyRawType;
var a = addGenericClass('A', ['T', 'U']);
- var bT = new TypeParameter('T', objectClass.rawType);
+ var bT = new TypeParameter('T', coreTypes.objectLegacyRawType);
var bTT = new TypeParameterType(bT);
var b = addClass(new Class(
name: 'B',
@@ -549,12 +549,12 @@
}
void test_getClassAsInstanceOf_generic_implements() {
- var int = coreTypes.intClass.rawType;
- var bool = coreTypes.boolClass.rawType;
+ var int = coreTypes.intLegacyRawType;
+ var bool = coreTypes.boolLegacyRawType;
var a = addGenericClass('A', ['T', 'U']);
- var bT = new TypeParameter('T', objectClass.rawType);
+ var bT = new TypeParameter('T', coreTypes.objectLegacyRawType);
var bTT = new TypeParameterType(bT);
var b = addClass(new Class(
name: 'B',
@@ -583,12 +583,12 @@
}
void test_getClassAsInstanceOf_generic_with() {
- var int = coreTypes.intClass.rawType;
- var bool = coreTypes.boolClass.rawType;
+ var int = coreTypes.intLegacyRawType;
+ var bool = coreTypes.boolLegacyRawType;
var a = addGenericClass('A', ['T', 'U']);
- var bT = new TypeParameter('T', objectClass.rawType);
+ var bT = new TypeParameter('T', coreTypes.objectLegacyRawType);
var bTT = new TypeParameterType(bT);
var b = addClass(new Class(
name: 'B',
@@ -1195,12 +1195,12 @@
}
void test_getTypeAsInstanceOf_generic_extends() {
- var int = coreTypes.intClass.rawType;
- var bool = coreTypes.boolClass.rawType;
+ var int = coreTypes.intLegacyRawType;
+ var bool = coreTypes.boolLegacyRawType;
var a = addGenericClass('A', ['T', 'U']);
- var bT = new TypeParameter('T', objectClass.rawType);
+ var bT = new TypeParameter('T', coreTypes.objectLegacyRawType);
var bTT = new TypeParameterType(bT);
var b = addClass(new Class(
name: 'B',
diff --git a/pkg/kernel/test/type_parser.dart b/pkg/kernel/test/type_parser.dart
index a534824..e4b88ae 100644
--- a/pkg/kernel/test/type_parser.dart
+++ b/pkg/kernel/test/type_parser.dart
@@ -328,7 +328,9 @@
TreeNode lookup(String name) {
return name.length == 1
? typeParameters.putIfAbsent(
- name, () => new TypeParameter(name, lookupClass('Object').rawType))
+ name,
+ () => new TypeParameter(
+ name, new InterfaceType(lookupClass('Object'))))
: lookupClass(name);
}
diff --git a/pkg/kernel/test/typedef_unalias_test.dart b/pkg/kernel/test/typedef_unalias_test.dart
index 9457680..f9d448b 100644
--- a/pkg/kernel/test/typedef_unalias_test.dart
+++ b/pkg/kernel/test/typedef_unalias_test.dart
@@ -15,10 +15,10 @@
main() {
harnessTest('`Foo` where typedef Foo = C', (TestHarness harness) {
- var foo = new Typedef('Foo', harness.otherClass.rawType);
+ var foo = new Typedef('Foo', harness.otherLegacyRawType);
harness.enclosingLibrary.addTypedef(foo);
var type = new TypedefType(foo);
- expect(type.unalias, equals(harness.otherClass.rawType));
+ expect(type.unalias, equals(harness.otherLegacyRawType));
});
harnessTest('`Foo<Obj>` where typedef Foo<T> = C<T>', (TestHarness harness) {
var param = harness.makeTypeParameter('T');
@@ -26,9 +26,9 @@
new InterfaceType(harness.otherClass, [new TypeParameterType(param)]),
typeParameters: [param]);
harness.enclosingLibrary.addTypedef(foo);
- var input = new TypedefType(foo, [harness.objectClass.rawType]);
+ var input = new TypedefType(foo, [harness.objectLegacyRawType]);
var expected =
- new InterfaceType(harness.otherClass, [harness.objectClass.rawType]);
+ new InterfaceType(harness.otherClass, [harness.objectLegacyRawType]);
expect(input.unalias, equals(expected));
});
harnessTest('`Bar<Obj>` where typedef Bar<T> = Foo<T>, Foo<T> = C<T>',
@@ -45,9 +45,9 @@
typeParameters: [barParam]);
harness.enclosingLibrary.addTypedef(foo);
harness.enclosingLibrary.addTypedef(bar);
- var input = new TypedefType(bar, [harness.objectClass.rawType]);
+ var input = new TypedefType(bar, [harness.objectLegacyRawType]);
var expected =
- new InterfaceType(harness.otherClass, [harness.objectClass.rawType]);
+ new InterfaceType(harness.otherClass, [harness.objectLegacyRawType]);
expect(input.unalias, equals(expected));
});
harnessTest('`Foo<Foo<C>>` where typedef Foo<T> = C<T>',
@@ -58,10 +58,10 @@
typeParameters: [param]);
harness.enclosingLibrary.addTypedef(foo);
var input = new TypedefType(foo, [
- new TypedefType(foo, [harness.objectClass.rawType])
+ new TypedefType(foo, [harness.objectLegacyRawType])
]);
var expected = new InterfaceType(harness.otherClass, [
- new TypedefType(foo, [harness.objectClass.rawType])
+ new TypedefType(foo, [harness.objectLegacyRawType])
]);
expect(input.unalias, equals(expected));
});
diff --git a/pkg/kernel/test/verify_test.dart b/pkg/kernel/test/verify_test.dart
index 7f32330..56498c6 100644
--- a/pkg/kernel/test/verify_test.dart
+++ b/pkg/kernel/test/verify_test.dart
@@ -274,7 +274,7 @@
});
positiveTest('Valid typedef Foo = `(C) => void`', (TestHarness test) {
var typedef_ = new Typedef(
- 'Foo', new FunctionType([test.otherClass.rawType], const VoidType()));
+ 'Foo', new FunctionType([test.otherLegacyRawType], const VoidType()));
test.addNode(typedef_);
});
positiveTest('Valid typedef Foo = C<dynamic>', (TestHarness test) {
@@ -286,7 +286,7 @@
var foo = new Typedef('Foo', null);
var bar = new Typedef('Bar', null);
foo.type = new TypedefType(bar);
- bar.type = test.otherClass.rawType;
+ bar.type = test.otherLegacyRawType;
test.enclosingLibrary.addTypedef(foo);
test.enclosingLibrary.addTypedef(bar);
});
@@ -294,13 +294,13 @@
var foo = new Typedef('Foo', null);
var bar = new Typedef('Bar', null);
foo.type = new InterfaceType(test.otherClass, [new TypedefType(bar)]);
- bar.type = test.otherClass.rawType;
+ bar.type = test.otherLegacyRawType;
test.enclosingLibrary.addTypedef(foo);
test.enclosingLibrary.addTypedef(bar);
});
positiveTest('Valid typedef type in field', (TestHarness test) {
var typedef_ = new Typedef(
- 'Foo', new FunctionType([test.otherClass.rawType], const VoidType()));
+ 'Foo', new FunctionType([test.otherLegacyRawType], const VoidType()));
var field = new Field(new Name('field'),
type: new TypedefType(typedef_), isStatic: true);
test.enclosingLibrary.addTypedef(typedef_);
@@ -396,14 +396,14 @@
first.type = new TypedefType(typedef_);
});
positiveTest('Valid typedef Foo<T extends C> = C<T>', (TestHarness test) {
- var param = new TypeParameter('T', test.otherClass.rawType);
+ var param = new TypeParameter('T', test.otherLegacyRawType);
var foo = new Typedef('Foo',
new InterfaceType(test.otherClass, [new TypeParameterType(param)]),
typeParameters: [param]);
test.addNode(foo);
});
positiveTest('Valid typedef Foo<T extends C<T>> = C<T>', (TestHarness test) {
- var param = new TypeParameter('T', test.otherClass.rawType);
+ var param = new TypeParameter('T', test.otherLegacyRawType);
param.bound =
new InterfaceType(test.otherClass, [new TypeParameterType(param)]);
var foo = new Typedef('Foo',
@@ -458,7 +458,7 @@
" but the typedef declares 1 parameters.", (TestHarness test) {
var param = test.makeTypeParameter('T');
var foo =
- new Typedef('Foo', test.otherClass.rawType, typeParameters: [param]);
+ new Typedef('Foo', test.otherLegacyRawType, typeParameters: [param]);
var field = new Field(new Name('field'),
type: new TypedefType(foo, []), isStatic: true);
test.enclosingLibrary.addTypedef(foo);
@@ -468,7 +468,7 @@
'Dangling typedef reference',
"Dangling reference to 'typedef Foo = test_lib::OtherClass<dynamic>*;\n'"
", parent is: 'null'", (TestHarness test) {
- var foo = new Typedef('Foo', test.otherClass.rawType, typeParameters: []);
+ var foo = new Typedef('Foo', test.otherLegacyRawType, typeParameters: []);
var field = new Field(new Name('field'),
type: new TypedefType(foo, []), isStatic: true);
test.enclosingLibrary.addMember(field);
@@ -503,6 +503,10 @@
Class otherClass;
+ InterfaceType objectLegacyRawType;
+ InterfaceType enclosingLegacyRawType;
+ InterfaceType otherLegacyRawType;
+
void addNode(TreeNode node) {
if (node is Expression) {
addExpression(node);
@@ -545,7 +549,7 @@
VariableDeclaration makeVariable() => new VariableDeclaration(null);
TypeParameter makeTypeParameter([String name]) {
- return new TypeParameter(name, new InterfaceType(objectClass));
+ return new TypeParameter(name, objectLegacyRawType);
}
TestHarness() {
@@ -558,6 +562,8 @@
component.libraries.add(stubLibrary..parent = component);
stubLibrary.name = 'dart.core';
objectClass = new Class(name: 'Object');
+ objectLegacyRawType =
+ new InterfaceType(objectClass, const <DartType>[], Nullability.legacy);
stubLibrary.addClass(objectClass);
enclosingLibrary = new Library(Uri.parse('file://test.dart'));
component.libraries.add(enclosingLibrary..parent = component);
@@ -567,6 +573,8 @@
name: 'TestClass',
typeParameters: [classTypeParameter],
supertype: objectClass.asRawSupertype);
+ enclosingLegacyRawType = new InterfaceType(enclosingClass,
+ const <DartType>[const DynamicType()], Nullability.legacy);
enclosingLibrary.addClass(enclosingClass);
enclosingMember = new Procedure(new Name('test'), ProcedureKind.Method,
new FunctionNode(new EmptyStatement()));
@@ -575,6 +583,8 @@
name: 'OtherClass',
typeParameters: [makeTypeParameter('OtherT')],
supertype: objectClass.asRawSupertype);
+ otherLegacyRawType = new InterfaceType(
+ otherClass, const <DartType>[const DynamicType()], Nullability.legacy);
enclosingLibrary.addClass(otherClass);
}
}
diff --git a/pkg/nnbd_migration/lib/instrumentation.dart b/pkg/nnbd_migration/lib/instrumentation.dart
new file mode 100644
index 0000000..a108610
--- /dev/null
+++ b/pkg/nnbd_migration/lib/instrumentation.dart
@@ -0,0 +1,259 @@
+// Copyright (c) 2019, 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.
+
+import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/dart/element/type.dart';
+import 'package:analyzer/src/generated/source.dart';
+import 'package:nnbd_migration/nnbd_migration.dart';
+import 'package:nnbd_migration/nullability_state.dart';
+
+/// Information exposed to the migration client about the set of nullability
+/// nodes decorating a type in the program being migrated.
+abstract class DecoratedTypeInfo {
+ /// Information about the graph node associated with the decision of whether
+ /// or not to make this type into a nullable type.
+ NullabilityNodeInfo get node;
+
+ /// If [type] is a function type, information about the set of nullability
+ /// nodes decorating the type's return type.
+ DecoratedTypeInfo get returnType;
+
+ /// The original (pre-migration) type that is being migrated.
+ DartType get type;
+
+ /// If [type] is a function type, looks up information about the set of
+ /// nullability nodes decorating one of the type's named parameter types.
+ DecoratedTypeInfo namedParameter(String name);
+
+ /// If [type] is a function type, looks up information about the set of
+ /// nullability nodes decorating one of the type's positional parameter types.
+ /// (This could be an optional or a required positional parameter).
+ DecoratedTypeInfo positionalParameter(int i);
+
+ /// If [type] is an interface type, looks up information about the set of
+ /// nullability nodes decorating one of the type's type arguments.
+ DecoratedTypeInfo typeArgument(int i);
+}
+
+/// Information exposed to the migration client about an edge in the nullability
+/// graph.
+///
+/// A graph edge represents a dependency relationship between two types being
+/// migrated, suggesting that if one type (the source) is made nullable, it may
+/// be desirable to make the other type (the destination) nullable as well.
+abstract class EdgeInfo implements FixReasonInfo {
+ /// Information about the graph node that this edge "points to".
+ NullabilityNodeInfo get destinationNode;
+
+ /// The set of "guard nodes" for this edge. Guard nodes are graph nodes whose
+ /// nullability determines whether it is important to satisfy a graph edge.
+ /// If at least one of an edge's guards is non-nullable, then it is not
+ /// important to satisfy the graph edge. (Typically this is because the code
+ /// that led to the graph edge being created is only reachable if the guards
+ /// are all nullable).
+ Iterable<NullabilityNodeInfo> get guards;
+
+ /// A boolean indicating whether the graph edge is a "hard" edge. Hard edges
+ /// are associated with unconditional control flow, and thus allow information
+ /// about non-nullability to be propagated "upstream" through the nullability
+ /// graph.
+ bool get isHard;
+
+ /// A boolean indicating whether the graph edge is "satisfied". At its heart,
+ /// the nullability propagation algorithm is an effort to satisfy graph edges
+ /// in a way that corresponds to the user's intent. A graph edge is
+ /// considered satisfied if any of the following is true:
+ /// - Its [sourceNode] is non-nullable.
+ /// - One of its [guards] is non-nullable.
+ /// - Its [destinationNode] is nullable.
+ bool get isSatisfied;
+
+ /// A boolean indicating whether the graph edge is a "union" edge. Union
+ /// edges are edges for which the nullability propagation algorithm tries to
+ /// ensure that both the [sourceNode] and the [destinationNode] have the
+ /// same nullability. Typically these are associated with situations where
+ /// Dart language semantics require two types to be the same type (e.g. a type
+ /// formal bound on a generic function type in a base class, and the
+ /// corresponding type formal bound on a generic function type in an
+ /// overriding class).
+ ///
+ /// The [isHard] property is always true for union edges.
+ bool get isUnion;
+
+ /// Information about the graph node that this edge "points away from".
+ NullabilityNodeInfo get sourceNode;
+}
+
+/// Information exposed to the migration client about the location in source
+/// code that led an edge to be introduced into the nullability graph.
+abstract class EdgeOriginInfo {
+ /// The AST node that led the edge to be introduced into the nullability
+ /// graph.
+ AstNode get node;
+
+ /// The source file that [node] appears in.
+ Source get source;
+}
+
+/// Interface used by the migration engine to expose information to its client
+/// about a reason for a modification to the source file.
+abstract class FixReasonInfo {}
+
+/// Interface used by the migration engine to expose information to its client
+/// about the decisions made during migration, and how those decisions relate to
+/// the input source code.
+abstract class NullabilityMigrationInstrumentation {
+ /// Called whenever an explicit [typeAnnotation] is found in the source code,
+ /// to report the nullability [node] that was associated with this type. If
+ /// the migration engine determines that the [node] should be nullable, a `?`
+ /// will be inserted after the type annotation.
+ void explicitTypeNullability(
+ Source source, TypeAnnotation typeAnnotation, NullabilityNodeInfo node);
+
+ /// Called whenever reference is made to an [element] outside of the code
+ /// being migrated, to report the nullability nodes associated with the type
+ /// of the element.
+ void externalDecoratedType(Element element, DecoratedTypeInfo decoratedType);
+
+ /// Called whenever a fix is decided upon, to report the reasons for the fix.
+ void fix(SingleNullabilityFix fix, Iterable<FixReasonInfo> reasons);
+
+ /// Called whenever the migration engine creates a graph edge between
+ /// nullability nodes, to report information about the edge that was created,
+ /// and why it was created.
+ void graphEdge(EdgeInfo edge, EdgeOriginInfo originInfo);
+
+ /// Called when the migration engine start up, to report information about the
+ /// immutable migration nodes [never] and [always] that are used as the
+ /// starting point for nullability propagation.
+ void immutableNodes(NullabilityNodeInfo never, NullabilityNodeInfo always);
+
+ /// Called whenever the migration engine encounters an implicit return type
+ /// associated with an AST node, to report the nullability nodes associated
+ /// with the implicit return type of the AST node.
+ ///
+ /// [node] is the AST node having an implicit return type; it may be an
+ /// executable declaration, function-typed formal parameter declaration,
+ /// function type alias declaration, GenericFunctionType, or a function
+ /// expression.
+ void implicitReturnType(
+ Source source, AstNode node, DecoratedTypeInfo decoratedReturnType);
+
+ /// Called whenever the migration engine encounters an implicit type
+ /// associated with an AST node, to report the nullability nodes associated
+ /// with the implicit type of the AST node.
+ ///
+ /// [node] is the AST node having an implicit type; it may be a formal
+ /// parameter, a declared identifier, or a variable in a variable declaration
+ /// list.
+ void implicitType(
+ Source source, AstNode node, DecoratedTypeInfo decoratedType);
+
+ /// Called whenever the migration engine encounters an AST node with implicit
+ /// type arguments, to report the nullability nodes associated with the
+ /// implicit type arguments of the AST node.
+ ///
+ /// [node] is the AST node having implicit type arguments; it may be a
+ /// constructor redirection, function expression invocation, method
+ /// invocation, instance creation expression, list/map/set literal, or type
+ /// annotation.
+ void implicitTypeArguments(
+ Source source, AstNode node, Iterable<DecoratedTypeInfo> types);
+
+ /// Called whenever the migration engine performs a step in the propagation of
+ /// nullability information through the nullability graph, to report details
+ /// of the step that was performed and why.
+ void propagationStep(PropagationInfo info);
+}
+
+/// Information exposed to the migration client about a single node in the
+/// nullability graph.
+abstract class NullabilityNodeInfo implements FixReasonInfo {
+ /// Indicates whether the node is immutable. The only immutable nodes in the
+ /// nullability graph are the nodes `never` and `always` that are used as the
+ /// starting points for nullability propagation.
+ bool get isImmutable;
+
+ /// After migration is complete, this getter can be used to query whether
+ /// the type associated with this node was determined to be nullable.
+ bool get isNullable;
+}
+
+/// Information exposed to the migration client about a single step in the
+/// nullability propagation algorithm, in which the nullability state of a
+/// single node was changed.
+abstract class PropagationInfo {
+ /// The edge that caused the nullability state of [node] to be set to
+ /// [newState], or `null` if the nullability state was changed for reasons
+ /// not associated with an edge. Will be `null` when [reason] is
+ /// [StateChangeReason.substituteInner] or
+ /// [StateChangeReason.substituteOuter], non-null otherwise.
+ EdgeInfo get edge;
+
+ /// The new state that [node] was placed into.
+ NullabilityState get newState;
+
+ /// The nullability node whose state was changed.
+ NullabilityNodeInfo get node;
+
+ /// The reason the nullability node's state was changed.
+ StateChangeReason get reason;
+
+ /// The substitution node that caused the nullability state of [node] to be
+ /// set to [newState], or `null` if the nullability state was changed for
+ /// reasons not associated with a substitution node. Will be non-null when
+ /// [reason] is [StateChangeReason.substituteInner] or
+ /// [StateChangeReason.substituteOuter], `null` otherwise.
+ SubstitutionNodeInfo get substitutionNode;
+}
+
+/// Enum representing the various reasons why a nullability node might change
+/// state during nullability propagation.
+enum StateChangeReason {
+ /// A union edge exists between this node and a node that is known a priori to
+ /// be nullable, so this node is being made nullable as well.
+ union,
+
+ /// A hard or union edge exists whose source is this node, and whose
+ /// destination is non-nullable, so this node is being made non-nullable as
+ /// well.
+ upstream,
+
+ /// An edge exists whose destination is this node, and whose source is
+ /// nullable, so this node is being made nullable as well.
+ downstream,
+
+ /// An edge exists whose source is this node, and whose destination is exact
+ /// nullable, so this node is being made exact nullable as well.
+ exactUpstream,
+
+ /// A substitution node exists whose inner node points to this node, and the
+ /// substitution node is nullable, so this node is being made nullable as
+ /// well.
+ substituteInner,
+
+ /// A substitution node exists whose outer node points to this node, and the
+ /// substitution node is nullable, so this node is being made nullable as
+ /// well.
+ substituteOuter,
+}
+
+/// Information exposed to the migration client about a node in the nullability
+/// graph resulting from a type substitution.
+abstract class SubstitutionNodeInfo extends NullabilityNodeInfo {
+ /// Nullability node representing the inner type of the substitution.
+ ///
+ /// For example, if this NullabilityNode arose from substituting `int*` for
+ /// `T` in the type `T*`, [innerNode] is the nullability corresponding to the
+ /// `*` in `int*`.
+ NullabilityNodeInfo get innerNode;
+
+ /// Nullability node representing the outer type of the substitution.
+ ///
+ /// For example, if this NullabilityNode arose from substituting `int*` for
+ /// `T` in the type `T*`, [innerNode] is the nullability corresponding to the
+ /// `*` in `T*`.
+ NullabilityNodeInfo get outerNode;
+}
diff --git a/pkg/nnbd_migration/lib/nnbd_migration.dart b/pkg/nnbd_migration/lib/nnbd_migration.dart
index e20f78f..8bb4062 100644
--- a/pkg/nnbd_migration/lib/nnbd_migration.dart
+++ b/pkg/nnbd_migration/lib/nnbd_migration.dart
@@ -7,6 +7,7 @@
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/src/generated/source.dart';
import 'package:meta/meta.dart';
+import 'package:nnbd_migration/instrumentation.dart';
import 'package:nnbd_migration/src/nullability_migration_impl.dart';
/// Description of fixes that might be performed by nullability migration.
@@ -68,7 +69,9 @@
/// complete. TODO(paulberry): remove this mode once the migration algorithm
/// is fully implemented.
factory NullabilityMigration(NullabilityMigrationListener listener,
- {bool permissive}) = NullabilityMigrationImpl;
+ {bool permissive,
+ NullabilityMigrationInstrumentation instrumentation}) =
+ NullabilityMigrationImpl;
void finish();
diff --git a/pkg/nnbd_migration/lib/nullability_state.dart b/pkg/nnbd_migration/lib/nullability_state.dart
new file mode 100644
index 0000000..fdeda46
--- /dev/null
+++ b/pkg/nnbd_migration/lib/nullability_state.dart
@@ -0,0 +1,36 @@
+// Copyright (c) 2019, 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.
+
+/// State of a nullability node.
+class NullabilityState {
+ /// State of a nullability node whose nullability hasn't been decided yet.
+ static const undetermined = NullabilityState._('undetermined', false);
+
+ /// State of a nullability node that has been determined to be non-nullable
+ /// by propagating upstream.
+ static const nonNullable = NullabilityState._('non-nullable', false);
+
+ /// State of a nullability node that has been determined to be nullable by
+ /// propagating downstream.
+ static const ordinaryNullable = NullabilityState._('ordinary nullable', true);
+
+ /// State of a nullability node that has been determined to be nullable by
+ /// propagating upstream from a contravariant use of a generic.
+ static const exactNullable = NullabilityState._('exact nullable', true);
+
+ /// Name of the state (for use in debugging).
+ final String name;
+
+ /// Indicates whether the given state should be considered nullable.
+ ///
+ /// After propagation, any nodes that remain in the undetermined state are
+ /// considered to be non-nullable, so this field is returns `false` for nodes
+ /// in that state.
+ final bool isNullable;
+
+ const NullabilityState._(this.name, this.isNullable);
+
+ @override
+ String toString() => name;
+}
diff --git a/pkg/nnbd_migration/lib/src/already_migrated_code_decorator.dart b/pkg/nnbd_migration/lib/src/already_migrated_code_decorator.dart
index f34d762..23c98c2 100644
--- a/pkg/nnbd_migration/lib/src/already_migrated_code_decorator.dart
+++ b/pkg/nnbd_migration/lib/src/already_migrated_code_decorator.dart
@@ -3,6 +3,7 @@
// BSD-style license that can be found in the LICENSE file.
import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/dart/element/nullability_suffix.dart';
import 'package:analyzer/dart/element/type.dart';
import 'package:analyzer/src/dart/element/type.dart';
import 'package:analyzer/src/generated/resolver.dart';
@@ -89,11 +90,10 @@
allSupertypes.addAll(class_.superclassConstraints);
allSupertypes.addAll(class_.interfaces);
allSupertypes.addAll(class_.mixins);
- var type = class_.type;
+ var type = class_.thisType;
if (type.isDartAsyncFuture) {
// Add FutureOr<T> as a supertype of Future<T>.
- allSupertypes
- .add(_typeProvider.futureOrType.instantiate(type.typeArguments));
+ allSupertypes.add(_typeProvider.futureOrType2(type.typeArguments.single));
}
return allSupertypes.map(decorate);
}
diff --git a/pkg/nnbd_migration/lib/src/conditional_discard.dart b/pkg/nnbd_migration/lib/src/conditional_discard.dart
index 144bd82..0295834 100644
--- a/pkg/nnbd_migration/lib/src/conditional_discard.dart
+++ b/pkg/nnbd_migration/lib/src/conditional_discard.dart
@@ -2,6 +2,7 @@
// 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.
+import 'package:nnbd_migration/instrumentation.dart';
import 'package:nnbd_migration/src/nullability_node.dart';
/// Container for information gathered during nullability migration about a
@@ -48,4 +49,10 @@
/// Indicates whether the code path that results from the condition evaluating
/// to `true` is reachable after migration.
bool get keepTrue => trueGuard == null || trueGuard.isNullable;
+
+ @override
+ Iterable<FixReasonInfo> get reasons sync* {
+ if (!keepTrue) yield falseGuard;
+ if (!keepFalse) yield trueGuard;
+ }
}
diff --git a/pkg/nnbd_migration/lib/src/decorated_class_hierarchy.dart b/pkg/nnbd_migration/lib/src/decorated_class_hierarchy.dart
index 8c46c9e..3935f4d4 100644
--- a/pkg/nnbd_migration/lib/src/decorated_class_hierarchy.dart
+++ b/pkg/nnbd_migration/lib/src/decorated_class_hierarchy.dart
@@ -3,6 +3,7 @@
// BSD-style license that can be found in the LICENSE file.
import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/dart/element/nullability_suffix.dart';
import 'package:analyzer/dart/element/type.dart';
import 'package:nnbd_migration/src/decorated_type.dart';
import 'package:nnbd_migration/src/node_builder.dart';
@@ -53,7 +54,13 @@
ClassElement class_, ClassElement superclass) {
assert(!(class_.library.isDartCore && class_.name == 'Null'));
if (superclass.typeParameters.isEmpty) {
- return DecoratedType(superclass.type, _graph.never);
+ return DecoratedType(
+ superclass.instantiate(
+ typeArguments: const [],
+ nullabilitySuffix: NullabilitySuffix.none,
+ ),
+ _graph.never,
+ );
}
return _getGenericSupertypeDecorations(class_)[superclass] ??
(throw StateError('Unrelated types: $class_ and $superclass'));
diff --git a/pkg/nnbd_migration/lib/src/decorated_type.dart b/pkg/nnbd_migration/lib/src/decorated_type.dart
index 9982d1f..8cb67ac 100644
--- a/pkg/nnbd_migration/lib/src/decorated_type.dart
+++ b/pkg/nnbd_migration/lib/src/decorated_type.dart
@@ -6,13 +6,15 @@
import 'package:analyzer/dart/element/type.dart';
import 'package:analyzer/src/dart/element/element.dart';
import 'package:analyzer/src/dart/element/type.dart';
+import 'package:analyzer/src/dart/element/type_algebra.dart';
import 'package:analyzer/src/generated/resolver.dart';
+import 'package:nnbd_migration/instrumentation.dart';
import 'package:nnbd_migration/src/nullability_node.dart';
/// Representation of a type in the code to be migrated. In addition to
/// tracking the (unmigrated) [DartType], we track the [ConstraintVariable]s
/// indicating whether the type, and the types that compose it, are nullable.
-class DecoratedType {
+class DecoratedType implements DecoratedTypeInfo {
/// Mapping from type parameter elements to the decorated types of those type
/// parameters' bounds.
///
@@ -21,11 +23,13 @@
/// stored in [Variables._decoratedTypeParameterBounds].
static final _decoratedTypeParameterBounds = Expando<DecoratedType>();
+ @override
final DartType type;
+ @override
final NullabilityNode node;
- /// If `this` is a function type, the [DecoratedType] of its return type.
+ @override
final DecoratedType returnType;
/// If `this` is a function type, the [DecoratedType] of each of its
@@ -319,6 +323,12 @@
type.instantiate(undecoratedArgumentTypes), substitution);
}
+ @override
+ DecoratedTypeInfo namedParameter(String name) => namedParameters[name];
+
+ @override
+ DecoratedTypeInfo positionalParameter(int i) => positionalParameters[i];
+
/// Apply the given [substitution] to this type.
///
/// [undecoratedResult] is the result of the substitution, as determined by
@@ -328,13 +338,10 @@
[DartType undecoratedResult]) {
if (substitution.isEmpty) return this;
if (undecoratedResult == null) {
- List<DartType> argumentTypes = [];
- List<DartType> parameterTypes = [];
- for (var entry in substitution.entries) {
- argumentTypes.add(entry.value.type);
- parameterTypes.add(entry.key.type);
- }
- undecoratedResult = type.substitute2(argumentTypes, parameterTypes);
+ undecoratedResult = Substitution.fromPairs(
+ substitution.keys.toList(),
+ substitution.values.map((d) => d.type).toList(),
+ ).substituteType(type);
}
return _substitute(substitution, undecoratedResult);
}
@@ -387,6 +394,9 @@
}
}
+ @override
+ DecoratedTypeInfo typeArgument(int i) => typeArguments[i];
+
/// Creates a shallow copy of `this`, replacing the nullability node.
DecoratedType withNode(NullabilityNode node) => DecoratedType(type, node,
returnType: returnType,
diff --git a/pkg/nnbd_migration/lib/src/edge_builder.dart b/pkg/nnbd_migration/lib/src/edge_builder.dart
index f802599..1663b16 100644
--- a/pkg/nnbd_migration/lib/src/edge_builder.dart
+++ b/pkg/nnbd_migration/lib/src/edge_builder.dart
@@ -16,6 +16,7 @@
import 'package:analyzer/src/generated/source.dart';
import 'package:front_end/src/fasta/flow_analysis/flow_analysis.dart';
import 'package:meta/meta.dart';
+import 'package:nnbd_migration/instrumentation.dart';
import 'package:nnbd_migration/nnbd_migration.dart';
import 'package:nnbd_migration/src/conditional_discard.dart';
import 'package:nnbd_migration/src/decorated_class_hierarchy.dart';
@@ -96,6 +97,8 @@
final NullabilityMigrationListener /*?*/ listener;
+ final NullabilityMigrationInstrumentation /*?*/ instrumentation;
+
final NullabilityGraph _graph;
TypeProvider _typeProvider;
@@ -189,7 +192,8 @@
List<String> _objectGetNames;
EdgeBuilder(this._typeProvider, this._typeSystem, this._variables,
- this._graph, this.source, this.listener)
+ this._graph, this.source, this.listener,
+ {this.instrumentation})
: _decoratedClassHierarchy = DecoratedClassHierarchy(_variables, _graph),
_inheritanceManager = InheritanceManager3(_typeSystem),
_notNullType = DecoratedType(_typeProvider.objectType, _graph.never),
@@ -263,7 +267,22 @@
var intentNode = _conditionInfo.trueDemonstratesNonNullIntent;
if (intentNode != null && _conditionInfo.postDominatingIntent) {
_graph.connect(_conditionInfo.trueDemonstratesNonNullIntent,
- _graph.never, NonNullAssertionOrigin(source, node.offset),
+ _graph.never, NonNullAssertionOrigin(source, node),
+ hard: true);
+ }
+ }
+ node.message?.accept(this);
+ return null;
+ }
+
+ @override
+ DecoratedType visitAssertInitializer(AssertInitializer node) {
+ _checkExpressionNotNull(node.condition);
+ if (identical(_conditionInfo?.condition, node.condition)) {
+ var intentNode = _conditionInfo.trueDemonstratesNonNullIntent;
+ if (intentNode != null && _conditionInfo.postDominatingIntent) {
+ _graph.connect(_conditionInfo.trueDemonstratesNonNullIntent,
+ _graph.never, NonNullAssertionOrigin(source, node),
hard: true);
}
}
@@ -273,17 +292,16 @@
@override
DecoratedType visitAssignmentExpression(AssignmentExpression node) {
- _CompoundOperatorInfo compoundOperatorInfo;
bool isQuestionAssign = false;
+ bool isCompound = false;
if (node.operator.type == TokenType.QUESTION_QUESTION_EQ) {
isQuestionAssign = true;
} else if (node.operator.type != TokenType.EQ) {
- compoundOperatorInfo = _CompoundOperatorInfo(
- node.staticElement, node.operator.offset, node.staticType);
+ isCompound = true;
}
var expressionType = _handleAssignment(node.rightHandSide,
destinationExpression: node.leftHandSide,
- compoundOperatorInfo: compoundOperatorInfo,
+ compoundOperatorInfo: isCompound ? node : null,
questionAssignNode: isQuestionAssign ? node : null);
var conditionalNode = _conditionalNodes[node.leftHandSide];
if (conditionalNode != null) {
@@ -356,8 +374,8 @@
});
var ifNullNode = NullabilityNode.forIfNotNull();
expressionType = DecoratedType(node.staticType, ifNullNode);
- _connect(rightType.node, expressionType.node,
- IfNullOrigin(source, node.offset));
+ _connect(
+ rightType.node, expressionType.node, IfNullOrigin(source, node));
} finally {
_flowAnalysis.ifNullExpression_end();
_guards.removeLast();
@@ -461,7 +479,7 @@
.asSubstitution);
var superConstructorDecoratedType =
_variables.decoratedElementType(superConstructorElement);
- var origin = ImplicitMixinSuperCallOrigin(source, node.offset);
+ var origin = ImplicitMixinSuperCallOrigin(source, node);
_unionDecoratedTypeParameters(
constructorDecoratedType, superConstructorDecoratedType, origin);
}
@@ -546,7 +564,7 @@
_connect(
_graph.always,
getOrComputeElementType(node.declaredElement).node,
- OptionalFormalParameterOrigin(source, node.offset));
+ OptionalFormalParameterOrigin(source, node));
}
} else {
_handleAssignment(defaultValue,
@@ -604,7 +622,7 @@
var parameterElement = node.declaredElement as FieldFormalParameterElement;
var parameterType = _variables.decoratedElementType(parameterElement);
var fieldType = _variables.decoratedElementType(parameterElement.field);
- var origin = FieldFormalParameterOrigin(source, node.offset);
+ var origin = FieldFormalParameterOrigin(source, node);
if (node.type == null) {
_unionDecoratedTypes(parameterType, fieldType, origin);
} else {
@@ -799,6 +817,8 @@
decoratedTypeArguments = typeArgumentTypes
.map((t) => DecoratedType.forImplicitType(_typeProvider, t, _graph))
.toList();
+ instrumentation?.implicitTypeArguments(
+ source, node, decoratedTypeArguments);
} else {
// Note: this could happen if the code being migrated has errors.
typeArgumentTypes = const [];
@@ -821,16 +841,36 @@
@override
DecoratedType visitIsExpression(IsExpression node) {
var type = node.type;
- if (type is NamedType && type.typeArguments != null) {
- // TODO(brianwilkerson) Figure out what constraints we need to add to
- // allow the tool to decide whether to make the type arguments nullable.
- // TODO(brianwilkerson)
- _unimplemented(node, 'Is expression with type arguments');
+ type.accept(this);
+ var decoratedType = _variables.decoratedTypeAnnotation(source, type);
+ if (type is NamedType) {
+ // The main type of the is check historically could not be nullable.
+ // Making it nullable could change runtime behavior.
+ _connect(decoratedType.node, _graph.never,
+ IsCheckMainTypeOrigin(source, type));
+ if (type.typeArguments != null) {
+ // TODO(mfairhurst): connect arguments to the expression type when they
+ // relate.
+ type.typeArguments.arguments.forEach((argument) {
+ _connect(
+ _graph.always,
+ _variables.decoratedTypeAnnotation(source, argument).node,
+ IsCheckComponentTypeOrigin(source, argument));
+ });
+ }
} else if (type is GenericFunctionType) {
// TODO(brianwilkerson)
_unimplemented(node, 'Is expression with GenericFunctionType');
}
- node.visitChildren(this);
+ var expression = node.expression;
+ expression.accept(this);
+ if (expression is SimpleIdentifier) {
+ var element = expression.staticElement;
+ if (element is VariableElement) {
+ _flowAnalysis.isExpression_end(
+ node, element, node.notOperator != null, decoratedType);
+ }
+ }
return DecoratedType(node.staticType, _graph.never);
}
@@ -854,8 +894,10 @@
try {
var listType = node.staticType as InterfaceType;
if (node.typeArguments == null) {
- _currentLiteralElementType = DecoratedType.forImplicitType(
+ var elementType = DecoratedType.forImplicitType(
_typeProvider, listType.typeArguments[0], _graph);
+ instrumentation?.implicitTypeArguments(source, node, [elementType]);
+ _currentLiteralElementType = elementType;
} else {
_currentLiteralElementType = _variables.decoratedTypeAnnotation(
source, node.typeArguments.arguments[0]);
@@ -1082,8 +1124,10 @@
try {
if (typeArguments == null) {
assert(setOrMapType.typeArguments.length == 1);
- _currentLiteralElementType = DecoratedType.forImplicitType(
+ var elementType = DecoratedType.forImplicitType(
_typeProvider, setOrMapType.typeArguments[0], _graph);
+ instrumentation?.implicitTypeArguments(source, node, [elementType]);
+ _currentLiteralElementType = elementType;
} else {
assert(typeArguments.length == 1);
_currentLiteralElementType =
@@ -1103,10 +1147,14 @@
try {
if (typeArguments == null) {
assert(setOrMapType.typeArguments.length == 2);
- _currentMapKeyType = DecoratedType.forImplicitType(
+ var keyType = DecoratedType.forImplicitType(
_typeProvider, setOrMapType.typeArguments[0], _graph);
- _currentMapValueType = DecoratedType.forImplicitType(
+ _currentMapKeyType = keyType;
+ var valueType = DecoratedType.forImplicitType(
_typeProvider, setOrMapType.typeArguments[1], _graph);
+ _currentMapValueType = valueType;
+ instrumentation
+ ?.implicitTypeArguments(source, node, [keyType, valueType]);
} else {
assert(typeArguments.length == 2);
_currentMapKeyType =
@@ -1157,8 +1205,8 @@
if (_typeSystem.isSubtypeOf(
spreadType, _typeProvider.mapObjectObjectType)) {
assert(_currentMapKeyType != null && _currentMapValueType != null);
- final expectedType = _typeSystem.instantiateType(_typeProvider.mapType,
- [_currentMapKeyType.type, _currentMapValueType.type]);
+ final expectedType = _typeProvider.mapType2(
+ _currentMapKeyType.type, _currentMapValueType.type);
final expectedDecoratedType = DecoratedType.forImplicitType(
_typeProvider, expectedType, _graph,
typeArguments: [_currentMapKeyType, _currentMapValueType]);
@@ -1168,8 +1216,8 @@
} else if (_typeSystem.isSubtypeOf(
spreadType, _typeProvider.iterableDynamicType)) {
assert(_currentLiteralElementType != null);
- final expectedType = _typeSystem.instantiateType(
- _typeProvider.iterableType, [_currentLiteralElementType.type]);
+ final expectedType =
+ _typeProvider.iterableType2(_currentLiteralElementType.type);
final expectedDecoratedType = DecoratedType.forImplicitType(
_typeProvider, expectedType, _graph,
typeArguments: [_currentLiteralElementType]);
@@ -1290,7 +1338,7 @@
throw new StateError('No type annotation for type name '
'${typeName.toSource()}, offset=${typeName.offset}');
}
- var origin = InstantiateToBoundsOrigin(source, typeName.offset);
+ var origin = InstantiateToBoundsOrigin(source, typeName);
for (int i = 0; i < instantiatedType.typeArguments.length; i++) {
_unionDecoratedTypes(
instantiatedType.typeArguments[i],
@@ -1335,7 +1383,7 @@
'(${initializer.toSource()}) offset=${initializer.offset}');
}
_unionDecoratedTypes(initializerType, destinationType,
- InitializerInferenceOrigin(source, variable.name.offset));
+ InitializerInferenceOrigin(source, variable));
} else {
_handleAssignment(initializer, destinationType: destinationType);
}
@@ -1413,8 +1461,8 @@
{bool hard = false}) {
var edge = _graph.connect(source, destination, origin,
hard: hard, guards: _guards);
- if (origin is ExpressionChecks) {
- origin.edges.add(edge);
+ if (origin is ExpressionChecksOrigin) {
+ origin.checks.edges.add(edge);
}
}
@@ -1545,7 +1593,7 @@
DecoratedType _handleAssignment(Expression expression,
{DecoratedType destinationType,
Expression destinationExpression,
- _CompoundOperatorInfo compoundOperatorInfo,
+ AssignmentExpression compoundOperatorInfo,
Expression questionAssignNode,
bool canInsertChecks = true}) {
assert(
@@ -1576,16 +1624,18 @@
throw StateError('No type computed for ${expression.runtimeType} '
'(${expression.toSource()}) offset=${expression.offset}');
}
- ExpressionChecks expressionChecks;
+ ExpressionChecksOrigin expressionChecksOrigin;
if (canInsertChecks && !sourceType.type.isDynamic) {
- expressionChecks = ExpressionChecks(expression.end);
- _variables.recordExpressionChecks(source, expression, expressionChecks);
+ expressionChecksOrigin = ExpressionChecksOrigin(
+ source, expression, ExpressionChecks(expression.end));
+ _variables.recordExpressionChecks(
+ source, expression, expressionChecksOrigin);
}
if (compoundOperatorInfo != null) {
- var compoundOperatorMethod = compoundOperatorInfo.method;
+ var compoundOperatorMethod = compoundOperatorInfo.staticElement;
if (compoundOperatorMethod != null) {
_checkAssignment(
- CompoundAssignmentOrigin(source, compoundOperatorInfo.offset),
+ CompoundAssignmentOrigin(source, compoundOperatorInfo),
source: destinationType,
destination: _notNullType,
hard: _postDominatedLocals
@@ -1593,14 +1643,14 @@
DecoratedType compoundOperatorType =
getOrComputeElementType(compoundOperatorMethod);
assert(compoundOperatorType.positionalParameters.length > 0);
- _checkAssignment(expressionChecks,
+ _checkAssignment(expressionChecksOrigin,
source: sourceType,
destination: compoundOperatorType.positionalParameters[0],
hard: _postDominatedLocals.isReferenceInScope(expression));
- sourceType = _fixNumericTypes(compoundOperatorType.returnType,
- compoundOperatorInfo.undecoratedType);
+ sourceType = _fixNumericTypes(
+ compoundOperatorType.returnType, compoundOperatorInfo.staticType);
_checkAssignment(
- CompoundAssignmentOrigin(source, compoundOperatorInfo.offset),
+ CompoundAssignmentOrigin(source, compoundOperatorInfo),
source: sourceType,
destination: destinationType,
hard: false);
@@ -1608,7 +1658,7 @@
sourceType = _dynamicType;
}
} else {
- _checkAssignment(expressionChecks,
+ _checkAssignment(expressionChecksOrigin,
source: sourceType,
destination: destinationType,
hard: _postDominatedLocals.isReferenceInScope(expression));
@@ -1690,9 +1740,9 @@
}
if (declaredElement is! ConstructorElement) {
var classElement = declaredElement.enclosingElement as ClassElement;
- var origin = InheritanceOrigin(source, node.offset);
+ var origin = InheritanceOrigin(source, node);
for (var overriddenElement in _inheritanceManager.getOverridden(
- classElement.type,
+ classElement.thisType,
Name(classElement.library.source.uri, declaredElement.name)) ??
const <ExecutableElement>[]) {
if (overriddenElement is ExecutableMember) {
@@ -1787,11 +1837,33 @@
_flowAnalysis.for_bodyBegin(
node is Statement ? node : null, parts.condition);
} else if (parts is ForEachParts) {
+ Element lhsElement;
if (parts is ForEachPartsWithDeclaration) {
- _flowAnalysis.add(parts.loopVariable.declaredElement, assigned: true);
+ var variableElement = parts.loopVariable.declaredElement;
+ lhsElement = variableElement;
+ _flowAnalysis.add(variableElement, assigned: false);
+ } else if (parts is ForEachPartsWithIdentifier) {
+ lhsElement = parts.identifier.staticElement;
+ } else {
+ throw StateError(
+ 'Unexpected ForEachParts subtype: ${parts.runtimeType}');
}
- _checkExpressionNotNull(parts.iterable);
- _flowAnalysis.forEach_bodyBegin(_assignedVariables.writtenInNode(node));
+ var iterableType = _checkExpressionNotNull(parts.iterable);
+ if (lhsElement != null) {
+ DecoratedType lhsType = _variables.decoratedElementType(lhsElement);
+ var iterableTypeType = iterableType.type;
+ if (_typeSystem.isSubtypeOf(
+ iterableTypeType, _typeProvider.iterableDynamicType)) {
+ var elementType = _decoratedClassHierarchy
+ .asInstanceOf(
+ iterableType, _typeProvider.iterableDynamicType.element)
+ .typeArguments[0];
+ _checkAssignment(ForEachVariableOrigin(source, parts),
+ source: elementType, destination: lhsType, hard: false);
+ }
+ }
+ _flowAnalysis.forEach_bodyBegin(_assignedVariables.writtenInNode(node),
+ lhsElement is VariableElement ? lhsElement : null);
}
// The condition may fail/iterable may be empty, so the body gets a new
@@ -1859,6 +1931,7 @@
.map((argType) =>
DecoratedType.forImplicitType(_typeProvider, argType, _graph))
.toList();
+ instrumentation?.implicitTypeArguments(source, node, argumentTypes);
calleeType = calleeType.instantiate(argumentTypes);
} else if (constructorTypeParameters != null) {
// No need to instantiate; caller has already substituted in the
@@ -1907,8 +1980,8 @@
// Any parameters not supplied must be optional.
for (var entry in calleeType.namedParameters.entries) {
if (suppliedNamedParameters.contains(entry.key)) continue;
- entry.value.node.recordNamedParameterNotSupplied(_guards, _graph,
- NamedParameterNotSuppliedOrigin(source, node.offset));
+ entry.value.node.recordNamedParameterNotSupplied(
+ _guards, _graph, NamedParameterNotSuppliedOrigin(source, node));
}
return calleeType.returnType;
}
@@ -2012,7 +2085,7 @@
NullabilityNode _nullabilityNodeForGLB(
AstNode astNode, NullabilityNode leftNode, NullabilityNode rightNode) {
var node = NullabilityNode.forGLB();
- var origin = GreatestLowerBoundOrigin(source, astNode.offset);
+ var origin = GreatestLowerBoundOrigin(source, astNode);
_graph.connect(leftNode, node, origin, guards: [rightNode]);
_graph.connect(node, leftNode, origin);
_graph.connect(node, rightNode, origin);
@@ -2127,12 +2200,50 @@
return;
}
if (destinationType.isDartAsyncFutureOr) {
+ var s1 = destination.typeArguments[0];
+ if (sourceType.isDartAsyncFutureOr) {
+ // This is a special case not in the subtyping spec. The subtyping spec
+ // covers this case by expanding the LHS first, which is fine but
+ // leads to redundant edges (which might be confusing for users)
+ // if T0 is FutureOr<S0> then:
+ // - T0 <: T1 iff Future<S0> <: T1 and S0 <: T1
+ // Since T1 is FutureOr<S1>, this is equivalent to:
+ // - T0 <: T1 iff (Future<S0> <: Future<S1> or Future<S0> <: S1) and
+ // (S0 <: Future<S1> or S0 <: S1)
+ // Which is equivalent to:
+ // - T0 <: T1 iff (S0 <: S1 or Future<S0> <: S1) and
+ // (S0 <: Future<S1> or S0 <: S1)
+ // Which is equivalent to (distributing the "and"):
+ // - T0 <: T1 iff (S0 <: S1 and (S0 <: Future<S1> or S0 <: S1)) or
+ // (Future<S0> <: S1 and (S0 <: Future<S1> or S0 <: S1))
+ // Which is equivalent to (distributing the "and"s):
+ // - T0 <: T1 iff (S0 <: S1 and S0 <: Future<S1>) or
+ // (S0 <: S1 and S0 <: S1) or
+ // (Future<S0> <: S1 and S0 <: Future<S1>) or
+ // (Future<S0> <: S1 and S0 <: S1)
+ // If S0 <: S1, the relation is satisfied. Otherwise the only term that
+ // matters is (Future<S0> <: S1 and S0 <: Future<S1>), so this is
+ // equivalent to:
+ // - T0 <: T1 iff S0 <: S1 or (Future<S0> <: S1 and S0 <: Future<S1>)
+ // Let's consider whether there are any cases where the RHS of this "or"
+ // can be satisfied but not the LHS. That is, assume that
+ // Future<S0> <: S1 and S0 <: Future<S1> hold, but not S0 <: S1. S1
+ // must not be a top type (otherwise S0 <: S1 would hold), so the only
+ // way Future<S0> <: S1 can hold is if S1 is Future<A> or FutureOr<A>
+ // for some A. In either case, Future<S1> simplifies to Future<A>, so
+ // we know that S0 <: Future<A>. Also, in either case, Future<A> <: S1.
+ // Combining these, we have that S0 <: S1, contradicting our assumption.
+ // So the RHS of the "or" is redundant, and we can simplify to:
+ // - S0 <: S1.
+ var s0 = source.typeArguments[0];
+ _checkAssignment(origin, source: s0, destination: s1, hard: false);
+ return;
+ }
// (From the subtyping spec):
// if T1 is FutureOr<S1> then T0 <: T1 iff any of the following hold:
// - either T0 <: Future<S1>
- var s1 = destination.typeArguments[0];
if (_typeSystem.isSubtypeOf(
- sourceType, _typeProvider.futureType.instantiate([s1.type]))) {
+ sourceType, _typeProvider.futureType2(s1.type))) {
// E.g. FutureOr<int> = (... as Future<int>)
// This is handled by the InterfaceType logic below, since we treat
// FutureOr as a supertype of Future.
@@ -2229,14 +2340,6 @@
DecoratedType _getTypeParameterTypeBound(DecoratedType type);
}
-class _CompoundOperatorInfo {
- final MethodElement method;
- final int offset;
- final DartType undecoratedType;
-
- _CompoundOperatorInfo(this.method, this.offset, this.undecoratedType);
-}
-
/// Information about a binary expression whose boolean value could possibly
/// affect nullability analysis.
class _ConditionInfo {
diff --git a/pkg/nnbd_migration/lib/src/edge_origin.dart b/pkg/nnbd_migration/lib/src/edge_origin.dart
index efc646b..27db686 100644
--- a/pkg/nnbd_migration/lib/src/edge_origin.dart
+++ b/pkg/nnbd_migration/lib/src/edge_origin.dart
@@ -2,7 +2,9 @@
// 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.
+import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/src/generated/source.dart';
+import 'package:nnbd_migration/instrumentation.dart';
/// Edge origin resulting from the use of a type that is always nullable.
///
@@ -12,40 +14,51 @@
/// this class is used for the edge connecting `always` to the type of f's `x`
/// parameter, due to the fact that the `dynamic` type is always considered
/// nullable.
-class AlwaysNullableTypeOrigin extends EdgeOriginWithLocation {
- AlwaysNullableTypeOrigin(Source source, int offset) : super(source, offset);
+class AlwaysNullableTypeOrigin extends EdgeOrigin {
+ AlwaysNullableTypeOrigin(Source source, AstNode node) : super(source, node);
}
/// Edge origin resulting from the use of a value on the LHS of a compound
/// assignment.
-class CompoundAssignmentOrigin extends EdgeOriginWithLocation {
- CompoundAssignmentOrigin(Source source, int offset) : super(source, offset);
+class CompoundAssignmentOrigin extends EdgeOrigin {
+ CompoundAssignmentOrigin(Source source, AssignmentExpression node)
+ : super(source, node);
+
+ @override
+ AssignmentExpression get node => super.node as AssignmentExpression;
}
/// Common interface for classes providing information about how an edge came
/// to be; that is, what was found in the source code that led the migration
/// tool to create the edge.
-abstract class EdgeOrigin {
- const EdgeOrigin();
-}
-
-/// Common base class for edge origins that are associated with a single
-/// location in the source code.
-abstract class EdgeOriginWithLocation extends EdgeOrigin {
- /// The source file containing the code construct that led to the edge.
+abstract class EdgeOrigin extends EdgeOriginInfo {
+ @override
final Source source;
- /// The offset within the source file of the code construct that led to the
- /// edge.
- final int offset;
+ @override
+ final AstNode node;
- EdgeOriginWithLocation(this.source, this.offset);
+ EdgeOrigin(this.source, this.node);
}
/// Edge origin resulting from the relationship between a field formal parameter
/// and the corresponding field.
-class FieldFormalParameterOrigin extends EdgeOriginWithLocation {
- FieldFormalParameterOrigin(Source source, int offset) : super(source, offset);
+class FieldFormalParameterOrigin extends EdgeOrigin {
+ FieldFormalParameterOrigin(Source source, FieldFormalParameter node)
+ : super(source, node);
+}
+
+/// Edge origin resulting from the use of an iterable type in a for-each loop.
+///
+/// For example, in the following code snippet:
+/// void f(Iterable<int> l) {
+/// for (int i in l) {}
+/// }
+///
+/// this class is used for the edge connecting the type of `l`'s `int` type
+/// parameter to the type of `i`.
+class ForEachVariableOrigin extends EdgeOrigin {
+ ForEachVariableOrigin(Source source, ForEachParts node) : super(source, node);
}
/// Edge origin resulting from the use of greatest lower bound.
@@ -57,13 +70,13 @@
/// the `int` in the return type is nullable if both the `int`s in the types of
/// `x` and `y` are nullable, due to the fact that the `int` in the return type
/// is the greatest lower bound of the two other `int`s.
-class GreatestLowerBoundOrigin extends EdgeOriginWithLocation {
- GreatestLowerBoundOrigin(Source source, int offset) : super(source, offset);
+class GreatestLowerBoundOrigin extends EdgeOrigin {
+ GreatestLowerBoundOrigin(Source source, AstNode node) : super(source, node);
}
/// Edge origin resulting from the presence of a `??` operator.
-class IfNullOrigin extends EdgeOriginWithLocation {
- IfNullOrigin(Source source, int offset) : super(source, offset);
+class IfNullOrigin extends EdgeOrigin {
+ IfNullOrigin(Source source, AstNode node) : super(source, node);
}
/// Edge origin resulting from the implicit call from a mixin application
@@ -79,19 +92,20 @@
/// this class is used for the edge connecting the types of the `i` parameters
/// between the implicit constructor for `D` and the explicit constructor for
/// `C`.
-class ImplicitMixinSuperCallOrigin extends EdgeOriginWithLocation {
- ImplicitMixinSuperCallOrigin(Source source, int offset)
- : super(source, offset);
+class ImplicitMixinSuperCallOrigin extends EdgeOrigin {
+ ImplicitMixinSuperCallOrigin(Source source, ClassTypeAlias node)
+ : super(source, node);
}
/// Edge origin resulting from an inheritance relationship between two methods.
-class InheritanceOrigin extends EdgeOriginWithLocation {
- InheritanceOrigin(Source source, int offset) : super(source, offset);
+class InheritanceOrigin extends EdgeOrigin {
+ InheritanceOrigin(Source source, AstNode node) : super(source, node);
}
/// Edge origin resulting from a type that is inferred from its initializer.
-class InitializerInferenceOrigin extends EdgeOriginWithLocation {
- InitializerInferenceOrigin(Source source, int offset) : super(source, offset);
+class InitializerInferenceOrigin extends EdgeOrigin {
+ InitializerInferenceOrigin(Source source, VariableDeclaration node)
+ : super(source, node);
}
/// Edge origin resulting from a class that is instantiated to bounds.
@@ -102,8 +116,29 @@
///
/// this class is used for the edge connecting the type of x's type parameter
/// with the type bound in the declaration of C.
-class InstantiateToBoundsOrigin extends EdgeOriginWithLocation {
- InstantiateToBoundsOrigin(Source source, int offset) : super(source, offset);
+class InstantiateToBoundsOrigin extends EdgeOrigin {
+ InstantiateToBoundsOrigin(Source source, TypeName node) : super(source, node);
+}
+
+/// Edge origin resulting from the use of a type as a component type in an 'is'
+/// check.
+///
+/// Somewhat opposite of the principle type, allowing improper non-null type
+/// parameters etc. in an is check (`is List<int>` instead of `is List<int?>`)
+/// could introduce a change to runtime behavior.
+class IsCheckComponentTypeOrigin extends EdgeOrigin {
+ IsCheckComponentTypeOrigin(Source source, TypeAnnotation node)
+ : super(source, node);
+}
+
+/// Edge origin resulting from the use of a type as the main type in an 'is'
+/// check.
+///
+/// Before the migration, there was no way to say `is int?`, and therefore,
+// `is int` should migrate to non-null int.
+class IsCheckMainTypeOrigin extends EdgeOrigin {
+ IsCheckMainTypeOrigin(Source source, TypeAnnotation node)
+ : super(source, node);
}
/// Edge origin resulting from a call site that does not supply a named
@@ -118,9 +153,9 @@
/// this class is used for the edge connecting `always` to the type of f's `i`
/// parameter, due to the fact that the call to `f` implicitly passes a null
/// value for `i`.
-class NamedParameterNotSuppliedOrigin extends EdgeOriginWithLocation {
- NamedParameterNotSuppliedOrigin(Source source, int offset)
- : super(source, offset);
+class NamedParameterNotSuppliedOrigin extends EdgeOrigin {
+ NamedParameterNotSuppliedOrigin(Source source, AstNode node)
+ : super(source, node);
}
/// Edge origin resulting from the presence of a non-null assertion.
@@ -132,8 +167,8 @@
///
/// this class is used for the edge connecting the type of f's `i` parameter to
/// `never`, due to the assert statement proclaiming that `i` is not `null`.
-class NonNullAssertionOrigin extends EdgeOriginWithLocation {
- NonNullAssertionOrigin(Source source, int offset) : super(source, offset);
+class NonNullAssertionOrigin extends EdgeOrigin {
+ NonNullAssertionOrigin(Source source, Assertion node) : super(source, node);
}
/// Edge origin resulting from the presence of an explicit nullability hint
@@ -144,8 +179,9 @@
///
/// this class is used for the edge connecting `always` to the type of f's `i`
/// parameter, due to the presence of the `/*?*/` comment.
-class NullabilityCommentOrigin extends EdgeOriginWithLocation {
- NullabilityCommentOrigin(Source source, int offset) : super(source, offset);
+class NullabilityCommentOrigin extends EdgeOrigin {
+ NullabilityCommentOrigin(Source source, TypeAnnotation node)
+ : super(source, node);
}
/// Edge origin resulting from the presence of an optional formal parameter.
@@ -155,7 +191,7 @@
///
/// this class is used for the edge connecting `always` to the type of f's `i`
/// parameter, due to the fact that `i` is optional and has no initializer.
-class OptionalFormalParameterOrigin extends EdgeOriginWithLocation {
- OptionalFormalParameterOrigin(Source source, int offset)
- : super(source, offset);
+class OptionalFormalParameterOrigin extends EdgeOrigin {
+ OptionalFormalParameterOrigin(Source source, DefaultFormalParameter node)
+ : super(source, node);
}
diff --git a/pkg/nnbd_migration/lib/src/expression_checks.dart b/pkg/nnbd_migration/lib/src/expression_checks.dart
index fd87c85..1dffb8d 100644
--- a/pkg/nnbd_migration/lib/src/expression_checks.dart
+++ b/pkg/nnbd_migration/lib/src/expression_checks.dart
@@ -2,7 +2,11 @@
// 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.
+import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer/src/generated/source.dart';
import 'package:analyzer_plugin/protocol/protocol_common.dart';
+import 'package:nnbd_migration/instrumentation.dart';
+import 'package:nnbd_migration/nnbd_migration.dart';
import 'package:nnbd_migration/src/edge_origin.dart';
import 'package:nnbd_migration/src/nullability_node.dart';
import 'package:nnbd_migration/src/potential_modification.dart';
@@ -15,7 +19,7 @@
/// based on the nullability of the type itself (which can be checked by adding
/// a trailing `!`) from checks based on type parameters (which will have to be
/// checked using an `as` expression).
-class ExpressionChecks extends PotentialModification implements EdgeOrigin {
+class ExpressionChecks extends PotentialModification {
/// Source offset where a trailing `!` might need to be inserted.
final int offset;
@@ -42,6 +46,10 @@
ExpressionChecks(this.offset);
@override
+ NullabilityFixDescription get description =>
+ NullabilityFixDescription.checkExpression;
+
+ @override
bool get isEmpty {
for (var edge in edges) {
if (!edge.isSatisfied) return false;
@@ -58,4 +66,22 @@
// reified to contain only non-null ints.
return isEmpty ? [] : [SourceEdit(offset, 0, '!')];
}
+
+ @override
+ Iterable<FixReasonInfo> get reasons sync* {
+ for (var edge in edges) {
+ if (!edge.isSatisfied) yield edge;
+ }
+ }
+}
+
+/// [EdgeOrigin] object associated with [ExpressionChecks]. This is a separate
+/// object so that it can safely store a pointer to an AST node. (We don't want
+/// to store pointers to AST nodes in [ExpressionChecks] objects because they
+/// are persisted for the duration of the migration calculation).
+class ExpressionChecksOrigin extends EdgeOrigin {
+ final ExpressionChecks checks;
+
+ ExpressionChecksOrigin(Source source, Expression node, this.checks)
+ : super(source, node);
}
diff --git a/pkg/nnbd_migration/lib/src/node_builder.dart b/pkg/nnbd_migration/lib/src/node_builder.dart
index 01061d1..1f5d917 100644
--- a/pkg/nnbd_migration/lib/src/node_builder.dart
+++ b/pkg/nnbd_migration/lib/src/node_builder.dart
@@ -5,6 +5,7 @@
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/ast/visitor.dart';
import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/dart/element/nullability_suffix.dart';
import 'package:analyzer/dart/element/type.dart';
import 'package:analyzer/src/dart/element/handle.dart';
import 'package:analyzer/src/dart/element/type.dart';
@@ -12,6 +13,7 @@
import 'package:analyzer/src/generated/source.dart';
import 'package:front_end/src/scanner/token.dart';
import 'package:meta/meta.dart';
+import 'package:nnbd_migration/instrumentation.dart';
import 'package:nnbd_migration/nnbd_migration.dart';
import 'package:nnbd_migration/src/conditional_discard.dart';
import 'package:nnbd_migration/src/decorated_type.dart';
@@ -56,6 +58,8 @@
final NullabilityMigrationListener /*?*/ listener;
+ final NullabilityMigrationInstrumentation /*?*/ instrumentation;
+
final NullabilityGraph _graph;
final TypeProvider _typeProvider;
@@ -70,7 +74,8 @@
final DecoratedType _nonNullableStackTraceType;
NodeBuilder(this._variables, this.source, this.listener, this._graph,
- this._typeProvider)
+ this._typeProvider,
+ {this.instrumentation})
: _dynamicType = DecoratedType(_typeProvider.dynamicType, _graph.always),
_nonNullableObjectType =
DecoratedType(_typeProvider.objectType, _graph.never),
@@ -82,14 +87,21 @@
DecoratedType exceptionType = node.exceptionType?.accept(this);
if (node.exceptionParameter != null) {
// If there is no `on Type` part of the catch clause, the type is dynamic.
- exceptionType ??= _dynamicType;
+ if (exceptionType == null) {
+ exceptionType = _dynamicType;
+ instrumentation?.implicitType(
+ source, node.exceptionParameter, exceptionType);
+ }
_variables.recordDecoratedElementType(
node.exceptionParameter.staticElement, exceptionType);
}
if (node.stackTraceParameter != null) {
// The type of stack traces is always StackTrace (non-nullable).
+ var stackTraceType = _nonNullableStackTraceType;
_variables.recordDecoratedElementType(
- node.stackTraceParameter.staticElement, _nonNullableStackTraceType);
+ node.stackTraceParameter.staticElement, stackTraceType);
+ instrumentation?.implicitType(
+ source, node.stackTraceParameter, stackTraceType);
}
node.stackTraceParameter?.accept(this);
node.body?.accept(this);
@@ -152,6 +164,7 @@
@override
DecoratedType visitConstructorDeclaration(ConstructorDeclaration node) {
_handleExecutableDeclaration(
+ node,
node.declaredElement,
node.metadata,
null,
@@ -168,11 +181,13 @@
node.metadata.accept(this);
DecoratedType type = node.type?.accept(this);
if (node.identifier != null) {
+ if (type == null) {
+ type = DecoratedType.forImplicitType(
+ _typeProvider, node.declaredElement.type, _graph);
+ instrumentation?.implicitType(source, node, type);
+ }
_variables.recordDecoratedElementType(
- node.identifier.staticElement,
- type ??
- DecoratedType.forImplicitType(
- _typeProvider, node.declaredElement.type, _graph));
+ node.identifier.staticElement, type);
}
return type;
}
@@ -204,6 +219,7 @@
@override
DecoratedType visitFunctionDeclaration(FunctionDeclaration node) {
_handleExecutableDeclaration(
+ node,
node.declaredElement,
node.metadata,
node.returnType,
@@ -217,7 +233,7 @@
@override
DecoratedType visitFunctionExpression(FunctionExpression node) {
- _handleExecutableDeclaration(node.declaredElement, null, null,
+ _handleExecutableDeclaration(node, node.declaredElement, null, null,
node.typeParameters, node.parameters, null, node.body, null);
return null;
}
@@ -235,6 +251,7 @@
// Inferred return type.
decoratedReturnType = DecoratedType.forImplicitType(
_typeProvider, functionType.returnType, _graph);
+ instrumentation?.implicitReturnType(source, node, decoratedReturnType);
}
var previousPositionalParameters = _positionalParameters;
var previousNamedParameters = _namedParameters;
@@ -291,6 +308,7 @@
@override
DecoratedType visitMethodDeclaration(MethodDeclaration node) {
_handleExecutableDeclaration(
+ node,
node.declaredElement,
node.metadata,
node.returnType,
@@ -325,7 +343,7 @@
if (type.isVoid || type.isDynamic) {
var nullabilityNode = NullabilityNode.forTypeAnnotation(node.end);
_graph.connect(_graph.always, nullabilityNode,
- AlwaysNullableTypeOrigin(source, node.offset));
+ AlwaysNullableTypeOrigin(source, node));
var decoratedType = DecoratedType(type, nullabilityNode);
_variables.recordDecoratedTypeAnnotation(
source, node, decoratedType, null);
@@ -343,6 +361,7 @@
.map((t) =>
DecoratedType.forImplicitType(_typeProvider, t, _graph))
.toList();
+ instrumentation?.implicitTypeArguments(source, node, typeArguments);
} else {
typeArguments =
node.typeArguments.arguments.map((t) => t.accept(this)).toList();
@@ -353,10 +372,13 @@
}
if (node is GenericFunctionType) {
var returnType = node.returnType;
- decoratedReturnType = returnType == null
- ? DecoratedType.forImplicitType(
- _typeProvider, DynamicTypeImpl.instance, _graph)
- : returnType.accept(this);
+ if (returnType == null) {
+ decoratedReturnType = DecoratedType.forImplicitType(
+ _typeProvider, DynamicTypeImpl.instance, _graph);
+ instrumentation?.implicitReturnType(source, node, decoratedReturnType);
+ } else {
+ decoratedReturnType = returnType.accept(this);
+ }
positionalParameters = <DecoratedType>[];
namedParameters = <String, DecoratedType>{};
typeFormalBounds = <DecoratedType>[];
@@ -411,12 +433,12 @@
switch (_classifyComment(commentToken)) {
case _NullabilityComment.bang:
_graph.connect(decoratedType.node, _graph.never,
- NullabilityCommentOrigin(source, commentToken.offset),
+ NullabilityCommentOrigin(source, node),
hard: true);
break;
case _NullabilityComment.question:
_graph.connect(_graph.always, decoratedType.node,
- NullabilityCommentOrigin(source, commentToken.offset));
+ NullabilityCommentOrigin(source, node));
break;
case _NullabilityComment.none:
break;
@@ -437,7 +459,7 @@
} else {
var nullabilityNode = NullabilityNode.forInferredType();
_graph.union(_graph.always, nullabilityNode,
- AlwaysNullableTypeOrigin(source, node.offset));
+ AlwaysNullableTypeOrigin(source, node));
decoratedBound = DecoratedType(_typeProvider.objectType, nullabilityNode);
}
_typeFormalBounds?.add(decoratedBound);
@@ -453,11 +475,12 @@
for (var variable in node.variables) {
variable.metadata.accept(this);
var declaredElement = variable.declaredElement;
- _variables.recordDecoratedElementType(
- declaredElement,
- type ??
- DecoratedType.forImplicitType(
- _typeProvider, declaredElement.type, _graph));
+ if (type == null) {
+ type = DecoratedType.forImplicitType(
+ _typeProvider, declaredElement.type, _graph);
+ instrumentation?.implicitType(source, node, type);
+ }
+ _variables.recordDecoratedElementType(declaredElement, type);
variable.initializer?.accept(this);
}
return null;
@@ -474,14 +497,23 @@
DecoratedType _createDecoratedTypeForClass(
ClassElement classElement, AstNode node) {
var typeArguments = classElement.typeParameters
- .map((t) => DecoratedType(t.type, _graph.never))
+ .map((t) => t.instantiate(nullabilitySuffix: NullabilitySuffix.star))
.toList();
- return DecoratedType(classElement.type, _graph.never,
- typeArguments: typeArguments);
+ var decoratedTypeArguments =
+ typeArguments.map((t) => DecoratedType(t, _graph.never)).toList();
+ return DecoratedType(
+ classElement.instantiate(
+ typeArguments: typeArguments,
+ nullabilitySuffix: NullabilitySuffix.star,
+ ),
+ _graph.never,
+ typeArguments: decoratedTypeArguments,
+ );
}
/// Common handling of function and method declarations.
void _handleExecutableDeclaration(
+ AstNode node,
ExecutableElement declaredElement,
NodeList<Annotation> metadata,
TypeAnnotation returnType,
@@ -500,10 +532,12 @@
// implicit return type.
decoratedReturnType = _createDecoratedTypeForClass(
declaredElement.enclosingElement, parameters.parent);
+ instrumentation?.implicitReturnType(source, node, decoratedReturnType);
} else {
// Inferred return type.
decoratedReturnType = DecoratedType.forImplicitType(
_typeProvider, functionType.returnType, _graph);
+ instrumentation?.implicitReturnType(source, node, decoratedReturnType);
}
var previousPositionalParameters = _positionalParameters;
var previousNamedParameters = _namedParameters;
@@ -541,15 +575,22 @@
node.metadata?.accept(this);
DecoratedType decoratedType;
if (parameters == null) {
- decoratedType = type != null
- ? type.accept(this)
- : DecoratedType.forImplicitType(
- _typeProvider, declaredElement.type, _graph);
+ if (type != null) {
+ decoratedType = type.accept(this);
+ } else {
+ decoratedType = DecoratedType.forImplicitType(
+ _typeProvider, declaredElement.type, _graph);
+ instrumentation?.implicitType(source, node, decoratedType);
+ }
} else {
- var decoratedReturnType = type == null
- ? DecoratedType.forImplicitType(
- _typeProvider, DynamicTypeImpl.instance, _graph)
- : type.accept(this);
+ DecoratedType decoratedReturnType;
+ if (type == null) {
+ decoratedReturnType = DecoratedType.forImplicitType(
+ _typeProvider, DynamicTypeImpl.instance, _graph);
+ instrumentation?.implicitReturnType(source, node, decoratedReturnType);
+ } else {
+ decoratedReturnType = type.accept(this);
+ }
if (typeParameters != null) {
// TODO(paulberry)
_unimplemented(
@@ -707,7 +748,7 @@
/// Associates a set of nullability checks with the given expression [node].
void recordExpressionChecks(
- Source source, Expression expression, ExpressionChecks checks);
+ Source source, Expression expression, ExpressionChecksOrigin origin);
}
/// Types of comments that can influence nullability
diff --git a/pkg/nnbd_migration/lib/src/nullability_migration_impl.dart b/pkg/nnbd_migration/lib/src/nullability_migration_impl.dart
index 53c75ec..247fee8 100644
--- a/pkg/nnbd_migration/lib/src/nullability_migration_impl.dart
+++ b/pkg/nnbd_migration/lib/src/nullability_migration_impl.dart
@@ -6,9 +6,9 @@
import 'package:analyzer/dart/analysis/results.dart';
import 'package:analyzer/src/generated/source.dart';
import 'package:meta/meta.dart';
+import 'package:nnbd_migration/instrumentation.dart';
import 'package:nnbd_migration/nnbd_migration.dart';
import 'package:nnbd_migration/src/edge_builder.dart';
-import 'package:nnbd_migration/src/expression_checks.dart';
import 'package:nnbd_migration/src/node_builder.dart';
import 'package:nnbd_migration/src/nullability_node.dart';
import 'package:nnbd_migration/src/potential_modification.dart';
@@ -24,6 +24,8 @@
final bool _permissive;
+ final NullabilityMigrationInstrumentation _instrumentation;
+
/// Prepares to perform nullability migration.
///
/// If [permissive] is `true`, exception handling logic will try to proceed
@@ -31,10 +33,15 @@
/// complete. TODO(paulberry): remove this mode once the migration algorithm
/// is fully implemented.
NullabilityMigrationImpl(NullabilityMigrationListener listener,
- {bool permissive: false})
- : this._(listener, NullabilityGraph(), permissive);
+ {bool permissive: false,
+ NullabilityMigrationInstrumentation instrumentation})
+ : this._(listener, NullabilityGraph(instrumentation: instrumentation),
+ permissive, instrumentation);
- NullabilityMigrationImpl._(this.listener, this._graph, this._permissive);
+ NullabilityMigrationImpl._(
+ this.listener, this._graph, this._permissive, this._instrumentation) {
+ _instrumentation?.immutableNodes(_graph.never, _graph.always);
+ }
void finish() {
_graph.propagate();
@@ -48,26 +55,31 @@
// it, we can't report on every unsatisfied edge. We need to figure out a
// way to report unsatisfied edges that isn't too overwhelming.
if (_variables != null) {
- broadcast(_variables, listener);
+ broadcast(_variables, listener, _instrumentation);
}
}
void prepareInput(ResolvedUnitResult result) {
- _variables ??= Variables(_graph, result.typeProvider);
+ _variables ??= Variables(_graph, result.typeProvider,
+ instrumentation: _instrumentation);
var unit = result.unit;
unit.accept(NodeBuilder(_variables, unit.declaredElement.source,
- _permissive ? listener : null, _graph, result.typeProvider));
+ _permissive ? listener : null, _graph, result.typeProvider,
+ instrumentation: _instrumentation));
}
void processInput(ResolvedUnitResult result) {
var unit = result.unit;
unit.accept(EdgeBuilder(result.typeProvider, result.typeSystem, _variables,
- _graph, unit.declaredElement.source, _permissive ? listener : null));
+ _graph, unit.declaredElement.source, _permissive ? listener : null,
+ instrumentation: _instrumentation));
}
@visibleForTesting
static void broadcast(
- Variables variables, NullabilityMigrationListener listener) {
+ Variables variables,
+ NullabilityMigrationListener listener,
+ NullabilityMigrationInstrumentation instrumentation) {
for (var entry in variables.getPotentialModifications().entries) {
var source = entry.key;
final lineInfo = LineInfo.fromContent(source.contents.data);
@@ -79,6 +91,7 @@
var fix =
_SingleNullabilityFix(source, potentialModification, lineInfo);
listener.addFix(fix);
+ instrumentation?.fix(fix, potentialModification.reasons);
for (var edit in modifications) {
listener.addEdit(fix, edit);
}
@@ -100,32 +113,6 @@
factory _SingleNullabilityFix(Source source,
PotentialModification potentialModification, LineInfo lineInfo) {
- // TODO(paulberry): once everything is migrated into the analysis server,
- // the migration engine can just create SingleNullabilityFix objects
- // directly and set their kind appropriately; we won't need to translate the
- // kinds using a bunch of `is` checks.
- NullabilityFixDescription desc;
- if (potentialModification is ExpressionChecks) {
- desc = NullabilityFixDescription.checkExpression;
- } else if (potentialModification is PotentiallyAddQuestionSuffix) {
- desc = NullabilityFixDescription.makeTypeNullable(
- potentialModification.type.toString());
- } else if (potentialModification is ConditionalModification) {
- desc = potentialModification.discard.keepFalse
- ? NullabilityFixDescription.discardThen
- : NullabilityFixDescription.discardElse;
- } else if (potentialModification is PotentiallyAddImport) {
- desc =
- NullabilityFixDescription.addImport(potentialModification.importPath);
- } else if (potentialModification is PotentiallyAddRequired) {
- desc = NullabilityFixDescription.addRequired(
- potentialModification.className,
- potentialModification.methodName,
- potentialModification.parameterName);
- } else {
- throw new UnimplementedError('TODO(paulberry)');
- }
-
Location location;
if (potentialModification.modifications.isNotEmpty) {
@@ -140,7 +127,8 @@
);
}
- return _SingleNullabilityFix._(source, desc, location: location);
+ return _SingleNullabilityFix._(source, potentialModification.description,
+ location: location);
}
_SingleNullabilityFix._(this.source, this.description, {Location location})
diff --git a/pkg/nnbd_migration/lib/src/nullability_node.dart b/pkg/nnbd_migration/lib/src/nullability_node.dart
index 244df1e..f0122b0 100644
--- a/pkg/nnbd_migration/lib/src/nullability_node.dart
+++ b/pkg/nnbd_migration/lib/src/nullability_node.dart
@@ -4,6 +4,8 @@
import 'package:analyzer/src/generated/source.dart';
import 'package:meta/meta.dart';
+import 'package:nnbd_migration/instrumentation.dart';
+import 'package:nnbd_migration/nullability_state.dart';
import 'edge_origin.dart';
@@ -11,45 +13,43 @@
/// object to another [NullabilityNode] that is "downstream" from it (meaning
/// that if the former node is nullable, then the latter node will either have
/// to be nullable, or null checks will have to be added).
-class NullabilityEdge {
- /// The node that is downstream.
+class NullabilityEdge implements EdgeInfo {
+ @override
final NullabilityNode destinationNode;
- /// A set of source nodes. By convention, the first node is the primary
- /// source and the other nodes are "guards". The destination node will only
- /// need to be made nullable if all the source nodes are nullable.
- final List<NullabilityNode> sources;
+ /// A set of upstream nodes. By convention, the first node is the source node
+ /// and the other nodes are "guards". The destination node will only need to
+ /// be made nullable if all the upstream nodes are nullable.
+ final List<NullabilityNode> upstreamNodes;
final _NullabilityEdgeKind _kind;
- /// An [EdgeOrigin] object indicating what was found in the source code that
- /// caused the edge to be generated.
- final EdgeOrigin origin;
+ NullabilityEdge._(this.destinationNode, this.upstreamNodes, this._kind);
- NullabilityEdge._(
- this.destinationNode, this.sources, this._kind, this.origin);
+ @override
+ Iterable<NullabilityNode> get guards => upstreamNodes.skip(1);
- Iterable<NullabilityNode> get guards => sources.skip(1);
+ @override
+ bool get isHard => _kind != _NullabilityEdgeKind.soft;
- bool get hard => _kind != _NullabilityEdgeKind.soft;
-
- /// Indicates whether nullability was successfully propagated through this
- /// edge.
+ @override
bool get isSatisfied {
if (!_isTriggered) return true;
return destinationNode.isNullable;
}
+ @override
bool get isUnion => _kind == _NullabilityEdgeKind.union;
- NullabilityNode get primarySource => sources.first;
+ @override
+ NullabilityNode get sourceNode => upstreamNodes.first;
- /// Indicates whether all the sources of this edge are nullable (and thus
- /// downstream nullability propagation should try to make the destination node
- /// nullable, if possible).
+ /// Indicates whether all the upstream nodes of this edge are nullable (and
+ /// thus downstream nullability propagation should try to make the destination
+ /// node nullable, if possible).
bool get _isTriggered {
- for (var source in sources) {
- if (!source.isNullable) return false;
+ for (var upstreamNode in upstreamNodes) {
+ if (!upstreamNode.isNullable) return false;
}
return true;
}
@@ -70,7 +70,7 @@
edgeDecorations.addAll(guards);
var edgeDecoration =
edgeDecorations.isEmpty ? '' : '-(${edgeDecorations.join(', ')})';
- return '$primarySource $edgeDecoration-> $destinationNode';
+ return '$sourceNode $edgeDecoration-> $destinationNode';
}
}
@@ -85,9 +85,11 @@
/// propagation.
static const _debugAfterPropagation = false;
+ final NullabilityMigrationInstrumentation /*?*/ instrumentation;
+
/// Set containing all [NullabilityNode]s that have been passed as the
- /// `sourceNode` argument to [connect].
- final _allSourceNodes = Set<NullabilityNode>.identity();
+ /// `upstreamNode` argument to [connect].
+ final _allUpstreamNodes = Set<NullabilityNode>.identity();
/// Returns a [NullabilityNode] that is a priori nullable.
///
@@ -124,6 +126,8 @@
/// nodes that have not yet been resolved.
List<NullabilityNodeForSubstitution> _pendingSubstitutions = [];
+ NullabilityGraph({this.instrumentation});
+
/// After calling [propagate], this getter may be queried to access the set of
/// edges that could not be satisfied.
Iterable<NullabilityEdge> get unsatisfiedEdges => _unsatisfiedEdges;
@@ -139,9 +143,9 @@
NullabilityEdge connect(NullabilityNode sourceNode,
NullabilityNode destinationNode, EdgeOrigin origin,
{bool hard: false, List<NullabilityNode> guards: const []}) {
- var sources = [sourceNode]..addAll(guards);
+ var upstreamNodes = [sourceNode]..addAll(guards);
var kind = hard ? _NullabilityEdgeKind.hard : _NullabilityEdgeKind.soft;
- return _connect(sources, destinationNode, kind, origin);
+ return _connect(upstreamNodes, destinationNode, kind, origin);
}
/// Determine if [source] is in the code being migrated.
@@ -171,45 +175,46 @@
}
NullabilityEdge _connect(
- List<NullabilityNode> sources,
+ List<NullabilityNode> upstreamNodes,
NullabilityNode destinationNode,
_NullabilityEdgeKind kind,
EdgeOrigin origin) {
- var edge = NullabilityEdge._(destinationNode, sources, kind, origin);
- for (var source in sources) {
- _connectDownstream(source, edge);
+ var edge = NullabilityEdge._(destinationNode, upstreamNodes, kind);
+ instrumentation?.graphEdge(edge, origin);
+ for (var upstreamNode in upstreamNodes) {
+ _connectDownstream(upstreamNode, edge);
}
destinationNode._upstreamEdges.add(edge);
return edge;
}
- void _connectDownstream(NullabilityNode source, NullabilityEdge edge) {
- _allSourceNodes.add(source);
- source._downstreamEdges.add(edge);
- if (source is _NullabilityNodeCompound) {
- for (var component in source._components) {
+ void _connectDownstream(NullabilityNode upstreamNode, NullabilityEdge edge) {
+ _allUpstreamNodes.add(upstreamNode);
+ upstreamNode._downstreamEdges.add(edge);
+ if (upstreamNode is _NullabilityNodeCompound) {
+ for (var component in upstreamNode._components) {
_connectDownstream(component, edge);
}
}
}
void _debugDump() {
- for (var source in _allSourceNodes) {
- var edges = source._downstreamEdges;
+ for (var upstreamNode in _allUpstreamNodes) {
+ var edges = upstreamNode._downstreamEdges;
var destinations =
- edges.where((edge) => edge.primarySource == source).map((edge) {
+ edges.where((edge) => edge.sourceNode == upstreamNode).map((edge) {
var suffixes = <Object>[];
if (edge.isUnion) {
suffixes.add('union');
- } else if (edge.hard) {
+ } else if (edge.isHard) {
suffixes.add('hard');
}
suffixes.addAll(edge.guards);
var suffix = suffixes.isNotEmpty ? ' (${suffixes.join(', ')})' : '';
return '${edge.destinationNode}$suffix';
});
- var state = source._state;
- print('$source ($state) -> ${destinations.join(', ')}');
+ var state = upstreamNode._state;
+ print('$upstreamNode ($state) -> ${destinations.join(', ')}');
}
}
@@ -220,13 +225,15 @@
while (_pendingEdges.isNotEmpty) {
var edge = _pendingEdges.removeLast();
if (!edge.isUnion) continue;
- // Union edges always have exactly one source, so we don't need to check
- // whether all sources are nullable.
- assert(edge.sources.length == 1);
+ // Union edges always have exactly one upstream node, so we don't need to
+ // check whether all upstream nodes are nullable.
+ assert(edge.upstreamNodes.length == 1);
var node = edge.destinationNode;
if (node is NullabilityNodeMutable && !node.isNullable) {
_unionedWithAlways.add(node);
- node._state = _NullabilityState.ordinaryNullable;
+ _setState(_PropagationStep(
+ node, NullabilityState.ordinaryNullable, StateChangeReason.union,
+ edge: edge));
// Was not previously nullable, so we need to propagate.
_pendingEdges.addAll(node._downstreamEdges);
}
@@ -244,14 +251,16 @@
var edge = _pendingEdges.removeLast();
if (!edge._isTriggered) continue;
var node = edge.destinationNode;
- if (node._state == _NullabilityState.nonNullable) {
+ if (node._state == NullabilityState.nonNullable) {
// The node has already been marked as non-nullable, so the edge can't
// be satisfied.
_unsatisfiedEdges.add(edge);
continue;
}
if (node is NullabilityNodeMutable && !node.isNullable) {
- _setNullable(node);
+ _setNullable(_PropagationStep(node, NullabilityState.ordinaryNullable,
+ StateChangeReason.downstream,
+ edge: edge));
}
}
if (_pendingSubstitutions.isEmpty) break;
@@ -270,11 +279,13 @@
_pendingEdges.addAll(never._upstreamEdges);
while (_pendingEdges.isNotEmpty) {
var edge = _pendingEdges.removeLast();
- if (!edge.hard) continue;
- var node = edge.primarySource;
+ if (!edge.isHard) continue;
+ var node = edge.sourceNode;
if (node is NullabilityNodeMutable &&
- node._state == _NullabilityState.undetermined) {
- node._state = _NullabilityState.nonNullable;
+ node._state == NullabilityState.undetermined) {
+ _setState(_PropagationStep(
+ node, NullabilityState.nonNullable, StateChangeReason.upstream,
+ edge: edge));
// Was not previously in the set of non-null intent nodes, so we need to
// propagate.
_pendingEdges.addAll(node._upstreamEdges);
@@ -288,8 +299,8 @@
// If both nodes pointed to by the substitution node are in the non-nullable
// state, then no resolution is needed; the substitution node can’t be
// satisfied.
- if (substitutionNode.innerNode._state == _NullabilityState.nonNullable &&
- substitutionNode.outerNode._state == _NullabilityState.nonNullable) {
+ if (substitutionNode.innerNode._state == NullabilityState.nonNullable &&
+ substitutionNode.outerNode._state == NullabilityState.nonNullable) {
_unsatisfiedSubstitutions.add(substitutionNode);
return;
}
@@ -302,8 +313,12 @@
// Otherwise, if the inner node is in the non-nullable state, then we set
// the outer node to the ordinary nullable state.
- if (substitutionNode.innerNode._state == _NullabilityState.nonNullable) {
- _setNullable(substitutionNode.outerNode as NullabilityNodeMutable);
+ if (substitutionNode.innerNode._state == NullabilityState.nonNullable) {
+ _setNullable(_PropagationStep(
+ substitutionNode.outerNode as NullabilityNodeMutable,
+ NullabilityState.ordinaryNullable,
+ StateChangeReason.substituteOuter,
+ substitutionNode: substitutionNode));
return;
}
@@ -312,28 +327,43 @@
// rule: if there is an edge A → B, where A is in the undetermined or
// ordinary nullable state, and B is in the exact nullable state, then A’s
// state is changed to exact nullable.
- var pendingNodes = [substitutionNode.innerNode];
- while (pendingNodes.isNotEmpty) {
- var node = pendingNodes.removeLast();
+ var pendingEdges = <NullabilityEdge>[];
+ var node = substitutionNode.innerNode;
+ if (node is NullabilityNodeMutable) {
+ var oldState = _setNullable(_PropagationStep(node,
+ NullabilityState.exactNullable, StateChangeReason.substituteInner,
+ substitutionNode: substitutionNode));
+ if (oldState != NullabilityState.exactNullable) {
+ // Was not previously in the "exact nullable" state. Need to
+ // propagate.
+ for (var edge in node._upstreamEdges) {
+ pendingEdges.add(edge);
+ }
+ }
+ }
+ while (pendingEdges.isNotEmpty) {
+ var edge = pendingEdges.removeLast();
+ var node = edge.sourceNode;
if (node is NullabilityNodeMutable) {
- var oldState =
- _setNullable(node, newState: _NullabilityState.exactNullable);
- if (oldState != _NullabilityState.exactNullable) {
+ var oldState = _setNullable(_PropagationStep(node,
+ NullabilityState.exactNullable, StateChangeReason.exactUpstream,
+ edge: edge));
+ if (oldState != NullabilityState.exactNullable) {
// Was not previously in the "exact nullable" state. Need to
// propagate.
for (var edge in node._upstreamEdges) {
- pendingNodes.add(edge.primarySource);
+ pendingEdges.add(edge);
}
}
}
}
}
- _NullabilityState _setNullable(NullabilityNodeMutable node,
- {_NullabilityState newState = _NullabilityState.ordinaryNullable}) {
- assert(newState.isNullable);
+ NullabilityState _setNullable(_PropagationStep propagationStep) {
+ var node = propagationStep.node;
+ assert(propagationStep.newState.isNullable);
var oldState = node._state;
- node._state = newState;
+ _setState(propagationStep);
if (!oldState.isNullable) {
// Was not previously nullable, so we need to propagate.
_pendingEdges.addAll(node._downstreamEdges);
@@ -343,6 +373,11 @@
}
return oldState;
}
+
+ void _setState(_PropagationStep propagationStep) {
+ propagationStep.node._state = propagationStep.newState;
+ instrumentation?.propagationStep(propagationStep);
+ }
}
/// Same as [NullabilityGraph], but extended with extra methods for easier
@@ -351,6 +386,8 @@
class NullabilityGraphForTesting extends NullabilityGraph {
final List<NullabilityEdge> _allEdges = [];
+ final Map<NullabilityEdge, EdgeOrigin> _edgeOrigins = {};
+
/// Prints out a representation of the graph nodes. Useful in debugging
/// broken tests.
void debugDump() {
@@ -363,14 +400,19 @@
return _allEdges;
}
+ /// Retrieves the [EdgeOrigin] object that was used to create [edge].
+ @visibleForTesting
+ EdgeOrigin getEdgeOrigin(NullabilityEdge edge) => _edgeOrigins[edge];
+
@override
NullabilityEdge _connect(
- List<NullabilityNode> sources,
+ List<NullabilityNode> upstreamNodes,
NullabilityNode destinationNode,
_NullabilityEdgeKind kind,
EdgeOrigin origin) {
- var edge = super._connect(sources, destinationNode, kind, origin);
+ var edge = super._connect(upstreamNodes, destinationNode, kind, origin);
_allEdges.add(edge);
+ _edgeOrigins[edge] = origin;
return edge;
}
}
@@ -381,7 +423,7 @@
/// nullability inference graph is encoded into the wrapped constraint
/// variables. Over time this will be replaced by a first class representation
/// of the nullability inference graph.
-abstract class NullabilityNode {
+abstract class NullabilityNode implements NullabilityNodeInfo {
static final _debugNamesInUse = Set<String>();
bool _isPossiblyOptional = false;
@@ -451,6 +493,7 @@
/// After nullability propagation, this getter can be used to query whether
/// the type associated with this node should be considered nullable.
+ @override
bool get isNullable;
/// Indicates whether this node is associated with a named parameter for which
@@ -459,7 +502,7 @@
String get _debugPrefix;
- _NullabilityState get _state;
+ NullabilityState get _state;
/// Records the fact that an invocation was made to a function with named
/// parameters, and the named parameter associated with this node was not
@@ -520,19 +563,12 @@
/// Derived class for nullability nodes that arise from type variable
/// substitution.
-class NullabilityNodeForSubstitution extends _NullabilityNodeCompound {
- /// Nullability node representing the inner type of the substitution.
- ///
- /// For example, if this NullabilityNode arose from substituting `int*` for
- /// `T` in the type `T*`, [innerNode] is the nullability corresponding to the
- /// `*` in `int*`.
+class NullabilityNodeForSubstitution extends _NullabilityNodeCompound
+ implements SubstitutionNodeInfo {
+ @override
final NullabilityNode innerNode;
- /// Nullability node representing the outer type of the substitution.
- ///
- /// For example, if this NullabilityNode arose from substituting `int*` for
- /// `T` in the type `T*`, [innerNode] is the nullability corresponding to the
- /// `*` in `T*`.
+ @override
final NullabilityNode outerNode;
NullabilityNodeForSubstitution._(this.innerNode, this.outerNode);
@@ -549,15 +585,18 @@
/// Nearly all nullability nodes derive from this class; the only exceptions are
/// the fixed nodes "always "never".
abstract class NullabilityNodeMutable extends NullabilityNode {
- _NullabilityState _state;
+ NullabilityState _state;
NullabilityNodeMutable._(
- {_NullabilityState initialState: _NullabilityState.undetermined})
+ {NullabilityState initialState: NullabilityState.undetermined})
: _state = initialState,
super._();
@override
- bool get isExactNullable => _state == _NullabilityState.exactNullable;
+ bool get isExactNullable => _state == NullabilityState.exactNullable;
+
+ @override
+ bool get isImmutable => false;
@override
bool get isNullable => _state.isNullable;
@@ -605,9 +644,12 @@
bool get isExactNullable => isNullable;
@override
- _NullabilityState get _state => isNullable
- ? _NullabilityState.exactNullable
- : _NullabilityState.nonNullable;
+ bool get isImmutable => true;
+
+ @override
+ NullabilityState get _state => isNullable
+ ? NullabilityState.exactNullable
+ : NullabilityState.nonNullable;
}
class _NullabilityNodeSimple extends NullabilityNodeMutable {
@@ -615,39 +657,25 @@
final String _debugPrefix;
_NullabilityNodeSimple(this._debugPrefix)
- : super._(initialState: _NullabilityState.undetermined);
+ : super._(initialState: NullabilityState.undetermined);
}
-/// State of a nullability node.
-class _NullabilityState {
- /// State of a nullability node whose nullability hasn't been decided yet.
- static const undetermined = _NullabilityState._('undetermined', false);
-
- /// State of a nullability node that has been determined to be non-nullable
- /// by propagating upstream.
- static const nonNullable = _NullabilityState._('non-nullable', false);
-
- /// State of a nullability node that has been determined to be nullable by
- /// propagating downstream.
- static const ordinaryNullable =
- _NullabilityState._('ordinary nullable', true);
-
- /// State of a nullability node that has been determined to be nullable by
- /// propagating upstream from a contravariant use of a generic.
- static const exactNullable = _NullabilityState._('exact nullable', true);
-
- /// Name of the state (for use in debugging).
- final String name;
-
- /// Indicates whether the given state should be considered nullable.
- ///
- /// After propagation, any nodes that remain in the undetermined state are
- /// considered to be non-nullable, so this field is returns `false` for nodes
- /// in that state.
- final bool isNullable;
-
- const _NullabilityState._(this.name, this.isNullable);
+class _PropagationStep implements PropagationInfo {
+ @override
+ final NullabilityNodeMutable node;
@override
- String toString() => name;
+ final NullabilityState newState;
+
+ @override
+ final StateChangeReason reason;
+
+ @override
+ final NullabilityEdge edge;
+
+ @override
+ final NullabilityNodeForSubstitution substitutionNode;
+
+ _PropagationStep(this.node, this.newState, this.reason,
+ {this.edge, this.substitutionNode});
}
diff --git a/pkg/nnbd_migration/lib/src/potential_modification.dart b/pkg/nnbd_migration/lib/src/potential_modification.dart
index d4f13c3..ac60b15 100644
--- a/pkg/nnbd_migration/lib/src/potential_modification.dart
+++ b/pkg/nnbd_migration/lib/src/potential_modification.dart
@@ -5,6 +5,8 @@
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/element/type.dart';
import 'package:analyzer_plugin/protocol/protocol_common.dart' show SourceEdit;
+import 'package:nnbd_migration/instrumentation.dart';
+import 'package:nnbd_migration/nnbd_migration.dart';
import 'package:nnbd_migration/src/conditional_discard.dart';
import 'package:nnbd_migration/src/nullability_node.dart';
@@ -44,6 +46,11 @@
this.discard, this.condition, this.thenStatement, this.elseStatement);
@override
+ NullabilityFixDescription get description => discard.keepFalse
+ ? NullabilityFixDescription.discardThen
+ : NullabilityFixDescription.discardElse;
+
+ @override
bool get isEmpty => discard.keepTrue && discard.keepFalse;
@override
@@ -81,6 +88,9 @@
}
return result;
}
+
+ @override
+ Iterable<FixReasonInfo> get reasons => discard.reasons;
}
/// Records information about the possible addition of an import to the source
@@ -101,6 +111,10 @@
}
@override
+ NullabilityFixDescription get description =>
+ NullabilityFixDescription.addImport(importPath);
+
+ @override
bool get isEmpty {
for (PotentialModification usage in _usages) {
if (!usage.isEmpty) {
@@ -115,6 +129,13 @@
Iterable<SourceEdit> get modifications =>
isEmpty ? const [] : [SourceEdit(_offset, 0, "import '$importPath';\n")];
+ @override
+ Iterable<FixReasonInfo> get reasons sync* {
+ for (var usage in _usages) {
+ if (!usage.isEmpty) yield* usage.reasons;
+ }
+ }
+
void addUsage(PotentialModification usage) {
_usages.add(usage);
}
@@ -130,11 +151,18 @@
PotentiallyAddQuestionSuffix(this.node, this.type, this._offset);
@override
+ NullabilityFixDescription get description =>
+ NullabilityFixDescription.makeTypeNullable(type.toString());
+
+ @override
bool get isEmpty => !node.isNullable;
@override
Iterable<SourceEdit> get modifications =>
isEmpty ? [] : [SourceEdit(_offset, 0, '?')];
+
+ @override
+ Iterable<FixReasonInfo> get reasons => [node];
}
/// Records information about the possible addition of a `@required` annotation
@@ -160,21 +188,35 @@
this.methodName, this.parameterName);
@override
+ NullabilityFixDescription get description =>
+ NullabilityFixDescription.addRequired(
+ className, methodName, parameterName);
+
+ @override
bool get isEmpty => _node.isNullable;
@override
Iterable<SourceEdit> get modifications =>
isEmpty ? const [] : [SourceEdit(_offset, 0, '@required ')];
+
+ @override
+ Iterable<FixReasonInfo> get reasons => [_node];
}
/// Interface used by data structures representing potential modifications to
/// the code being migrated.
abstract class PotentialModification {
+ /// Gets a [NullabilityFixDescription] describing this modification.
+ NullabilityFixDescription get description;
+
bool get isEmpty;
/// Gets the individual migrations that need to be done, considering the
/// solution to the constraint equations.
Iterable<SourceEdit> get modifications;
+
+ /// Gets the reasons for this potential modification.
+ Iterable<FixReasonInfo> get reasons;
}
/// Helper object used by [ConditionalModification] to keep track of AST nodes
diff --git a/pkg/nnbd_migration/lib/src/variables.dart b/pkg/nnbd_migration/lib/src/variables.dart
index e1e88ee..8406cd4 100644
--- a/pkg/nnbd_migration/lib/src/variables.dart
+++ b/pkg/nnbd_migration/lib/src/variables.dart
@@ -9,6 +9,7 @@
import 'package:analyzer/src/dart/element/type.dart';
import 'package:analyzer/src/generated/resolver.dart';
import 'package:analyzer/src/generated/source.dart';
+import 'package:nnbd_migration/instrumentation.dart';
import 'package:nnbd_migration/src/already_migrated_code_decorator.dart';
import 'package:nnbd_migration/src/conditional_discard.dart';
import 'package:nnbd_migration/src/decorated_type.dart';
@@ -33,7 +34,9 @@
final AlreadyMigratedCodeDecorator _alreadyMigratedCodeDecorator;
- Variables(this._graph, TypeProvider typeProvider)
+ final NullabilityMigrationInstrumentation /*?*/ instrumentation;
+
+ Variables(this._graph, TypeProvider typeProvider, {this.instrumentation})
: _alreadyMigratedCodeDecorator =
AlreadyMigratedCodeDecorator(_graph, typeProvider);
@@ -142,6 +145,7 @@
void recordDecoratedTypeAnnotation(Source source, TypeAnnotation node,
DecoratedType type, PotentiallyAddQuestionSuffix potentialModification) {
+ instrumentation?.explicitTypeNullability(source, node, type.node);
if (potentialModification != null)
_addPotentialModification(source, potentialModification);
(_decoratedTypeAnnotations[source] ??=
@@ -160,8 +164,8 @@
@override
void recordExpressionChecks(
- Source source, Expression expression, ExpressionChecks checks) {
- _addPotentialModification(source, checks);
+ Source source, Expression expression, ExpressionChecksOrigin origin) {
+ _addPotentialModification(source, origin.checks);
}
@override
@@ -240,6 +244,7 @@
// TODO(paulberry)
throw UnimplementedError('Decorating ${element.runtimeType}');
}
+ instrumentation?.externalDecoratedType(element, decoratedType);
return decoratedType;
}
diff --git a/pkg/nnbd_migration/test/already_migrated_code_decorator_test.dart b/pkg/nnbd_migration/test/already_migrated_code_decorator_test.dart
index b2b058c..7a20cc3 100644
--- a/pkg/nnbd_migration/test/already_migrated_code_decorator_test.dart
+++ b/pkg/nnbd_migration/test/already_migrated_code_decorator_test.dart
@@ -3,6 +3,7 @@
// BSD-style license that can be found in the LICENSE file.
import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/dart/element/nullability_suffix.dart';
import 'package:analyzer/dart/element/type.dart';
import 'package:analyzer/src/dart/element/element.dart';
import 'package:analyzer/src/dart/element/type.dart';
@@ -51,7 +52,7 @@
DecoratedType decoratedType,
NullabilityNode expectedNullability,
void Function(DecoratedType) checkArgument) {
- expect(decoratedType.type.element, typeProvider.futureOrType.element);
+ expect(decoratedType.type.element, typeProvider.futureOrElement);
expect(decoratedType.node, expectedNullability);
checkArgument(decoratedType.typeArguments[0]);
}
@@ -215,7 +216,7 @@
}
test_getImmediateSupertypes_future() {
- var element = typeProvider.futureType.element;
+ var element = typeProvider.futureElement;
var decoratedSupertypes =
decorator.getImmediateSupertypes(element).toList();
var typeParam = element.typeParameters[0];
@@ -231,9 +232,12 @@
test_getImmediateSupertypes_generic() {
var t = ElementFactory.typeParameterElement('T');
var class_ = ElementFactory.classElement3(
- name: 'C',
- typeParameters: [t],
- supertype: typeProvider.iterableType.instantiate([t.type]));
+ name: 'C',
+ typeParameters: [t],
+ supertype: typeProvider.iterableType2(
+ t.instantiate(nullabilitySuffix: NullabilitySuffix.star),
+ ),
+ );
var decoratedSupertypes = decorator.getImmediateSupertypes(class_).toList();
expect(decoratedSupertypes, hasLength(1));
checkIterable(decoratedSupertypes[0], never,
diff --git a/pkg/nnbd_migration/test/api_test.dart b/pkg/nnbd_migration/test/api_test.dart
index e7593d2..6b01783 100644
--- a/pkg/nnbd_migration/test/api_test.dart
+++ b/pkg/nnbd_migration/test/api_test.dart
@@ -2,14 +2,13 @@
// 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.
-import 'package:analyzer/dart/ast/ast.dart';
-import 'package:analyzer/src/generated/source.dart';
import 'package:analyzer_plugin/protocol/protocol_common.dart';
import 'package:nnbd_migration/nnbd_migration.dart';
import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
import 'abstract_context.dart';
+import 'api_test_base.dart';
main() {
defineReflectiveSuite(() {
@@ -41,7 +40,7 @@
for (var path in input.keys) {
newFile(path, content: input[path]);
}
- var listener = new _TestMigrationListener();
+ var listener = new TestMigrationListener();
var migration =
NullabilityMigration(listener, permissive: _usePermissiveMode);
for (var path in input.keys) {
@@ -53,7 +52,7 @@
}
migration.finish();
var sourceEdits = <String, List<SourceEdit>>{};
- for (var entry in listener._edits.entries) {
+ for (var entry in listener.edits.entries) {
var path = entry.key.fullName;
expect(expectedOutput.keys, contains(path));
sourceEdits[path] = entry.value;
@@ -77,6 +76,17 @@
/// Mixin containing test cases for the provisional API.
mixin _ProvisionalApiTestCases on _ProvisionalApiTestBase {
+ @FailingTest(issue: 'https://github.com/dart-lang/sdk/issues/38461')
+ test_add_required() async {
+ var content = '''
+int f({String s}) => s.length;
+''';
+ var expected = '''
+int f({required String s}) => s.length;
+''';
+ await _checkSingleFileChanges(content, expected);
+ }
+
test_assign_null_to_generic_type() async {
var content = '''
main() {
@@ -91,6 +101,37 @@
await _checkSingleFileChanges(content, expected);
}
+ @FailingTest(issue: 'https://github.com/dart-lang/sdk/issues/38341')
+ test_back_propagation_stops_at_implicitly_typed_variables() async {
+ var content = '''
+class C {
+ int v;
+ C(this.v);
+}
+f(C c) {
+ var x = c.v;
+ print(x + 1);
+}
+main() {
+ C(null);
+}
+''';
+ var expected = '''
+class C {
+ int? v;
+ C(this.v);
+}
+f(C c) {
+ var x = c.v!;
+ print(x + 1);
+}
+main() {
+ C(null);
+}
+''';
+ await _checkSingleFileChanges(content, expected);
+ }
+
test_catch_simple() async {
var content = '''
void f() {
@@ -439,6 +480,20 @@
await _checkSingleFileChanges(content, expected);
}
+ @FailingTest(issue: 'https://github.com/dart-lang/sdk/issues/38462')
+ test_convert_required() async {
+ addMetaPackage();
+ var content = '''
+import 'package:meta/meta.dart';
+void f({@required String s}) {}
+''';
+ var expected = '''
+import 'package:meta/meta.dart';
+void f({required String s}) {}
+''';
+ await _checkSingleFileChanges(content, expected);
+ }
+
test_data_flow_assignment_field() async {
var content = '''
class C {
@@ -878,6 +933,32 @@
await _checkSingleFileChanges(content, expected);
}
+ test_definitely_assigned_value() async {
+ var content = '''
+String f(bool b) {
+ String s;
+ if (b) {
+ s = 'true';
+ } else {
+ s = 'false';
+ }
+ return s;
+}
+''';
+ var expected = '''
+String f(bool b) {
+ String s;
+ if (b) {
+ s = 'true';
+ } else {
+ s = 'false';
+ }
+ return s;
+}
+''';
+ await _checkSingleFileChanges(content, expected);
+ }
+
test_discard_simple_condition() async {
var content = '''
int f(int i) {
@@ -1212,6 +1293,32 @@
await _checkSingleFileChanges(content, expected);
}
+ test_for_each_basic() async {
+ var content = '''
+void f(List<int> l) {
+ for (var x in l) {
+ g(x);
+ }
+}
+void g(int x) {}
+main() {
+ f([null]);
+}
+''';
+ var expected = '''
+void f(List<int?> l) {
+ for (var x in l) {
+ g(x);
+ }
+}
+void g(int? x) {}
+main() {
+ f([null]);
+}
+''';
+ await _checkSingleFileChanges(content, expected);
+ }
+
test_function_expression() async {
var content = '''
int f(int i) {
@@ -1629,6 +1736,32 @@
await _checkSingleFileChanges(content, expected);
}
+ test_is_promotion_implies_non_nullable() async {
+ var content = '''
+bool f(Object o) => o is int && o.isEven;
+main() {
+ f(null);
+}
+''';
+ var expected = '''
+bool f(Object? o) => o is int && o.isEven;
+main() {
+ f(null);
+}
+''';
+ await _checkSingleFileChanges(content, expected);
+ }
+
+ test_isExpression_typeName_typeArguments() async {
+ var content = '''
+bool f(a) => a is List<int>;
+''';
+ var expected = '''
+bool f(a) => a is List<int?>;
+''';
+ await _checkSingleFileChanges(content, expected);
+ }
+
test_local_function() async {
var content = '''
int f(int i) {
@@ -2021,6 +2154,29 @@
await _checkSingleFileChanges(content, expected);
}
+ @FailingTest(issue: 'https://github.com/dart-lang/sdk/issues/38344')
+ test_not_definitely_assigned_value() async {
+ var content = '''
+String f(bool b) {
+ String s;
+ if (b) {
+ s = 'true';
+ }
+ return s;
+}
+''';
+ var expected = '''
+String? f(bool b) {
+ String? s;
+ if (b) {
+ s = 'true';
+ }
+ return s;
+}
+''';
+ await _checkSingleFileChanges(content, expected);
+ }
+
test_null_aware_getter_invocation() async {
var content = '''
bool f(int i) => i?.isEven;
@@ -2097,6 +2253,25 @@
await _checkSingleFileChanges(content, expected);
}
+ @FailingTest(issue: 'https://github.com/dart-lang/sdk/issues/38339')
+ test_operator_eq_with_inferred_parameter_type() async {
+ var content = '''
+class C {
+ operator==(Object other) {
+ return other is C;
+ }
+}
+''';
+ var expected = '''
+class C {
+ operator==(Object other) {
+ return other is C;
+ }
+}
+''';
+ await _checkSingleFileChanges(content, expected);
+ }
+
test_override_parameter_type_non_nullable() async {
var content = '''
abstract class Base {
@@ -2918,6 +3093,27 @@
''';
await _checkSingleFileChanges(content, expected);
}
+
+ @FailingTest(issue: 'https://github.com/dart-lang/sdk/issues/38453')
+ test_unconditional_use_of_field_formal_param_does_not_create_hard_edge() async {
+ var content = '''
+class C {
+ int i;
+ int j;
+ C.one(this.i) : j = i + 1;
+ C.two() : i = null, j = 0;
+}
+''';
+ var expected = '''
+class C {
+ int? i;
+ int j;
+ C.one(this.i) : j = i! + 1;
+ C.two() : i = null, j = 0;
+}
+''';
+ await _checkSingleFileChanges(content, expected);
+ }
}
@reflectiveTest
@@ -2947,23 +3143,3 @@
driver.resetUriResolution();
}
}
-
-class _TestMigrationListener implements NullabilityMigrationListener {
- final _edits = <Source, List<SourceEdit>>{};
-
- List<String> details = [];
-
- @override
- void addEdit(SingleNullabilityFix fix, SourceEdit edit) {
- (_edits[fix.source] ??= []).add(edit);
- }
-
- @override
- void addFix(SingleNullabilityFix fix) {}
-
- @override
- void reportException(
- Source source, AstNode node, Object exception, StackTrace stackTrace) {
- fail('Exception reported: $exception');
- }
-}
diff --git a/pkg/nnbd_migration/test/api_test_base.dart b/pkg/nnbd_migration/test/api_test_base.dart
new file mode 100644
index 0000000..f886f0d
--- /dev/null
+++ b/pkg/nnbd_migration/test/api_test_base.dart
@@ -0,0 +1,29 @@
+// Copyright (c) 2019, 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.
+
+import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer/src/generated/source.dart';
+import 'package:analyzer_plugin/protocol/protocol_common.dart';
+import 'package:nnbd_migration/nnbd_migration.dart';
+import 'package:test/test.dart';
+
+class TestMigrationListener implements NullabilityMigrationListener {
+ final edits = <Source, List<SourceEdit>>{};
+
+ List<String> details = [];
+
+ @override
+ void addEdit(SingleNullabilityFix fix, SourceEdit edit) {
+ (edits[fix.source] ??= []).add(edit);
+ }
+
+ @override
+ void addFix(SingleNullabilityFix fix) {}
+
+ @override
+ void reportException(
+ Source source, AstNode node, Object exception, StackTrace stackTrace) {
+ fail('Exception reported: $exception');
+ }
+}
diff --git a/pkg/nnbd_migration/test/decorated_type_test.dart b/pkg/nnbd_migration/test/decorated_type_test.dart
index a0ea3f0..61e8b6d 100644
--- a/pkg/nnbd_migration/test/decorated_type_test.dart
+++ b/pkg/nnbd_migration/test/decorated_type_test.dart
@@ -36,7 +36,7 @@
NullabilityNode get always => graph.always;
- ClassElement get listElement => typeProvider.listType.element;
+ ClassElement get listElement => typeProvider.listElement;
void setUp() {
NullabilityNode.clearDebugNames();
diff --git a/pkg/nnbd_migration/test/edge_builder_flow_analysis_test.dart b/pkg/nnbd_migration/test/edge_builder_flow_analysis_test.dart
index 3643d8a..50a4879 100644
--- a/pkg/nnbd_migration/test/edge_builder_flow_analysis_test.dart
+++ b/pkg/nnbd_migration/test/edge_builder_flow_analysis_test.dart
@@ -712,6 +712,35 @@
assertEdge(iNode, jNode, hard: false);
}
+ test_for_each_assigns_to_declared_var() async {
+ await analyze('''
+void f(Iterable<int> x) {
+ for (int i in x) {
+ g(i);
+ }
+}
+void g(int j) {}
+''');
+ var iNode = decoratedTypeAnnotation('int i').node;
+ // No edge from never to i because it is assigned before it is used.
+ assertNoEdge(never, iNode);
+ }
+
+ test_for_each_assigns_to_identifier() async {
+ await analyze('''
+void f(Iterable<int> x) {
+ int i;
+ for (i in x) {
+ g(i);
+ }
+}
+void g(int j) {}
+''');
+ var iNode = decoratedTypeAnnotation('int i').node;
+ // No edge from never to i because it is assigned before it is used.
+ assertNoEdge(never, iNode);
+ }
+
test_for_each_cancels_promotions_for_assignments_in_body() async {
await analyze('''
void f(int i, int j, Iterable<Object> x) {
@@ -732,6 +761,31 @@
assertEdge(jNode, never, hard: false);
}
+ test_for_each_collection_assigns_to_declared_var() async {
+ await analyze('''
+void f(Iterable<int> x) {
+ [for (int i in x) g(i)];
+}
+void g(int j) {}
+''');
+ var iNode = decoratedTypeAnnotation('int i').node;
+ // No edge from never to i because it is assigned before it is used.
+ assertNoEdge(never, iNode);
+ }
+
+ test_for_each_collection_assigns_to_identifier() async {
+ await analyze('''
+void f(Iterable<int> x) {
+ int i;
+ [for (i in x) g(i)];
+}
+void g(int j) {}
+''');
+ var iNode = decoratedTypeAnnotation('int i').node;
+ // No edge from never to i because it is assigned before it is used.
+ assertNoEdge(never, iNode);
+ }
+
test_for_each_collection_cancels_promotions_for_assignments_in_body() async {
await analyze('''
void f(int i, int j, Iterable<Object> x) {
@@ -925,6 +979,48 @@
assertEdge(iNode, kNode, hard: true);
}
+ test_is() async {
+ await analyze('''
+void f(num n) {
+ if (n is int) {
+ g(n);
+ }
+ h(n);
+}
+void g(int i) {}
+void h(num m) {}
+''');
+ var iNode = decoratedTypeAnnotation('int i').node;
+ var nNode = decoratedTypeAnnotation('num n').node;
+ var mNode = decoratedTypeAnnotation('num m').node;
+ // No edge from n to i because n is known to be non-nullable at the site of
+ // the call to g
+ assertNoEdge(nNode, iNode);
+ // But there is an edge from n to m.
+ assertEdge(nNode, mNode, hard: true);
+ }
+
+ test_is_not() async {
+ await analyze('''
+void f(num n) {
+ if (n is! int) {} else {
+ g(n);
+ }
+ h(n);
+}
+void g(int i) {}
+void h(num m) {}
+''');
+ var iNode = decoratedTypeAnnotation('int i').node;
+ var nNode = decoratedTypeAnnotation('num n').node;
+ var mNode = decoratedTypeAnnotation('num m').node;
+ // No edge from n to i because n is known to be non-nullable at the site of
+ // the call to g
+ assertNoEdge(nNode, iNode);
+ // But there is an edge from n to m.
+ assertEdge(nNode, mNode, hard: true);
+ }
+
test_local_function_parameters() async {
await analyze('''
void f() {
diff --git a/pkg/nnbd_migration/test/edge_builder_test.dart b/pkg/nnbd_migration/test/edge_builder_test.dart
index 1db66dc..e70c987 100644
--- a/pkg/nnbd_migration/test/edge_builder_test.dart
+++ b/pkg/nnbd_migration/test/edge_builder_test.dart
@@ -3,6 +3,7 @@
// BSD-style license that can be found in the LICENSE file.
import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/dart/element/nullability_suffix.dart';
import 'package:analyzer/dart/element/type.dart';
import 'package:analyzer/src/dart/element/element.dart';
import 'package:analyzer/src/dart/element/member.dart';
@@ -173,6 +174,14 @@
assertEdge(t1.typeArguments[0].node, t2.typeArguments[0].node, hard: false);
}
+ void test_future_or_to_future_or() {
+ var t1 = futureOr(int_());
+ var t2 = futureOr(int_());
+ assign(t1, t2, hard: true);
+ assertEdge(t1.node, t2.node, hard: true);
+ assertEdge(t1.typeArguments[0].node, t2.typeArguments[0].node, hard: false);
+ }
+
test_generic_to_dynamic() {
var t = list(object());
assign(t, dynamic_);
@@ -348,7 +357,7 @@
if (node == never) return;
for (var edge in getEdges(anyNode, node)) {
- expect(edge.primarySource, never);
+ expect(edge.sourceNode, never);
}
}
@@ -357,14 +366,14 @@
/// [expressionChecks] is the object tracking whether or not a null check is
/// needed.
void assertNullCheck(
- ExpressionChecks expressionChecks, NullabilityEdge expectedEdge) {
- expect(expressionChecks.edges, contains(expectedEdge));
+ ExpressionChecksOrigin expressionChecks, NullabilityEdge expectedEdge) {
+ expect(expressionChecks.checks.edges, contains(expectedEdge));
}
/// Gets the [ExpressionChecks] associated with the expression whose text
/// representation is [text], or `null` if the expression has no
/// [ExpressionChecks] associated with it.
- ExpressionChecks checkExpression(String text) {
+ ExpressionChecksOrigin checkExpression(String text) {
return variables.checkExpression(findNode.expression(text));
}
@@ -421,6 +430,17 @@
assertEdge(decoratedTypeAnnotation('int i').node, never, hard: true);
}
+ test_assert_initializer_demonstrates_non_null_intent() async {
+ await analyze('''
+class C {
+ C(int i)
+ : assert(i != null);
+}
+''');
+
+ assertEdge(decoratedTypeAnnotation('int i').node, never, hard: true);
+ }
+
test_assign_bound_to_type_parameter() async {
await analyze('''
class C<T extends List<int>> {
@@ -592,7 +612,11 @@
await analyze(code);
var targetEdge =
assertEdge(decoratedTypeAnnotation('C y').node, never, hard: true);
- expect((targetEdge.origin as CompoundAssignmentOrigin).offset,
+ expect(
+ (graph.getEdgeOrigin(targetEdge) as CompoundAssignmentOrigin)
+ .node
+ .operator
+ .offset,
code.indexOf('+='));
assertNullCheck(
checkExpression('z);'),
@@ -603,7 +627,11 @@
decoratedTypeAnnotation('C operator').node,
decoratedTypeAnnotation('C y').node,
hard: false);
- expect((operatorReturnEdge.origin as CompoundAssignmentOrigin).offset,
+ expect(
+ (graph.getEdgeOrigin(operatorReturnEdge) as CompoundAssignmentOrigin)
+ .node
+ .operator
+ .offset,
code.indexOf('+='));
var fReturnEdge = assertEdge(decoratedTypeAnnotation('C operator').node,
decoratedTypeAnnotation('C f').node,
@@ -621,7 +649,11 @@
await analyze(code);
var targetEdge =
assertEdge(decoratedTypeAnnotation('C<int> y').node, never, hard: true);
- expect((targetEdge.origin as CompoundAssignmentOrigin).offset,
+ expect(
+ (graph.getEdgeOrigin(targetEdge) as CompoundAssignmentOrigin)
+ .node
+ .operator
+ .offset,
code.indexOf('+='));
assertNullCheck(
checkExpression('z);'),
@@ -632,7 +664,11 @@
decoratedTypeAnnotation('C<T> operator').node,
decoratedTypeAnnotation('C<int> y').node,
hard: false);
- expect((operatorReturnEdge.origin as CompoundAssignmentOrigin).offset,
+ expect(
+ (graph.getEdgeOrigin(operatorReturnEdge) as CompoundAssignmentOrigin)
+ .node
+ .operator
+ .offset,
code.indexOf('+='));
var fReturnEdge = assertEdge(decoratedTypeAnnotation('C<T> operator').node,
decoratedTypeAnnotation('C<int> f').node,
@@ -1732,6 +1768,92 @@
decoratedTypeAnnotation('int i').node);
}
+ test_for_each_element_with_declaration() async {
+ await analyze('''
+void f(List<int> l) {
+ [for (int i in l) 0];
+}
+''');
+ assertEdge(decoratedTypeAnnotation('List<int>').node, never, hard: true);
+ assertEdge(substitutionNode(decoratedTypeAnnotation('int> l').node, never),
+ decoratedTypeAnnotation('int i').node,
+ hard: false);
+ }
+
+ test_for_each_element_with_declaration_implicit_type() async {
+ await analyze('''
+void f(List<int> l) {
+ [for (var i in l) g(i)];
+}
+int g(int j) => 0;
+''');
+ var jNode = decoratedTypeAnnotation('int j').node;
+ var iMatcher = anyNode;
+ assertEdge(iMatcher, jNode, hard: false);
+ var iNode = iMatcher.matchingNode;
+ assertEdge(decoratedTypeAnnotation('List<int>').node, never, hard: true);
+ assertEdge(
+ substitutionNode(decoratedTypeAnnotation('int> l').node, never), iNode,
+ hard: false);
+ }
+
+ test_for_each_element_with_identifier() async {
+ await analyze('''
+void f(List<int> l) {
+ int x;
+ [for (x in l) 0];
+}
+''');
+ assertEdge(decoratedTypeAnnotation('List<int>').node, never, hard: true);
+ assertEdge(substitutionNode(decoratedTypeAnnotation('int> l').node, never),
+ decoratedTypeAnnotation('int x').node,
+ hard: false);
+ }
+
+ test_for_each_with_declaration() async {
+ await analyze('''
+void f(List<int> l) {
+ for (int i in l) {}
+}
+''');
+ assertEdge(decoratedTypeAnnotation('List<int>').node, never, hard: true);
+ assertEdge(substitutionNode(decoratedTypeAnnotation('int> l').node, never),
+ decoratedTypeAnnotation('int i').node,
+ hard: false);
+ }
+
+ test_for_each_with_declaration_implicit_type() async {
+ await analyze('''
+void f(List<int> l) {
+ for (var i in l) {
+ g(i);
+ }
+}
+void g(int j) {}
+''');
+ var jNode = decoratedTypeAnnotation('int j').node;
+ var iMatcher = anyNode;
+ assertEdge(iMatcher, jNode, hard: false);
+ var iNode = iMatcher.matchingNode;
+ assertEdge(decoratedTypeAnnotation('List<int>').node, never, hard: true);
+ assertEdge(
+ substitutionNode(decoratedTypeAnnotation('int> l').node, never), iNode,
+ hard: false);
+ }
+
+ test_for_each_with_identifier() async {
+ await analyze('''
+void f(List<int> l) {
+ int x;
+ for (x in l) {}
+}
+''');
+ assertEdge(decoratedTypeAnnotation('List<int>').node, never, hard: true);
+ assertEdge(substitutionNode(decoratedTypeAnnotation('int> l').node, never),
+ decoratedTypeAnnotation('int x').node,
+ hard: false);
+ }
+
test_for_element_list() async {
await analyze('''
void f(List<int> ints) {
@@ -2463,7 +2585,7 @@
''');
var edge = assertEdge(anyNode, decoratedTypeAnnotation('int> f').node,
hard: false);
- var inferredTypeArgument = edge.primarySource;
+ var inferredTypeArgument = edge.sourceNode;
assertEdge(
decoratedTypeAnnotation('int> x').node,
substitutionNode(
@@ -2482,8 +2604,8 @@
var nullable_c_t = decoratedTypeAnnotation('C<int>').typeArguments[0].node;
var nullable_t = decoratedTypeAnnotation('T t').node;
var check_i = checkExpression('i/*check*/');
- var nullable_c_t_or_nullable_t =
- check_i.edges.single.destinationNode as NullabilityNodeForSubstitution;
+ var nullable_c_t_or_nullable_t = check_i.checks.edges.single.destinationNode
+ as NullabilityNodeForSubstitution;
expect(nullable_c_t_or_nullable_t.innerNode, same(nullable_c_t));
expect(nullable_c_t_or_nullable_t.outerNode, same(nullable_t));
assertNullCheck(check_i,
@@ -2501,8 +2623,8 @@
var nullable_c_t = decoratedTypeAnnotation('C<int>').typeArguments[0].node;
var nullable_t = decoratedTypeAnnotation('T t').node;
var check_i = checkExpression('i/*check*/');
- var nullable_c_t_or_nullable_t =
- check_i.edges.single.destinationNode as NullabilityNodeForSubstitution;
+ var nullable_c_t_or_nullable_t = check_i.checks.edges.single.destinationNode
+ as NullabilityNodeForSubstitution;
expect(nullable_c_t_or_nullable_t.innerNode, same(nullable_c_t));
expect(nullable_c_t_or_nullable_t.outerNode, same(nullable_t));
assertNullCheck(check_i,
@@ -2650,6 +2772,18 @@
}
@failingTest
+ test_isExpression_directlyRelatedTypeParameter() async {
+ await analyze('''
+bool f(List<num> list) => list is List<int>
+''');
+ assertNoUpstreamNullability(decoratedTypeAnnotation('bool').node);
+ assertEdge(decoratedTypeAnnotation('List<int>').node, never, hard: false);
+ assertEdge(decoratedTypeAnnotation('num').node,
+ decoratedTypeAnnotation('int').node,
+ hard: false);
+ }
+
+ @failingTest
test_isExpression_genericFunctionType() async {
await analyze('''
bool f(a) => a is int Function(String);
@@ -2657,19 +2791,33 @@
assertNoUpstreamNullability(decoratedTypeAnnotation('bool').node);
}
+ @failingTest
+ test_isExpression_indirectlyRelatedTypeParameter() async {
+ await analyze('''
+bool f(Iterable<num> iter) => iter is List<int>
+''');
+ assertNoUpstreamNullability(decoratedTypeAnnotation('bool').node);
+ assertEdge(decoratedTypeAnnotation('List').node, never, hard: false);
+ assertEdge(decoratedTypeAnnotation('num').node,
+ decoratedTypeAnnotation('int').node,
+ hard: false);
+ }
+
test_isExpression_typeName_noTypeArguments() async {
await analyze('''
bool f(a) => a is String;
''');
assertNoUpstreamNullability(decoratedTypeAnnotation('bool').node);
+ assertEdge(decoratedTypeAnnotation('String').node, never, hard: false);
}
- @failingTest
test_isExpression_typeName_typeArguments() async {
await analyze('''
bool f(a) => a is List<int>;
''');
assertNoUpstreamNullability(decoratedTypeAnnotation('bool').node);
+ assertEdge(decoratedTypeAnnotation('List').node, never, hard: false);
+ assertEdge(always, decoratedTypeAnnotation('int').node, hard: false);
}
test_library_metadata() async {
@@ -2701,7 +2849,7 @@
expect(returnTypeEdges.length, 1);
final returnTypeEdge = returnTypeEdges.single;
- final listArgType = returnTypeEdge.primarySource;
+ final listArgType = returnTypeEdge.sourceNode;
assertNoUpstreamNullability(listArgType);
}
@@ -2718,7 +2866,7 @@
expect(returnTypeEdges.length, 1);
final returnTypeEdge = returnTypeEdges.single;
- final listArgType = returnTypeEdge.primarySource;
+ final listArgType = returnTypeEdge.sourceNode;
assertEdge(always, listArgType, hard: false);
}
@@ -2919,8 +3067,8 @@
var nullable_c_t = decoratedTypeAnnotation('C<int>').typeArguments[0].node;
var nullable_t = decoratedTypeAnnotation('T t').node;
var check_i = checkExpression('i/*check*/');
- var nullable_c_t_or_nullable_t =
- check_i.edges.single.destinationNode as NullabilityNodeForSubstitution;
+ var nullable_c_t_or_nullable_t = check_i.checks.edges.single.destinationNode
+ as NullabilityNodeForSubstitution;
expect(nullable_c_t_or_nullable_t.innerNode, same(nullable_c_t));
expect(nullable_c_t_or_nullable_t.outerNode, same(nullable_t));
assertNullCheck(check_i,
@@ -2945,8 +3093,8 @@
.node;
expect(nullable_t, same(never));
var check_i = checkExpression('i/*check*/');
- var nullable_list_t_or_nullable_t =
- check_i.edges.single.destinationNode as NullabilityNodeForSubstitution;
+ var nullable_list_t_or_nullable_t = check_i
+ .checks.edges.single.destinationNode as NullabilityNodeForSubstitution;
expect(nullable_list_t_or_nullable_t.innerNode, same(nullable_list_t));
expect(nullable_list_t_or_nullable_t.outerNode, same(nullable_t));
assertNullCheck(check_i,
@@ -2964,8 +3112,8 @@
var nullable_f_t = decoratedTypeAnnotation('int>').node;
var nullable_t = decoratedTypeAnnotation('T t').node;
var check_i = checkExpression('i/*check*/');
- var nullable_f_t_or_nullable_t =
- check_i.edges.single.destinationNode as NullabilityNodeForSubstitution;
+ var nullable_f_t_or_nullable_t = check_i.checks.edges.single.destinationNode
+ as NullabilityNodeForSubstitution;
expect(nullable_f_t_or_nullable_t.innerNode, same(nullable_f_t));
expect(nullable_f_t_or_nullable_t.outerNode, same(nullable_t));
assertNullCheck(check_i,
@@ -3057,8 +3205,8 @@
''');
var check_i = checkExpression('(f<int>(1))');
var nullable_f_t = decoratedTypeAnnotation('int>').node;
- var nullable_f_t_or_nullable_t =
- check_i.edges.single.primarySource as NullabilityNodeForSubstitution;
+ var nullable_f_t_or_nullable_t = check_i.checks.edges.single.sourceNode
+ as NullabilityNodeForSubstitution;
var nullable_t = decoratedTypeAnnotation('T f').node;
expect(nullable_f_t_or_nullable_t.innerNode, same(nullable_f_t));
expect(nullable_f_t_or_nullable_t.outerNode, same(nullable_t));
@@ -4446,9 +4594,9 @@
assertNoUpstreamNullability(mapNode);
assertNoUpstreamNullability(
- assertEdge(anyNode, keyNode, hard: false).primarySource);
+ assertEdge(anyNode, keyNode, hard: false).sourceNode);
assertNoUpstreamNullability(
- assertEdge(anyNode, valueNode, hard: false).primarySource);
+ assertEdge(anyNode, valueNode, hard: false).sourceNode);
}
test_setOrMapLiteral_map_noTypeArgument_nullableKey() async {
@@ -4462,10 +4610,10 @@
var mapNode = decoratedTypeAnnotation('Map').node;
assertNoUpstreamNullability(mapNode);
- assertEdge(always, assertEdge(anyNode, keyNode, hard: false).primarySource,
+ assertEdge(always, assertEdge(anyNode, keyNode, hard: false).sourceNode,
hard: false);
assertNoUpstreamNullability(
- assertEdge(anyNode, valueNode, hard: false).primarySource);
+ assertEdge(anyNode, valueNode, hard: false).sourceNode);
}
test_setOrMapLiteral_map_noTypeArgument_nullableKeyAndValue() async {
@@ -4479,10 +4627,9 @@
var mapNode = decoratedTypeAnnotation('Map').node;
assertNoUpstreamNullability(mapNode);
- assertEdge(always, assertEdge(anyNode, keyNode, hard: false).primarySource,
+ assertEdge(always, assertEdge(anyNode, keyNode, hard: false).sourceNode,
hard: false);
- assertEdge(
- always, assertEdge(anyNode, valueNode, hard: false).primarySource,
+ assertEdge(always, assertEdge(anyNode, valueNode, hard: false).sourceNode,
hard: false);
}
@@ -4498,9 +4645,8 @@
assertNoUpstreamNullability(mapNode);
assertNoUpstreamNullability(
- assertEdge(anyNode, keyNode, hard: false).primarySource);
- assertEdge(
- always, assertEdge(anyNode, valueNode, hard: false).primarySource,
+ assertEdge(anyNode, keyNode, hard: false).sourceNode);
+ assertEdge(always, assertEdge(anyNode, valueNode, hard: false).sourceNode,
hard: false);
}
@@ -4569,7 +4715,7 @@
assertNoUpstreamNullability(setNode);
assertNoUpstreamNullability(
- assertEdge(anyNode, valueNode, hard: false).primarySource);
+ assertEdge(anyNode, valueNode, hard: false).sourceNode);
}
test_setOrMapLiteral_set_noTypeArgument_nullableElement() async {
@@ -4582,8 +4728,7 @@
var setNode = decoratedTypeAnnotation('Set').node;
assertNoUpstreamNullability(setNode);
- assertEdge(
- always, assertEdge(anyNode, valueNode, hard: false).primarySource,
+ assertEdge(always, assertEdge(anyNode, valueNode, hard: false).sourceNode,
hard: false);
}
@@ -4952,7 +5097,7 @@
await analyze('''
void f(List<int> x) {}
''');
- var listClass = typeProvider.listType.element;
+ var listClass = typeProvider.listElement;
var listBound =
variables.decoratedTypeParameterBound(listClass.typeParameters[0]);
expect(listBound.type.toString(), 'dynamic');
@@ -5062,7 +5207,13 @@
var class_ = (type.type as InterfaceType).element;
if (class_ == superclass) return type;
if (superclass.name == 'Object') {
- return DecoratedType(superclass.type, type.node);
+ return DecoratedType(
+ superclass.instantiate(
+ typeArguments: const [],
+ nullabilitySuffix: NullabilitySuffix.star,
+ ),
+ type.node,
+ );
}
if (class_.name == 'MyListOfList' && superclass.name == 'List') {
return assignmentCheckerTest._myListOfListSupertype
@@ -5070,8 +5221,13 @@
}
if (class_.name == 'Future' && superclass.name == 'FutureOr') {
return DecoratedType(
- superclass.type.instantiate([type.typeArguments[0].type]), type.node,
- typeArguments: [type.typeArguments[0]]);
+ superclass.instantiate(
+ typeArguments: [type.typeArguments[0].type],
+ nullabilitySuffix: NullabilitySuffix.star,
+ ),
+ type.node,
+ typeArguments: [type.typeArguments[0]],
+ );
}
throw UnimplementedError(
'TODO(paulberry): asInstanceOf($type, $superclass)');
@@ -5084,6 +5240,8 @@
}
}
-class _TestEdgeOrigin extends EdgeOrigin {
+class _TestEdgeOrigin implements EdgeOrigin {
const _TestEdgeOrigin();
+
+ noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
}
diff --git a/pkg/nnbd_migration/test/instrumentation_test.dart b/pkg/nnbd_migration/test/instrumentation_test.dart
new file mode 100644
index 0000000..942bb85
--- /dev/null
+++ b/pkg/nnbd_migration/test/instrumentation_test.dart
@@ -0,0 +1,849 @@
+// Copyright (c) 2019, 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.
+
+import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/src/generated/source.dart';
+import 'package:analyzer/src/test_utilities/find_node.dart';
+import 'package:nnbd_migration/instrumentation.dart';
+import 'package:nnbd_migration/nnbd_migration.dart';
+import 'package:nnbd_migration/nullability_state.dart';
+import 'package:test/test.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'abstract_context.dart';
+import 'api_test_base.dart';
+
+main() {
+ defineReflectiveSuite(() {
+ defineReflectiveTests(_InstrumentationTest);
+ });
+}
+
+class _InstrumentationClient implements NullabilityMigrationInstrumentation {
+ final _InstrumentationTest test;
+
+ _InstrumentationClient(this.test);
+
+ @override
+ void explicitTypeNullability(
+ Source source, TypeAnnotation typeAnnotation, NullabilityNodeInfo node) {
+ expect(source, test.source);
+ expect(test.explicitTypeNullability, isNot(contains(typeAnnotation)));
+ test.explicitTypeNullability[typeAnnotation] = node;
+ }
+
+ @override
+ void externalDecoratedType(Element element, DecoratedTypeInfo decoratedType) {
+ expect(test.externalDecoratedType, isNot(contains(element)));
+ test.externalDecoratedType[element] = decoratedType;
+ }
+
+ @override
+ void fix(SingleNullabilityFix fix, Iterable<FixReasonInfo> reasons) {
+ test.fixes[fix] = reasons.toList();
+ }
+
+ @override
+ void graphEdge(EdgeInfo edge, EdgeOriginInfo originInfo) {
+ expect(test.edgeOrigin, isNot(contains(edge)));
+ test.edges.add(edge);
+ test.edgeOrigin[edge] = originInfo;
+ }
+
+ @override
+ void immutableNodes(NullabilityNodeInfo never, NullabilityNodeInfo always) {
+ test.never = never;
+ test.always = always;
+ }
+
+ @override
+ void implicitReturnType(
+ Source source, AstNode node, DecoratedTypeInfo decoratedReturnType) {
+ expect(source, test.source);
+ expect(test.implicitReturnType, isNot(contains(node)));
+ test.implicitReturnType[node] = decoratedReturnType;
+ }
+
+ @override
+ void implicitType(
+ Source source, AstNode node, DecoratedTypeInfo decoratedType) {
+ expect(source, test.source);
+ expect(test.implicitType, isNot(contains(node)));
+ test.implicitType[node] = decoratedType;
+ }
+
+ @override
+ void implicitTypeArguments(
+ Source source, AstNode node, Iterable<DecoratedTypeInfo> types) {
+ expect(source, test.source);
+ expect(test.implicitTypeArguments, isNot(contains(node)));
+ test.implicitTypeArguments[node] = types.toList();
+ }
+
+ @override
+ void propagationStep(PropagationInfo info) {
+ test.propagationSteps.add(info);
+ }
+}
+
+@reflectiveTest
+class _InstrumentationTest extends AbstractContextTest {
+ NullabilityNodeInfo always;
+
+ final Map<TypeAnnotation, NullabilityNodeInfo> explicitTypeNullability = {};
+
+ final Map<Element, DecoratedTypeInfo> externalDecoratedType = {};
+
+ final List<EdgeInfo> edges = [];
+
+ Map<SingleNullabilityFix, List<FixReasonInfo>> fixes = {};
+
+ final Map<AstNode, DecoratedTypeInfo> implicitReturnType = {};
+
+ final Map<AstNode, DecoratedTypeInfo> implicitType = {};
+
+ final Map<AstNode, List<DecoratedTypeInfo>> implicitTypeArguments = {};
+
+ NullabilityNodeInfo never;
+
+ final List<PropagationInfo> propagationSteps = [];
+
+ final Map<EdgeInfo, EdgeOriginInfo> edgeOrigin = {};
+
+ FindNode findNode;
+
+ Source source;
+
+ Future<void> analyze(String content) async {
+ var sourcePath = convertPath('/home/test/lib/test.dart');
+ newFile(sourcePath, content: content);
+ var listener = new TestMigrationListener();
+ var migration = NullabilityMigration(listener,
+ instrumentation: _InstrumentationClient(this));
+ var result = await session.getResolvedUnit(sourcePath);
+ source = result.unit.declaredElement.source;
+ findNode = FindNode(content, result.unit);
+ migration.prepareInput(result);
+ migration.processInput(result);
+ migration.finish();
+ }
+
+ test_explicitTypeNullability() async {
+ var content = '''
+int x = 1;
+int y = null;
+''';
+ await analyze(content);
+ expect(explicitTypeNullability[findNode.typeAnnotation('int x')].isNullable,
+ false);
+ expect(explicitTypeNullability[findNode.typeAnnotation('int y')].isNullable,
+ true);
+ }
+
+ test_externalDecoratedType() async {
+ await analyze('''
+main() {
+ print(1);
+}
+''');
+ expect(
+ externalDecoratedType[findNode.simple('print').staticElement]
+ .type
+ .toString(),
+ 'void Function(Object)');
+ }
+
+ test_fix_reason_edge() async {
+ await analyze('''
+void f(int x) {
+ print(x.isEven);
+}
+void g(int y, bool b) {
+ if (b) {
+ f(y);
+ }
+}
+main() {
+ g(null, false);
+}
+''');
+ var yUsage = findNode.simple('y);');
+ var entry =
+ fixes.entries.where((e) => e.key.location.offset == yUsage.end).single;
+ var reasons = entry.value;
+ expect(reasons, hasLength(1));
+ var edge = reasons[0] as EdgeInfo;
+ expect(edge.sourceNode,
+ same(explicitTypeNullability[findNode.typeAnnotation('int y')]));
+ expect(edge.destinationNode,
+ same(explicitTypeNullability[findNode.typeAnnotation('int x')]));
+ expect(edge.isSatisfied, false);
+ expect(edgeOrigin[edge].node, same(yUsage));
+ }
+
+ test_fix_reason_node() async {
+ await analyze('''
+int x = null;
+''');
+ var entries = fixes.entries.toList();
+ expect(entries, hasLength(1));
+ var intAnnotation = findNode.typeAnnotation('int');
+ expect(entries.single.key.location.offset, intAnnotation.end);
+ var reasons = entries.single.value;
+ expect(reasons, hasLength(1));
+ expect(reasons.single, same(explicitTypeNullability[intAnnotation]));
+ }
+
+ test_graphEdge() async {
+ await analyze('''
+int f(int x) => x;
+''');
+ var xNode = explicitTypeNullability[findNode.typeAnnotation('int x')];
+ var returnNode = explicitTypeNullability[findNode.typeAnnotation('int f')];
+ expect(
+ edges.where(
+ (e) => e.sourceNode == xNode && e.destinationNode == returnNode),
+ hasLength(1));
+ }
+
+ test_graphEdge_guards() async {
+ await analyze('''
+int f(int i, int j) {
+ if (i == null) {
+ return j;
+ }
+ return 1;
+}
+''');
+ var iNode = explicitTypeNullability[findNode.typeAnnotation('int i')];
+ var jNode = explicitTypeNullability[findNode.typeAnnotation('int j')];
+ var returnNode = explicitTypeNullability[findNode.typeAnnotation('int f')];
+ var matchingEdges = edges
+ .where((e) => e.sourceNode == jNode && e.destinationNode == returnNode)
+ .toList();
+ expect(matchingEdges, hasLength(1));
+ expect(matchingEdges.single.guards, hasLength(1));
+ expect(matchingEdges.single.guards.single, iNode);
+ }
+
+ test_graphEdge_hard() async {
+ await analyze('''
+int f(int x) => x;
+''');
+ var xNode = explicitTypeNullability[findNode.typeAnnotation('int x')];
+ var returnNode = explicitTypeNullability[findNode.typeAnnotation('int f')];
+ var matchingEdges = edges
+ .where((e) => e.sourceNode == xNode && e.destinationNode == returnNode)
+ .toList();
+ expect(matchingEdges, hasLength(1));
+ expect(matchingEdges.single.isUnion, false);
+ expect(matchingEdges.single.isHard, true);
+ }
+
+ test_graphEdge_isSatisfied() async {
+ await analyze('''
+void f1(int i, bool b) {
+ f2(i, b);
+}
+void f2(int j, bool b) {
+ if (b) {
+ f3(j);
+ }
+}
+void f3(int k) {
+ f4(k);
+}
+void f4(int l) {
+ print(l.isEven);
+}
+main() {
+ f1(null, false);
+}
+''');
+ var iNode = explicitTypeNullability[findNode.typeAnnotation('int i')];
+ var jNode = explicitTypeNullability[findNode.typeAnnotation('int j')];
+ var kNode = explicitTypeNullability[findNode.typeAnnotation('int k')];
+ var lNode = explicitTypeNullability[findNode.typeAnnotation('int l')];
+ var iToJ = edges
+ .where((e) => e.sourceNode == iNode && e.destinationNode == jNode)
+ .single;
+ var jToK = edges
+ .where((e) => e.sourceNode == jNode && e.destinationNode == kNode)
+ .single;
+ var kToL = edges
+ .where((e) => e.sourceNode == kNode && e.destinationNode == lNode)
+ .single;
+ expect(iNode.isNullable, true);
+ expect(jNode.isNullable, true);
+ expect(kNode.isNullable, false);
+ expect(lNode.isNullable, false);
+ expect(iToJ.isSatisfied, true);
+ expect(jToK.isSatisfied, false);
+ expect(kToL.isSatisfied, true);
+ }
+
+ test_graphEdge_origin() async {
+ await analyze('''
+int f(int x) => x;
+''');
+ var xNode = explicitTypeNullability[findNode.typeAnnotation('int x')];
+ var returnNode = explicitTypeNullability[findNode.typeAnnotation('int f')];
+ var matchingEdges = edges
+ .where((e) => e.sourceNode == xNode && e.destinationNode == returnNode)
+ .toList();
+ var origin = edgeOrigin[matchingEdges.single];
+ expect(origin.source, source);
+ expect(origin.node, findNode.simple('x;'));
+ }
+
+ test_graphEdge_soft() async {
+ await analyze('''
+int f(int x, bool b) {
+ if (b) return x;
+ return 0;
+}
+''');
+ var xNode = explicitTypeNullability[findNode.typeAnnotation('int x')];
+ var returnNode = explicitTypeNullability[findNode.typeAnnotation('int f')];
+ var matchingEdges = edges
+ .where((e) => e.sourceNode == xNode && e.destinationNode == returnNode)
+ .toList();
+ expect(matchingEdges, hasLength(1));
+ expect(matchingEdges.single.isUnion, false);
+ expect(matchingEdges.single.isHard, false);
+ }
+
+ test_graphEdge_union() async {
+ await analyze('''
+class C {
+ int i;
+ C(this.i); /*constructor*/
+}
+''');
+ var fieldNode = explicitTypeNullability[findNode.typeAnnotation('int')];
+ var formalParamNode =
+ implicitType[findNode.fieldFormalParameter('i); /*constructor*/')].node;
+ var matchingEdges = edges
+ .where((e) =>
+ e.sourceNode == fieldNode && e.destinationNode == formalParamNode)
+ .toList();
+ expect(matchingEdges, hasLength(1));
+ expect(matchingEdges.single.isUnion, true);
+ expect(matchingEdges.single.isHard, true);
+ matchingEdges = edges
+ .where((e) =>
+ e.sourceNode == formalParamNode && e.destinationNode == fieldNode)
+ .toList();
+ expect(matchingEdges, hasLength(1));
+ expect(matchingEdges.single.isUnion, true);
+ expect(matchingEdges.single.isHard, true);
+ }
+
+ test_immutableNode_always() async {
+ await analyze('''
+int x = null;
+''');
+ expect(always.isImmutable, true);
+ expect(always.isNullable, true);
+ var xNode = explicitTypeNullability[findNode.typeAnnotation('int')];
+ var edge = edges.where((e) => e.destinationNode == xNode).single;
+ expect(edge.sourceNode, always);
+ }
+
+ test_immutableNode_never() async {
+ await analyze('''
+bool f(int x) => x.isEven;
+''');
+ expect(never.isImmutable, true);
+ expect(never.isNullable, false);
+ var xNode = explicitTypeNullability[findNode.typeAnnotation('int')];
+ var edge = edges.where((e) => e.sourceNode == xNode).single;
+ expect(edge.destinationNode, never);
+ }
+
+ test_implicitReturnType_constructor() async {
+ await analyze('''
+class C {
+ factory C() => f(true);
+ C.named();
+}
+C f(bool b) => b ? C.named() : null;
+''');
+ var factoryReturnNode = implicitReturnType[findNode.constructor('C(')].node;
+ var fReturnNode = explicitTypeNullability[findNode.typeAnnotation('C f')];
+ expect(
+ edges.where((e) =>
+ e.sourceNode == fReturnNode &&
+ e.destinationNode == factoryReturnNode),
+ hasLength(1));
+ }
+
+ test_implicitReturnType_formalParameter() async {
+ await analyze('''
+Object f(callback()) => callback();
+''');
+ var paramReturnNode =
+ implicitReturnType[findNode.functionTypedFormalParameter('callback())')]
+ .node;
+ var fReturnNode =
+ explicitTypeNullability[findNode.typeAnnotation('Object')];
+ expect(
+ edges.where((e) =>
+ e.sourceNode == paramReturnNode &&
+ e.destinationNode == fReturnNode),
+ hasLength(1));
+ }
+
+ test_implicitReturnType_function() async {
+ await analyze('''
+f() => 1;
+Object g() => f();
+''');
+ var fReturnNode =
+ implicitReturnType[findNode.functionDeclaration('f() =>')].node;
+ var gReturnNode =
+ explicitTypeNullability[findNode.typeAnnotation('Object')];
+ expect(
+ edges.where((e) =>
+ e.sourceNode == fReturnNode && e.destinationNode == gReturnNode),
+ hasLength(1));
+ }
+
+ test_implicitReturnType_functionExpression() async {
+ await analyze('''
+main() {
+ int Function() f = () => g();
+}
+int g() => 1;
+''');
+ var fReturnNode =
+ explicitTypeNullability[findNode.typeAnnotation('int Function')];
+ var functionExpressionReturnNode =
+ implicitReturnType[findNode.functionExpression('() => g()')].node;
+ var gReturnNode = explicitTypeNullability[findNode.typeAnnotation('int g')];
+ expect(
+ edges.where((e) =>
+ e.sourceNode == gReturnNode &&
+ e.destinationNode == functionExpressionReturnNode),
+ hasLength(1));
+ expect(
+ edges.where((e) =>
+ e.sourceNode == functionExpressionReturnNode &&
+ e.destinationNode == fReturnNode),
+ hasLength(1));
+ }
+
+ test_implicitReturnType_functionTypeAlias() async {
+ await analyze('''
+typedef F();
+Object f(F callback) => callback();
+''');
+ var typedefReturnNode =
+ implicitReturnType[findNode.functionTypeAlias('F()')].node;
+ var fReturnNode =
+ explicitTypeNullability[findNode.typeAnnotation('Object')];
+ expect(
+ edges.where((e) =>
+ e.sourceNode == typedefReturnNode &&
+ e.destinationNode == fReturnNode),
+ hasLength(1));
+ }
+
+ test_implicitReturnType_genericFunctionType() async {
+ await analyze('''
+Object f(Function() callback) => callback();
+''');
+ var callbackReturnNode =
+ implicitReturnType[findNode.genericFunctionType('Function()')].node;
+ var fReturnNode =
+ explicitTypeNullability[findNode.typeAnnotation('Object')];
+ expect(
+ edges.where((e) =>
+ e.sourceNode == callbackReturnNode &&
+ e.destinationNode == fReturnNode),
+ hasLength(1));
+ }
+
+ test_implicitReturnType_method() async {
+ await analyze('''
+abstract class Base {
+ int f();
+}
+abstract class Derived extends Base {
+ f /*derived*/();
+}
+''');
+ var baseReturnNode =
+ explicitTypeNullability[findNode.typeAnnotation('int')];
+ var derivedReturnNode =
+ implicitReturnType[findNode.methodDeclaration('f /*derived*/')].node;
+ expect(
+ edges.where((e) =>
+ e.sourceNode == derivedReturnNode &&
+ e.destinationNode == baseReturnNode),
+ hasLength(1));
+ }
+
+ test_implicitType_catch_exception() async {
+ await analyze('''
+void f() {
+ try {} catch (e) {
+ Object o = e;
+ }
+}
+''');
+ var oNode = explicitTypeNullability[findNode.typeAnnotation('Object')];
+ var eNode = implicitType[findNode.simple('e)')].node;
+ expect(
+ edges.where((e) => e.sourceNode == eNode && e.destinationNode == oNode),
+ hasLength(1));
+ }
+
+ test_implicitType_catch_stackTrace() async {
+ await analyze('''
+void f() {
+ try {} catch (e, st) {
+ Object o = st;
+ }
+}
+''');
+ var oNode = explicitTypeNullability[findNode.typeAnnotation('Object')];
+ var stNode = implicitType[findNode.simple('st)')].node;
+ expect(
+ edges
+ .where((e) => e.sourceNode == stNode && e.destinationNode == oNode),
+ hasLength(1));
+ }
+
+ test_implicitType_declaredIdentifier_forEachPartsWithDeclaration() async {
+ await analyze('''
+void f(List<int> l) {
+ for (var x in l) {
+ int y = x;
+ }
+}
+''');
+ var xNode = implicitType[(findNode.forStatement('for').forLoopParts
+ as ForEachPartsWithDeclaration)
+ .loopVariable]
+ .node;
+ var yNode = explicitTypeNullability[findNode.typeAnnotation('int y')];
+ expect(
+ edges.where((e) => e.sourceNode == xNode && e.destinationNode == yNode),
+ hasLength(1));
+ }
+
+ test_implicitType_formalParameter() async {
+ await analyze('''
+abstract class Base {
+ void f(int i);
+}
+abstract class Derived extends Base {
+ void f(i); /*derived*/
+}
+''');
+ var baseParamNode =
+ explicitTypeNullability[findNode.typeAnnotation('int i')];
+ var derivedParamNode =
+ implicitType[findNode.simpleParameter('i); /*derived*/')].node;
+ expect(
+ edges.where((e) =>
+ e.sourceNode == baseParamNode &&
+ e.destinationNode == derivedParamNode),
+ hasLength(1));
+ }
+
+ test_implicitType_namedParameter() async {
+ await analyze('''
+abstract class Base {
+ void f(void callback({int i}));
+}
+abstract class Derived extends Base {
+ void f(callback);
+}
+''');
+ var baseParamParamNode =
+ explicitTypeNullability[findNode.typeAnnotation('int i')];
+ var derivedParamParamNode =
+ implicitType[findNode.simpleParameter('callback)')]
+ .namedParameter('i')
+ .node;
+ expect(
+ edges.where((e) =>
+ e.sourceNode == baseParamParamNode &&
+ e.destinationNode == derivedParamParamNode),
+ hasLength(1));
+ }
+
+ test_implicitType_positionalParameter() async {
+ await analyze('''
+abstract class Base {
+ void f(void callback(int i));
+}
+abstract class Derived extends Base {
+ void f(callback);
+}
+''');
+ var baseParamParamNode =
+ explicitTypeNullability[findNode.typeAnnotation('int i')];
+ var derivedParamParamNode =
+ implicitType[findNode.simpleParameter('callback)')]
+ .positionalParameter(0)
+ .node;
+ expect(
+ edges.where((e) =>
+ e.sourceNode == baseParamParamNode &&
+ e.destinationNode == derivedParamParamNode),
+ hasLength(1));
+ }
+
+ test_implicitType_returnType() async {
+ await analyze('''
+abstract class Base {
+ void f(int callback());
+}
+abstract class Derived extends Base {
+ void f(callback);
+}
+''');
+ var baseParamReturnNode =
+ explicitTypeNullability[findNode.typeAnnotation('int callback')];
+ var derivedParamReturnNode =
+ implicitType[findNode.simpleParameter('callback)')].returnType.node;
+ expect(
+ edges.where((e) =>
+ e.sourceNode == baseParamReturnNode &&
+ e.destinationNode == derivedParamReturnNode),
+ hasLength(1));
+ }
+
+ test_implicitType_typeArgument() async {
+ await analyze('''
+abstract class Base {
+ void f(List<int> x);
+}
+abstract class Derived extends Base {
+ void f(x); /*derived*/
+}
+''');
+ var baseParamArgNode =
+ explicitTypeNullability[findNode.typeAnnotation('int>')];
+ var derivedParamArgNode =
+ implicitType[findNode.simpleParameter('x); /*derived*/')]
+ .typeArgument(0)
+ .node;
+ expect(
+ edges.where((e) =>
+ e.sourceNode == derivedParamArgNode &&
+ e.destinationNode == baseParamArgNode),
+ hasLength(1));
+ }
+
+ test_implicitType_variableDeclarationList() async {
+ await analyze('''
+void f(int i) {
+ var j = i;
+}
+''');
+ var iNode = explicitTypeNullability[findNode.typeAnnotation('int')];
+ var jNode = implicitType[findNode.variableDeclarationList('j')].node;
+ expect(
+ edges.where((e) => e.sourceNode == iNode && e.destinationNode == jNode),
+ hasLength(1));
+ }
+
+ test_implicitTypeArguments_genericFunctionCall() async {
+ await analyze('''
+List<T> g<T>(T t) {}
+List<int> f() => g(null);
+''');
+ var implicitInvocationTypeArgumentNode =
+ implicitTypeArguments[findNode.methodInvocation('g(null)')].single.node;
+ var returnElementNode =
+ explicitTypeNullability[findNode.typeAnnotation('int')];
+ expect(edges.where((e) {
+ var destination = e.destinationNode;
+ return e.sourceNode == always &&
+ destination is SubstitutionNodeInfo &&
+ destination.innerNode == implicitInvocationTypeArgumentNode;
+ }), hasLength(1));
+ expect(edges.where((e) {
+ var source = e.sourceNode;
+ return source is SubstitutionNodeInfo &&
+ source.innerNode == implicitInvocationTypeArgumentNode &&
+ e.destinationNode == returnElementNode;
+ }), hasLength(1));
+ }
+
+ test_implicitTypeArguments_genericMethodCall() async {
+ await analyze('''
+class C {
+ List<T> g<T>(T t) {}
+}
+List<int> f(C c) => c.g(null);
+''');
+ var implicitInvocationTypeArgumentNode =
+ implicitTypeArguments[findNode.methodInvocation('c.g(null)')]
+ .single
+ .node;
+ var returnElementNode =
+ explicitTypeNullability[findNode.typeAnnotation('int')];
+ expect(edges.where((e) {
+ var destination = e.destinationNode;
+ return e.sourceNode == always &&
+ destination is SubstitutionNodeInfo &&
+ destination.innerNode == implicitInvocationTypeArgumentNode;
+ }), hasLength(1));
+ expect(edges.where((e) {
+ var source = e.sourceNode;
+ return source is SubstitutionNodeInfo &&
+ source.innerNode == implicitInvocationTypeArgumentNode &&
+ e.destinationNode == returnElementNode;
+ }), hasLength(1));
+ }
+
+ test_implicitTypeArguments_instanceCreationExpression() async {
+ await analyze('''
+class C<T> {
+ C(T t);
+}
+C<int> f() => C(null);
+''');
+ var implicitInvocationTypeArgumentNode =
+ implicitTypeArguments[findNode.instanceCreation('C(null)')].single.node;
+ var returnElementNode =
+ explicitTypeNullability[findNode.typeAnnotation('int')];
+ expect(edges.where((e) {
+ var destination = e.destinationNode;
+ return e.sourceNode == always &&
+ destination is SubstitutionNodeInfo &&
+ destination.innerNode == implicitInvocationTypeArgumentNode;
+ }), hasLength(1));
+ expect(
+ edges.where((e) =>
+ e.sourceNode == implicitInvocationTypeArgumentNode &&
+ e.destinationNode == returnElementNode),
+ hasLength(1));
+ }
+
+ test_implicitTypeArguments_listLiteral() async {
+ await analyze('''
+List<int> f() => [null];
+''');
+ var implicitListLiteralElementNode =
+ implicitTypeArguments[findNode.listLiteral('[null]')].single.node;
+ var returnElementNode =
+ explicitTypeNullability[findNode.typeAnnotation('int')];
+ expect(
+ edges.where((e) =>
+ e.sourceNode == always &&
+ e.destinationNode == implicitListLiteralElementNode),
+ hasLength(1));
+ expect(
+ edges.where((e) =>
+ e.sourceNode == implicitListLiteralElementNode &&
+ e.destinationNode == returnElementNode),
+ hasLength(1));
+ }
+
+ test_implicitTypeArguments_mapLiteral() async {
+ await analyze('''
+Map<int, String> f() => {1: null};
+''');
+ var implicitMapLiteralTypeArguments =
+ implicitTypeArguments[findNode.setOrMapLiteral('{1: null}')];
+ expect(implicitMapLiteralTypeArguments, hasLength(2));
+ var implicitMapLiteralKeyNode = implicitMapLiteralTypeArguments[0].node;
+ var implicitMapLiteralValueNode = implicitMapLiteralTypeArguments[1].node;
+ var returnKeyNode = explicitTypeNullability[findNode.typeAnnotation('int')];
+ var returnValueNode =
+ explicitTypeNullability[findNode.typeAnnotation('String')];
+ expect(
+ edges.where((e) =>
+ e.sourceNode == never &&
+ e.destinationNode == implicitMapLiteralKeyNode),
+ hasLength(1));
+ expect(
+ edges.where((e) =>
+ e.sourceNode == implicitMapLiteralKeyNode &&
+ e.destinationNode == returnKeyNode),
+ hasLength(1));
+ expect(
+ edges.where((e) =>
+ e.sourceNode == always &&
+ e.destinationNode == implicitMapLiteralValueNode),
+ hasLength(1));
+ expect(
+ edges.where((e) =>
+ e.sourceNode == implicitMapLiteralValueNode &&
+ e.destinationNode == returnValueNode),
+ hasLength(1));
+ }
+
+ test_implicitTypeArguments_setLiteral() async {
+ await analyze('''
+Set<int> f() => {null};
+''');
+ var implicitSetLiteralElementNode =
+ implicitTypeArguments[findNode.setOrMapLiteral('{null}')].single.node;
+ var returnElementNode =
+ explicitTypeNullability[findNode.typeAnnotation('int')];
+ expect(
+ edges.where((e) =>
+ e.sourceNode == always &&
+ e.destinationNode == implicitSetLiteralElementNode),
+ hasLength(1));
+ expect(
+ edges.where((e) =>
+ e.sourceNode == implicitSetLiteralElementNode &&
+ e.destinationNode == returnElementNode),
+ hasLength(1));
+ }
+
+ test_implicitTypeArguments_typeAnnotation() async {
+ await analyze('''
+List<Object> f(List l) => l;
+''');
+ var implicitListElementType =
+ implicitTypeArguments[findNode.typeAnnotation('List l')].single.node;
+ var implicitReturnElementType =
+ explicitTypeNullability[findNode.typeAnnotation('Object')];
+ expect(
+ edges.where((e) =>
+ e.sourceNode == implicitListElementType &&
+ e.destinationNode == implicitReturnElementType),
+ hasLength(1));
+ }
+
+ test_propagationStep() async {
+ await analyze('''
+int x = null;
+''');
+ var xNode = explicitTypeNullability[findNode.typeAnnotation('int')];
+ var step = propagationSteps.where((s) => s.node == xNode).single;
+ expect(step.newState, NullabilityState.ordinaryNullable);
+ expect(step.reason, StateChangeReason.downstream);
+ expect(step.edge.sourceNode, always);
+ expect(step.edge.destinationNode, xNode);
+ }
+
+ test_substitutionNode() async {
+ await analyze('''
+class C<T> {
+ void f(T t) {}
+}
+voig g(C<int> x, int y) {
+ x.f(y);
+}
+''');
+ var yNode = explicitTypeNullability[findNode.typeAnnotation('int y')];
+ var edge = edges.where((e) => e.sourceNode == yNode).single;
+ var sNode = edge.destinationNode as SubstitutionNodeInfo;
+ expect(sNode.innerNode,
+ explicitTypeNullability[findNode.typeAnnotation('int>')]);
+ expect(sNode.outerNode,
+ explicitTypeNullability[findNode.typeAnnotation('T t')]);
+ }
+}
diff --git a/pkg/nnbd_migration/test/migration_visitor_test_base.dart b/pkg/nnbd_migration/test/migration_visitor_test_base.dart
index f335eb45..4c16e02 100644
--- a/pkg/nnbd_migration/test/migration_visitor_test_base.dart
+++ b/pkg/nnbd_migration/test/migration_visitor_test_base.dart
@@ -4,6 +4,7 @@
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/dart/element/nullability_suffix.dart';
import 'package:analyzer/src/dart/element/element.dart';
import 'package:analyzer/src/dart/element/type.dart';
import 'package:analyzer/src/generated/resolver.dart';
@@ -28,8 +29,12 @@
NullabilityNode get matchingNode => _matchingNodes.single;
@override
- bool matches(NullabilityNode node) {
+ void matched(NullabilityNode node) {
_matchingNodes.add(node);
+ }
+
+ @override
+ bool matches(NullabilityNode node) {
return true;
}
}
@@ -80,15 +85,14 @@
}
DecoratedType future(DecoratedType parameter, {NullabilityNode node}) {
- return DecoratedType(typeProvider.futureType.instantiate([parameter.type]),
- node ?? newNode(),
+ return DecoratedType(
+ typeProvider.futureType2(parameter.type), node ?? newNode(),
typeArguments: [parameter]);
}
DecoratedType futureOr(DecoratedType parameter, {NullabilityNode node}) {
return DecoratedType(
- typeProvider.futureOrType.instantiate([parameter.type]),
- node ?? newNode(),
+ typeProvider.futureOrType2(parameter.type), node ?? newNode(),
typeArguments: [parameter]);
}
@@ -96,8 +100,7 @@
DecoratedType(typeProvider.intType, node ?? newNode());
DecoratedType list(DecoratedType elementType, {NullabilityNode node}) =>
- DecoratedType(typeProvider.listType.instantiate([elementType.type]),
- node ?? newNode(),
+ DecoratedType(typeProvider.listType2(elementType.type), node ?? newNode(),
typeArguments: [elementType]);
NullabilityNode newNode() => NullabilityNode.forTypeAnnotation(_offset++);
@@ -113,8 +116,14 @@
}
DecoratedType typeParameterType(TypeParameterElement typeParameter,
- {NullabilityNode node}) =>
- DecoratedType(typeParameter.type, node ?? newNode());
+ {NullabilityNode node}) {
+ return DecoratedType(
+ typeParameter.instantiate(
+ nullabilitySuffix: NullabilitySuffix.star,
+ ),
+ node ?? newNode(),
+ );
+ }
}
/// Base functionality that must be implemented by classes mixing in
@@ -159,7 +168,7 @@
fail('Found multiple edges $source -> $destination');
} else {
var edge = edges[0];
- expect(edge.hard, hard);
+ expect(edge.isHard, hard);
expect(edge.guards, unorderedEquals(guards));
return edge;
}
@@ -187,7 +196,7 @@
var edges = getEdges(x, y);
for (var edge in edges) {
if (edge.isUnion) {
- expect(edge.sources, hasLength(1));
+ expect(edge.upstreamNodes, hasLength(1));
return;
}
}
@@ -203,12 +212,16 @@
List<NullabilityEdge> getEdges(Object source, Object destination) {
var sourceMatcher = NodeMatcher(source);
var destinationMatcher = NodeMatcher(destination);
- return graph
- .getAllEdges()
- .where((e) =>
- sourceMatcher.matches(e.primarySource) &&
- destinationMatcher.matches(e.destinationNode))
- .toList();
+ var result = <NullabilityEdge>[];
+ for (var edge in graph.getAllEdges()) {
+ if (sourceMatcher.matches(edge.sourceNode) &&
+ destinationMatcher.matches(edge.destinationNode)) {
+ sourceMatcher.matched(edge.sourceNode);
+ destinationMatcher.matched(edge.destinationNode);
+ result.add(edge);
+ }
+ }
+ return result;
}
/// Creates a [NodeMatcher] matching a substitution node whose inner and outer
@@ -227,7 +240,7 @@
final _decoratedExpressionTypes = <Expression, DecoratedType>{};
- final _expressionChecks = <Expression, ExpressionChecks>{};
+ final _expressionChecks = <Expression, ExpressionChecksOrigin>{};
final _possiblyOptional = <DefaultFormalParameter, NullabilityNode>{};
@@ -235,7 +248,7 @@
: super(graph, typeProvider);
/// Gets the [ExpressionChecks] associated with the given [expression].
- ExpressionChecks checkExpression(Expression expression) =>
+ ExpressionChecksOrigin checkExpression(Expression expression) =>
_expressionChecks[_normalizeExpression(expression)];
/// Gets the [conditionalDiscard] associated with the given [expression].
@@ -265,9 +278,9 @@
@override
void recordExpressionChecks(
- Source source, Expression expression, ExpressionChecks checks) {
- super.recordExpressionChecks(source, expression, checks);
- _expressionChecks[_normalizeExpression(expression)] = checks;
+ Source source, Expression expression, ExpressionChecksOrigin origin) {
+ super.recordExpressionChecks(source, expression, origin);
+ _expressionChecks[_normalizeExpression(expression)] = origin;
}
@override
@@ -360,6 +373,8 @@
'Unclear how to match node expectation of type ${expectation.runtimeType}');
}
+ void matched(NullabilityNode node);
+
bool matches(NullabilityNode node);
}
@@ -370,6 +385,9 @@
_ExactNodeMatcher(this._expectation);
@override
+ void matched(NullabilityNode node) {}
+
+ @override
bool matches(NullabilityNode node) => node == _expectation;
}
@@ -382,6 +400,18 @@
_SubstitutionNodeMatcher(this.inner, this.outer);
@override
+ void matched(NullabilityNode node) {
+ if (node is NullabilityNodeForSubstitution) {
+ inner.matched(node.innerNode);
+ outer.matched(node.outerNode);
+ } else {
+ throw StateError(
+ 'matched should only be called on nodes for which matches returned '
+ 'true');
+ }
+ }
+
+ @override
bool matches(NullabilityNode node) {
return node is NullabilityNodeForSubstitution &&
inner.matches(node.innerNode) &&
diff --git a/pkg/nnbd_migration/test/nullability_migration_impl_test.dart b/pkg/nnbd_migration/test/nullability_migration_impl_test.dart
index e145a95..39ba9f3 100644
--- a/pkg/nnbd_migration/test/nullability_migration_impl_test.dart
+++ b/pkg/nnbd_migration/test/nullability_migration_impl_test.dart
@@ -39,7 +39,7 @@
when(innerModification.isEmpty).thenReturn(false);
- NullabilityMigrationImpl.broadcast(variables, listener);
+ NullabilityMigrationImpl.broadcast(variables, listener, null);
final fix = verify(listener.addFix(captureAny)).captured.single
as SingleNullabilityFix;
@@ -68,7 +68,7 @@
when(potentialModification.modifications).thenReturn([]);
- NullabilityMigrationImpl.broadcast(variables, listener);
+ NullabilityMigrationImpl.broadcast(variables, listener, null);
verifyNever(listener.addFix(any));
verifyNever(listener.reportException(any, any, any, any));
@@ -80,7 +80,7 @@
final source = SourceMock('');
when(variables.getPotentialModifications()).thenReturn({source: []});
- NullabilityMigrationImpl.broadcast(variables, listener);
+ NullabilityMigrationImpl.broadcast(variables, listener, null);
verifyNever(listener.addFix(any));
verifyNever(listener.reportException(any, any, any, any));
diff --git a/pkg/nnbd_migration/test/nullability_node_test.dart b/pkg/nnbd_migration/test/nullability_node_test.dart
index eac19ce..e256963e 100644
--- a/pkg/nnbd_migration/test/nullability_node_test.dart
+++ b/pkg/nnbd_migration/test/nullability_node_test.dart
@@ -628,4 +628,6 @@
}
}
-class _TestEdgeOrigin extends EdgeOrigin {}
+class _TestEdgeOrigin implements EdgeOrigin {
+ noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
+}
diff --git a/pkg/nnbd_migration/test/test_all.dart b/pkg/nnbd_migration/test/test_all.dart
index 48a36fd..fed8c12 100644
--- a/pkg/nnbd_migration/test/test_all.dart
+++ b/pkg/nnbd_migration/test/test_all.dart
@@ -12,7 +12,10 @@
import 'edge_builder_flow_analysis_test.dart'
as edge_builder_flow_analysis_test;
import 'edge_builder_test.dart' as edge_builder_test;
+import 'instrumentation_test.dart' as instrumentation_test;
import 'node_builder_test.dart' as node_builder_test;
+import 'nullability_migration_impl_test.dart'
+ as nullability_migration_impl_test;
import 'nullability_node_test.dart' as nullability_node_test;
import 'utilities/test_all.dart' as utilities;
@@ -24,7 +27,9 @@
decorated_type_test.main();
edge_builder_flow_analysis_test.main();
edge_builder_test.main();
+ instrumentation_test.main();
node_builder_test.main();
+ nullability_migration_impl_test.main();
nullability_node_test.main();
utilities.main();
});
diff --git a/pkg/test_runner/lib/src/configuration.dart b/pkg/test_runner/lib/src/configuration.dart
index 47dfdae..ac08814 100644
--- a/pkg/test_runner/lib/src/configuration.dart
+++ b/pkg/test_runner/lib/src/configuration.dart
@@ -9,6 +9,7 @@
import 'package:smith/smith.dart';
import 'compiler_configuration.dart';
+import 'feature.dart';
import 'path.dart';
import 'repository.dart';
import 'runtime_configuration.dart';
@@ -347,6 +348,33 @@
CompilerConfiguration get compilerConfiguration =>
_compilerConfiguration ??= CompilerConfiguration(this);
+ Set<Feature> _supportedFeatures;
+
+ /// The set of [Feature]s supported by this configuration.
+ Set<Feature> get supportedFeatures {
+ if (_supportedFeatures != null) return _supportedFeatures;
+
+ _supportedFeatures = {};
+ switch (nnbdMode) {
+ case NnbdMode.legacy:
+ _supportedFeatures.add(Feature.nnbdLegacy);
+ break;
+ case NnbdMode.weak:
+ _supportedFeatures.add(Feature.nnbd);
+ _supportedFeatures.add(Feature.nnbdWeak);
+ break;
+ case NnbdMode.strong:
+ _supportedFeatures.add(Feature.nnbd);
+ _supportedFeatures.add(Feature.nnbdStrong);
+ break;
+ }
+
+ // TODO(rnystrom): Define more features for things like "dart:io", separate
+ // int/double representation, etc.
+
+ return _supportedFeatures;
+ }
+
/// Determines if this configuration has a compatible compiler and runtime
/// and other valid fields.
///
diff --git a/pkg/test_runner/lib/src/feature.dart b/pkg/test_runner/lib/src/feature.dart
new file mode 100644
index 0000000..ae9d48b
--- /dev/null
+++ b/pkg/test_runner/lib/src/feature.dart
@@ -0,0 +1,35 @@
+// Copyright (c) 2019, 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.
+
+/// A capability that a Dart implementation may or may not provide that a test
+/// may require.
+///
+/// Each [TestConfiguration] specifies the set of features it supports. A test
+/// can have a "// Requirements" comment indicating the names of features it
+/// requires. If a test requires a feature not supported by the current
+/// configution, the test runner automatically skips it.
+class Feature {
+ /// Opted out of NNBD and still using the legacy semantics.
+ static const nnbdLegacy = Feature._("nnbd-legacy");
+
+ /// Opted in to NNBD features.
+ ///
+ /// Note that this does not imply either strong or weak checking. A test that
+ /// only requires "nnbd" should run in both weak and strong checking modes.
+ static const nnbd = Feature._("nnbd");
+
+ /// Weak checking of NNBD features.
+ static const nnbdWeak = Feature._("nnbd-weak");
+
+ /// Full strong checking of NNBD features.
+ static const nnbdStrong = Feature._("nnbd-strong");
+
+ static const all = [nnbdLegacy, nnbd, nnbdWeak, nnbdStrong];
+
+ final String name;
+
+ const Feature._(this.name);
+
+ String toString() => name;
+}
diff --git a/pkg/test_runner/lib/src/multitest.dart b/pkg/test_runner/lib/src/multitest.dart
index fad45a9..0031d5e 100644
--- a/pkg/test_runner/lib/src/multitest.dart
+++ b/pkg/test_runner/lib/src/multitest.dart
@@ -69,7 +69,6 @@
/// ddd //# 07: static type warning
/// fff
/// ```
-import "dart:async";
import "dart:io";
import "path.dart";
@@ -171,9 +170,9 @@
///
/// Writes the resulting tests to [outputDir] and returns a list of [TestFile]s
/// for each of those generated tests.
-Future<List<TestFile>> splitMultitest(
+List<TestFile> splitMultitest(
TestFile multitest, String outputDir, Path suiteDir,
- {bool hotReload}) async {
+ {bool hotReload}) {
// Each key in the map tests is a multitest tag or "none", and the texts of
// the generated test is its value.
var tests = <String, String>{};
@@ -186,7 +185,6 @@
// Copy all the relative imports of the multitest.
var importsToCopy = _findAllRelativeImports(multitest.path);
- var futureCopies = <Future>[];
for (var relativeImport in importsToCopy) {
var importPath = Path(relativeImport);
// Make sure the target directory exists.
@@ -197,14 +195,11 @@
// Copy file. Because some test suites may be read-only, we don't
// want to copy the permissions, so we create the copy by writing.
- final source = File(sourceDir.join(importPath).toNativePath()).openRead();
- final target = File(targetDir.join(importPath).toNativePath()).openWrite();
- futureCopies.add(source.cast<List<int>>().pipe(target));
+ var contents =
+ File(sourceDir.join(importPath).toNativePath()).readAsBytesSync();
+ File(targetDir.join(importPath).toNativePath()).writeAsBytesSync(contents);
}
- // Wait until all imports are copied before scheduling test cases.
- await Future.wait(futureCopies);
-
var baseFilename = multitest.path.filenameWithoutExtension;
var testFiles = <TestFile>[];
diff --git a/pkg/test_runner/lib/src/process_queue.dart b/pkg/test_runner/lib/src/process_queue.dart
index 01a2fb1..37941de 100644
--- a/pkg/test_runner/lib/src/process_queue.dart
+++ b/pkg/test_runner/lib/src/process_queue.dart
@@ -235,17 +235,12 @@
// system, generate tests, and search test files for options.
var testCache = <String, List<TestFile>>{};
- var iterator = testSuites.iterator;
- void enqueueNextSuite() {
- if (!iterator.moveNext()) {
- // We're finished with building the dependency graph.
- graph.seal();
- } else {
- iterator.current.forEachTest(_newTest, testCache, enqueueNextSuite);
- }
+ for (var suite in testSuites) {
+ suite.findTestCases(_add, testCache);
}
- enqueueNextSuite();
+ // We're finished with building the dependency graph.
+ graph.seal();
}
/// Adds a test case to the list of active test cases, and adds its commands
@@ -259,14 +254,14 @@
/// command of the previous copy of the test case. This dependency is
/// marked as a "timingDependency", so that it doesn't depend on the previous
/// test completing successfully, just on it completing.
- void _newTest(TestCase testCase) {
+ void _add(TestCase testCase) {
Node<Command> lastNode;
for (var i = 0; i < testCase.configuration.repeat; ++i) {
if (i > 0) {
testCase = testCase.indexedCopy(i);
}
remainingTestCases.add(testCase);
- bool isFirstCommand = true;
+ var isFirstCommand = true;
for (var command in testCase.commands) {
// Make exactly *one* node in the dependency graph for every command.
// This ensures that we never have two commands c1 and c2 in the graph
@@ -280,7 +275,7 @@
command2node[command] = node;
command2testCases[command] = <TestCase>[];
}
- // Keep mapping from command to all testCases that refer to it
+ // Keep mapping from command to all testCases that refer to it.
command2testCases[command].add(testCase);
lastNode = node;
diff --git a/pkg/test_runner/lib/src/runtime_configuration.dart b/pkg/test_runner/lib/src/runtime_configuration.dart
index 04f4629..da7d327 100644
--- a/pkg/test_runner/lib/src/runtime_configuration.dart
+++ b/pkg/test_runner/lib/src/runtime_configuration.dart
@@ -97,13 +97,10 @@
bool get shouldSkipNegativeTests => false;
/// Returns the path to the Dart VM executable.
- String get dartVmBinaryFileName {
- // Controlled by user with the option "--dart".
- var dartExecutable = _configuration.dartPath ?? dartVmExecutableFileName;
-
- TestUtils.ensureExists(dartExecutable, _configuration);
- return dartExecutable;
- }
+ ///
+ /// Controlled by user with the option "--dart".
+ String get dartVmBinaryFileName =>
+ _configuration.dartPath ?? dartVmExecutableFileName;
String get dartVmExecutableFileName {
return _configuration.useSdk
diff --git a/pkg/test_runner/lib/src/test_case.dart b/pkg/test_runner/lib/src/test_case.dart
index 2b153eaa..0dfc63f 100644
--- a/pkg/test_runner/lib/src/test_case.dart
+++ b/pkg/test_runner/lib/src/test_case.dart
@@ -14,7 +14,6 @@
import 'configuration.dart';
import 'output_log.dart';
import 'process_queue.dart';
-import 'repository.dart';
import 'test_file.dart';
import 'utils.dart';
@@ -55,28 +54,20 @@
TestConfiguration configuration;
String displayName;
- int hash = 0;
Set<Expectation> expectedOutcomes;
final TestFile testFile;
TestCase(this.displayName, this.commands, this.configuration,
this.expectedOutcomes,
- {TestFile testFile})
- : testFile = testFile {
+ {this.testFile}) {
// A test case should do something.
assert(commands.isNotEmpty);
-
- if (testFile != null) {
- hash = (testFile.originPath?.relativeTo(Repository.dir)?.toString())
- .hashCode;
- }
}
TestCase indexedCopy(int index) {
var newCommands = commands.map((c) => c.indexedCopy(index)).toList();
return TestCase(displayName, newCommands, configuration, expectedOutcomes,
- testFile: testFile)
- ..hash = hash;
+ testFile: testFile);
}
bool get hasRuntimeError => testFile?.hasRuntimeError ?? false;
diff --git a/pkg/test_runner/lib/src/test_configurations.dart b/pkg/test_runner/lib/src/test_configurations.dart
index 5123fd1..674c55c 100644
--- a/pkg/test_runner/lib/src/test_configurations.dart
+++ b/pkg/test_runner/lib/src/test_configurations.dart
@@ -116,7 +116,7 @@
// If we specifically pass in a suite only run that.
if (configuration.suiteDirectory != null) {
var suitePath = Path(configuration.suiteDirectory);
- testSuites.add(PKGTestSuite(configuration, suitePath));
+ testSuites.add(PackageTestSuite(configuration, suitePath));
} else {
for (var testSuiteDir in TEST_SUITE_DIRECTORIES) {
var name = testSuiteDir.filename;
diff --git a/pkg/test_runner/lib/src/test_file.dart b/pkg/test_runner/lib/src/test_file.dart
index f24719a..f908add 100644
--- a/pkg/test_runner/lib/src/test_file.dart
+++ b/pkg/test_runner/lib/src/test_file.dart
@@ -3,6 +3,7 @@
// BSD-style license that can be found in the LICENSE file.
import 'dart:io';
+import 'feature.dart';
import 'path.dart';
import 'static_error.dart';
@@ -23,21 +24,29 @@
List<String> _splitWords(String s) =>
s.split(' ').where((e) => e != '').toList();
-List<String> _parseOption(String filePath, String contents, String name,
+List<T> _parseOption<T>(
+ String filePath, String contents, String name, T Function(String) convert,
{bool allowMultiple = false}) {
var matches = RegExp('// $name=(.*)').allMatches(contents);
if (!allowMultiple && matches.length > 1) {
throw Exception('More than one "// $name=" line in test $filePath');
}
- var options = <String>[];
+ var options = <T>[];
for (var match in matches) {
- options.addAll(_splitWords(match[1]));
+ for (var option in _splitWords(match[1])) {
+ options.add(convert(option));
+ }
}
return options;
}
+List<String> _parseStringOption(String filePath, String contents, String name,
+ {bool allowMultiple = false}) =>
+ _parseOption<String>(filePath, contents, name, (string) => string,
+ allowMultiple: allowMultiple);
+
abstract class _TestFileBase {
/// The test suite directory containing this test.
final Path _suiteDirectory;
@@ -66,8 +75,20 @@
/// static error reporting.
bool get isStaticErrorTest => expectedErrors.isNotEmpty;
+ /// A hash code used to spread tests across shards.
+ int get shardHash {
+ // The VM C++ unit tests have a special fake TestFile with no suite
+ // directory or path. Don't crash in that case.
+ // TODO(rnystrom): Is there a cleaner solution? Should we use the C++ file
+ // as the path for the TestFile?
+ if (originPath == null) return 0;
+
+ return originPath.relativeTo(_suiteDirectory).toString().hashCode;
+ }
+
_TestFileBase(this._suiteDirectory, this.path, this.expectedErrors) {
- assert(path.isAbsolute);
+ // The VM C++ unit tests have a special fake TestFile with no path.
+ if (path != null) assert(path.isAbsolute);
}
/// The logical name of the test.
@@ -152,6 +173,7 @@
Path suiteDirectory, String filePath, String contents) {
if (filePath.endsWith('.dill')) {
return TestFile._(suiteDirectory, Path(filePath), [],
+ requirements: [],
vmOptions: [[]],
sharedOptions: [],
dart2jsOptions: [],
@@ -171,6 +193,16 @@
otherResources: []);
}
+ // Required features.
+ var requirements =
+ _parseOption<Feature>(filePath, contents, 'Requirements', (name) {
+ for (var feature in Feature.all) {
+ if (feature.name == name) return feature;
+ }
+
+ throw FormatException('Unknown feature "$name" in test $filePath');
+ });
+
// VM options.
var vmOptions = <List<String>>[];
var matches = _vmOptionsRegExp.allMatches(contents);
@@ -180,14 +212,16 @@
if (vmOptions.isEmpty) vmOptions.add(<String>[]);
// Other options.
- var dartOptions = _parseOption(filePath, contents, 'DartOptions');
- var sharedOptions = _parseOption(filePath, contents, 'SharedOptions');
- var dart2jsOptions = _parseOption(filePath, contents, 'dart2jsOptions');
- var ddcOptions = _parseOption(filePath, contents, 'dartdevcOptions');
- var otherResources =
- _parseOption(filePath, contents, 'OtherResources', allowMultiple: true);
- var sharedObjects =
- _parseOption(filePath, contents, 'SharedObjects', allowMultiple: true);
+ var dartOptions = _parseStringOption(filePath, contents, 'DartOptions');
+ var sharedOptions = _parseStringOption(filePath, contents, 'SharedOptions');
+ var dart2jsOptions =
+ _parseStringOption(filePath, contents, 'dart2jsOptions');
+ var ddcOptions = _parseStringOption(filePath, contents, 'dartdevcOptions');
+ var otherResources = _parseStringOption(
+ filePath, contents, 'OtherResources',
+ allowMultiple: true);
+ var sharedObjects = _parseStringOption(filePath, contents, 'SharedObjects',
+ allowMultiple: true);
// Environment.
Map<String, String> environment;
@@ -292,6 +326,7 @@
hasStaticWarning: contents.contains("@static-warning"),
hasCrash: false,
subtestNames: subtestNames,
+ requirements: requirements,
sharedOptions: sharedOptions,
dartOptions: dartOptions,
dart2jsOptions: dart2jsOptions,
@@ -314,6 +349,7 @@
isMultitest = false,
isMultiHtmlTest = false,
subtestNames = [],
+ requirements = [],
sharedOptions = [],
dartOptions = [],
dart2jsOptions = [],
@@ -335,6 +371,7 @@
this.hasStaticWarning,
this.hasCrash,
this.subtestNames,
+ this.requirements,
this.sharedOptions,
this.dartOptions,
this.dart2jsOptions,
@@ -364,6 +401,14 @@
final bool hasCrash;
final List<String> subtestNames;
+
+ /// The features that a test configuration must support in order to run this
+ /// test.
+ ///
+ /// If the current configuration does not support one or more of these
+ /// requirements, the test is implicitly skipped.
+ final List<Feature> requirements;
+
final List<String> sharedOptions;
final List<String> dartOptions;
final List<String> dart2jsOptions;
@@ -398,6 +443,7 @@
hasStaticWarning: $hasStaticWarning
hasCrash: $hasCrash
subtestNames: $subtestNames
+ requirements: $requirements
sharedOptions: $sharedOptions
dartOptions: $dartOptions
dart2jsOptions: $dart2jsOptions
@@ -437,6 +483,7 @@
String get packageRoot => _origin.packageRoot;
String get packages => _origin.packages;
+ List<Feature> get requirements => _origin.requirements;
List<String> get dart2jsOptions => _origin.dart2jsOptions;
List<String> get dartOptions => _origin.dartOptions;
List<String> get ddcOptions => _origin.ddcOptions;
diff --git a/pkg/test_runner/lib/src/test_suite.dart b/pkg/test_runner/lib/src/test_suite.dart
index f2fb6c7..08fc09b 100644
--- a/pkg/test_runner/lib/src/test_suite.dart
+++ b/pkg/test_runner/lib/src/test_suite.dart
@@ -10,7 +10,6 @@
/// and creating [TestCase]s for those files that meet the relevant criteria.
/// - Preparing tests, including copying files and frameworks to temporary
/// directories, and computing the command line and arguments to be run.
-import 'dart:async';
import 'dart:io';
import 'dart:math';
@@ -32,9 +31,6 @@
typedef TestCaseEvent = void Function(TestCase testCase);
-/// A simple function that tests [arg] and returns `true` or `false`.
-typedef Predicate<T> = bool Function(T arg);
-
typedef CreateTest = void Function(Path filePath, Path originTestPath,
{bool hasSyntaxError,
bool hasCompileError,
@@ -44,57 +40,6 @@
typedef VoidFunction = void Function();
-/// Calls [function] asynchronously. Returns a future that completes with the
-/// result of the function. If the function is `null`, returns a future that
-/// completes immediately with `null`.
-Future asynchronously<T>(T function()) {
- if (function == null) return Future<T>.value(null);
-
- var completer = Completer<T>();
- Timer.run(() => completer.complete(function()));
-
- return completer.future;
-}
-
-/// A completer that waits until all added [Future]s complete.
-// TODO(rnystrom): Copied from web_components. Remove from here when it gets
-// added to dart:core. (See #6626.)
-class FutureGroup {
- static const _finished = -1;
- int _pending = 0;
- final Completer<List> _completer = Completer();
- final List<Future> futures = [];
- bool wasCompleted = false;
-
- /// Wait for [task] to complete (assuming this barrier has not already been
- /// marked as completed, otherwise you'll get an exception indicating that a
- /// future has already been completed).
- void add(Future task) {
- if (_pending == _finished) {
- throw Exception("FutureFutureAlreadyCompleteException");
- }
- _pending++;
- var handledTaskFuture = task.catchError((e, StackTrace s) {
- if (!wasCompleted) {
- _completer.completeError(e, s);
- wasCompleted = true;
- }
- }).then((_) {
- _pending--;
- if (_pending == 0) {
- _pending = _finished;
- if (!wasCompleted) {
- _completer.complete(futures);
- wasCompleted = true;
- }
- }
- });
- futures.add(handledTaskFuture);
- }
-
- Future<List> get future => _completer.future;
-}
-
/// A TestSuite represents a collection of tests. It creates a [TestCase]
/// object for each test to be run, and passes the test cases to a callback.
///
@@ -106,7 +51,6 @@
final List<String> statusFilePaths;
/// This function is set by subclasses before enqueueing starts.
- Function doTest;
Map<String, String> _environmentOverrides;
TestSuite(this.configuration, this.suiteName, this.statusFilePaths) {
@@ -139,28 +83,26 @@
return name;
}
- /// Call the callback function onTest with a [TestCase] argument for each
- /// test in the suite. When all tests have been processed, call [onDone].
+ /// Calls [onTest] with each [TestCase] produced by the suite for the
+ /// current configuration.
///
/// The [testCache] argument provides a persistent store that can be used to
/// cache information about the test suite, so that directories do not need
/// to be listed each time.
- Future forEachTest(
- TestCaseEvent onTest, Map<String, List<TestFile>> testCache,
- [VoidFunction onDone]);
+ void findTestCases(
+ TestCaseEvent onTest, Map<String, List<TestFile>> testCache);
- /// This function is called for every TestCase of this test suite. It:
+ /// Creates a [TestCase] and passes it to [onTest] if there is a relevant
+ /// test to run for [testFile] in the current configuration.
///
- /// - Handles sharding.
- /// - Updates [SummaryReport].
- /// - Handle skip markers.
- /// - Tests if the selector matches.
- ///
- /// and enqueue the test if necessary.
- void enqueueNewTestCase(TestFile testFile, String fullName,
- List<Command> commands, Set<Expectation> expectations) {
+ /// This handles skips, shards, selector matching, and updating the
+ /// [SummaryReport].
+ void _addTestCase(TestFile testFile, String fullName, List<Command> commands,
+ Set<Expectation> expectations, TestCaseEvent onTest) {
var displayName = '$suiteName/$fullName';
+ if (!_isRelevantTest(testFile, displayName, expectations)) return;
+
// If the test is not going to be run at all, then a RuntimeError,
// MissingRuntimeError or Timeout will never occur.
// Instead, treat that as Pass.
@@ -173,51 +115,70 @@
if (expectations.isEmpty) expectations.add(Expectation.pass);
}
- var negative = testFile != null && isNegative(testFile);
var testCase = TestCase(displayName, commands, configuration, expectations,
testFile: testFile);
- if (negative &&
- configuration.runtimeConfiguration.shouldSkipNegativeTests) {
- return;
- }
-
- // Handle sharding based on the original test path (i.e. all multitests
- // of a given original test belong to the same shard)
- if (configuration.shardCount > 1 &&
- testCase.hash % configuration.shardCount != configuration.shard - 1) {
- return;
- }
-
- // Test if the selector includes this test.
- var pattern = configuration.selectors[suiteName];
- if (!pattern.hasMatch(displayName)) {
- return;
- }
- if (configuration.testList != null &&
- !configuration.testList.contains(displayName)) {
- return;
- }
-
- if (configuration.hotReload || configuration.hotReloadRollback) {
- // Handle reload special cases.
- if (expectations.contains(Expectation.compileTimeError) ||
- testCase.hasCompileError) {
- // Running a test that expects a compilation error with hot reloading
- // is redundant with a regular run of the test.
- return;
- }
- }
// Update Summary report.
if (configuration.printReport) {
summaryReport.add(testCase);
}
- // Handle skipped tests.
+ if (!_shouldSkipTest(expectations)) {
+ onTest(testCase);
+ }
+ }
+
+ /// Whether it is meaningful to run [testFile] with [expectations] under the
+ /// current configuration.
+ ///
+ /// Does not take skips into account, but does "skip" tests for other
+ /// fundamental reasons.
+ bool _isRelevantTest(
+ TestFile testFile, String displayName, Set<Expectation> expectations) {
+ // Test if the selector includes this test.
+ var pattern = configuration.selectors[suiteName];
+ if (!pattern.hasMatch(displayName)) {
+ return false;
+ }
+
+ if (configuration.testList != null &&
+ !configuration.testList.contains(displayName)) {
+ return false;
+ }
+
+ if (isNegative(testFile) &&
+ configuration.runtimeConfiguration.shouldSkipNegativeTests) {
+ return false;
+ }
+
+ // Handle sharding based on the original test path. All multitests of a
+ // given original test belong to the same shard.
+ if (configuration.shardCount > 1 &&
+ testFile.shardHash % configuration.shardCount !=
+ configuration.shard - 1) {
+ return false;
+ }
+
+ if (configuration.hotReload || configuration.hotReloadRollback) {
+ // Handle reload special cases.
+ if (expectations.contains(Expectation.compileTimeError) ||
+ testFile.hasCompileError) {
+ // Running a test that expects a compilation error with hot reloading
+ // is redundant with a regular run of the test.
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ /// Whether a test with [expectations] should be skipped under the current
+ /// configuration.
+ bool _shouldSkipTest(Set<Expectation> expectations) {
if (expectations.contains(Expectation.skip) ||
expectations.contains(Expectation.skipByDesign) ||
expectations.contains(Expectation.skipSlow)) {
- return;
+ return true;
}
if (configuration.fastTestsOnly &&
@@ -225,10 +186,10 @@
expectations.contains(Expectation.skipSlow) ||
expectations.contains(Expectation.timeout) ||
expectations.contains(Expectation.dartkTimeout))) {
- return;
+ return true;
}
- doTest(testCase);
+ return false;
}
bool isNegative(TestFile testFile) =>
@@ -316,21 +277,15 @@
}
}
- Future<Null> forEachTest(TestCaseEvent onTest, Map testCache,
- [VoidFunction onDone]) async {
- doTest = onTest;
-
+ void findTestCases(TestCaseEvent onTest, Map testCache) {
var statusFiles =
statusFilePaths.map((statusFile) => "$dartDir/$statusFile").toList();
var expectations = ExpectationSet.read(statusFiles, configuration);
try {
- for (VMUnitTest test in await _listTests(hostRunnerPath)) {
- _addTest(expectations, test);
+ for (var test in _listTests(hostRunnerPath)) {
+ _addTest(expectations, test, onTest);
}
-
- doTest = null;
- if (onDone != null) onDone();
} catch (error, s) {
print("Fatal error occurred: $error");
print(s);
@@ -338,7 +293,8 @@
}
}
- void _addTest(ExpectationSet testExpectations, VMUnitTest test) {
+ void _addTest(
+ ExpectationSet testExpectations, VMUnitTest test, TestCaseEvent onTest) {
var fullName = 'cc/${test.name}';
var expectations = testExpectations.expectations(fullName);
@@ -375,11 +331,11 @@
var command = ProcessCommand(
'run_vm_unittest', targetRunnerPath, args, environmentOverrides);
- enqueueNewTestCase(testFile, fullName, [command], expectations);
+ _addTestCase(testFile, fullName, [command], expectations, onTest);
}
- Future<Iterable<VMUnitTest>> _listTests(String runnerPath) async {
- var result = await Process.run(runnerPath, ["--list"]);
+ Iterable<VMUnitTest> _listTests(String runnerPath) {
+ var result = Process.runSync(runnerPath, ["--list"]);
if (result.exitCode != 0) {
throw "Failed to list tests: '$runnerPath --list'. "
"Process exited with ${result.exitCode}";
@@ -407,8 +363,6 @@
/// directory, and creates [TestCase]s that compile and/or run them.
class StandardTestSuite extends TestSuite {
final Path suiteDir;
- ExpectationSet testExpectations;
- List<TestFile> cachedTests;
final Path dartDir;
final bool listRecursively;
final List<String> extraVmOptions;
@@ -470,8 +424,8 @@
_selectorFilenameRegExp = RegExp(pattern);
}
- /// Creates a test suite whose file organization matches an expected structure.
- /// To use this, your suite should look like:
+ /// Creates a test suite whose file organization matches an expected
+ /// structure. To use this, your suite should look like:
///
/// dart/
/// path/
@@ -490,7 +444,7 @@
///
/// If you follow that convention, then you can construct one of these like:
///
- /// new StandardTestSuite.forDirectory(configuration, 'path/to/mytestsuite');
+ /// StandardTestSuite.forDirectory(configuration, 'path/to/mytestsuite');
///
/// instead of having to create a custom [StandardTestSuite] subclass. In
/// particular, if you add 'path/to/mytestsuite' to [TEST_SUITE_DIRECTORIES]
@@ -524,64 +478,58 @@
List<String> additionalOptions(Path filePath) => [];
- Future forEachTest(
- TestCaseEvent onTest, Map<String, List<TestFile>> testCache,
- [VoidFunction onDone]) async {
- doTest = onTest;
- testExpectations = readExpectations();
+ void findTestCases(
+ TestCaseEvent onTest, Map<String, List<TestFile>> testCache) {
+ var expectations = _readExpectations();
- // Check if we have already found and generated the tests for this suite.
- if (!testCache.containsKey(suiteName)) {
- cachedTests = testCache[suiteName] = <TestFile>[];
- await enqueueTests();
- } else {
- for (var testFile in testCache[suiteName]) {
- enqueueTestCaseFromTestFile(testFile);
- }
+ // Check if we have already found the test files for this suite.
+ var testFiles = testCache[suiteName];
+ if (testFiles == null) {
+ testFiles = [...findTests()];
+ testCache[suiteName] = testFiles;
}
- testExpectations = null;
- cachedTests = null;
- doTest = null;
- if (onDone != null) onDone();
+
+ // Produce test cases for each test file.
+ for (var testFile in testFiles) {
+ _testCasesFromTestFile(testFile, expectations, onTest);
+ }
+ }
+
+ /// Walks the file system to find all test files relevant to this test suite.
+ Iterable<TestFile> findTests() {
+ var dir = Directory(suiteDir.toNativePath());
+ if (!dir.existsSync()) {
+ print('Directory containing tests missing: ${suiteDir.toNativePath()}');
+ return const [];
+ }
+
+ return _searchDirectory(dir);
}
/// Reads the status files and completes with the parsed expectations.
- ExpectationSet readExpectations() {
- var statusFiles = statusFilePaths.where((String statusFilePath) {
- var file = File(dartDir.append(statusFilePath).toNativePath());
- return file.existsSync();
- }).map((statusFilePath) {
- return dartDir.append(statusFilePath).toNativePath();
- }).toList();
+ ExpectationSet _readExpectations() {
+ var statusFiles = <String>[];
+ for (var relativePath in statusFilePaths) {
+ var file = File(dartDir.append(relativePath).toNativePath());
+ if (!file.existsSync()) continue;
+ statusFiles.add(file.path);
+ }
return ExpectationSet.read(statusFiles, configuration);
}
- Future enqueueTests() {
- Directory dir = Directory(suiteDir.toNativePath());
- return dir.exists().then((exists) {
- if (!exists) {
- print('Directory containing tests missing: ${suiteDir.toNativePath()}');
- return Future.value(null);
- } else {
- var group = FutureGroup();
- enqueueDirectory(dir, group);
- return group.future;
- }
- });
+ /// Looks for test files in [directory].
+ Iterable<TestFile> _searchDirectory(Directory directory) sync* {
+ for (var entry in directory.listSync(recursive: listRecursively)) {
+ if (entry is File) yield* _processFile(entry.path);
+ }
}
- void enqueueDirectory(Directory dir, FutureGroup group) {
- var lister = dir
- .list(recursive: listRecursively)
- .where((fse) => fse is File)
- .forEach((FileSystemEntity entity) {
- enqueueFile((entity as File).path, group);
- });
- group.add(lister);
- }
-
- void enqueueFile(String filePath, FutureGroup group) {
+ /// Gets the set of [TestFile]s based on the source file at [filePath].
+ ///
+ /// This may produce zero [TestFile]s if [filePath] isn't a test. It may
+ /// produce more than one if the file is a multitest.
+ Iterable<TestFile> _processFile(String filePath) sync* {
// This is an optimization to avoid scanning and generating extra tests.
// The definitive check against configuration.testList is performed in
// TestSuite.enqueueNewTestCase().
@@ -598,29 +546,31 @@
var testFile = TestFile.read(suiteDir, filePath);
if (testFile.isMultitest) {
- group.add(splitMultitest(testFile, buildDir, suiteDir,
- hotReload:
- configuration.hotReload || configuration.hotReloadRollback)
- .then((splitTests) {
- for (var test in splitTests) {
- cachedTests.add(test);
- enqueueTestCaseFromTestFile(test);
- }
- }));
+ for (var test in splitMultitest(testFile, buildDir, suiteDir,
+ hotReload:
+ configuration.hotReload || configuration.hotReloadRollback)) {
+ yield test;
+ }
} else {
- cachedTests.add(testFile);
- enqueueTestCaseFromTestFile(testFile);
+ yield testFile;
}
}
- void enqueueTestCaseFromTestFile(TestFile testFile) {
- // Static error tests are currently skipped on every implementation except
- // analyzer and Fasta.
+ /// Calls [onTest] with every [TestCase] that should be produced from
+ /// [testFile].
+ ///
+ /// This will generally be one or no tests if the test should be skipped but
+ /// may be more if [testFile] is a browser multitest or has multiple VM
+ /// options.
+ void _testCasesFromTestFile(
+ TestFile testFile, ExpectationSet expectations, TestCaseEvent onTest) {
+ // Static error tests are skipped on every implementation except analyzer
+ // and Fasta.
// TODO(rnystrom): Should other configurations that use CFE support static
// error tests?
// TODO(rnystrom): Skipping this here is a little unusual because most
- // skips are handled in enqueueStandardTest(). However, if the configuration
- // is running on browser, calling enqueueStandardTest() will try to create
+ // skips are handled in _addTestCase(). However, if the configuration
+ // is running on a browser, calling _addTestCase() will try to create
// a set of commands which ultimately causes an exception in
// DummyRuntimeConfiguration. This avoids that.
if (testFile.isStaticErrorTest &&
@@ -629,12 +579,17 @@
return;
}
+ // The configuration must support everything the test needs.
+ if (!configuration.supportedFeatures.containsAll(testFile.requirements)) {
+ return;
+ }
+
if (configuration.compilerConfiguration.hasCompiler &&
(testFile.hasCompileError || testFile.isStaticErrorTest)) {
// If a compile-time error is expected, and we're testing a
// compiler, we never need to attempt to run the program (in a
// browser or otherwise).
- enqueueStandardTest(testFile);
+ _enqueueStandardTest(testFile, expectations, onTest);
} else if (configuration.runtime.isBrowser) {
var expectationsMap = <String, Set<Expectation>>{};
@@ -646,20 +601,21 @@
expectationsMap = <String, Set<Expectation>>{};
for (var subtest in subtestNames) {
expectationsMap[subtest] =
- testExpectations.expectations('${testFile.name}/$subtest');
+ expectations.expectations('${testFile.name}/$subtest');
}
} else {
expectationsMap[testFile.name] =
- testExpectations.expectations(testFile.name);
+ expectations.expectations(testFile.name);
}
- _enqueueBrowserTest(testFile, expectationsMap);
+ _enqueueBrowserTest(testFile, expectationsMap, onTest);
} else {
- enqueueStandardTest(testFile);
+ _enqueueStandardTest(testFile, expectations, onTest);
}
}
- void enqueueStandardTest(TestFile testFile) {
+ void _enqueueStandardTest(
+ TestFile testFile, ExpectationSet expectations, TestCaseEvent onTest) {
var commonArguments = _commonArgumentsFromFile(testFile);
var vmOptionsList = getVmOptions(testFile);
@@ -674,8 +630,8 @@
allVmOptions = vmOptions.toList()..addAll(extraVmOptions);
}
- var expectations = testExpectations.expectations(testFile.name);
- var isCrashExpected = expectations.contains(Expectation.crash);
+ var testExpectations = expectations.expectations(testFile.name);
+ var isCrashExpected = testExpectations.contains(Expectation.crash);
var commands = _makeCommands(testFile, vmOptionsVariant, allVmOptions,
commonArguments, isCrashExpected);
var variantTestName = testFile.name;
@@ -683,7 +639,8 @@
variantTestName = "${testFile.name}/$vmOptionsVariant";
}
- enqueueNewTestCase(testFile, variantTestName, commands, expectations);
+ _addTestCase(
+ testFile, variantTestName, commands, testExpectations, onTest);
}
}
@@ -811,8 +768,8 @@
/// In order to handle browser multitests, [expectations] is a map of subtest
/// names to expectation sets. If the test is not a multitest, the map has
/// a single key, `testFile.name`.
- void _enqueueBrowserTest(
- TestFile testFile, Map<String, Set<Expectation>> expectations) {
+ void _enqueueBrowserTest(TestFile testFile,
+ Map<String, Set<Expectation>> expectations, TestCaseEvent onTest) {
var tempDir = createOutputDirectory(testFile.path);
var compilationTempDir = createCompilationOutputDirectory(testFile.path);
var nameNoExt = testFile.path.filenameWithoutExtension;
@@ -879,11 +836,12 @@
'${testFile.name}/$subtestName',
subtestName,
expectations[subtestName],
- htmlPath);
+ htmlPath,
+ onTest);
}
} else {
_enqueueSingleBrowserTest(commands, testFile, testFile.name, null,
- expectations[testFile.name], htmlPath);
+ expectations[testFile.name], htmlPath, onTest);
}
}
@@ -894,7 +852,8 @@
String testName,
String subtestName,
Set<Expectation> expectations,
- String htmlPath) {
+ String htmlPath,
+ TestCaseEvent onTest) {
// Construct the command that executes the browser test.
commands = commands.toList();
@@ -906,7 +865,7 @@
var fullName = testName;
if (subtestName != null) fullName += "/$subtestName";
- enqueueNewTestCase(testFile, fullName, commands, expectations);
+ _addTestCase(testFile, fullName, commands, expectations, onTest);
}
List<String> _commonArgumentsFromFile(TestFile testFile) {
@@ -976,26 +935,26 @@
/// Used for testing packages in one-off settings, i.e., we pass in the actual
/// directory that we want to test.
-class PKGTestSuite extends StandardTestSuite {
- PKGTestSuite(TestConfiguration configuration, Path directoryPath)
+class PackageTestSuite extends StandardTestSuite {
+ PackageTestSuite(TestConfiguration configuration, Path directoryPath)
: super(configuration, directoryPath.filename, directoryPath,
["$directoryPath/.status"],
recursive: true);
- void _enqueueBrowserTest(
- TestFile testFile, Map<String, Set<Expectation>> expectations) {
+ void _enqueueBrowserTest(TestFile testFile,
+ Map<String, Set<Expectation>> expectations, TestCaseEvent onTest) {
var dir = testFile.path.directoryPath;
var nameNoExt = testFile.path.filenameWithoutExtension;
var customHtmlPath = dir.append('$nameNoExt.html');
var customHtml = File(customHtmlPath.toNativePath());
if (!customHtml.existsSync()) {
- super._enqueueBrowserTest(testFile, expectations);
+ super._enqueueBrowserTest(testFile, expectations, onTest);
} else {
var fullPath = _createUrlPathFromFile(customHtmlPath);
var command = Command.browserTest(fullPath, configuration,
retry: !isNegative(testFile));
- enqueueNewTestCase(
- testFile, testFile.name, [command], expectations[testFile.name]);
+ _addTestCase(testFile, testFile.name, [command],
+ expectations[testFile.name], onTest);
}
}
}
@@ -1015,15 +974,13 @@
List<String> additionalOptions(Path filePath, {bool showSdkWarnings}) =>
const ['--fatal-warnings', '--fatal-type-errors', '--sdk-warnings'];
- Future enqueueTests() {
- var group = FutureGroup();
-
+ Iterable<TestFile> findTests() {
var dir = Directory(suiteDir.append('lib').toNativePath());
if (dir.existsSync()) {
- enqueueDirectory(dir, group);
+ return _searchDirectory(dir);
}
- return group.future;
+ return const [];
}
bool isTestFile(String filename) {
diff --git a/pkg/test_runner/test/test_file_test.dart b/pkg/test_runner/test/test_file_test.dart
index b35c116..7418bda 100644
--- a/pkg/test_runner/test/test_file_test.dart
+++ b/pkg/test_runner/test/test_file_test.dart
@@ -5,10 +5,13 @@
import 'package:expect/expect.dart';
+import 'package:test_runner/src/feature.dart';
import 'package:test_runner/src/path.dart';
import 'package:test_runner/src/static_error.dart';
import 'package:test_runner/src/test_file.dart';
+import 'utils.dart';
+
// Note: This test file validates how some of the special markers used by the
// test runner are parsed. But this test is also run *by* that same test
// runner, and we don't want it to see the markers inside the string literals
@@ -27,11 +30,12 @@
testParseErrorExpectations();
testName();
testMultitest();
+ testShardHash();
}
void testParseDill() {
// Handles ".dill" files.
- var file = parse("", path: "test.dill");
+ var file = parseTestFile("", path: "test.dill");
Expect.isNotNull(file.vmOptions);
Expect.equals(1, file.vmOptions.length);
Expect.listEquals(<String>[], file.vmOptions.first);
@@ -57,7 +61,7 @@
void testParseVMOptions() {
expectVMOptions(String source, List<List<String>> expected) {
- var file = parse(source);
+ var file = parseTestFile(source);
Expect.isNotNull(file.vmOptions);
Expect.equals(expected.length, file.vmOptions.length);
for (var i = 0; i < expected.length; i++) {
@@ -85,29 +89,31 @@
void testParseOtherOptions() {
// No options.
- var file = parse("");
+ var file = parseTestFile("");
Expect.listEquals(<String>[], file.dartOptions);
Expect.listEquals(<String>[], file.sharedOptions);
Expect.listEquals(<String>[], file.dart2jsOptions);
Expect.listEquals(<String>[], file.ddcOptions);
Expect.listEquals(<String>[], file.otherResources);
Expect.listEquals(<String>[], file.sharedObjects);
+ Expect.listEquals(<String>[], file.requirements);
// Single options split into words.
- file = parse("""
+ file = parseTestFile("""
/\/ DartOptions=dart options
/\/ SharedOptions=shared options
/\/ dart2jsOptions=dart2js options
/\/ dartdevcOptions=ddc options
/\/ OtherResources=other resources
/\/ SharedObjects=shared objects
+ /\/ Requirements=nnbd nnbd-strong
""");
Expect.listEquals(["dart", "options"], file.dartOptions);
Expect.listEquals(["shared", "options"], file.sharedOptions);
Expect.listEquals(["dart2js", "options"], file.dart2jsOptions);
Expect.listEquals(["ddc", "options"], file.ddcOptions);
Expect.listEquals(["other", "resources"], file.otherResources);
- Expect.listEquals(["shared", "objects"], file.sharedObjects);
+ Expect.listEquals([Feature.nnbd, Feature.nnbdStrong], file.requirements);
// Disallows multiple lines for some options.
expectParseThrows("""
@@ -126,9 +132,13 @@
/\/ dartdevcOptions=first
/\/ dartdevcOptions=second
""");
+ expectParseThrows("""
+ /\/ Requirements=nnbd
+ /\/ Requirements=nnbd-strong
+ """);
// Merges multiple lines for others.
- file = parse("""
+ file = parseTestFile("""
/\/ OtherResources=other resources
/\/ OtherResources=even more
/\/ SharedObjects=shared objects
@@ -137,22 +147,27 @@
Expect.listEquals(
["other", "resources", "even", "more"], file.otherResources);
Expect.listEquals(["shared", "objects", "many", "more"], file.sharedObjects);
+
+ // Disallows unrecognized features in requirements.
+ expectParseThrows("""
+ /\/ Requirements=unknown-feature
+ """);
}
void testParseEnvironment() {
// No environment.
- var file = parse("");
+ var file = parseTestFile("");
Expect.isNull(file.environment);
// Without values.
- file = parse("""
+ file = parseTestFile("""
/\/ Environment=some value
/\/ Environment=another one
""");
Expect.mapEquals({"some value": "", "another one": ""}, file.environment);
// With values.
- file = parse("""
+ file = parseTestFile("""
/\/ Environment=some value=its value
/\/ Environment=another one = also value
""");
@@ -163,18 +178,18 @@
void testParsePackages() {
// No option.
- var file = parse("");
+ var file = parseTestFile("");
Expect.isNull(file.packages);
// Single option is converted to a path.
- file = parse("""
+ file = parseTestFile("""
/\/ Packages=packages thing
""");
Expect.isTrue(
file.packages.endsWith("${Platform.pathSeparator}packages thing"));
// "none" is left alone.
- file = parse("""
+ file = parseTestFile("""
/\/ Packages=none
""");
Expect.equals("none", file.packages);
@@ -188,11 +203,11 @@
void testParseMultitest() {
// Not present.
- var file = parse("");
+ var file = parseTestFile("");
Expect.isFalse(file.isMultitest);
// Present.
- file = parse("""
+ file = parseTestFile("""
main() {} /\/# 01: compile-time error
""");
Expect.isTrue(file.isMultitest);
@@ -200,14 +215,14 @@
void testParseMultiHtmltest() {
// Not present.
- var file = parse("");
+ var file = parseTestFile("");
Expect.isFalse(file.isMultiHtmlTest);
Expect.listEquals(<String>[], file.subtestNames);
// Present.
// Note: the "${''}" is to prevent the test runner running *this* test file
// from parsing it as a multi-HTML test.
- file = parse("""
+ file = parseTestFile("""
main() {
useHtml\IndividualConfiguration();
group('pixel_manipulation', () {
@@ -225,35 +240,35 @@
void testParseErrorFlags() {
// Not present.
- var file = parse("");
+ var file = parseTestFile("");
Expect.isFalse(file.hasSyntaxError);
Expect.isFalse(file.hasCompileError);
Expect.isFalse(file.hasRuntimeError);
Expect.isFalse(file.hasStaticWarning);
Expect.isFalse(file.hasCrash);
- file = parse("@syntax\-error");
+ file = parseTestFile("@syntax\-error");
Expect.isTrue(file.hasSyntaxError);
Expect.isTrue(file.hasCompileError); // Note: true.
Expect.isFalse(file.hasRuntimeError);
Expect.isFalse(file.hasStaticWarning);
Expect.isFalse(file.hasCrash);
- file = parse("@compile\-error");
+ file = parseTestFile("@compile\-error");
Expect.isFalse(file.hasSyntaxError);
Expect.isTrue(file.hasCompileError);
Expect.isFalse(file.hasRuntimeError);
Expect.isFalse(file.hasStaticWarning);
Expect.isFalse(file.hasCrash);
- file = parse("@runtime\-error");
+ file = parseTestFile("@runtime\-error");
Expect.isFalse(file.hasSyntaxError);
Expect.isFalse(file.hasCompileError);
Expect.isTrue(file.hasRuntimeError);
Expect.isFalse(file.hasStaticWarning);
Expect.isFalse(file.hasCrash);
- file = parse("@static\-warning");
+ file = parseTestFile("@static\-warning");
Expect.isFalse(file.hasSyntaxError);
Expect.isFalse(file.hasCompileError);
Expect.isFalse(file.hasRuntimeError);
@@ -493,7 +508,7 @@
}
void testMultitest() {
- var file = parse("", path: "origin.dart");
+ var file = parseTestFile("", path: "origin.dart");
Expect.isFalse(file.hasSyntaxError);
Expect.isFalse(file.hasCompileError);
Expect.isFalse(file.hasRuntimeError);
@@ -537,22 +552,28 @@
Expect.isTrue(d.hasStaticWarning);
}
+void testShardHash() {
+ // Test files with paths should successfully return some kind of integer. We
+ // don't want to depend on the hash algorithm, so we can't really be more
+ // specific than that.
+ var testFile = parseTestFile("", path: "a_test.dart");
+ Expect.isTrue(testFile.shardHash is int);
+
+ // VM test files are hard-coded to return hash zero because they don't have a
+ // path to base the hash on.
+ Expect.equals(0, TestFile.vmUnitTest().shardHash);
+}
+
void expectParseErrorExpectations(String source, List<StaticError> errors) {
- var file = parse(source);
+ var file = parseTestFile(source);
Expect.listEquals(errors.map((error) => error.toString()).toList(),
file.expectedErrors.map((error) => error.toString()).toList());
}
void expectFormatError(String source) {
- Expect.throwsFormatException(() => parse(source));
+ Expect.throwsFormatException(() => parseTestFile(source));
}
void expectParseThrows(String source) {
- Expect.throws(() => parse(source));
-}
-
-TestFile parse(String source, {String path = "some_test.dart"}) {
- path = Path(path).absolute.toNativePath();
- var suiteDirectory = Path(path).directoryPath;
- return TestFile.parse(suiteDirectory, path, source);
+ Expect.throws(() => parseTestFile(source));
}
diff --git a/pkg/test_runner/test/test_runner_test.dart b/pkg/test_runner/test/test_runner_test.dart
index 4123612..eea706f 100644
--- a/pkg/test_runner/test/test_runner_test.dart
+++ b/pkg/test_runner/test/test_runner_test.dart
@@ -71,7 +71,7 @@
CustomTestSuite(TestConfiguration configuration)
: super(configuration, "CustomTestSuite", []);
- Future forEachTest(TestCaseEvent onTest, Map testCache, [onDone]) async {
+ void findTestCases(TestCaseEvent onTest, Map testCache) {
void enqueueTestCase(TestCase testCase) {
TestController.numTests++;
onTest(testCase);
@@ -89,10 +89,6 @@
enqueueTestCase(testCaseFail);
enqueueTestCase(testCaseTimeout);
enqueueTestCase(testCaseFailUnexpected);
-
- if (onDone != null) {
- onDone();
- }
}
TestCase _makeNormalTestCase(
diff --git a/pkg/test_runner/test/test_suite_test.dart b/pkg/test_runner/test/test_suite_test.dart
new file mode 100644
index 0000000..30304d1
--- /dev/null
+++ b/pkg/test_runner/test/test_suite_test.dart
@@ -0,0 +1,55 @@
+// Copyright (c) 2019, 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.
+import 'package:expect/expect.dart';
+
+import 'package:test_runner/src/test_file.dart';
+
+import 'utils.dart';
+
+void main() {
+ testNnbdRequirements();
+}
+
+void testNnbdRequirements() {
+ // Note: The backslashes are to avoid the test_runner thinking these are
+ // Requirements markers for this file itself.
+ var testFiles = [
+ parseTestFile("", path: "none_test.dart"),
+ parseTestFile("/\/ Requirements=nnbd", path: "nnbd_test.dart"),
+ parseTestFile("/\/ Requirements=nnbd-legacy", path: "legacy_test.dart"),
+ parseTestFile("/\/ Requirements=nnbd-weak", path: "weak_test.dart"),
+ parseTestFile("/\/ Requirements=nnbd-strong", path: "strong_test.dart"),
+ ];
+
+ expectTestCases(
+ [], testFiles, ["language_2/none_test", "language_2/legacy_test"]);
+
+ expectTestCases(["--nnbd=legacy"], testFiles,
+ ["language_2/none_test", "language_2/legacy_test"]);
+
+ expectTestCases(["--nnbd=weak"], testFiles,
+ ["language_2/none_test", "language_2/nnbd_test", "language_2/weak_test"]);
+
+ expectTestCases(
+ ["--nnbd=strong"],
+ testFiles,
+ [
+ "language_2/none_test",
+ "language_2/nnbd_test",
+ "language_2/strong_test"
+ ]);
+}
+
+void expectTestCases(List<String> options, List<TestFile> testFiles,
+ List<String> expectedCaseNames) {
+ var configuration = makeConfiguration(options);
+ var suite = makeTestSuite(configuration, testFiles);
+
+ var testCaseNames = <String>[];
+ suite.findTestCases((testCase) {
+ testCaseNames.add(testCase.displayName);
+ }, {});
+
+ Expect.listEquals(expectedCaseNames, testCaseNames);
+}
diff --git a/pkg/test_runner/test/utils.dart b/pkg/test_runner/test/utils.dart
new file mode 100644
index 0000000..e3ccc1b
--- /dev/null
+++ b/pkg/test_runner/test/utils.dart
@@ -0,0 +1,35 @@
+// Copyright (c) 2019, 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.
+import 'package:test_runner/src/configuration.dart';
+import 'package:test_runner/src/options.dart';
+import 'package:test_runner/src/path.dart';
+import 'package:test_runner/src/test_file.dart';
+import 'package:test_runner/src/test_suite.dart';
+
+final Path _suiteDirectory = Path("language_2");
+
+TestFile parseTestFile(String source, {String path = "some_test.dart"}) {
+ path = _suiteDirectory.absolute.append(path).toNativePath();
+ return TestFile.parse(_suiteDirectory.absolute, path, source);
+}
+
+// TODO(rnystrom): Would be nice if there was a simpler way to create a
+// configuration for use in unit tests.
+TestConfiguration makeConfiguration(List<String> arguments) =>
+ OptionsParser().parse([...arguments, "language_2"]).first;
+
+/// Creates a [StandardTestSuite] hardcoded to contain [testFiles].
+StandardTestSuite makeTestSuite(
+ TestConfiguration configuration, List<TestFile> testFiles) =>
+ _MockTestSuite(configuration, testFiles);
+
+class _MockTestSuite extends StandardTestSuite {
+ final List<TestFile> _testFiles;
+
+ _MockTestSuite(TestConfiguration configuration, this._testFiles)
+ : super(configuration, "language_2", _suiteDirectory, []);
+
+ @override
+ Iterable<TestFile> findTests() => _testFiles;
+}
diff --git a/pkg/test_runner/tool/co19.dart b/pkg/test_runner/tool/co19.dart
deleted file mode 100644
index 72b7a6d..0000000
--- a/pkg/test_runner/tool/co19.dart
+++ /dev/null
@@ -1,55 +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.
-
-/// Tool for running co19 tests. Used when updating co19.
-///
-/// Currently, this tool is merely a convenience around multiple
-/// invocations of test.dart. Long term, we hope to evolve this into a
-/// script that can automate most of the tasks necessary when updating
-/// co19.
-///
-/// Usage:
-/// [: dart pkg/test_runner/tool/co19.dart :]
-import 'package:test_runner/src/configuration.dart';
-import 'package:test_runner/src/options.dart';
-import 'package:test_runner/src/test_configurations.dart';
-
-const List<String> _commonArguments = <String>[
- '--report',
- '--progress=diff',
- 'co19'
-];
-
-const List<List<String>> _commandLines = <List<String>>[
- <String>['-mrelease,debug', '-rvm', '-cnone'],
- <String>['-mrelease,debug', '-rvm', '-cnone', '--checked'],
- <String>['-mrelease', '-rnone', '-cdart2analyzer'],
- <String>['-mrelease', '-rd8', '-cdart2js', '--use-sdk'],
- <String>['-mrelease', '-rd8,jsshell', '-cdart2js', '--use-sdk', '--minified'],
- <String>['-mrelease', '-rd8,jsshell', '-cdart2js', '--use-sdk', '--checked'],
- <String>[
- '-mrelease',
- '-rd8,jsshell',
- '-cdart2js',
- '--use-sdk',
- '--checked',
- '--fast-startup'
- ],
-];
-
-void main(List<String> args) {
- var optionsParser = OptionsParser();
- var configurations = <TestConfiguration>[];
- for (var commandLine in _commandLines) {
- var arguments = <String>[];
- arguments.addAll(_commonArguments);
- arguments.addAll(args);
- arguments.addAll(commandLine);
- configurations.addAll(optionsParser.parse(arguments));
- }
-
- if (configurations != null || configurations.isNotEmpty) {
- testConfigurations(configurations);
- }
-}
diff --git a/pkg/vm/bin/kernel_service.dart b/pkg/vm/bin/kernel_service.dart
index 6c72584..3021d8e 100644
--- a/pkg/vm/bin/kernel_service.dart
+++ b/pkg/vm/bin/kernel_service.dart
@@ -23,7 +23,7 @@
import 'dart:async' show Future, ZoneSpecification, runZoned;
import 'dart:collection' show UnmodifiableMapBase;
import 'dart:convert' show utf8;
-import 'dart:io' show File, Platform, stderr hide FileSystemEntity;
+import 'dart:io' show Directory, File, Platform, stderr hide FileSystemEntity;
import 'dart:isolate';
import 'dart:typed_data' show Uint8List;
@@ -535,7 +535,21 @@
if (verbose) {
for (int i = 0; i < request.length; i++) {
var part = request[i];
- String partToString = part.toString();
+ String partToString;
+ if (part is List && part.isNotEmpty) {
+ // Assume this is large and printing all of it takes a lot of time.
+ StringBuffer sb = new StringBuffer();
+ String prepend = "[";
+ for (int j = 0; j < part.length; j++) {
+ sb.write(prepend);
+ sb.write(part[j]);
+ prepend = ", ";
+ if (sb.length > 256) break;
+ }
+ partToString = sb.toString();
+ } else {
+ partToString = part.toString();
+ }
if (partToString.length > 256) {
partToString = partToString.substring(0, 255) + "...";
}
@@ -683,7 +697,7 @@
// In training mode make sure to read the sdk a few more times...
ProcessedOptions p = new ProcessedOptions(options: compiler.options);
var bytes = await p.loadSdkSummaryBytes();
- for (int i = 0; i < 100; i++) {
+ for (int i = 0; i < 5; i++) {
p.loadComponent(bytes, null);
}
@@ -744,7 +758,32 @@
return fileSystem;
}
-train(String scriptUri, String platformKernelPath, bool bytecode) {
+train(String scriptUri, String platformKernelPath, bool bytecode) async {
+ // Train on program asked to train on.
+ await trainInternal(scriptUri, platformKernelPath, bytecode);
+
+ // Also train a few times on a hello-world program to make sure we exercise
+ // the startup sequence.
+ Directory tmpDir =
+ Directory.systemTemp.createTempSync("kernel_service_train");
+ File helloDart = new File.fromUri(tmpDir.uri.resolve("hello.dart"));
+ helloDart.writeAsStringSync("""
+ main() {
+ print("Hello, World!");
+ }
+ """);
+ try {
+ for (int i = 0; i < 10; i++) {
+ await trainInternal(
+ helloDart.uri.toString(), platformKernelPath, bytecode);
+ }
+ } finally {
+ tmpDir.deleteSync(recursive: true);
+ }
+}
+
+Future trainInternal(
+ String scriptUri, String platformKernelPath, bool bytecode) async {
var tag = kTrainTag;
var responsePort = new RawReceivePort();
responsePort.handler = (response) {
@@ -775,7 +814,7 @@
null /* multirootFilepaths */,
null /* multirootScheme */,
];
- _processLoadRequest(request);
+ await _processLoadRequest(request);
}
main([args]) {
diff --git a/pkg/vm/lib/bytecode/gen_bytecode.dart b/pkg/vm/lib/bytecode/gen_bytecode.dart
index cee493c..c14d3ab 100644
--- a/pkg/vm/lib/bytecode/gen_bytecode.dart
+++ b/pkg/vm/lib/bytecode/gen_bytecode.dart
@@ -1545,10 +1545,14 @@
if (!hasErrors) {
Code code;
if (hasCode) {
- if (options.emitLocalVarInfo && node.function != null) {
- // Leave the scope which was entered in _setupInitialContext.
- asm.localVariableTable
- .leaveScope(asm.offset, node.function.fileEndOffset);
+ if (options.emitLocalVarInfo) {
+ // Leave the scopes which were entered in _genPrologue and
+ // _setupInitialContext.
+ asm.localVariableTable.leaveAllScopes(
+ asm.offset,
+ node.function != null
+ ? node.function.fileEndOffset
+ : node.fileEndOffset);
}
List<int> parameterFlags = null;
@@ -1673,47 +1677,75 @@
asm.emitPopLocal(locals.contextVarIndexInFrame);
}
- // CheckStack must see a properly initialized context when stress-testing
- // stack trace collection.
- asm.emitCheckStack(0);
+ if (locals.hasFunctionTypeArgsVar && function.typeParameters.isNotEmpty) {
+ assert(!(node is Procedure && node.isFactory));
- if (locals.hasFunctionTypeArgsVar) {
- if (function.typeParameters.isNotEmpty) {
- assert(!(node is Procedure && node.isFactory));
-
- Label done = new Label();
-
- if (isClosure) {
- _handleDelayedTypeArguments(done);
- }
-
- asm.emitCheckFunctionTypeArgs(function.typeParameters.length,
- locals.functionTypeArgsVarIndexInFrame);
-
- _handleDefaultTypeArguments(function, done);
-
- asm.bind(done);
- }
+ Label done = new Label();
if (isClosure) {
- if (function.typeParameters.isNotEmpty) {
- final int numParentTypeArgs = locals.numParentTypeArguments;
- asm.emitPush(locals.functionTypeArgsVarIndexInFrame);
- asm.emitPush(locals.closureVarIndexInFrame);
- asm.emitLoadFieldTOS(
- cp.addInstanceField(closureFunctionTypeArguments));
- _genPushInt(numParentTypeArgs);
- _genPushInt(numParentTypeArgs + function.typeParameters.length);
- _genDirectCall(
- prependTypeArguments, objectTable.getArgDescHandle(4), 4);
- asm.emitPopLocal(locals.functionTypeArgsVarIndexInFrame);
- } else {
- asm.emitPush(locals.closureVarIndexInFrame);
- asm.emitLoadFieldTOS(
- cp.addInstanceField(closureFunctionTypeArguments));
- asm.emitPopLocal(locals.functionTypeArgsVarIndexInFrame);
+ _handleDelayedTypeArguments(done);
+ }
+
+ asm.emitCheckFunctionTypeArgs(function.typeParameters.length,
+ locals.functionTypeArgsVarIndexInFrame);
+
+ _handleDefaultTypeArguments(function, done);
+
+ asm.bind(done);
+ }
+
+ // Open initial scope before the first CheckStack, as VM might
+ // need to know context level.
+ if (options.emitLocalVarInfo && function != null) {
+ asm.localVariableTable.enterScope(
+ asm.offset,
+ isClosure ? locals.contextLevelAtEntry : locals.currentContextLevel,
+ function.fileOffset);
+ if (locals.hasContextVar) {
+ asm.localVariableTable
+ .recordContextVariable(asm.offset, locals.contextVarIndexInFrame);
+ }
+ if (locals.hasReceiver) {
+ _declareLocalVariable(locals.receiverVar, function.fileOffset);
+ }
+ for (var v in function.positionalParameters) {
+ if (!locals.isCaptured(v)) {
+ _declareLocalVariable(v, function.fileOffset);
}
}
+ for (var v in locals.sortedNamedParameters) {
+ if (!locals.isCaptured(v)) {
+ _declareLocalVariable(v, function.fileOffset);
+ }
+ }
+ if (locals.hasFunctionTypeArgsVar) {
+ _declareLocalVariable(locals.functionTypeArgsVar, function.fileOffset);
+ }
+ }
+
+ // CheckStack must see a properly initialized context when stress-testing
+ // stack trace collection.
+ // Also, simdbc doesn't support arguments descriptor SpecialDbcRegister as
+ // a source location for deopt info, so CheckStack should be generated
+ // after the code which uses arguments descriptor.
+ asm.emitCheckStack(0);
+
+ if (locals.hasFunctionTypeArgsVar && isClosure) {
+ if (function.typeParameters.isNotEmpty) {
+ final int numParentTypeArgs = locals.numParentTypeArguments;
+ asm.emitPush(locals.functionTypeArgsVarIndexInFrame);
+ asm.emitPush(locals.closureVarIndexInFrame);
+ asm.emitLoadFieldTOS(cp.addInstanceField(closureFunctionTypeArguments));
+ _genPushInt(numParentTypeArgs);
+ _genPushInt(numParentTypeArgs + function.typeParameters.length);
+ _genDirectCall(
+ prependTypeArguments, objectTable.getArgDescHandle(4), 4);
+ asm.emitPopLocal(locals.functionTypeArgsVarIndexInFrame);
+ } else {
+ asm.emitPush(locals.closureVarIndexInFrame);
+ asm.emitLoadFieldTOS(cp.addInstanceField(closureFunctionTypeArguments));
+ asm.emitPopLocal(locals.functionTypeArgsVarIndexInFrame);
+ }
}
}
@@ -1761,26 +1793,10 @@
void _setupInitialContext(FunctionNode function) {
_allocateContextIfNeeded();
- if (options.emitLocalVarInfo && function != null) {
- // Open scope after allocating context.
- asm.localVariableTable.enterScope(
- asm.offset, locals.currentContextLevel, function.fileOffset);
- if (locals.hasContextVar) {
- asm.localVariableTable
- .recordContextVariable(asm.offset, locals.contextVarIndexInFrame);
- }
- if (locals.hasReceiver) {
- _declareLocalVariable(locals.receiverVar, function.fileOffset);
- }
- for (var v in function.positionalParameters) {
- _declareLocalVariable(v, function.fileOffset);
- }
- for (var v in locals.sortedNamedParameters) {
- _declareLocalVariable(v, function.fileOffset);
- }
- if (locals.hasFunctionTypeArgsVar) {
- _declareLocalVariable(locals.functionTypeArgsVar, function.fileOffset);
- }
+ if (options.emitLocalVarInfo && locals.currentContextSize > 0) {
+ // Open a new scope after allocating context.
+ asm.localVariableTable.enterScope(asm.offset, locals.currentContextLevel,
+ function != null ? function.fileOffset : enclosingMember.fileOffset);
}
if (locals.hasCapturedParameters) {
@@ -1795,8 +1811,10 @@
_genStoreVar(locals.capturedReceiverVar);
}
}
- function.positionalParameters.forEach(_copyParamIfCaptured);
- locals.sortedNamedParameters.forEach(_copyParamIfCaptured);
+ if (function != null) {
+ function.positionalParameters.forEach(_copyParamIfCaptured);
+ locals.sortedNamedParameters.forEach(_copyParamIfCaptured);
+ }
}
}
@@ -1825,6 +1843,9 @@
void _copyParamIfCaptured(VariableDeclaration variable) {
if (locals.isCaptured(variable)) {
+ if (options.emitLocalVarInfo) {
+ _declareLocalVariable(variable, enclosingFunction.fileOffset);
+ }
_genPushContextForVariable(variable);
asm.emitPush(locals.getOriginalParamSlotIndex(variable));
_genStoreVar(variable);
@@ -2191,8 +2212,9 @@
}
if (options.emitLocalVarInfo) {
- // Leave the scope which was entered in _setupInitialContext.
- asm.localVariableTable.leaveScope(asm.offset, function.fileEndOffset);
+ // Leave the scopes which were entered in _genPrologue and
+ // _setupInitialContext.
+ asm.localVariableTable.leaveAllScopes(asm.offset, function.fileEndOffset);
}
cp.addEndClosureFunctionScope();
diff --git a/pkg/vm/lib/bytecode/local_variable_table.dart b/pkg/vm/lib/bytecode/local_variable_table.dart
index 9da3d17..24607fa 100644
--- a/pkg/vm/lib/bytecode/local_variable_table.dart
+++ b/pkg/vm/lib/bytecode/local_variable_table.dart
@@ -159,6 +159,12 @@
}
}
+ void leaveAllScopes(int pc, int endPosition) {
+ while (activeScopes.isNotEmpty) {
+ leaveScope(pc, endPosition);
+ }
+ }
+
void recordContextVariable(int pc, int index) {
assert(contextVariable == null);
contextVariable = new ContextVariable(pc, index);
diff --git a/pkg/vm/lib/bytecode/object_table.dart b/pkg/vm/lib/bytecode/object_table.dart
index 9b35141..57452d0 100644
--- a/pkg/vm/lib/bytecode/object_table.dart
+++ b/pkg/vm/lib/bytecode/object_table.dart
@@ -6,7 +6,6 @@
import 'package:kernel/ast.dart' hide MapEntry;
import 'package:kernel/core_types.dart' show CoreTypes;
-import 'package:kernel/type_algebra.dart' show getFreshTypeParameters;
import 'bytecode_serialization.dart'
show
@@ -1962,7 +1961,7 @@
@override
ObjectHandle visitBottomType(BottomType node) =>
- objectTable.getHandle(objectTable.coreTypes.nullClass.rawType);
+ objectTable.getHandle(objectTable.coreTypes.nullType);
@override
ObjectHandle visitInterfaceType(InterfaceType node) {
@@ -2060,27 +2059,8 @@
.getOrAddObject(new _TypeParameterHandle(parentHandle, indexInParent));
}
- /// This is a workaround to <https://github.com/dart-lang/sdk/issues/37536>.
- /// TODO(37536): remove this workaround once the issue is fixed.
- ///
- /// In certain cases, front-end produces function types with type parameters
- /// which already belong to a closure. This results in the incorrect
- /// canonicalization of types.
- ///
- /// This method corrects FunctionType by creating fresh type parameters.
- FunctionType _fixTypeParameters(FunctionType type) {
- for (var typeParam in type.typeParameters) {
- if (typeParam.parent != null) {
- final fresh = getFreshTypeParameters(type.typeParameters);
- return fresh.applyToFunctionType(type);
- }
- }
- return type;
- }
-
@override
ObjectHandle visitFunctionType(FunctionType node) {
- node = _fixTypeParameters(node);
final int numEnclosingTypeParameters = _typeParameters.length;
for (int i = 0; i < node.typeParameters.length; ++i) {
_typeParameters[node.typeParameters[i]] = objectTable.getOrAddObject(
diff --git a/pkg/vm/lib/frontend_server.dart b/pkg/vm/lib/frontend_server.dart
index ba383ba..65164f6 100644
--- a/pkg/vm/lib/frontend_server.dart
+++ b/pkg/vm/lib/frontend_server.dart
@@ -361,6 +361,7 @@
}
Component component;
+ Iterable<Uri> compiledSources;
if (options['incremental']) {
_compilerOptions = compilerOptions;
_bytecodeOptions = bytecodeOptions;
@@ -370,8 +371,11 @@
_generator =
generator ?? _createGenerator(new Uri.file(_initializeFromDill));
await invalidateIfInitializingFromDill();
- component = await _runWithPrintRedirection(() async =>
- await _generateBytecodeIfNeeded(await _generator.compile()));
+ component = await _runWithPrintRedirection(() async {
+ final c = await _generator.compile();
+ compiledSources = c.uriToSource.keys;
+ return await _generateBytecodeIfNeeded(c);
+ });
} else {
if (options['link-platform']) {
// TODO(aam): Remove linkedDependencies once platform is directly embedded
@@ -380,7 +384,7 @@
sdkRoot.resolve(platformKernelDill)
];
}
- component = await _runWithPrintRedirection(() => compileToKernel(
+ final results = await _runWithPrintRedirection(() => compileToKernel(
_mainSource, compilerOptions,
aot: options['aot'],
useGlobalTypeFlowAnalysis: options['tfa'],
@@ -389,6 +393,8 @@
bytecodeOptions: bytecodeOptions,
dropAST: options['drop-ast'],
useProtobufTreeShaker: options['protobuf-tree-shaker']));
+ component = results.component;
+ compiledSources = results.compiledSources;
}
if (component != null) {
if (transformer != null) {
@@ -399,12 +405,12 @@
filterExternal: importDill != null);
_outputStream.writeln(boundaryKey);
- await _outputDependenciesDelta(component);
+ await _outputDependenciesDelta(compiledSources);
_outputStream
.writeln('$boundaryKey $_kernelBinaryFilename ${errors.length}');
final String depfile = options['depfile'];
if (depfile != null) {
- await writeDepfile(compilerOptions.fileSystem, component,
+ await writeDepfile(compilerOptions.fileSystem, compiledSources,
_kernelBinaryFilename, depfile);
}
@@ -430,9 +436,9 @@
return component;
}
- void _outputDependenciesDelta(Component component) async {
+ void _outputDependenciesDelta(Iterable<Uri> compiledSources) async {
Set<Uri> uris = new Set<Uri>();
- for (Uri uri in component.uriToSource.keys) {
+ for (Uri uri in compiledSources) {
// Skip empty or corelib dependencies.
if (uri == null || uri.scheme == 'org-dartlang-sdk') continue;
uris.add(uri);
@@ -557,10 +563,11 @@
if (deltaProgram != null && transformer != null) {
transformer.transform(deltaProgram);
}
+ final compiledSources = deltaProgram.uriToSource.keys;
deltaProgram = await _generateBytecodeIfNeeded(deltaProgram);
await writeDillFile(deltaProgram, _kernelBinaryFilename);
_outputStream.writeln(boundaryKey);
- await _outputDependenciesDelta(deltaProgram);
+ await _outputDependenciesDelta(compiledSources);
_outputStream
.writeln('$boundaryKey $_kernelBinaryFilename ${errors.length}');
_kernelBinaryFilename = _kernelBinaryFilenameIncremental;
@@ -902,6 +909,11 @@
}
if (options['train']) {
+ if (options.rest.isEmpty) {
+ throw Exception('Must specify input.dart');
+ }
+
+ final String input = options.rest[0];
final String sdkRoot = options['sdk-root'];
final String platform = options['platform'];
final Directory temp =
@@ -920,8 +932,7 @@
compiler ??=
new FrontendCompiler(output, printerFactory: binaryPrinterFactory);
- await compiler.compile(Platform.script.toFilePath(), options,
- generator: generator);
+ await compiler.compile(input, options, generator: generator);
compiler.acceptLastDelta();
await compiler.recompileDelta();
compiler.acceptLastDelta();
diff --git a/pkg/vm/lib/kernel_front_end.dart b/pkg/vm/lib/kernel_front_end.dart
index 49262b7..3c71ea3 100644
--- a/pkg/vm/lib/kernel_front_end.dart
+++ b/pkg/vm/lib/kernel_front_end.dart
@@ -212,7 +212,7 @@
}
..embedSourceText = embedSources;
- final component = await compileToKernel(mainUri, compilerOptions,
+ final results = await compileToKernel(mainUri, compilerOptions,
aot: aot,
useGlobalTypeFlowAnalysis: tfa,
environmentDefines: environmentDefines,
@@ -223,7 +223,7 @@
errorPrinter.printCompilationMessages();
- if (errorDetector.hasCompilationErrors || (component == null)) {
+ if (errorDetector.hasCompilationErrors || (results.component == null)) {
return compileTimeErrorExitCode;
}
@@ -233,7 +233,7 @@
final IOSink sink = new File(outputFileName).openWrite();
final BinaryPrinter printer = new BinaryPrinter(sink);
- printer.writeComponentFile(component);
+ printer.writeComponentFile(results.component);
await sink.close();
if (bytecodeOptions.showBytecodeSizeStatistics && !splitOutputByPackages) {
@@ -241,14 +241,15 @@
}
if (depfile != null) {
- await writeDepfile(fileSystem, component, outputFileName, depfile);
+ await writeDepfile(
+ fileSystem, results.compiledSources, outputFileName, depfile);
}
if (splitOutputByPackages) {
await writeOutputSplitByPackages(
mainUri,
compilerOptions,
- component,
+ results.component,
outputFileName,
genBytecode: genBytecode,
bytecodeOptions: bytecodeOptions,
@@ -259,12 +260,22 @@
return successExitCode;
}
+/// Results of [compileToKernel]: generated kernel [Component] and
+/// collection of compiled sources.
+class KernelCompilationResults {
+ final Component component;
+ final Iterable<Uri> compiledSources;
+
+ KernelCompilationResults(this.component, this.compiledSources);
+}
+
/// Generates a kernel representation of the program whose main library is in
/// the given [source]. Intended for whole program (non-modular) compilation.
///
/// VM-specific replacement of [kernelForProgram].
///
-Future<Component> compileToKernel(Uri source, CompilerOptions options,
+Future<KernelCompilationResults> compileToKernel(
+ Uri source, CompilerOptions options,
{bool aot: false,
bool useGlobalTypeFlowAnalysis: false,
Map<String, String> environmentDefines,
@@ -280,6 +291,7 @@
setVMEnvironmentDefines(environmentDefines, options);
CompilerResult compilerResult = await kernelForProgram(source, options);
Component component = compilerResult?.component;
+ final compiledSources = component?.uriToSource?.keys;
// Run global transformations only if component is correct.
if (aot && component != null) {
@@ -306,7 +318,7 @@
// Restore error handler (in case 'options' are reused).
options.onDiagnostic = errorDetector.previousErrorHandler;
- return component;
+ return new KernelCompilationResults(component, compiledSources);
}
void setVMEnvironmentDefines(
@@ -686,12 +698,12 @@
/// Create ninja dependencies file, as described in
/// https://ninja-build.org/manual.html#_depfile
-Future<void> writeDepfile(FileSystem fileSystem, Component component,
+Future<void> writeDepfile(FileSystem fileSystem, Iterable<Uri> compiledSources,
String output, String depfile) async {
final IOSink file = new File(depfile).openWrite();
file.write(_escapePath(output));
file.write(':');
- for (Uri dep in component.uriToSource.keys) {
+ for (Uri dep in compiledSources) {
// Skip empty or corelib dependencies.
if (dep == null || dep.scheme == 'org-dartlang-sdk') continue;
Uri uri = await asFileUri(fileSystem, dep);
diff --git a/pkg/vm/lib/target/dart_runner.dart b/pkg/vm/lib/target/dart_runner.dart
index 270f365..fc814ac 100644
--- a/pkg/vm/lib/target/dart_runner.dart
+++ b/pkg/vm/lib/target/dart_runner.dart
@@ -45,7 +45,5 @@
];
@override
- List<String> get extraRequiredLibrariesPlatform => const <String>[
- 'dart:profiler',
- ];
+ List<String> get extraRequiredLibrariesPlatform => const <String>[];
}
diff --git a/pkg/vm/lib/target/flutter.dart b/pkg/vm/lib/target/flutter.dart
index 8022a27..9d63c74 100644
--- a/pkg/vm/lib/target/flutter.dart
+++ b/pkg/vm/lib/target/flutter.dart
@@ -48,9 +48,7 @@
];
@override
- List<String> get extraRequiredLibrariesPlatform => const <String>[
- 'dart:profiler',
- ];
+ List<String> get extraRequiredLibrariesPlatform => const <String>[];
@override
void performPreConstantEvaluationTransformations(
diff --git a/pkg/vm/lib/target/flutter_runner.dart b/pkg/vm/lib/target/flutter_runner.dart
index 53363e2..816c030 100644
--- a/pkg/vm/lib/target/flutter_runner.dart
+++ b/pkg/vm/lib/target/flutter_runner.dart
@@ -46,7 +46,5 @@
];
@override
- List<String> get extraRequiredLibrariesPlatform => const <String>[
- 'dart:profiler',
- ];
+ List<String> get extraRequiredLibrariesPlatform => const <String>[];
}
diff --git a/pkg/vm/lib/target/vm.dart b/pkg/vm/lib/target/vm.dart
index 23a6832..eefc73c 100644
--- a/pkg/vm/lib/target/vm.dart
+++ b/pkg/vm/lib/target/vm.dart
@@ -41,9 +41,6 @@
VmTarget(this.flags);
@override
- bool get legacyMode => flags.legacyMode;
-
- @override
bool get enableNoSuchMethodForwarders => true;
@override
@@ -80,9 +77,7 @@
];
@override
- List<String> get extraRequiredLibrariesPlatform => const <String>[
- 'dart:profiler',
- ];
+ List<String> get extraRequiredLibrariesPlatform => const <String>[];
void _patchVmConstants(CoreTypes coreTypes) {
// Fix Endian.host to be a const field equal to Endian.little instead of
@@ -181,7 +176,7 @@
new IntLiteral(type)..fileOffset = offset,
_fixedLengthList(
coreTypes,
- coreTypes.typeClass.rawType,
+ coreTypes.typeLegacyRawType,
arguments.types.map((t) => new TypeLiteral(t)).toList(),
arguments.fileOffset),
_fixedLengthList(coreTypes, const DynamicType(), arguments.positional,
@@ -195,11 +190,11 @@
new SymbolLiteral(arg.name)..fileOffset = arg.fileOffset,
arg.value)
..fileOffset = arg.fileOffset;
- })), keyType: coreTypes.symbolClass.rawType)
+ })), keyType: coreTypes.symbolLegacyRawType)
..isConst = (arguments.named.length == 0)
..fileOffset = arguments.fileOffset
], types: [
- coreTypes.symbolClass.rawType,
+ coreTypes.symbolLegacyRawType,
new DynamicType()
]))
..fileOffset = offset
diff --git a/pkg/vm/lib/transformations/type_flow/analysis.dart b/pkg/vm/lib/transformations/type_flow/analysis.dart
index 2d434d2..75a8332 100644
--- a/pkg/vm/lib/transformations/type_flow/analysis.dart
+++ b/pkg/vm/lib/transformations/type_flow/analysis.dart
@@ -134,7 +134,7 @@
final nsmArgs = new Args<Type>([
receiver,
new Type.cone(
- typeFlowAnalysis.environment.coreTypes.invocationClass.rawType)
+ typeFlowAnalysis.environment.coreTypes.invocationLegacyRawType)
]);
final nsmInvocation =
@@ -438,8 +438,9 @@
}
if (selector is InterfaceSelector) {
- final staticReceiverType =
- new Type.fromStatic(selector.member.enclosingClass.rawType);
+ final staticReceiverType = new Type.fromStatic(typeFlowAnalysis
+ .environment.coreTypes
+ .legacyRawType(selector.member.enclosingClass));
receiver = receiver.intersection(
staticReceiverType, typeFlowAnalysis.hierarchyCache);
assertx(receiver is! NullableType);
@@ -1239,6 +1240,7 @@
Class get futureOrClass => environment.coreTypes.futureOrClass;
Class get futureClass => environment.coreTypes.futureClass;
Class get functionClass => environment.coreTypes.functionClass;
+ CoreTypes get coreTypes => environment.coreTypes;
}
class _WorkList {
diff --git a/pkg/vm/lib/transformations/type_flow/summary_collector.dart b/pkg/vm/lib/transformations/type_flow/summary_collector.dart
index 7254e6c..a5d3532 100644
--- a/pkg/vm/lib/transformations/type_flow/summary_collector.dart
+++ b/pkg/vm/lib/transformations/type_flow/summary_collector.dart
@@ -344,8 +344,8 @@
_summary = new Summary(
parameterCount: numArgs, positionalParameterCount: numArgs);
// TODO(alexmarkov): subclass cone
- _receiver = _declareParameter(
- "this", member.enclosingClass.rawType, null,
+ _receiver = _declareParameter("this",
+ _environment.coreTypes.legacyRawType(member.enclosingClass), null,
isReceiver: true);
_environment.thisType = member.enclosingClass?.thisType;
} else {
@@ -391,8 +391,8 @@
if (hasReceiver) {
// TODO(alexmarkov): subclass cone
- _receiver = _declareParameter(
- "this", member.enclosingClass.rawType, null,
+ _receiver = _declareParameter("this",
+ _environment.coreTypes.legacyRawType(member.enclosingClass), null,
isReceiver: true);
_environment.thisType = member.enclosingClass?.thisType;
}
@@ -524,7 +524,8 @@
if (hasReceiverArg(member)) {
assertx(member.enclosingClass != null);
- Type receiver = new Type.cone(member.enclosingClass.rawType);
+ Type receiver = new Type.cone(
+ _environment.coreTypes.legacyRawType(member.enclosingClass));
args.add(receiver);
}
diff --git a/pkg/vm/lib/transformations/type_flow/types.dart b/pkg/vm/lib/transformations/type_flow/types.dart
index 9d34b39..4b5a7a1 100644
--- a/pkg/vm/lib/transformations/type_flow/types.dart
+++ b/pkg/vm/lib/transformations/type_flow/types.dart
@@ -9,6 +9,8 @@
import 'package:kernel/ast.dart';
+import 'package:kernel/core_types.dart';
+
import 'utils.dart';
abstract class GenericInterfacesInfo {
@@ -46,6 +48,7 @@
Class get futureOrClass;
Class get futureClass;
Class get functionClass;
+ CoreTypes get coreTypes;
}
/// Basic normalization of Dart types.
@@ -53,7 +56,12 @@
DartType _normalizeDartType(DartType type) {
if (type is InterfaceType) {
// TODO(alexmarkov): take generic type arguments into account
- return type.classNode.rawType;
+ // TODO(alexmarkov): cache the created raw type or use a CoreTypes object
+ return new InterfaceType(
+ type.classNode,
+ new List<DartType>.filled(
+ type.classNode.typeParameters.length, const DynamicType()),
+ Nullability.legacy);
} else if (type is FunctionType) {
// TODO(alexmarkov): support function types
return const DynamicType();
@@ -536,7 +544,9 @@
return other;
}
} else if (other is ConcreteType) {
- if (typeHierarchy.isSubtype(other.classNode.rawType, this.dartType)) {
+ if (typeHierarchy.isSubtype(
+ typeHierarchy.coreTypes.legacyRawType(other.classNode),
+ this.dartType)) {
return this;
}
}
@@ -561,7 +571,9 @@
return this;
}
} else if (other is ConcreteType) {
- if (typeHierarchy.isSubtype(other.classNode.rawType, this.dartType)) {
+ if (typeHierarchy.isSubtype(
+ typeHierarchy.coreTypes.legacyRawType(other.classNode),
+ this.dartType)) {
return other;
} else {
return const EmptyType();
@@ -626,7 +638,8 @@
@override
bool isSubtypeOf(TypeHierarchy typeHierarchy, DartType dartType) =>
- typeHierarchy.isSubtype(classNode.rawType, dartType);
+ typeHierarchy.isSubtype(
+ typeHierarchy.coreTypes.legacyRawType(classNode), dartType);
bool isSubtypeOfRuntimeType(
TypeHierarchy typeHierarchy, RuntimeType runtimeType) {
@@ -639,7 +652,9 @@
return false;
}
- if (!typeHierarchy.isSubtype(this.classNode.rawType, runtimeType._type)) {
+ if (!typeHierarchy.isSubtype(
+ typeHierarchy.coreTypes.legacyRawType(this.classNode),
+ runtimeType._type)) {
return false;
}
@@ -649,7 +664,8 @@
if (runtimeDartType.typeArguments.isEmpty) return true;
if (runtimeDartType.classNode == typeHierarchy.futureOrClass) {
if (typeHierarchy.isSubtype(
- classNode.rawType, typeHierarchy.futureClass.rawType) ||
+ typeHierarchy.coreTypes.legacyRawType(classNode),
+ typeHierarchy.coreTypes.futureLegacyRawType) ||
classNode == typeHierarchy.futureOrClass) {
final RuntimeType lhs =
typeArgs == null ? RuntimeType(DynamicType(), null) : typeArgs[0];
diff --git a/pkg/vm/test/frontend_server_test.dart b/pkg/vm/test/frontend_server_test.dart
index ed121c0..37df317 100644
--- a/pkg/vm/test/frontend_server_test.dart
+++ b/pkg/vm/test/frontend_server_test.dart
@@ -28,7 +28,7 @@
final CompilerInterface compiler = new _MockedCompiler();
test('train with mocked compiler completes', () async {
- await starter(<String>['--train'], compiler: compiler);
+ await starter(<String>['--train', 'foo.dart'], compiler: compiler);
});
});
@@ -313,6 +313,14 @@
'--incremental',
];
+ Directory tempDir;
+ setUp(() {
+ tempDir = Directory.systemTemp.createTempSync();
+ });
+ tearDown(() {
+ tempDir.delete(recursive: true);
+ });
+
test('compile then accept', () async {
final StreamController<List<int>> inputStreamController =
new StreamController<List<int>>();
@@ -359,11 +367,13 @@
binaryPrinterFactory: printerFactory,
);
- inputStreamController.add('compile file1.dart\n'.codeUnits);
+ final source = new File('${tempDir.path}/file1.dart');
+ inputStreamController.add('compile ${source.path}\n'.codeUnits);
await receivedResult.first;
inputStreamController.add('accept\n'.codeUnits);
receivedResult = new ReceivePort();
- inputStreamController.add('recompile def\nfile1.dart\ndef\n'.codeUnits);
+ inputStreamController
+ .add('recompile def\n${source.path}\ndef\n'.codeUnits);
await receivedResult.first;
inputStreamController.add('quit\n'.codeUnits);
@@ -989,11 +999,41 @@
'--platform=${platformKernel.path}',
'--output-dill=${dillFile.path}',
'--gen-bytecode',
+ '--drop-ast',
file.path,
];
expect(await starter(args), 0);
});
+ test('compile with bytecode and produce deps file', () async {
+ var sourceFoo = new File('${tempDir.path}/foo.dart')..createSync();
+ sourceFoo.writeAsStringSync("import 'bar.dart'; main() { barfunc(); }\n");
+ var sourceBar = new File('${tempDir.path}/bar.dart')..createSync();
+ sourceBar.writeAsStringSync("barfunc() {}\n");
+ var dillFile = new File('${tempDir.path}/app.dill');
+ expect(dillFile.existsSync(), equals(false));
+ var depFile = new File('${tempDir.path}/app.dill.d');
+ expect(depFile.existsSync(), equals(false));
+ final List<String> args = <String>[
+ '--sdk-root=${sdkRoot.toFilePath()}',
+ '--incremental',
+ '--platform=${platformKernel.path}',
+ '--output-dill=${dillFile.path}',
+ '--depfile=${depFile.path}',
+ '--gen-bytecode',
+ '--drop-ast',
+ sourceFoo.path,
+ ];
+ expect(await starter(args), 0);
+ expect(depFile.existsSync(), true);
+ var depContents = depFile.readAsStringSync();
+ print(depContents);
+ var depContentsParsed = depContents.split(': ');
+ expect(path.basename(depContentsParsed[0]), path.basename(dillFile.path));
+ expect(depContentsParsed[1], contains(path.basename(sourceFoo.path)));
+ expect(depContentsParsed[1], contains(path.basename(sourceBar.path)));
+ });
+
test('compile "package:"-file', () async {
Directory lib = new Directory('${tempDir.path}/lib')..createSync();
new File('${lib.path}/foo.dart')
diff --git a/pkg/vm/test/transformations/type_flow/types_test.dart b/pkg/vm/test/transformations/type_flow/types_test.dart
index b317843..3d2dc5d 100644
--- a/pkg/vm/test/transformations/type_flow/types_test.dart
+++ b/pkg/vm/test/transformations/type_flow/types_test.dart
@@ -5,12 +5,14 @@
import 'dart:core' hide Type;
import 'package:kernel/ast.dart';
+import 'package:kernel/core_types.dart';
import 'package:test/test.dart';
import 'package:vm/transformations/type_flow/types.dart';
class TestTypeHierarchy implements TypeHierarchy {
final Map<DartType, List<DartType>> subtypes;
final Map<DartType, Type> specializations;
+ final CoreTypes coreTypes = new CoreTypes(new Component());
TestTypeHierarchy(this.subtypes, this.specializations);
diff --git a/pkg/vm/testcases/bytecode/async.dart.expect b/pkg/vm/testcases/bytecode/async.dart.expect
index 74730b1..e79ab6e 100644
--- a/pkg/vm/testcases/bytecode/async.dart.expect
+++ b/pkg/vm/testcases/bytecode/async.dart.expect
@@ -2207,9 +2207,9 @@
import "dart:async";
- static field (dart.async::Future<dart.core::int*>*) →* dart.async::Future<dart.core::Null*>* asyncInFieldInitializer = (dart.async::Future<dart.core::int*>* x) → dart.async::Future<dart.core::Null*>* /* originally async */ {
- final dart.async::_AsyncAwaitCompleter<dart.core::Null*>* :async_completer = new dart.async::_AsyncAwaitCompleter::•<dart.core::Null*>();
- dart.async::FutureOr<dart.core::Null*>* :return_value;
+ static field (dart.async::Future<dart.core::int*>*) →* dart.async::Future<dart.core::Null?>* asyncInFieldInitializer = (dart.async::Future<dart.core::int*>* x) → dart.async::Future<dart.core::Null?>* /* originally async */ {
+ final dart.async::_AsyncAwaitCompleter<dart.core::Null?>* :async_completer = new dart.async::_AsyncAwaitCompleter::•<dart.core::Null?>();
+ dart.async::FutureOr<dart.core::Null?>* :return_value;
dynamic :async_stack_trace;
dynamic :async_op_then;
dynamic :async_op_error;
diff --git a/pkg/vm/testcases/bytecode/closures.dart.expect b/pkg/vm/testcases/bytecode/closures.dart.expect
index 76d15ca..3b9cc78 100644
--- a/pkg/vm/testcases/bytecode/closures.dart.expect
+++ b/pkg/vm/testcases/bytecode/closures.dart.expect
@@ -103,8 +103,8 @@
Bytecode {
Entry 2
- CheckStack 0
CheckFunctionTypeArgs 8, r0
+ CheckStack 0
PushConstant CP#0
StoreLocal r1
Push r1
@@ -321,7 +321,6 @@
Push FP[-6]
LoadFieldTOS CP#1
PopLocal r1
- CheckStack 0
Push FP[-6]
LoadFieldTOS CP#3
StoreLocal r0
@@ -332,6 +331,7 @@
L1:
CheckFunctionTypeArgs 1, r0
L2:
+ CheckStack 0
Push r0
Push FP[-6]
LoadFieldTOS CP#6
@@ -573,8 +573,8 @@
Bytecode {
Entry 5
- CheckStack 0
CheckFunctionTypeArgs 2, r0
+ CheckStack 0
AllocateContext 0, 1
PopLocal r1
Push r1
@@ -664,7 +664,6 @@
Push FP[-5]
LoadFieldTOS CP#1
PopLocal r1
- CheckStack 0
Push FP[-5]
LoadFieldTOS CP#3
StoreLocal r0
@@ -675,6 +674,7 @@
L1:
CheckFunctionTypeArgs 2, r0
L2:
+ CheckStack 0
Push r0
Push FP[-5]
LoadFieldTOS CP#6
@@ -724,7 +724,6 @@
Push FP[-5]
LoadFieldTOS CP#1
PopLocal r1
- CheckStack 0
Push FP[-5]
LoadFieldTOS CP#3
StoreLocal r0
@@ -735,6 +734,7 @@
L1:
CheckFunctionTypeArgs 2, r0
L2:
+ CheckStack 0
Push r0
Push FP[-5]
LoadFieldTOS CP#6
@@ -1656,11 +1656,11 @@
method foo<T3 extends dart.core::Object* = dynamic, T4 extends dart.core::Object* = dynamic>() → void {
function nested1<T5 extends dart.core::Object* = dynamic, T6 extends dart.core::Object* = dynamic>() → void {
function nested2<T7 extends dart.core::Object* = dynamic, T8 extends dart.core::Object* = dynamic>() → void {
- () →* dart.core::Null* nested3 = () → dart.core::Null* {
+ () →* dart.core::Null? nested3 = () → dart.core::Null? {
dart.core::print(<dart.core::Type*>[#lib::A::T1*, #lib::A::T2*, #lib::A::foo::T3*, #lib::A::foo::T4*, T5*, T6*, T7*, T8*]);
#lib::callWithArgs<#lib::A::T1*, #lib::A::T2*, #lib::A::foo::T3*, #lib::A::foo::T4*, T5*, T6*, T7*, T8*>();
};
- [@vm.call-site-attributes.metadata=receiverType:() →* dart.core::Null*] nested3.call();
+ [@vm.call-site-attributes.metadata=receiverType:() →* dart.core::Null?] nested3.call();
}
[@vm.call-site-attributes.metadata=receiverType:<T7 extends dart.core::Object* = dynamic, T8 extends dart.core::Object* = dynamic>() →* void] nested2.call<#lib::C7*, #lib::C8*>();
[@vm.call-site-attributes.metadata=receiverType:<T7 extends dart.core::Object* = dynamic, T8 extends dart.core::Object* = dynamic>() →* void] nested2.call<dart.core::List<#lib::C7*>*, dart.core::List<#lib::C8*>*>();
@@ -1680,7 +1680,7 @@
{
dart.core::int* y = 2;
dart.core::int* z = 3;
- (dart.core::int*) →* dart.core::Null* closure1 = (dart.core::int* y) → dart.core::Null* {
+ (dart.core::int*) →* dart.core::Null? closure1 = (dart.core::int* y) → dart.core::Null? {
x = y.{dart.core::num::+}(1);
if(x.{dart.core::num::>}(5)) {
dart.core::int* w = 4;
@@ -1692,8 +1692,8 @@
dart.core::print(w);
}
};
- [@vm.call-site-attributes.metadata=receiverType:(dart.core::int*) →* dart.core::Null*] closure1.call(10);
- [@vm.call-site-attributes.metadata=receiverType:(dart.core::int*) →* dart.core::Null*] closure1.call(11);
+ [@vm.call-site-attributes.metadata=receiverType:(dart.core::int*) →* dart.core::Null?] closure1.call(10);
+ [@vm.call-site-attributes.metadata=receiverType:(dart.core::int*) →* dart.core::Null?] closure1.call(11);
dart.core::print(y);
dart.core::print(z);
}
@@ -1701,10 +1701,10 @@
}
{
dart.core::int* x = 42;
- () →* dart.core::Null* closure3 = () → dart.core::Null* {
+ () →* dart.core::Null? closure3 = () → dart.core::Null? {
this.{#lib::B::foo} = x;
};
- [@vm.call-site-attributes.metadata=receiverType:() →* dart.core::Null*] closure3.call();
+ [@vm.call-site-attributes.metadata=receiverType:() →* dart.core::Null?] closure3.call();
}
}
}
@@ -1718,17 +1718,17 @@
dart.core::List<dart.core::Function*>* setI = <dart.core::Function*>[];
for (dart.core::int* i = 0; i.{dart.core::num::<}(10); i = i.{dart.core::num::+}(1)) {
[@vm.call-site-attributes.metadata=receiverType:dart.core::List<dart.core::Function*>*] getI.{dart.core::List::add}(() → dart.core::int* => i.{dart.core::num::+}(delta));
- [@vm.call-site-attributes.metadata=receiverType:dart.core::List<dart.core::Function*>*] setI.{dart.core::List::add}((dart.core::int* ii) → dart.core::Null* {
+ [@vm.call-site-attributes.metadata=receiverType:dart.core::List<dart.core::Function*>*] setI.{dart.core::List::add}((dart.core::int* ii) → dart.core::Null? {
i = ii.{dart.core::num::+}(delta);
});
}
}
method testForInLoop(dart.core::List<dart.core::int*>* list) → void {
for (dart.core::int* i in list) {
- () →* dart.core::Null* inc = () → dart.core::Null* {
+ () →* dart.core::Null? inc = () → dart.core::Null? {
i = i.{dart.core::num::+}(1);
};
- [@vm.call-site-attributes.metadata=receiverType:() →* dart.core::Null*] inc.call();
+ [@vm.call-site-attributes.metadata=receiverType:() →* dart.core::Null?] inc.call();
dart.core::print(i);
}
}
@@ -1741,18 +1741,18 @@
return () → #lib::D::T* => t;
}
method bar() → dynamic {
- return () → dart.core::Null* {
- function inner() → dart.core::Null* {}
- [@vm.call-site-attributes.metadata=receiverType:() →* dart.core::Null*] inner.call();
+ return () → dart.core::Null? {
+ function inner() → dart.core::Null? {}
+ [@vm.call-site-attributes.metadata=receiverType:() →* dart.core::Null?] inner.call();
};
}
}
static method simpleClosure() → dart.core::int* {
dart.core::int* x = 5;
- (dart.core::int*) →* dart.core::Null* inc = (dart.core::int* y) → dart.core::Null* {
+ (dart.core::int*) →* dart.core::Null? inc = (dart.core::int* y) → dart.core::Null? {
x = x.{dart.core::num::+}(y);
};
- [@vm.call-site-attributes.metadata=receiverType:(dart.core::int*) →* dart.core::Null*] inc.call(3);
+ [@vm.call-site-attributes.metadata=receiverType:(dart.core::int*) →* dart.core::Null?] inc.call(3);
return x;
}
static method callWithArgs<T1 extends dart.core::Object* = dynamic, T2 extends dart.core::Object* = dynamic, T3 extends dart.core::Object* = dynamic, T4 extends dart.core::Object* = dynamic, T5 extends dart.core::Object* = dynamic, T6 extends dart.core::Object* = dynamic, T7 extends dart.core::Object* = dynamic, T8 extends dart.core::Object* = dynamic>() → void {
diff --git a/pkg/vm/testcases/bytecode/instance_creation.dart.expect b/pkg/vm/testcases/bytecode/instance_creation.dart.expect
index 3154298..cb085fd 100644
--- a/pkg/vm/testcases/bytecode/instance_creation.dart.expect
+++ b/pkg/vm/testcases/bytecode/instance_creation.dart.expect
@@ -80,8 +80,8 @@
Bytecode {
Entry 2
- CheckStack 0
CheckFunctionTypeArgs 1, r0
+ CheckStack 0
PushNull
Push r0
InstantiateTypeArgumentsTOS 0, CP#1
diff --git a/pkg/vm/testcases/bytecode/literals.dart.expect b/pkg/vm/testcases/bytecode/literals.dart.expect
index 5b63921..b698f7ce 100644
--- a/pkg/vm/testcases/bytecode/literals.dart.expect
+++ b/pkg/vm/testcases/bytecode/literals.dart.expect
@@ -205,8 +205,8 @@
Bytecode {
Entry 2
- CheckStack 0
CheckFunctionTypeArgs 1, r0
+ CheckStack 0
PushConstant CP#0
PushConstant CP#1
PushInt 4
@@ -332,8 +332,8 @@
Bytecode {
Entry 1
- CheckStack 0
CheckFunctionTypeArgs 1, r0
+ CheckStack 0
PushConstant CP#0
DirectCall CP#1, 1
Drop1
diff --git a/pkg/vm/testcases/bytecode/optional_params.dart.expect b/pkg/vm/testcases/bytecode/optional_params.dart.expect
index 035d76c1..09d42e2 100644
--- a/pkg/vm/testcases/bytecode/optional_params.dart.expect
+++ b/pkg/vm/testcases/bytecode/optional_params.dart.expect
@@ -204,8 +204,8 @@
LoadConstant r3, CP#2
LoadConstant r3, CP#3
Frame 1
- CheckStack 0
CheckFunctionTypeArgs 2, r4
+ CheckStack 0
PushNull
Push r4
InstantiateType CP#4
diff --git a/pkg/vm/testcases/bytecode/super_calls.dart.expect b/pkg/vm/testcases/bytecode/super_calls.dart.expect
index aabc371..32781bb 100644
--- a/pkg/vm/testcases/bytecode/super_calls.dart.expect
+++ b/pkg/vm/testcases/bytecode/super_calls.dart.expect
@@ -53,8 +53,8 @@
Bytecode {
Entry 1
- CheckStack 0
CheckFunctionTypeArgs 1, r0
+ CheckStack 0
PushNull
ReturnTOS
}
diff --git a/pkg/vm/testcases/bytecode/type_ops.dart.expect b/pkg/vm/testcases/bytecode/type_ops.dart.expect
index af14940..de2ecc3 100644
--- a/pkg/vm/testcases/bytecode/type_ops.dart.expect
+++ b/pkg/vm/testcases/bytecode/type_ops.dart.expect
@@ -276,8 +276,8 @@
Bytecode {
Entry 1
- CheckStack 0
CheckFunctionTypeArgs 2, r0
+ CheckStack 0
Push FP[-5]
PushNull
Push r0
@@ -402,7 +402,6 @@
Bytecode {
Entry 1
- CheckStack 0
CheckFunctionTypeArgs 2, r0
JumpIfNotZeroTypeArgs L1
Push FP[-6]
@@ -411,6 +410,7 @@
InstantiateTypeArgumentsTOS 0, CP#1
PopLocal r0
L1:
+ CheckStack 0
JumpIfUnchecked L2
Push FP[-6]
LoadTypeArgumentsField CP#0
@@ -496,13 +496,13 @@
Bytecode {
Entry 1
- CheckStack 0
CheckFunctionTypeArgs 1, r0
JumpIfNotZeroTypeArgs L1
Push FP[-8]
LoadTypeArgumentsField CP#0
PopLocal r0
L1:
+ CheckStack 0
JumpIfUnchecked L2
Push FP[-8]
LoadTypeArgumentsField CP#0
@@ -567,13 +567,13 @@
Bytecode {
Entry 1
- CheckStack 0
CheckFunctionTypeArgs 1, r0
JumpIfNotZeroTypeArgs L1
Push FP[-8]
LoadTypeArgumentsField CP#0
PopLocal r0
L1:
+ CheckStack 0
JumpIfUnchecked L2
Push FP[-8]
LoadTypeArgumentsField CP#0
@@ -614,8 +614,8 @@
Bytecode {
Entry 2
- CheckStack 0
CheckFunctionTypeArgs 1, r0
+ CheckStack 0
JumpIfUnchecked L1
Push FP[-8]
LoadTypeArgumentsField CP#0
diff --git a/pkg/vm_service/CHANGELOG.md b/pkg/vm_service/CHANGELOG.md
index cd25650..68ded73 100644
--- a/pkg/vm_service/CHANGELOG.md
+++ b/pkg/vm_service/CHANGELOG.md
@@ -1,5 +1,9 @@
# Changelog
+## 2.0.0
+- **breaking**: VM service objects which have fields now have constructors with
+ named parameters for each field. Required fields are annotated with `@required`.
+
## 1.2.0
- Support service protocol version 3.27:
- Added `getCpuSamples` and `clearCpuSamples` methods
diff --git a/pkg/vm_service/java/src/org/dartlang/vm/service/VmServiceBase.java b/pkg/vm_service/java/src/org/dartlang/vm/service/VmServiceBase.java
index f794f6f..f335d5c 100644
--- a/pkg/vm_service/java/src/org/dartlang/vm/service/VmServiceBase.java
+++ b/pkg/vm_service/java/src/org/dartlang/vm/service/VmServiceBase.java
@@ -618,11 +618,13 @@
Logging.getLogger().logError("Response has invalid " + RESULT, e);
return;
}
- String responseType;
- try {
+ String responseType = "";
+ if (result.has(TYPE)) {
responseType = result.get(TYPE).getAsString();
- } catch (Exception e) {
- Logging.getLogger().logError("Response missing " + TYPE, e);
+ }
+ // ServiceExtensionConsumers do not care about the response type.
+ else if (!(consumer instanceof ServiceExtensionConsumer)) {
+ Logging.getLogger().logError("Response missing " + TYPE + ": " + result.toString());
return;
}
forwardResponse(consumer, responseType, result);
diff --git a/pkg/vm_service/lib/src/service_extension_registry.dart b/pkg/vm_service/lib/src/service_extension_registry.dart
index e256466..9ec1514 100644
--- a/pkg/vm_service/lib/src/service_extension_registry.dart
+++ b/pkg/vm_service/lib/src/service_extension_registry.dart
@@ -60,8 +60,10 @@
/// [EventKind.kServiceRegistered].
Event _toRegistrationEvent(String method,
{String kind = EventKind.kServiceRegistered}) =>
- Event()
- ..kind = kind
- ..service = method
- ..method = method;
+ Event(
+ kind: kind,
+ service: method,
+ method: method,
+ timestamp: DateTime.now().millisecondsSinceEpoch,
+ );
}
diff --git a/pkg/vm_service/lib/vm_service.dart b/pkg/vm_service/lib/vm_service.dart
index 2838a4e..2850348 100644
--- a/pkg/vm_service/lib/vm_service.dart
+++ b/pkg/vm_service/lib/vm_service.dart
@@ -13,6 +13,8 @@
import 'dart:convert' show base64, jsonDecode, jsonEncode, utf8;
import 'dart:typed_data';
+import 'package:meta/meta.dart';
+
import 'src/service_extension_registry.dart';
export 'src/service_extension_registry.dart' show ServiceExtensionRegistry;
@@ -1190,7 +1192,7 @@
} else if (method.startsWith('ext.')) {
// Remaining methods with `ext.` are assumed to be registered via
// dart:developer, which the service implementation handles.
- var args = params == null ? null : new Map.of(params);
+ var args = params == null ? null : Map.of(params);
var isolateId = args?.remove('isolateId');
response = await _serviceImplementation.callServiceExtension(method,
isolateId: isolateId, args: args);
@@ -1228,18 +1230,17 @@
Map<String, ServiceCallback> _services = {};
Log _log;
- StreamController<String> _onSend = new StreamController.broadcast(sync: true);
- StreamController<String> _onReceive =
- new StreamController.broadcast(sync: true);
+ StreamController<String> _onSend = StreamController.broadcast(sync: true);
+ StreamController<String> _onReceive = StreamController.broadcast(sync: true);
- final Completer _onDoneCompleter = new Completer();
+ final Completer _onDoneCompleter = Completer();
Map<String, StreamController<Event>> _eventControllers = {};
StreamController<Event> _getEventController(String eventName) {
StreamController<Event> controller = _eventControllers[eventName];
if (controller == null) {
- controller = new StreamController.broadcast();
+ controller = StreamController.broadcast();
_eventControllers[eventName] = controller;
}
return controller;
@@ -1257,7 +1258,7 @@
_streamSub = inStream.listen(_processMessage,
onDone: () => _onDoneCompleter.complete());
_writeMessage = writeMessage;
- _log = log == null ? new _NullLog() : log;
+ _log = log == null ? _NullLog() : log;
_disposeHandler = disposeHandler;
streamClosed?.then((_) {
if (!_onDoneCompleter.isCompleted) {
@@ -1671,7 +1672,7 @@
} else if (args == null) {
return _call(method, {'isolateId': isolateId});
} else {
- args = new Map.from(args);
+ args = Map.from(args);
if (isolateId != null) {
args['isolateId'] = isolateId;
}
@@ -1698,7 +1699,7 @@
Future<T> _call<T>(String method, [Map args]) {
String id = '${++_id}';
- Completer<T> completer = new Completer<T>();
+ Completer<T> completer = Completer<T>();
_completers[id] = completer;
_methodCalls[id] = method;
Map m = {'id': id, 'method': method};
@@ -1712,7 +1713,7 @@
/// Register a service for invocation.
void registerServiceCallback(String service, ServiceCallback cb) {
if (_services.containsKey(service)) {
- throw new Exception('Service \'${service}\' already registered');
+ throw Exception('Service \'${service}\' already registered');
}
_services[service] = cb;
}
@@ -1723,8 +1724,8 @@
if (message is String) {
_processMessageStr(message);
} else if (message is List<int>) {
- Uint8List list = new Uint8List.fromList(message);
- _processMessageByteData(new ByteData.view(list.buffer));
+ Uint8List list = Uint8List.fromList(message);
+ _processMessageByteData(ByteData.view(list.buffer));
} else if (message is ByteData) {
_processMessageByteData(message);
} else {
@@ -1736,11 +1737,11 @@
int offset = 0;
int metaSize = bytes.getUint32(offset + 4, Endian.big);
offset += 8;
- String meta = utf8.decode(new Uint8List.view(
- bytes.buffer, bytes.offsetInBytes + offset, metaSize));
+ String meta = utf8.decode(
+ Uint8List.view(bytes.buffer, bytes.offsetInBytes + offset, metaSize));
offset += metaSize;
- ByteData data = new ByteData.view(bytes.buffer,
- bytes.offsetInBytes + offset, bytes.lengthInBytes - offset);
+ ByteData data = ByteData.view(bytes.buffer, bytes.offsetInBytes + offset,
+ bytes.lengthInBytes - offset);
dynamic map = jsonDecode(meta);
if (map != null && map['method'] == 'streamNotify') {
String streamId = map['params']['streamId'];
@@ -1842,8 +1843,7 @@
class RPCError {
static RPCError parse(String callingMethod, dynamic json) {
- return new RPCError(
- callingMethod, json['code'], json['message'], json['data']);
+ return RPCError(callingMethod, json['code'], json['message'], json['data']);
}
final String callingMethod;
@@ -1867,7 +1867,7 @@
/// An `ExtensionData` is an arbitrary map that can have any contents.
class ExtensionData {
static ExtensionData parse(Map json) =>
- json == null ? null : new ExtensionData._fromJson(json);
+ json == null ? null : ExtensionData._fromJson(json);
final Map data;
@@ -2182,7 +2182,7 @@
class AllocationProfile extends Response {
static AllocationProfile parse(Map<String, dynamic> json) =>
- json == null ? null : new AllocationProfile._fromJson(json);
+ json == null ? null : AllocationProfile._fromJson(json);
/// Allocation information for all class types.
List<ClassHeapStats> members;
@@ -2202,11 +2202,15 @@
@optional
int dateLastServiceGC;
- AllocationProfile();
-
+ AllocationProfile({
+ @required this.members,
+ @required this.memoryUsage,
+ this.dateLastAccumulatorReset,
+ this.dateLastServiceGC,
+ });
AllocationProfile._fromJson(Map<String, dynamic> json)
: super._fromJson(json) {
- members = new List<ClassHeapStats>.from(
+ members = List<ClassHeapStats>.from(
createServiceObject(json['members'], const ['ClassHeapStats']));
memoryUsage =
createServiceObject(json['memoryUsage'], const ['MemoryUsage']);
@@ -2245,15 +2249,17 @@
/// `BeingInitialized` [Sentinel].
class BoundField {
static BoundField parse(Map<String, dynamic> json) =>
- json == null ? null : new BoundField._fromJson(json);
+ json == null ? null : BoundField._fromJson(json);
FieldRef decl;
/// [value] can be one of [InstanceRef] or [Sentinel].
dynamic value;
- BoundField();
-
+ BoundField({
+ @required this.decl,
+ @required this.value,
+ });
BoundField._fromJson(Map<String, dynamic> json) {
decl = createServiceObject(json['decl'], const ['FieldRef']);
value =
@@ -2285,7 +2291,7 @@
/// the `OptimizedOut` [Sentinel].
class BoundVariable extends Response {
static BoundVariable parse(Map<String, dynamic> json) =>
- json == null ? null : new BoundVariable._fromJson(json);
+ json == null ? null : BoundVariable._fromJson(json);
String name;
@@ -2301,8 +2307,13 @@
/// The last token position where this variable is visible to the scope.
int scopeEndTokenPos;
- BoundVariable();
-
+ BoundVariable({
+ @required this.name,
+ @required this.value,
+ @required this.declarationTokenPos,
+ @required this.scopeStartTokenPos,
+ @required this.scopeEndTokenPos,
+ });
BoundVariable._fromJson(Map<String, dynamic> json) : super._fromJson(json) {
name = json['name'];
value = createServiceObject(
@@ -2339,7 +2350,7 @@
/// library).
class Breakpoint extends Obj {
static Breakpoint parse(Map<String, dynamic> json) =>
- json == null ? null : new Breakpoint._fromJson(json);
+ json == null ? null : Breakpoint._fromJson(json);
/// A number identifying this breakpoint to the user.
int breakpointNumber;
@@ -2358,8 +2369,12 @@
/// [location] can be one of [SourceLocation] or [UnresolvedSourceLocation].
dynamic location;
- Breakpoint();
-
+ Breakpoint({
+ @required this.breakpointNumber,
+ @required this.resolved,
+ @required this.location,
+ this.isSyntheticAsyncContinuation,
+ });
Breakpoint._fromJson(Map<String, dynamic> json) : super._fromJson(json) {
breakpointNumber = json['breakpointNumber'];
resolved = json['resolved'];
@@ -2394,13 +2409,14 @@
/// `ClassRef` is a reference to a `Class`.
class ClassRef extends ObjRef {
static ClassRef parse(Map<String, dynamic> json) =>
- json == null ? null : new ClassRef._fromJson(json);
+ json == null ? null : ClassRef._fromJson(json);
/// The name of this class.
String name;
- ClassRef();
-
+ ClassRef({
+ @required this.name,
+ });
ClassRef._fromJson(Map<String, dynamic> json) : super._fromJson(json) {
name = json['name'];
}
@@ -2425,7 +2441,7 @@
/// A `Class` provides information about a Dart language class.
class Class extends Obj {
static Class parse(Map<String, dynamic> json) =>
- json == null ? null : new Class._fromJson(json);
+ json == null ? null : Class._fromJson(json);
/// The name of this class.
String name;
@@ -2478,8 +2494,21 @@
/// A list of subclasses of this class.
List<ClassRef> subclasses;
- Class();
-
+ Class({
+ @required this.name,
+ @required this.isAbstract,
+ @required this.isConst,
+ @required this.library,
+ @required this.interfaces,
+ @required this.fields,
+ @required this.functions,
+ @required this.subclasses,
+ this.error,
+ this.location,
+ this.superClass,
+ this.superType,
+ this.mixin,
+ });
Class._fromJson(Map<String, dynamic> json) : super._fromJson(json) {
name = json['name'];
error = createServiceObject(json['error'], const ['ErrorRef']);
@@ -2489,14 +2518,14 @@
location = createServiceObject(json['location'], const ['SourceLocation']);
superClass = createServiceObject(json['super'], const ['ClassRef']);
superType = createServiceObject(json['superType'], const ['InstanceRef']);
- interfaces = new List<InstanceRef>.from(
+ interfaces = List<InstanceRef>.from(
createServiceObject(json['interfaces'], const ['InstanceRef']));
mixin = createServiceObject(json['mixin'], const ['InstanceRef']);
- fields = new List<FieldRef>.from(
+ fields = List<FieldRef>.from(
createServiceObject(json['fields'], const ['FieldRef']));
- functions = new List<FuncRef>.from(
+ functions = List<FuncRef>.from(
createServiceObject(json['functions'], const ['FuncRef']));
- subclasses = new List<ClassRef>.from(
+ subclasses = List<ClassRef>.from(
createServiceObject(json['subclasses'], const ['ClassRef']));
}
@@ -2531,7 +2560,7 @@
class ClassHeapStats extends Response {
static ClassHeapStats parse(Map<String, dynamic> json) =>
- json == null ? null : new ClassHeapStats._fromJson(json);
+ json == null ? null : ClassHeapStats._fromJson(json);
/// The class for which this memory information is associated.
ClassRef classRef;
@@ -2550,8 +2579,13 @@
/// The number of instances of class which are currently alive.
int instancesCurrent;
- ClassHeapStats();
-
+ ClassHeapStats({
+ @required this.classRef,
+ @required this.accumulatedSize,
+ @required this.bytesCurrent,
+ @required this.instancesAccumulated,
+ @required this.instancesCurrent,
+ });
ClassHeapStats._fromJson(Map<String, dynamic> json) : super._fromJson(json) {
classRef = createServiceObject(json['class'], const ['ClassRef']);
accumulatedSize = json['accumulatedSize'];
@@ -2581,14 +2615,15 @@
class ClassList extends Response {
static ClassList parse(Map<String, dynamic> json) =>
- json == null ? null : new ClassList._fromJson(json);
+ json == null ? null : ClassList._fromJson(json);
List<ClassRef> classes;
- ClassList();
-
+ ClassList({
+ @required this.classes,
+ });
ClassList._fromJson(Map<String, dynamic> json) : super._fromJson(json) {
- classes = new List<ClassRef>.from(
+ classes = List<ClassRef>.from(
createServiceObject(json['classes'], const ['ClassRef']));
}
@@ -2608,7 +2643,7 @@
/// `CodeRef` is a reference to a `Code` object.
class CodeRef extends ObjRef {
static CodeRef parse(Map<String, dynamic> json) =>
- json == null ? null : new CodeRef._fromJson(json);
+ json == null ? null : CodeRef._fromJson(json);
/// A name for this code object.
String name;
@@ -2616,8 +2651,10 @@
/// What kind of code object is this?
/*CodeKind*/ String kind;
- CodeRef();
-
+ CodeRef({
+ @required this.name,
+ @required this.kind,
+ });
CodeRef._fromJson(Map<String, dynamic> json) : super._fromJson(json) {
name = json['name'];
kind = json['kind'];
@@ -2645,7 +2682,7 @@
/// A `Code` object represents compiled code in the Dart VM.
class Code extends ObjRef {
static Code parse(Map<String, dynamic> json) =>
- json == null ? null : new Code._fromJson(json);
+ json == null ? null : Code._fromJson(json);
/// A name for this code object.
String name;
@@ -2653,8 +2690,10 @@
/// What kind of code object is this?
/*CodeKind*/ String kind;
- Code();
-
+ Code({
+ @required this.name,
+ @required this.kind,
+ });
Code._fromJson(Map<String, dynamic> json) : super._fromJson(json) {
name = json['name'];
kind = json['kind'];
@@ -2681,13 +2720,14 @@
class ContextRef extends ObjRef {
static ContextRef parse(Map<String, dynamic> json) =>
- json == null ? null : new ContextRef._fromJson(json);
+ json == null ? null : ContextRef._fromJson(json);
/// The number of variables in this context.
int length;
- ContextRef();
-
+ ContextRef({
+ @required this.length,
+ });
ContextRef._fromJson(Map<String, dynamic> json) : super._fromJson(json) {
length = json['length'];
}
@@ -2714,7 +2754,7 @@
/// closure.
class Context extends Obj {
static Context parse(Map<String, dynamic> json) =>
- json == null ? null : new Context._fromJson(json);
+ json == null ? null : Context._fromJson(json);
/// The number of variables in this context.
int length;
@@ -2726,12 +2766,15 @@
/// The variables in this context object.
List<ContextElement> variables;
- Context();
-
+ Context({
+ @required this.length,
+ @required this.variables,
+ this.parent,
+ });
Context._fromJson(Map<String, dynamic> json) : super._fromJson(json) {
length = json['length'];
parent = createServiceObject(json['parent'], const ['Context']);
- variables = new List<ContextElement>.from(
+ variables = List<ContextElement>.from(
createServiceObject(json['variables'], const ['ContextElement']));
}
@@ -2757,13 +2800,14 @@
class ContextElement {
static ContextElement parse(Map<String, dynamic> json) =>
- json == null ? null : new ContextElement._fromJson(json);
+ json == null ? null : ContextElement._fromJson(json);
/// [value] can be one of [InstanceRef] or [Sentinel].
dynamic value;
- ContextElement();
-
+ ContextElement({
+ @required this.value,
+ });
ContextElement._fromJson(Map<String, dynamic> json) {
value =
createServiceObject(json['value'], const ['InstanceRef', 'Sentinel']);
@@ -2783,7 +2827,7 @@
/// See [getCpuSamples] and [CpuSample].
class CpuSamples extends Response {
static CpuSamples parse(Map<String, dynamic> json) =>
- json == null ? null : new CpuSamples._fromJson(json);
+ json == null ? null : CpuSamples._fromJson(json);
/// The sampling rate for the profiler in microseconds.
int samplePeriod;
@@ -2816,8 +2860,17 @@
/// timeOriginMicros + timeExtentMicros]`
List<CpuSample> samples;
- CpuSamples();
-
+ CpuSamples({
+ @required this.samplePeriod,
+ @required this.maxStackDepth,
+ @required this.sampleCount,
+ @required this.timeSpan,
+ @required this.timeOriginMicros,
+ @required this.timeExtentMicros,
+ @required this.pid,
+ @required this.functions,
+ @required this.samples,
+ });
CpuSamples._fromJson(Map<String, dynamic> json) : super._fromJson(json) {
samplePeriod = json['samplePeriod'];
maxStackDepth = json['maxStackDepth'];
@@ -2826,9 +2879,9 @@
timeOriginMicros = json['timeOriginMicros'];
timeExtentMicros = json['timeExtentMicros'];
pid = json['pid'];
- functions = new List<ProfileFunction>.from(
+ functions = List<ProfileFunction>.from(
createServiceObject(json['functions'], const ['ProfileFunction']));
- samples = new List<CpuSample>.from(
+ samples = List<CpuSample>.from(
createServiceObject(json['samples'], const ['CpuSample']));
}
@@ -2856,7 +2909,7 @@
/// See [getCpuSamples] and [CpuSamples].
class CpuSample {
static CpuSample parse(Map<String, dynamic> json) =>
- json == null ? null : new CpuSample._fromJson(json);
+ json == null ? null : CpuSample._fromJson(json);
/// The thread ID representing the thread on which this sample was collected.
int tid;
@@ -2890,15 +2943,21 @@
/// @Function(foo())` `functions[stack[2]] = @Function(main())`
List<int> stack;
- CpuSample();
-
+ CpuSample({
+ @required this.tid,
+ @required this.timestamp,
+ @required this.stack,
+ this.vmTag,
+ this.userTag,
+ this.truncated,
+ });
CpuSample._fromJson(Map<String, dynamic> json) {
tid = json['tid'];
timestamp = json['timestamp'];
vmTag = json['vmTag'];
userTag = json['userTag'];
truncated = json['truncated'];
- stack = new List<int>.from(json['stack']);
+ stack = List<int>.from(json['stack']);
}
Map<String, dynamic> toJson() {
@@ -2921,7 +2980,7 @@
/// `ErrorRef` is a reference to an `Error`.
class ErrorRef extends ObjRef {
static ErrorRef parse(Map<String, dynamic> json) =>
- json == null ? null : new ErrorRef._fromJson(json);
+ json == null ? null : ErrorRef._fromJson(json);
/// What kind of error is this?
/*ErrorKind*/ String kind;
@@ -2929,8 +2988,10 @@
/// A description of the error.
String message;
- ErrorRef();
-
+ ErrorRef({
+ @required this.kind,
+ @required this.message,
+ });
ErrorRef._fromJson(Map<String, dynamic> json) : super._fromJson(json) {
kind = json['kind'];
message = json['message'];
@@ -2959,7 +3020,7 @@
/// [rpc error].
class Error extends Obj {
static Error parse(Map<String, dynamic> json) =>
- json == null ? null : new Error._fromJson(json);
+ json == null ? null : Error._fromJson(json);
/// What kind of error is this?
/*ErrorKind*/ String kind;
@@ -2977,8 +3038,12 @@
@optional
InstanceRef stacktrace;
- Error();
-
+ Error({
+ @required this.kind,
+ @required this.message,
+ this.exception,
+ this.stacktrace,
+ });
Error._fromJson(Map<String, dynamic> json) : super._fromJson(json) {
kind = json['kind'];
message = json['message'];
@@ -3014,7 +3079,7 @@
/// For more information, see [events].
class Event extends Response {
static Event parse(Map<String, dynamic> json) =>
- json == null ? null : new Event._fromJson(json);
+ json == null ? null : Event._fromJson(json);
/// What kind of event is this?
/*EventKind*/ String kind;
@@ -3178,8 +3243,30 @@
@optional
String newValue;
- Event();
-
+ Event({
+ @required this.kind,
+ @required this.timestamp,
+ this.isolate,
+ this.vm,
+ this.breakpoint,
+ this.pauseBreakpoints,
+ this.topFrame,
+ this.exception,
+ this.bytes,
+ this.inspectee,
+ this.extensionRPC,
+ this.extensionKind,
+ this.extensionData,
+ this.timelineEvents,
+ this.atAsyncSuspension,
+ this.status,
+ this.logRecord,
+ this.service,
+ this.method,
+ this.alias,
+ this.flag,
+ this.newValue,
+ });
Event._fromJson(Map<String, dynamic> json) : super._fromJson(json) {
kind = json['kind'];
isolate = createServiceObject(json['isolate'], const ['IsolateRef']);
@@ -3188,7 +3275,7 @@
breakpoint = createServiceObject(json['breakpoint'], const ['Breakpoint']);
pauseBreakpoints = json['pauseBreakpoints'] == null
? null
- : new List<Breakpoint>.from(createServiceObject(
+ : List<Breakpoint>.from(createServiceObject(
json['pauseBreakpoints'], const ['Breakpoint']));
topFrame = createServiceObject(json['topFrame'], const ['Frame']);
exception = createServiceObject(json['exception'], const ['InstanceRef']);
@@ -3199,7 +3286,7 @@
extensionData = ExtensionData.parse(json['extensionData']);
timelineEvents = json['timelineEvents'] == null
? null
- : new List<TimelineEvent>.from(createServiceObject(
+ : List<TimelineEvent>.from(createServiceObject(
json['timelineEvents'], const ['TimelineEvent']));
atAsyncSuspension = json['atAsyncSuspension'];
status = json['status'];
@@ -3251,7 +3338,7 @@
/// An `FieldRef` is a reference to a `Field`.
class FieldRef extends ObjRef {
static FieldRef parse(Map<String, dynamic> json) =>
- json == null ? null : new FieldRef._fromJson(json);
+ json == null ? null : FieldRef._fromJson(json);
/// The name of this field.
String name;
@@ -3274,8 +3361,14 @@
/// Is this field static?
bool isStatic;
- FieldRef();
-
+ FieldRef({
+ @required this.name,
+ @required this.owner,
+ @required this.declaredType,
+ @required this.isConst,
+ @required this.isFinal,
+ @required this.isStatic,
+ });
FieldRef._fromJson(Map<String, dynamic> json) : super._fromJson(json) {
name = json['name'];
owner = createServiceObject(json['owner'], const ['ObjRef']);
@@ -3311,7 +3404,7 @@
/// A `Field` provides information about a Dart language field or variable.
class Field extends Obj {
static Field parse(Map<String, dynamic> json) =>
- json == null ? null : new Field._fromJson(json);
+ json == null ? null : Field._fromJson(json);
/// The name of this field.
String name;
@@ -3342,8 +3435,16 @@
@optional
SourceLocation location;
- Field();
-
+ Field({
+ @required this.name,
+ @required this.owner,
+ @required this.declaredType,
+ @required this.isConst,
+ @required this.isFinal,
+ @required this.isStatic,
+ this.staticValue,
+ this.location,
+ });
Field._fromJson(Map<String, dynamic> json) : super._fromJson(json) {
name = json['name'];
owner = createServiceObject(json['owner'], const ['ObjRef']);
@@ -3384,7 +3485,7 @@
/// A `Flag` represents a single VM command line flag.
class Flag {
static Flag parse(Map<String, dynamic> json) =>
- json == null ? null : new Flag._fromJson(json);
+ json == null ? null : Flag._fromJson(json);
/// The name of the flag.
String name;
@@ -3401,8 +3502,12 @@
@optional
String valueAsString;
- Flag();
-
+ Flag({
+ @required this.name,
+ @required this.comment,
+ @required this.modified,
+ this.valueAsString,
+ });
Flag._fromJson(Map<String, dynamic> json) {
name = json['name'];
comment = json['comment'];
@@ -3428,16 +3533,16 @@
/// A `FlagList` represents the complete set of VM command line flags.
class FlagList extends Response {
static FlagList parse(Map<String, dynamic> json) =>
- json == null ? null : new FlagList._fromJson(json);
+ json == null ? null : FlagList._fromJson(json);
/// A list of all flags in the VM.
List<Flag> flags;
- FlagList();
-
+ FlagList({
+ @required this.flags,
+ });
FlagList._fromJson(Map<String, dynamic> json) : super._fromJson(json) {
- flags =
- new List<Flag>.from(createServiceObject(json['flags'], const ['Flag']));
+ flags = List<Flag>.from(createServiceObject(json['flags'], const ['Flag']));
}
@override
@@ -3455,7 +3560,7 @@
class Frame extends Response {
static Frame parse(Map<String, dynamic> json) =>
- json == null ? null : new Frame._fromJson(json);
+ json == null ? null : Frame._fromJson(json);
int index;
@@ -3475,8 +3580,14 @@
/*FrameKind*/
String kind;
- Frame();
-
+ Frame({
+ @required this.index,
+ this.function,
+ this.code,
+ this.location,
+ this.vars,
+ this.kind,
+ });
Frame._fromJson(Map<String, dynamic> json) : super._fromJson(json) {
index = json['index'];
function = createServiceObject(json['function'], const ['FuncRef']);
@@ -3484,7 +3595,7 @@
location = createServiceObject(json['location'], const ['SourceLocation']);
vars = json['vars'] == null
? null
- : new List<BoundVariable>.from(
+ : List<BoundVariable>.from(
createServiceObject(json['vars'], const ['BoundVariable']));
kind = json['kind'];
}
@@ -3510,7 +3621,7 @@
/// An `FuncRef` is a reference to a `Func`.
class FuncRef extends ObjRef {
static FuncRef parse(Map<String, dynamic> json) =>
- json == null ? null : new FuncRef._fromJson(json);
+ json == null ? null : FuncRef._fromJson(json);
/// The name of this function.
String name;
@@ -3526,8 +3637,12 @@
/// Is this function const?
bool isConst;
- FuncRef();
-
+ FuncRef({
+ @required this.name,
+ @required this.owner,
+ @required this.isStatic,
+ @required this.isConst,
+ });
FuncRef._fromJson(Map<String, dynamic> json) : super._fromJson(json) {
name = json['name'];
owner = createServiceObject(
@@ -3561,7 +3676,7 @@
/// A `Func` represents a Dart language function.
class Func extends Obj {
static Func parse(Map<String, dynamic> json) =>
- json == null ? null : new Func._fromJson(json);
+ json == null ? null : Func._fromJson(json);
/// The name of this function.
String name;
@@ -3579,8 +3694,12 @@
@optional
CodeRef code;
- Func();
-
+ Func({
+ @required this.name,
+ @required this.owner,
+ this.location,
+ this.code,
+ });
Func._fromJson(Map<String, dynamic> json) : super._fromJson(json) {
name = json['name'];
owner = createServiceObject(
@@ -3613,7 +3732,7 @@
/// `InstanceRef` is a reference to an `Instance`.
class InstanceRef extends ObjRef {
static InstanceRef parse(Map<String, dynamic> json) =>
- json == null ? null : new InstanceRef._fromJson(json);
+ json == null ? null : InstanceRef._fromJson(json);
/// What kind of instance is this?
/*InstanceKind*/ String kind;
@@ -3711,8 +3830,19 @@
@optional
ContextRef closureContext;
- InstanceRef();
-
+ InstanceRef({
+ @required this.kind,
+ @required this.classRef,
+ this.valueAsString,
+ this.valueAsStringIsTruncated,
+ this.length,
+ this.name,
+ this.typeClass,
+ this.parameterizedClass,
+ this.pattern,
+ this.closureFunction,
+ this.closureContext,
+ });
InstanceRef._fromJson(Map<String, dynamic> json) : super._fromJson(json) {
kind = json['kind'];
classRef = createServiceObject(json['class'], const ['ClassRef']);
@@ -3762,7 +3892,7 @@
/// An `Instance` represents an instance of the Dart language class `Obj`.
class Instance extends Obj {
static Instance parse(Map<String, dynamic> json) =>
- json == null ? null : new Instance._fromJson(json);
+ json == null ? null : Instance._fromJson(json);
/// What kind of instance is this?
/*InstanceKind*/ String kind;
@@ -4000,8 +4130,32 @@
@optional
InstanceRef bound;
- Instance();
-
+ Instance({
+ @required this.kind,
+ @required this.classRef,
+ this.valueAsString,
+ this.valueAsStringIsTruncated,
+ this.length,
+ this.offset,
+ this.count,
+ this.name,
+ this.typeClass,
+ this.parameterizedClass,
+ this.fields,
+ this.elements,
+ this.associations,
+ this.bytes,
+ this.mirrorReferent,
+ this.pattern,
+ this.isCaseSensitive,
+ this.isMultiLine,
+ this.propertyKey,
+ this.propertyValue,
+ this.typeArguments,
+ this.parameterIndex,
+ this.targetType,
+ this.bound,
+ });
Instance._fromJson(Map<String, dynamic> json) : super._fromJson(json) {
kind = json['kind'];
classRef = createServiceObject(json['class'], const ['ClassRef']);
@@ -4016,15 +4170,15 @@
createServiceObject(json['parameterizedClass'], const ['ClassRef']);
fields = json['fields'] == null
? null
- : new List<BoundField>.from(
+ : List<BoundField>.from(
createServiceObject(json['fields'], const ['BoundField']));
elements = json['elements'] == null
? null
- : new List<dynamic>.from(
+ : List<dynamic>.from(
createServiceObject(json['elements'], const ['dynamic']));
associations = json['associations'] == null
? null
- : new List<MapAssociation>.from(
+ : List<MapAssociation>.from(
_createSpecificObject(json['associations'], MapAssociation.parse));
bytes = json['bytes'];
mirrorReferent =
@@ -4090,7 +4244,7 @@
/// `IsolateRef` is a reference to an `Isolate` object.
class IsolateRef extends Response {
static IsolateRef parse(Map<String, dynamic> json) =>
- json == null ? null : new IsolateRef._fromJson(json);
+ json == null ? null : IsolateRef._fromJson(json);
/// The id which is passed to the getIsolate RPC to load this isolate.
String id;
@@ -4101,8 +4255,11 @@
/// A name identifying this isolate. Not guaranteed to be unique.
String name;
- IsolateRef();
-
+ IsolateRef({
+ @required this.id,
+ @required this.number,
+ @required this.name,
+ });
IsolateRef._fromJson(Map<String, dynamic> json) : super._fromJson(json) {
id = json['id'];
number = json['number'];
@@ -4132,7 +4289,7 @@
/// An `Isolate` object provides information about one isolate in the VM.
class Isolate extends Response {
static Isolate parse(Map<String, dynamic> json) =>
- json == null ? null : new Isolate._fromJson(json);
+ json == null ? null : Isolate._fromJson(json);
/// The id which is passed to the getIsolate RPC to reload this isolate.
String id;
@@ -4187,8 +4344,22 @@
@optional
List<String> extensionRPCs;
- Isolate();
-
+ Isolate({
+ @required this.id,
+ @required this.number,
+ @required this.name,
+ @required this.startTime,
+ @required this.runnable,
+ @required this.livePorts,
+ @required this.pauseOnExit,
+ @required this.pauseEvent,
+ @required this.libraries,
+ @required this.breakpoints,
+ @required this.exceptionPauseMode,
+ this.rootLib,
+ this.error,
+ this.extensionRPCs,
+ });
Isolate._fromJson(Map<String, dynamic> json) : super._fromJson(json) {
id = json['id'];
number = json['number'];
@@ -4199,15 +4370,15 @@
pauseOnExit = json['pauseOnExit'];
pauseEvent = createServiceObject(json['pauseEvent'], const ['Event']);
rootLib = createServiceObject(json['rootLib'], const ['LibraryRef']);
- libraries = new List<LibraryRef>.from(
+ libraries = List<LibraryRef>.from(
createServiceObject(json['libraries'], const ['LibraryRef']));
- breakpoints = new List<Breakpoint>.from(
+ breakpoints = List<Breakpoint>.from(
createServiceObject(json['breakpoints'], const ['Breakpoint']));
error = createServiceObject(json['error'], const ['Error']);
exceptionPauseMode = json['exceptionPauseMode'];
extensionRPCs = json['extensionRPCs'] == null
? null
- : new List<String>.from(json['extensionRPCs']);
+ : List<String>.from(json['extensionRPCs']);
}
@override
@@ -4244,16 +4415,17 @@
/// See [getInboundReferences].
class InboundReferences extends Response {
static InboundReferences parse(Map<String, dynamic> json) =>
- json == null ? null : new InboundReferences._fromJson(json);
+ json == null ? null : InboundReferences._fromJson(json);
/// An array of inbound references to an object.
List<InboundReference> references;
- InboundReferences();
-
+ InboundReferences({
+ @required this.references,
+ });
InboundReferences._fromJson(Map<String, dynamic> json)
: super._fromJson(json) {
- references = new List<InboundReference>.from(
+ references = List<InboundReference>.from(
createServiceObject(json['references'], const ['InboundReference']));
}
@@ -4274,7 +4446,7 @@
/// See [getInboundReferences].
class InboundReference {
static InboundReference parse(Map<String, dynamic> json) =>
- json == null ? null : new InboundReference._fromJson(json);
+ json == null ? null : InboundReference._fromJson(json);
/// The object holding the inbound reference.
ObjRef source;
@@ -4289,8 +4461,11 @@
@optional
FieldRef parentField;
- InboundReference();
-
+ InboundReference({
+ @required this.source,
+ this.parentListIndex,
+ this.parentField,
+ });
InboundReference._fromJson(Map<String, dynamic> json) {
source = createServiceObject(json['source'], const ['ObjRef']);
parentListIndex = json['parentListIndex'];
@@ -4313,7 +4488,7 @@
/// See [getInstances].
class InstanceSet extends Response {
static InstanceSet parse(Map<String, dynamic> json) =>
- json == null ? null : new InstanceSet._fromJson(json);
+ json == null ? null : InstanceSet._fromJson(json);
/// The number of instances of the requested type currently allocated.
int totalCount;
@@ -4321,11 +4496,13 @@
/// An array of instances of the requested type.
List<ObjRef> instances;
- InstanceSet();
-
+ InstanceSet({
+ @required this.totalCount,
+ @required this.instances,
+ });
InstanceSet._fromJson(Map<String, dynamic> json) : super._fromJson(json) {
totalCount = json['totalCount'];
- instances = new List<ObjRef>.from(createServiceObject(
+ instances = List<ObjRef>.from(createServiceObject(
json['instances'] ?? json['samples'], const ['ObjRef']));
}
@@ -4347,7 +4524,7 @@
/// `LibraryRef` is a reference to a `Library`.
class LibraryRef extends ObjRef {
static LibraryRef parse(Map<String, dynamic> json) =>
- json == null ? null : new LibraryRef._fromJson(json);
+ json == null ? null : LibraryRef._fromJson(json);
/// The name of this library.
String name;
@@ -4355,8 +4532,10 @@
/// The uri of this library.
String uri;
- LibraryRef();
-
+ LibraryRef({
+ @required this.name,
+ @required this.uri,
+ });
LibraryRef._fromJson(Map<String, dynamic> json) : super._fromJson(json) {
name = json['name'];
uri = json['uri'];
@@ -4386,7 +4565,7 @@
/// See [setLibraryDebuggable].
class Library extends Obj {
static Library parse(Map<String, dynamic> json) =>
- json == null ? null : new Library._fromJson(json);
+ json == null ? null : Library._fromJson(json);
/// The name of this library.
String name;
@@ -4412,21 +4591,29 @@
/// A list of all classes in this library.
List<ClassRef> classes;
- Library();
-
+ Library({
+ @required this.name,
+ @required this.uri,
+ @required this.debuggable,
+ @required this.dependencies,
+ @required this.scripts,
+ @required this.variables,
+ @required this.functions,
+ @required this.classes,
+ });
Library._fromJson(Map<String, dynamic> json) : super._fromJson(json) {
name = json['name'];
uri = json['uri'];
debuggable = json['debuggable'];
- dependencies = new List<LibraryDependency>.from(
+ dependencies = List<LibraryDependency>.from(
_createSpecificObject(json['dependencies'], LibraryDependency.parse));
- scripts = new List<ScriptRef>.from(
+ scripts = List<ScriptRef>.from(
createServiceObject(json['scripts'], const ['ScriptRef']));
- variables = new List<FieldRef>.from(
+ variables = List<FieldRef>.from(
createServiceObject(json['variables'], const ['FieldRef']));
- functions = new List<FuncRef>.from(
+ functions = List<FuncRef>.from(
createServiceObject(json['functions'], const ['FuncRef']));
- classes = new List<ClassRef>.from(
+ classes = List<ClassRef>.from(
createServiceObject(json['classes'], const ['ClassRef']));
}
@@ -4457,7 +4644,7 @@
/// A `LibraryDependency` provides information about an import or export.
class LibraryDependency {
static LibraryDependency parse(Map<String, dynamic> json) =>
- json == null ? null : new LibraryDependency._fromJson(json);
+ json == null ? null : LibraryDependency._fromJson(json);
/// Is this dependency an import (rather than an export)?
bool isImport;
@@ -4471,8 +4658,12 @@
/// The library being imported or exported.
LibraryRef target;
- LibraryDependency();
-
+ LibraryDependency({
+ @required this.isImport,
+ @required this.isDeferred,
+ @required this.prefix,
+ @required this.target,
+ });
LibraryDependency._fromJson(Map<String, dynamic> json) {
isImport = json['isImport'];
isDeferred = json['isDeferred'];
@@ -4498,7 +4689,7 @@
class LogRecord extends Response {
static LogRecord parse(Map<String, dynamic> json) =>
- json == null ? null : new LogRecord._fromJson(json);
+ json == null ? null : LogRecord._fromJson(json);
/// The log message.
InstanceRef message;
@@ -4527,8 +4718,16 @@
/// A stack trace associated with this log event.
InstanceRef stackTrace;
- LogRecord();
-
+ LogRecord({
+ @required this.message,
+ @required this.time,
+ @required this.level,
+ @required this.sequenceNumber,
+ @required this.loggerName,
+ @required this.zone,
+ @required this.error,
+ @required this.stackTrace,
+ });
LogRecord._fromJson(Map<String, dynamic> json) : super._fromJson(json) {
message = createServiceObject(json['message'], const ['InstanceRef']);
time = json['time'];
@@ -4562,7 +4761,7 @@
class MapAssociation {
static MapAssociation parse(Map<String, dynamic> json) =>
- json == null ? null : new MapAssociation._fromJson(json);
+ json == null ? null : MapAssociation._fromJson(json);
/// [key] can be one of [InstanceRef] or [Sentinel].
dynamic key;
@@ -4570,8 +4769,10 @@
/// [value] can be one of [InstanceRef] or [Sentinel].
dynamic value;
- MapAssociation();
-
+ MapAssociation({
+ @required this.key,
+ @required this.value,
+ });
MapAssociation._fromJson(Map<String, dynamic> json) {
key = createServiceObject(json['key'], const ['InstanceRef', 'Sentinel']);
value =
@@ -4594,7 +4795,7 @@
/// isolate at a given point in time.
class MemoryUsage extends Response {
static MemoryUsage parse(Map<String, dynamic> json) =>
- json == null ? null : new MemoryUsage._fromJson(json);
+ json == null ? null : MemoryUsage._fromJson(json);
/// The amount of non-Dart memory that is retained by Dart objects. For
/// example, memory associated with Dart objects through APIs such as
@@ -4612,8 +4813,11 @@
/// equal to the heap capacity.
int heapUsage;
- MemoryUsage();
-
+ MemoryUsage({
+ @required this.externalUsage,
+ @required this.heapCapacity,
+ @required this.heapUsage,
+ });
MemoryUsage._fromJson(Map<String, dynamic> json) : super._fromJson(json) {
externalUsage = json['externalUsage'];
heapCapacity = json['heapCapacity'];
@@ -4641,7 +4845,7 @@
/// function that will be invoked to handle it.
class Message extends Response {
static Message parse(Map<String, dynamic> json) =>
- json == null ? null : new Message._fromJson(json);
+ json == null ? null : Message._fromJson(json);
/// The index in the isolate's message queue. The 0th message being the next
/// message to be processed.
@@ -4665,8 +4869,14 @@
@optional
SourceLocation location;
- Message();
-
+ Message({
+ @required this.index,
+ @required this.name,
+ @required this.messageObjectId,
+ @required this.size,
+ this.handler,
+ this.location,
+ });
Message._fromJson(Map<String, dynamic> json) : super._fromJson(json) {
index = json['index'];
name = json['name'];
@@ -4700,13 +4910,14 @@
/// samples. See [CpuSamples];
class NativeFunction {
static NativeFunction parse(Map<String, dynamic> json) =>
- json == null ? null : new NativeFunction._fromJson(json);
+ json == null ? null : NativeFunction._fromJson(json);
/// The name of the native function this object represents.
String name;
- NativeFunction();
-
+ NativeFunction({
+ @required this.name,
+ });
NativeFunction._fromJson(Map<String, dynamic> json) {
name = json['name'];
}
@@ -4725,14 +4936,15 @@
/// `NullValRef` is a reference to an a `NullVal`.
class NullValRef extends InstanceRef {
static NullValRef parse(Map<String, dynamic> json) =>
- json == null ? null : new NullValRef._fromJson(json);
+ json == null ? null : NullValRef._fromJson(json);
/// Always 'null'.
@override
String valueAsString;
- NullValRef();
-
+ NullValRef({
+ @required this.valueAsString,
+ });
NullValRef._fromJson(Map<String, dynamic> json) : super._fromJson(json) {
valueAsString = json['valueAsString'];
}
@@ -4759,14 +4971,15 @@
/// A `NullVal` object represents the Dart language value null.
class NullVal extends Instance {
static NullVal parse(Map<String, dynamic> json) =>
- json == null ? null : new NullVal._fromJson(json);
+ json == null ? null : NullVal._fromJson(json);
/// Always 'null'.
@override
String valueAsString;
- NullVal();
-
+ NullVal({
+ @required this.valueAsString,
+ });
NullVal._fromJson(Map<String, dynamic> json) : super._fromJson(json) {
valueAsString = json['valueAsString'];
}
@@ -4793,7 +5006,7 @@
/// `ObjRef` is a reference to a `Obj`.
class ObjRef extends Response {
static ObjRef parse(Map<String, dynamic> json) =>
- json == null ? null : new ObjRef._fromJson(json);
+ json == null ? null : ObjRef._fromJson(json);
/// A unique identifier for an Object. Passed to the getObject RPC to load
/// this Object.
@@ -4805,8 +5018,10 @@
@optional
bool fixedId;
- ObjRef();
-
+ ObjRef({
+ @required this.id,
+ this.fixedId,
+ });
ObjRef._fromJson(Map<String, dynamic> json) : super._fromJson(json) {
id = json['id'];
fixedId = json['fixedId'];
@@ -4833,7 +5048,7 @@
/// An `Obj` is a persistent object that is owned by some isolate.
class Obj extends Response {
static Obj parse(Map<String, dynamic> json) =>
- json == null ? null : new Obj._fromJson(json);
+ json == null ? null : Obj._fromJson(json);
/// A unique identifier for an Object. Passed to the getObject RPC to reload
/// this Object.
@@ -4868,8 +5083,12 @@
@optional
int size;
- Obj();
-
+ Obj({
+ @required this.id,
+ this.fixedId,
+ this.classRef,
+ this.size,
+ });
Obj._fromJson(Map<String, dynamic> json) : super._fromJson(json) {
id = json['id'];
fixedId = json['fixedId'];
@@ -4903,7 +5122,7 @@
/// See [CpuSamples].
class ProfileFunction {
static ProfileFunction parse(Map<String, dynamic> json) =>
- json == null ? null : new ProfileFunction._fromJson(json);
+ json == null ? null : ProfileFunction._fromJson(json);
/// The kind of function this object represents.
String kind;
@@ -4921,8 +5140,13 @@
/// The function captured during profiling.
dynamic function;
- ProfileFunction();
-
+ ProfileFunction({
+ @required this.kind,
+ @required this.inclusiveTicks,
+ @required this.exclusiveTicks,
+ @required this.resolvedUrl,
+ @required this.function,
+ });
ProfileFunction._fromJson(Map<String, dynamic> json) {
kind = json['kind'];
inclusiveTicks = json['inclusiveTicks'];
@@ -4950,13 +5174,14 @@
class ReloadReport extends Response {
static ReloadReport parse(Map<String, dynamic> json) =>
- json == null ? null : new ReloadReport._fromJson(json);
+ json == null ? null : ReloadReport._fromJson(json);
/// Did the reload succeed or fail?
bool success;
- ReloadReport();
-
+ ReloadReport({
+ @required this.success,
+ });
ReloadReport._fromJson(Map<String, dynamic> json) : super._fromJson(json) {
success = json['success'];
}
@@ -4977,7 +5202,7 @@
/// See [RetainingPath].
class RetainingObject {
static RetainingObject parse(Map<String, dynamic> json) =>
- json == null ? null : new RetainingObject._fromJson(json);
+ json == null ? null : RetainingObject._fromJson(json);
/// An object that is part of a retaining path.
ObjRef value;
@@ -4994,8 +5219,12 @@
@optional
String parentField;
- RetainingObject();
-
+ RetainingObject({
+ @required this.value,
+ this.parentListIndex,
+ this.parentMapKey,
+ this.parentField,
+ });
RetainingObject._fromJson(Map<String, dynamic> json) {
value = createServiceObject(json['value'], const ['ObjRef']);
parentListIndex = json['parentListIndex'];
@@ -5020,7 +5249,7 @@
/// See [getRetainingPath].
class RetainingPath extends Response {
static RetainingPath parse(Map<String, dynamic> json) =>
- json == null ? null : new RetainingPath._fromJson(json);
+ json == null ? null : RetainingPath._fromJson(json);
/// The length of the retaining path.
int length;
@@ -5033,12 +5262,15 @@
/// The chain of objects which make up the retaining path.
List<RetainingObject> elements;
- RetainingPath();
-
+ RetainingPath({
+ @required this.length,
+ @required this.gcRootType,
+ @required this.elements,
+ });
RetainingPath._fromJson(Map<String, dynamic> json) : super._fromJson(json) {
length = json['length'];
gcRootType = json['gcRootType'];
- elements = new List<RetainingObject>.from(
+ elements = List<RetainingObject>.from(
createServiceObject(json['elements'], const ['RetainingObject']));
}
@@ -5064,7 +5296,7 @@
/// [type] of response has been provided.
class Response {
static Response parse(Map<String, dynamic> json) =>
- json == null ? null : new Response._fromJson(json);
+ json == null ? null : Response._fromJson(json);
Map<String, dynamic> json;
@@ -5072,8 +5304,9 @@
/// allows the client distinguish between different kinds of responses.
String type;
- Response();
-
+ Response({
+ @required this.type,
+ });
Response._fromJson(this.json) {
type = json['type'];
}
@@ -5093,7 +5326,7 @@
/// not represent a problematic condition. They are normal.
class Sentinel extends Response {
static Sentinel parse(Map<String, dynamic> json) =>
- json == null ? null : new Sentinel._fromJson(json);
+ json == null ? null : Sentinel._fromJson(json);
/// What kind of sentinel is this?
/*SentinelKind*/ String kind;
@@ -5101,8 +5334,10 @@
/// A reasonable string representation of this sentinel.
String valueAsString;
- Sentinel();
-
+ Sentinel({
+ @required this.kind,
+ @required this.valueAsString,
+ });
Sentinel._fromJson(Map<String, dynamic> json) : super._fromJson(json) {
kind = json['kind'];
valueAsString = json['valueAsString'];
@@ -5126,13 +5361,14 @@
/// `ScriptRef` is a reference to a `Script`.
class ScriptRef extends ObjRef {
static ScriptRef parse(Map<String, dynamic> json) =>
- json == null ? null : new ScriptRef._fromJson(json);
+ json == null ? null : ScriptRef._fromJson(json);
/// The uri from which this script was loaded.
String uri;
- ScriptRef();
-
+ ScriptRef({
+ @required this.uri,
+ });
ScriptRef._fromJson(Map<String, dynamic> json) : super._fromJson(json) {
uri = json['uri'];
}
@@ -5186,7 +5422,7 @@
/// 102 | 2 | 7
class Script extends Obj {
static Script parse(Map<String, dynamic> json) =>
- json == null ? null : new Script._fromJson(json);
+ json == null ? null : Script._fromJson(json);
/// The uri from which this script was loaded.
String uri;
@@ -5210,8 +5446,14 @@
@optional
List<List<int>> tokenPosTable;
- Script();
-
+ Script({
+ @required this.uri,
+ @required this.library,
+ this.lineOffset,
+ this.columnOffset,
+ this.source,
+ this.tokenPosTable,
+ });
Script._fromJson(Map<String, dynamic> json) : super._fromJson(json) {
uri = json['uri'];
library = createServiceObject(json['library'], const ['LibraryRef']);
@@ -5220,8 +5462,8 @@
source = json['source'];
tokenPosTable = json['tokenPosTable'] == null
? null
- : new List<List<int>>.from(json['tokenPosTable']
- .map((dynamic list) => new List<int>.from(list)));
+ : List<List<int>>.from(
+ json['tokenPosTable'].map((dynamic list) => List<int>.from(list)));
}
@override
@@ -5250,14 +5492,15 @@
class ScriptList extends Response {
static ScriptList parse(Map<String, dynamic> json) =>
- json == null ? null : new ScriptList._fromJson(json);
+ json == null ? null : ScriptList._fromJson(json);
List<ScriptRef> scripts;
- ScriptList();
-
+ ScriptList({
+ @required this.scripts,
+ });
ScriptList._fromJson(Map<String, dynamic> json) : super._fromJson(json) {
- scripts = new List<ScriptRef>.from(
+ scripts = List<ScriptRef>.from(
createServiceObject(json['scripts'], const ['ScriptRef']));
}
@@ -5278,7 +5521,7 @@
/// script.
class SourceLocation extends Response {
static SourceLocation parse(Map<String, dynamic> json) =>
- json == null ? null : new SourceLocation._fromJson(json);
+ json == null ? null : SourceLocation._fromJson(json);
/// The script containing the source location.
ScriptRef script;
@@ -5290,8 +5533,11 @@
@optional
int endTokenPos;
- SourceLocation();
-
+ SourceLocation({
+ @required this.script,
+ @required this.tokenPos,
+ this.endTokenPos,
+ });
SourceLocation._fromJson(Map<String, dynamic> json) : super._fromJson(json) {
script = createServiceObject(json['script'], const ['ScriptRef']);
tokenPos = json['tokenPos'];
@@ -5318,7 +5564,7 @@
/// locations in an isolate.
class SourceReport extends Response {
static SourceReport parse(Map<String, dynamic> json) =>
- json == null ? null : new SourceReport._fromJson(json);
+ json == null ? null : SourceReport._fromJson(json);
/// A list of ranges in the program source. These ranges correspond to ranges
/// of executable code in the user's program (functions, methods,
@@ -5333,12 +5579,14 @@
/// A list of scripts, referenced by index in the report's ranges.
List<ScriptRef> scripts;
- SourceReport();
-
+ SourceReport({
+ @required this.ranges,
+ @required this.scripts,
+ });
SourceReport._fromJson(Map<String, dynamic> json) : super._fromJson(json) {
- ranges = new List<SourceReportRange>.from(
+ ranges = List<SourceReportRange>.from(
_createSpecificObject(json['ranges'], SourceReportRange.parse));
- scripts = new List<ScriptRef>.from(
+ scripts = List<ScriptRef>.from(
createServiceObject(json['scripts'], const ['ScriptRef']));
}
@@ -5364,7 +5612,7 @@
/// will not contain a `type` property.
class SourceReportCoverage {
static SourceReportCoverage parse(Map<String, dynamic> json) =>
- json == null ? null : new SourceReportCoverage._fromJson(json);
+ json == null ? null : SourceReportCoverage._fromJson(json);
/// A list of token positions in a SourceReportRange which have been executed.
/// The list is sorted.
@@ -5374,11 +5622,13 @@
/// executed. The list is sorted.
List<int> misses;
- SourceReportCoverage();
-
+ SourceReportCoverage({
+ @required this.hits,
+ @required this.misses,
+ });
SourceReportCoverage._fromJson(Map<String, dynamic> json) {
- hits = new List<int>.from(json['hits']);
- misses = new List<int>.from(json['misses']);
+ hits = List<int>.from(json['hits']);
+ misses = List<int>.from(json['misses']);
}
Map<String, dynamic> toJson() {
@@ -5402,7 +5652,7 @@
/// not contain a `type` property.
class SourceReportRange {
static SourceReportRange parse(Map<String, dynamic> json) =>
- json == null ? null : new SourceReportRange._fromJson(json);
+ json == null ? null : SourceReportRange._fromJson(json);
/// An index into the script table of the SourceReport, indicating which
/// script contains this range of code.
@@ -5434,8 +5684,15 @@
@optional
List<int> possibleBreakpoints;
- SourceReportRange();
-
+ SourceReportRange({
+ @required this.scriptIndex,
+ @required this.startPos,
+ @required this.endPos,
+ @required this.compiled,
+ this.error,
+ this.coverage,
+ this.possibleBreakpoints,
+ });
SourceReportRange._fromJson(Map<String, dynamic> json) {
scriptIndex = json['scriptIndex'];
startPos = json['startPos'];
@@ -5446,7 +5703,7 @@
_createSpecificObject(json['coverage'], SourceReportCoverage.parse);
possibleBreakpoints = json['possibleBreakpoints'] == null
? null
- : new List<int>.from(json['possibleBreakpoints']);
+ : List<int>.from(json['possibleBreakpoints']);
}
Map<String, dynamic> toJson() {
@@ -5471,7 +5728,7 @@
class Stack extends Response {
static Stack parse(Map<String, dynamic> json) =>
- json == null ? null : new Stack._fromJson(json);
+ json == null ? null : Stack._fromJson(json);
List<Frame> frames;
@@ -5483,20 +5740,24 @@
List<Message> messages;
- Stack();
-
+ Stack({
+ @required this.frames,
+ @required this.messages,
+ this.asyncCausalFrames,
+ this.awaiterFrames,
+ });
Stack._fromJson(Map<String, dynamic> json) : super._fromJson(json) {
- frames = new List<Frame>.from(
- createServiceObject(json['frames'], const ['Frame']));
+ frames =
+ List<Frame>.from(createServiceObject(json['frames'], const ['Frame']));
asyncCausalFrames = json['asyncCausalFrames'] == null
? null
- : new List<Frame>.from(
+ : List<Frame>.from(
createServiceObject(json['asyncCausalFrames'], const ['Frame']));
awaiterFrames = json['awaiterFrames'] == null
? null
- : new List<Frame>.from(
+ : List<Frame>.from(
createServiceObject(json['awaiterFrames'], const ['Frame']));
- messages = new List<Message>.from(
+ messages = List<Message>.from(
createServiceObject(json['messages'], const ['Message']));
}
@@ -5523,10 +5784,9 @@
/// successfully.
class Success extends Response {
static Success parse(Map<String, dynamic> json) =>
- json == null ? null : new Success._fromJson(json);
+ json == null ? null : Success._fromJson(json);
Success();
-
Success._fromJson(Map<String, dynamic> json) : super._fromJson(json);
@override
@@ -5541,7 +5801,7 @@
class Timeline extends Response {
static Timeline parse(Map<String, dynamic> json) =>
- json == null ? null : new Timeline._fromJson(json);
+ json == null ? null : Timeline._fromJson(json);
/// A list of timeline events.
List<TimelineEvent> traceEvents;
@@ -5552,10 +5812,13 @@
/// The duration of time covered by the timeline.
int timeExtentMicros;
- Timeline();
-
+ Timeline({
+ @required this.traceEvents,
+ @required this.timeOriginMicros,
+ @required this.timeExtentMicros,
+ });
Timeline._fromJson(Map<String, dynamic> json) : super._fromJson(json) {
- traceEvents = new List<TimelineEvent>.from(
+ traceEvents = List<TimelineEvent>.from(
createServiceObject(json['traceEvents'], const ['TimelineEvent']));
timeOriginMicros = json['timeOriginMicros'];
timeExtentMicros = json['timeExtentMicros'];
@@ -5582,10 +5845,9 @@
/// event.
class TimelineEvent {
static TimelineEvent parse(Map<String, dynamic> json) =>
- json == null ? null : new TimelineEvent._fromJson(json);
+ json == null ? null : TimelineEvent._fromJson(json);
TimelineEvent();
-
TimelineEvent._fromJson(Map<String, dynamic> json);
Map<String, dynamic> toJson() {
@@ -5598,7 +5860,7 @@
class TimelineFlags extends Response {
static TimelineFlags parse(Map<String, dynamic> json) =>
- json == null ? null : new TimelineFlags._fromJson(json);
+ json == null ? null : TimelineFlags._fromJson(json);
/// The name of the recorder currently in use. Recorder types include, but are
/// not limited to: Callback, Endless, Fuchsia, Ring, Startup, and Systrace.
@@ -5611,12 +5873,15 @@
/// The list of timeline streams that are currently enabled.
List<String> recordedStreams;
- TimelineFlags();
-
+ TimelineFlags({
+ @required this.recorderName,
+ @required this.availableStreams,
+ @required this.recordedStreams,
+ });
TimelineFlags._fromJson(Map<String, dynamic> json) : super._fromJson(json) {
recorderName = json['recorderName'];
- availableStreams = new List<String>.from(json['availableStreams']);
- recordedStreams = new List<String>.from(json['recordedStreams']);
+ availableStreams = List<String>.from(json['availableStreams']);
+ recordedStreams = List<String>.from(json['recordedStreams']);
}
@override
@@ -5638,13 +5903,14 @@
class Timestamp extends Response {
static Timestamp parse(Map<String, dynamic> json) =>
- json == null ? null : new Timestamp._fromJson(json);
+ json == null ? null : Timestamp._fromJson(json);
/// A timestamp in microseconds since epoch.
int timestamp;
- Timestamp();
-
+ Timestamp({
+ @required this.timestamp,
+ });
Timestamp._fromJson(Map<String, dynamic> json) : super._fromJson(json) {
timestamp = json['timestamp'];
}
@@ -5665,13 +5931,14 @@
/// `TypeArgumentsRef` is a reference to a `TypeArguments` object.
class TypeArgumentsRef extends ObjRef {
static TypeArgumentsRef parse(Map<String, dynamic> json) =>
- json == null ? null : new TypeArgumentsRef._fromJson(json);
+ json == null ? null : TypeArgumentsRef._fromJson(json);
/// A name for this type argument list.
String name;
- TypeArgumentsRef();
-
+ TypeArgumentsRef({
+ @required this.name,
+ });
TypeArgumentsRef._fromJson(Map<String, dynamic> json)
: super._fromJson(json) {
name = json['name'];
@@ -5699,7 +5966,7 @@
/// instantiated generic type.
class TypeArguments extends Obj {
static TypeArguments parse(Map<String, dynamic> json) =>
- json == null ? null : new TypeArguments._fromJson(json);
+ json == null ? null : TypeArguments._fromJson(json);
/// A name for this type argument list.
String name;
@@ -5710,11 +5977,13 @@
/// BoundedType.
List<InstanceRef> types;
- TypeArguments();
-
+ TypeArguments({
+ @required this.name,
+ @required this.types,
+ });
TypeArguments._fromJson(Map<String, dynamic> json) : super._fromJson(json) {
name = json['name'];
- types = new List<InstanceRef>.from(
+ types = List<InstanceRef>.from(
createServiceObject(json['types'], const ['InstanceRef']));
}
@@ -5749,7 +6018,7 @@
/// with a specific column number.
class UnresolvedSourceLocation extends Response {
static UnresolvedSourceLocation parse(Map<String, dynamic> json) =>
- json == null ? null : new UnresolvedSourceLocation._fromJson(json);
+ json == null ? null : UnresolvedSourceLocation._fromJson(json);
/// The script containing the source location if the script has been loaded.
@optional
@@ -5775,8 +6044,13 @@
@optional
int column;
- UnresolvedSourceLocation();
-
+ UnresolvedSourceLocation({
+ this.script,
+ this.scriptUri,
+ this.tokenPos,
+ this.line,
+ this.column,
+ });
UnresolvedSourceLocation._fromJson(Map<String, dynamic> json)
: super._fromJson(json) {
script = createServiceObject(json['script'], const ['ScriptRef']);
@@ -5804,7 +6078,7 @@
/// See [Versioning].
class Version extends Response {
static Version parse(Map<String, dynamic> json) =>
- json == null ? null : new Version._fromJson(json);
+ json == null ? null : Version._fromJson(json);
/// The major version number is incremented when the protocol is changed in a
/// potentially incompatible way.
@@ -5814,8 +6088,10 @@
/// backwards compatible way.
int minor;
- Version();
-
+ Version({
+ @required this.major,
+ @required this.minor,
+ });
Version._fromJson(Map<String, dynamic> json) : super._fromJson(json) {
major = json['major'];
minor = json['minor'];
@@ -5839,13 +6115,14 @@
/// `VMRef` is a reference to a `VM` object.
class VMRef extends Response {
static VMRef parse(Map<String, dynamic> json) =>
- json == null ? null : new VMRef._fromJson(json);
+ json == null ? null : VMRef._fromJson(json);
/// A name identifying this vm. Not guaranteed to be unique.
String name;
- VMRef();
-
+ VMRef({
+ @required this.name,
+ });
VMRef._fromJson(Map<String, dynamic> json) : super._fromJson(json) {
name = json['name'];
}
@@ -5865,7 +6142,7 @@
class VM extends Response {
static VM parse(Map<String, dynamic> json) =>
- json == null ? null : new VM._fromJson(json);
+ json == null ? null : VM._fromJson(json);
/// A name identifying this vm. Not guaranteed to be unique.
String name;
@@ -5896,8 +6173,17 @@
/// A list of isolates running in the VM.
List<IsolateRef> isolates;
- VM();
-
+ VM({
+ @required this.name,
+ @required this.architectureBits,
+ @required this.hostCPU,
+ @required this.operatingSystem,
+ @required this.targetCPU,
+ @required this.version,
+ @required this.pid,
+ @required this.startTime,
+ @required this.isolates,
+ });
VM._fromJson(Map<String, dynamic> json) : super._fromJson(json) {
name = json['name'];
architectureBits = json['architectureBits'];
@@ -5907,7 +6193,7 @@
version = json['version'];
pid = json['pid'];
startTime = json['startTime'];
- isolates = new List<IsolateRef>.from(
+ isolates = List<IsolateRef>.from(
createServiceObject(json['isolates'], const ['IsolateRef']));
}
diff --git a/pkg/vm_service/pubspec.yaml b/pkg/vm_service/pubspec.yaml
index d5e62e2..af6597f 100644
--- a/pkg/vm_service/pubspec.yaml
+++ b/pkg/vm_service/pubspec.yaml
@@ -2,7 +2,7 @@
description: >-
A library to communicate with a service implementing the Dart VM
service protocol.
-version: 1.2.0
+version: 2.0.0
author: Dart Team <misc@dartlang.org>
homepage: https://github.com/dart-lang/sdk/tree/master/pkg/vm_service
diff --git a/pkg/vm_service/test/server_test.dart b/pkg/vm_service/test/server_test.dart
index 4fdee8f..62a351f 100644
--- a/pkg/vm_service/test/server_test.dart
+++ b/pkg/vm_service/test/server_test.dart
@@ -35,27 +35,29 @@
group('method delegation', () {
test('works for simple methods', () {
var request = rpcRequest("getVersion");
- var version = Version()
- ..major = 1
- ..minor = 0;
+ var version = Version(major: 1, minor: 0);
when(serviceMock.getVersion()).thenAnswer((_) => Future.value(version));
expect(responsesController.stream, emits(rpcResponse(version)));
requestsController.add(request);
});
test('works for methods with parameters', () {
- var isolate = Isolate()
- ..id = '123'
- ..number = '0'
- ..startTime = 1
- ..runnable = true
- ..livePorts = 2
- ..pauseOnExit = false
- ..pauseEvent = (Event()
- ..kind = EventKind.kResume
- ..timestamp = 3)
- ..libraries = []
- ..breakpoints = [];
+ var isolate = Isolate(
+ name: 'isolate',
+ exceptionPauseMode: ExceptionPauseMode.kNone,
+ id: '123',
+ number: '0',
+ startTime: 1,
+ runnable: true,
+ livePorts: 2,
+ pauseOnExit: false,
+ pauseEvent: Event(
+ kind: EventKind.kResume,
+ timestamp: 3,
+ ),
+ libraries: [],
+ breakpoints: [],
+ );
var request = rpcRequest("getIsolate", params: {'isolateId': isolate.id});
when(serviceMock.getIsolate(isolate.id))
.thenAnswer((Invocation invocation) {
@@ -67,18 +69,22 @@
});
test('works for methods with list parameters', () {
- var isolate = Isolate()
- ..id = '123'
- ..number = '0'
- ..startTime = 1
- ..runnable = true
- ..livePorts = 2
- ..pauseOnExit = false
- ..pauseEvent = (Event()
- ..kind = EventKind.kResume
- ..timestamp = 3)
- ..libraries = []
- ..breakpoints = [];
+ var isolate = Isolate(
+ name: 'isolate',
+ exceptionPauseMode: ExceptionPauseMode.kNone,
+ id: '123',
+ number: '0',
+ startTime: 1,
+ runnable: true,
+ livePorts: 2,
+ pauseOnExit: false,
+ pauseEvent: Event(
+ kind: EventKind.kResume,
+ timestamp: 3,
+ ),
+ libraries: [],
+ breakpoints: [],
+ );
var request = rpcRequest("setVMTimelineFlags", params: {
'isolateId': isolate.id,
// Note: the dynamic list below is intentional in order to exercise the
@@ -100,7 +106,7 @@
test('with no params or isolateId', () {
var extension = 'ext.cool';
var request = rpcRequest(extension, params: null);
- var response = Response()..json = {"hello": "world"};
+ var response = Response(type: '')..json = {"hello": "world"};
when(serviceMock.callServiceExtension(
extension,
isolateId: argThat(isNull, named: 'isolateId'),
@@ -117,7 +123,7 @@
test('with isolateId and no other params', () {
var extension = 'ext.cool';
var request = rpcRequest(extension, params: {'isolateId': '1'});
- var response = Response()..json = {"hello": "world"};
+ var response = Response(type: '')..json = {"hello": "world"};
when(serviceMock.callServiceExtension(
extension,
isolateId: argThat(equals('1'), named: 'isolateId'),
@@ -135,7 +141,7 @@
var extension = 'ext.cool';
var params = {'cool': 'option'};
var request = rpcRequest(extension, params: params);
- var response = Response()..json = {"hello": "world"};
+ var response = Response(type: '')..json = {"hello": "world"};
when(serviceMock.callServiceExtension(
extension,
isolateId: argThat(isNull, named: 'isolateId'),
@@ -154,7 +160,7 @@
var params = {'cool': 'option'};
var request =
rpcRequest(extension, params: Map.of(params)..['isolateId'] = '1');
- var response = Response()..json = {"hello": "world"};
+ var response = Response(type: '')..json = {"hello": "world"};
when(serviceMock.callServiceExtension(
extension,
isolateId: argThat(equals("1"), named: 'isolateId'),
@@ -209,12 +215,14 @@
eventController = serviceMock.streamControllers[streamId];
var events = [
- Event()
- ..kind = EventKind.kIsolateStart
- ..timestamp = 0,
- Event()
- ..kind = EventKind.kIsolateExit
- ..timestamp = 1,
+ Event(
+ kind: EventKind.kIsolateStart,
+ timestamp: 0,
+ ),
+ Event(
+ kind: EventKind.kIsolateExit,
+ timestamp: 1,
+ )
];
events.forEach(eventController.add);
await expect(
@@ -231,9 +239,10 @@
requestsController.add(request);
await expect(responseQueue, emitsThrough(rpcResponse(response)));
- var nextEvent = Event()
- ..kind = EventKind.kIsolateReload
- ..timestamp = 2;
+ var nextEvent = Event(
+ kind: EventKind.kIsolateReload,
+ timestamp: 2,
+ );
eventController.add(nextEvent);
expect(responseQueue,
neverEmits(streamNotifyResponse(streamId, nextEvent)));
@@ -294,24 +303,32 @@
test('gives register and unregister events', () async {
var serviceId = 'ext.test.service';
var serviceRegisteredEvent = streamNotifyResponse(
- serviceStream,
- Event()
- ..kind = EventKind.kServiceRegistered
- ..method = serviceId
- ..service = serviceId);
+ serviceStream,
+ Event(
+ kind: EventKind.kServiceRegistered,
+ timestamp: 0,
+ method: serviceId,
+ service: serviceId,
+ ),
+ );
var serviceUnRegisteredEvent = streamNotifyResponse(
- serviceStream,
- Event()
- ..kind = EventKind.kServiceUnregistered
- ..method = serviceId
- ..service = serviceId);
+ serviceStream,
+ Event(
+ kind: EventKind.kServiceUnregistered,
+ timestamp: 0,
+ method: serviceId,
+ service: serviceId,
+ ),
+ );
requestsController.add(
rpcRequest('streamListen', params: {'streamId': serviceStream}));
requestsController
.add(rpcRequest('registerService', params: {'service': serviceId}));
await expect(
- responsesController.stream, emitsThrough(serviceRegisteredEvent));
+ responsesController.stream
+ .map((Map response) => stripEventTimestamp(response)),
+ emitsThrough(serviceRegisteredEvent));
// Connect another client to get the previous register events and the
// unregister event.
@@ -326,7 +343,8 @@
responsesController2.sink, serviceRegistry, null);
expect(
- responsesController2.stream,
+ responsesController2.stream
+ .map((Map response) => stripEventTimestamp(response)),
emitsThrough(emitsInOrder(
[serviceRegisteredEvent, serviceUnRegisteredEvent])));
@@ -380,7 +398,7 @@
clientInputController.sink, serviceRegistry, serviceMock);
var requestParams = {'foo': 'bar'};
- var expectedResponse = Response()..json = {'zap': 'zip'};
+ var expectedResponse = Response(type: '')..json = {'zap': 'zip'};
await client.registerService(serviceId, null);
// Duplicate registrations should fail.
expect(client.registerService(serviceId, null),
@@ -402,7 +420,7 @@
// This should complete as well.
await clientConnection.done;
- var mockResponse = Response()..json = {'mock': 'response'};
+ var mockResponse = Response(type: '')..json = {'mock': 'response'};
when(serviceMock.callServiceExtension(serviceId,
args: argThat(equals(requestParams), named: 'args'),
isolateId: argThat(isNull, named: 'isolateId')))
@@ -463,6 +481,14 @@
};
}
+Map<String, Object> stripEventTimestamp(Map response) {
+ if (response.containsKey('params') &&
+ response['params'].containsKey('event')) {
+ response['params']['event']['timestamp'] = 0;
+ }
+ return response;
+}
+
class MockVmService extends Mock implements VmServiceInterface {
final streamControllers = <String, StreamController<Event>>{};
diff --git a/pkg/vm_service/tool/dart/generate_dart.dart b/pkg/vm_service/tool/dart/generate_dart.dart
index 0a5f50f..58607c9 100644
--- a/pkg/vm_service/tool/dart/generate_dart.dart
+++ b/pkg/vm_service/tool/dart/generate_dart.dart
@@ -50,6 +50,8 @@
import 'dart:convert' show base64, jsonDecode, jsonEncode, utf8;
import 'dart:typed_data';
+import 'package:meta/meta.dart';
+
import 'src/service_extension_registry.dart';
export 'src/service_extension_registry.dart' show ServiceExtensionRegistry;
@@ -79,7 +81,7 @@
} else if (args == null) {
return _call(method, {'isolateId': isolateId});
} else {
- args = new Map.from(args);
+ args = Map.from(args);
if (isolateId != null) {
args['isolateId'] = isolateId;
}
@@ -106,7 +108,7 @@
Future<T> _call<T>(String method, [Map args]) {
String id = '${++_id}';
- Completer<T> completer = new Completer<T>();
+ Completer<T> completer = Completer<T>();
_completers[id] = completer;
_methodCalls[id] = method;
Map m = {'id': id, 'method': method};
@@ -120,7 +122,7 @@
/// Register a service for invocation.
void registerServiceCallback(String service, ServiceCallback cb) {
if (_services.containsKey(service)) {
- throw new Exception('Service \'${service}\' already registered');
+ throw Exception('Service \'${service}\' already registered');
}
_services[service] = cb;
}
@@ -131,8 +133,8 @@
if (message is String) {
_processMessageStr(message);
} else if (message is List<int>) {
- Uint8List list = new Uint8List.fromList(message);
- _processMessageByteData(new ByteData.view(list.buffer));
+ Uint8List list = Uint8List.fromList(message);
+ _processMessageByteData(ByteData.view(list.buffer));
} else if (message is ByteData) {
_processMessageByteData(message);
} else {
@@ -144,10 +146,10 @@
int offset = 0;
int metaSize = bytes.getUint32(offset + 4, Endian.big);
offset += 8;
- String meta = utf8.decode(new Uint8List.view(
+ String meta = utf8.decode(Uint8List.view(
bytes.buffer, bytes.offsetInBytes + offset, metaSize));
offset += metaSize;
- ByteData data = new ByteData.view(bytes.buffer, bytes.offsetInBytes + offset,
+ ByteData data = ByteData.view(bytes.buffer, bytes.offsetInBytes + offset,
bytes.lengthInBytes - offset);
dynamic map = jsonDecode(meta);
if (map != null && map['method'] == 'streamNotify') {
@@ -251,7 +253,7 @@
class RPCError {
static RPCError parse(String callingMethod, dynamic json) {
- return new RPCError(callingMethod, json['code'], json['message'], json['data']);
+ return RPCError(callingMethod, json['code'], json['message'], json['data']);
}
final String callingMethod;
@@ -275,7 +277,7 @@
/// An `ExtensionData` is an arbitrary map that can have any contents.
class ExtensionData {
static ExtensionData parse(Map json) =>
- json == null ? null : new ExtensionData._fromJson(json);
+ json == null ? null : ExtensionData._fromJson(json);
final Map data;
@@ -417,11 +419,11 @@
if (docs != null) docs = docs.trim();
if (definition.startsWith('class ')) {
- types.add(new Type(this, name, definition, docs));
+ types.add(Type(this, name, definition, docs));
} else if (name.substring(0, 1).toLowerCase() == name.substring(0, 1)) {
- methods.add(new Method(name, definition, docs));
+ methods.add(Method(name, definition, docs));
} else if (definition.startsWith('enum ')) {
- enums.add(new Enum(name, definition, docs));
+ enums.add(Enum(name, definition, docs));
} else {
throw 'unexpected entity: ${name}, ${definition}';
}
@@ -682,7 +684,7 @@
} else if (method.startsWith('ext.')) {
// Remaining methods with `ext.` are assumed to be registered via
// dart:developer, which the service implementation handles.
- var args = params == null ? null : new Map.of(params);
+ var args = params == null ? null : Map.of(params);
var isolateId = args?.remove('isolateId');
response = await _serviceImplementation.callServiceExtension(method,
isolateId: isolateId, args: args);
@@ -740,17 +742,17 @@
gen.writeStatement('Log _log;');
gen.write('''
-StreamController<String> _onSend = new StreamController.broadcast(sync: true);
-StreamController<String> _onReceive = new StreamController.broadcast(sync: true);
+StreamController<String> _onSend = StreamController.broadcast(sync: true);
+StreamController<String> _onReceive = StreamController.broadcast(sync: true);
-final Completer _onDoneCompleter = new Completer();
+final Completer _onDoneCompleter = Completer();
Map<String, StreamController<Event>> _eventControllers = {};
StreamController<Event> _getEventController(String eventName) {
StreamController<Event> controller = _eventControllers[eventName];
if (controller == null) {
- controller = new StreamController.broadcast();
+ controller = StreamController.broadcast();
_eventControllers[eventName] = controller;
}
return controller;
@@ -765,7 +767,7 @@
}) {
_streamSub = inStream.listen(_processMessage, onDone: ()=> _onDoneCompleter.complete());
_writeMessage = writeMessage;
- _log = log == null ? new _NullLog() : log;
+ _log = log == null ? _NullLog() : log;
_disposeHandler = disposeHandler;
streamClosed?.then((_) {
if (!_onDoneCompleter.isCompleted) {
@@ -973,7 +975,7 @@
if (line.isEmpty) {
inStreamDef = false;
} else {
- streamCategories.add(new StreamCategory(line));
+ streamCategories.add(StreamCategory(line));
}
}
}
@@ -1024,11 +1026,11 @@
final String name;
final String docs;
- MemberType returnType = new MemberType();
+ MemberType returnType = MemberType();
List<MethodArg> args = [];
Method(this.name, String definition, [this.docs]) {
- _parse(new Tokenizer(definition).tokenize());
+ _parse(Tokenizer(definition).tokenize());
}
bool get hasArgs => args.isNotEmpty;
@@ -1117,9 +1119,7 @@
gen.write(') ');
}
- void _parse(Token token) {
- new MethodParser(token).parseInto(this);
- }
+ void _parse(Token token) => MethodParser(token).parseInto(this);
}
class MemberType extends Member {
@@ -1139,7 +1139,7 @@
parser.advance();
}
parser.consume(')');
- TypeRef ref = new TypeRef('dynamic');
+ TypeRef ref = TypeRef('dynamic');
while (parser.consume('[')) {
parser.expect(']');
ref.arrayDepth++;
@@ -1147,7 +1147,7 @@
types.add(ref);
} else {
Token t = parser.expectName();
- TypeRef ref = new TypeRef(_coerceRefType(t.text));
+ TypeRef ref = TypeRef(_coerceRefType(t.text));
while (parser.consume('[')) {
parser.expect(']');
ref.arrayDepth++;
@@ -1236,8 +1236,6 @@
MethodArg(this.parent, this.type, this.name);
- // String get paramType => type;
-
void generate(DartGenerator gen) {
gen.write('${type.ref} ${name}');
}
@@ -1254,7 +1252,7 @@
List<TypeField> fields = [];
Type(this.parent, String categoryName, String definition, [this.docs]) {
- _parse(new Tokenizer(definition).tokenize());
+ _parse(Tokenizer(definition).tokenize());
}
Type._(this.parent, this.rawName, this.name, this.superName, this.docs);
@@ -1276,7 +1274,7 @@
final fields = map.values.toList().reversed.toList();
- return new Type._(parent, rawName, name, superName, docs)..fields = fields;
+ return Type._(parent, rawName, name, superName, docs)..fields = fields;
}
bool get isResponse {
@@ -1318,7 +1316,7 @@
if (superName != null) gen.write('extends ${superName} ');
gen.writeln('{');
gen.writeln('static ${name} parse(Map<String, dynamic> json) => '
- 'json == null ? null : new ${name}._fromJson(json);');
+ 'json == null ? null : ${name}._fromJson(json);');
gen.writeln();
if (name == 'Response') {
@@ -1330,9 +1328,22 @@
gen.writeln();
// ctors
- gen.writeln('${name}();');
- gen.writeln();
+ // Default
+ gen.write('${name}(');
+ if (fields.isNotEmpty) {
+ gen.write('{');
+ fields
+ .where((field) => !field.optional)
+ .forEach((field) => field.generateNamedParameter(gen));
+ fields
+ .where((field) => field.optional)
+ .forEach((field) => field.generateNamedParameter(gen));
+ gen.write('}');
+ }
+ gen.writeln(');');
+
+ // Build from JSON.
String superCall = superName == null ? '' : ": super._fromJson(json) ";
if (name == 'Response') {
gen.write('${name}._fromJson(this.json)');
@@ -1372,19 +1383,19 @@
} else if (name == 'Instance' && field.name == 'associations') {
// Special case `Instance.associations`.
gen.writeln("associations = json['associations'] == null "
- "? null : new List<MapAssociation>.from("
+ "? null : List<MapAssociation>.from("
"_createSpecificObject(json['associations'], MapAssociation.parse));");
} else if (name == '_CpuProfile' && field.name == 'codes') {
// Special case `_CpuProfile.codes`.
- gen.writeln("codes = new List<CodeRegion>.from("
+ gen.writeln("codes = List<CodeRegion>.from("
"_createSpecificObject(json['codes'], CodeRegion.parse));");
} else if (name == '_CpuProfile' && field.name == 'functions') {
// Special case `_CpuProfile.functions`.
- gen.writeln("functions = new List<ProfileFunction>.from("
+ gen.writeln("functions = List<ProfileFunction>.from("
"_createSpecificObject(json['functions'], ProfileFunction.parse));");
} else if (name == 'SourceReport' && field.name == 'ranges') {
// Special case `SourceReport.ranges`.
- gen.writeln("ranges = new List<SourceReportRange>.from("
+ gen.writeln("ranges = List<SourceReportRange>.from("
"_createSpecificObject(json['ranges'], SourceReportRange.parse));");
} else if (name == 'SourceReportRange' && field.name == 'coverage') {
// Special case `SourceReportRange.coverage`.
@@ -1392,7 +1403,7 @@
"json['coverage'], SourceReportCoverage.parse);");
} else if (name == 'Library' && field.name == 'dependencies') {
// Special case `Library.dependencies`.
- gen.writeln("dependencies = new List<LibraryDependency>.from("
+ gen.writeln("dependencies = List<LibraryDependency>.from("
"_createSpecificObject(json['dependencies'], "
"LibraryDependency.parse));");
} else if (name == 'Script' && field.name == 'tokenPosTable') {
@@ -1401,8 +1412,8 @@
if (field.optional) {
gen.write("json['tokenPosTable'] == null ? null : ");
}
- gen.writeln("new List<List<int>>.from(json['tokenPosTable'].map"
- "((dynamic list) => new List<int>.from(list)));");
+ gen.writeln("List<List<int>>.from(json['tokenPosTable'].map"
+ "((dynamic list) => List<int>.from(list)));");
} else if (field.type.isArray) {
TypeRef fieldType = field.type.types.first;
String typesList = _typeRefListToString(field.type.types);
@@ -1410,10 +1421,10 @@
if (field.optional) {
if (fieldType.isListTypeSimple) {
gen.writeln("${field.generatableName} = $ref == null ? null : "
- "new List<${fieldType.listTypeArg}>.from($ref);");
+ "List<${fieldType.listTypeArg}>.from($ref);");
} else {
gen.writeln("${field.generatableName} = $ref == null ? null : "
- "new List<${fieldType.listTypeArg}>.from(createServiceObject($ref, $typesList));");
+ "List<${fieldType.listTypeArg}>.from(createServiceObject($ref, $typesList));");
}
} else {
if (fieldType.isListTypeSimple) {
@@ -1421,20 +1432,20 @@
// `new` and `old`. Post 3.18, these will be null.
if (name == 'ClassHeapStats') {
gen.writeln("${field.generatableName} = $ref == null ? null : "
- "new List<${fieldType.listTypeArg}>.from($ref);");
+ "List<${fieldType.listTypeArg}>.from($ref);");
} else {
gen.writeln("${field.generatableName} = "
- "new List<${fieldType.listTypeArg}>.from($ref);");
+ "List<${fieldType.listTypeArg}>.from($ref);");
}
} else {
// Special case `InstanceSet`. Pre 3.20, instances were sent in a
// field named 'samples' instead of 'instances'.
if (name == 'InstanceSet') {
gen.writeln("${field.generatableName} = "
- "new List<${fieldType.listTypeArg}>.from(createServiceObject($ref ?? json['samples'], $typesList));");
+ "List<${fieldType.listTypeArg}>.from(createServiceObject($ref ?? json['samples'], $typesList));");
} else {
gen.writeln("${field.generatableName} = "
- "new List<${fieldType.listTypeArg}>.from(createServiceObject($ref, $typesList));");
+ "List<${fieldType.listTypeArg}>.from(createServiceObject($ref, $typesList));");
}
}
}
@@ -1615,9 +1626,7 @@
gen.writeln('');
}
- void _parse(Token token) {
- new TypeParser(token).parseInto(this);
- }
+ void _parse(Token token) => TypeParser(token).parseInto(this);
void calculateFieldOverrides() {
for (TypeField field in fields.toList()) {
@@ -1648,7 +1657,7 @@
final Type parent;
final String _docs;
- MemberType type = new MemberType();
+ MemberType type = MemberType();
String name;
bool optional = false;
String defaultValue;
@@ -1656,9 +1665,7 @@
TypeField(this.parent, this._docs);
- void setOverrides() {
- overrides = true;
- }
+ void setOverrides() => overrides = true;
String get docs {
String str = _docs == null ? '' : _docs;
@@ -1683,6 +1690,13 @@
gen.writeStatement('${typeName} ${generatableName};');
if (parent.fields.any((field) => field.hasDocs)) gen.writeln();
}
+
+ void generateNamedParameter(DartGenerator gen) {
+ if (!optional) {
+ gen.write('@required ');
+ }
+ gen.writeStatement('this.${generatableName},');
+ }
}
class Enum extends Member {
@@ -1692,7 +1706,7 @@
List<EnumValue> enums = [];
Enum(this.name, String definition, [this.docs]) {
- _parse(new Tokenizer(definition).tokenize());
+ _parse(Tokenizer(definition).tokenize());
}
Enum._(this.name, this.docs);
@@ -1711,7 +1725,7 @@
final enums = map.values.toList().reversed.toList();
- return new Enum._(name, docs)..enums = enums;
+ return Enum._(name, docs)..enums = enums;
}
String get prefix =>
@@ -1739,9 +1753,7 @@
gen.writeln('');
}
- void _parse(Token token) {
- new EnumParser(token).parseInto(this);
- }
+ void _parse(Token token) => EnumParser(token).parseInto(this);
}
class EnumValue extends Member {
@@ -1761,12 +1773,12 @@
class TextOutputVisitor implements NodeVisitor {
static String printText(Node node) {
- TextOutputVisitor visitor = new TextOutputVisitor();
+ TextOutputVisitor visitor = TextOutputVisitor();
node.accept(visitor);
return visitor.toString();
}
- StringBuffer buf = new StringBuffer();
+ StringBuffer buf = StringBuffer();
bool _em = false;
bool _href = false;
bool _blockquote = false;
@@ -1845,7 +1857,7 @@
while (peek().text != ')') {
Token type = expectName();
- TypeRef ref = new TypeRef(_coerceRefType(type.text));
+ TypeRef ref = TypeRef(_coerceRefType(type.text));
if (peek().text == '[') {
while (consume('[')) {
expect(']');
@@ -1857,15 +1869,14 @@
ref.genericTypes = [];
while (peek().text != '>') {
Token genericTypeName = expectName();
- ref.genericTypes
- .add(new TypeRef(_coerceRefType(genericTypeName.text)));
+ ref.genericTypes.add(TypeRef(_coerceRefType(genericTypeName.text)));
consume(',');
}
expect('>');
}
Token name = expectName();
- MethodArg arg = new MethodArg(method, ref, name.text);
+ MethodArg arg = MethodArg(method, ref, name.text);
if (consume('[')) {
expect('optional');
expect(']');
@@ -1906,7 +1917,7 @@
expect('{');
while (peek().text != '}') {
- TypeField field = new TypeField(type, collectComments());
+ TypeField field = TypeField(type, collectComments());
field.type.parse(this);
field.name = expectName().text;
if (consume('[')) {
@@ -1940,7 +1951,7 @@
t = expectName();
consume(',');
- e.enums.add(new EnumValue(e, t.text, docs));
+ e.enums.add(EnumValue(e, t.text, docs));
}
}
}
diff --git a/runtime/BUILD.gn b/runtime/BUILD.gn
index 529da63..a3cc367 100644
--- a/runtime/BUILD.gn
+++ b/runtime/BUILD.gn
@@ -240,6 +240,10 @@
"third_party/double-conversion/src:libdouble_conversion",
":generate_version_cc_file",
]
+ if (dart_enable_wasm) {
+ extra_deps += [ "//third_party/wasmer" ]
+ defines = [ "DART_ENABLE_WASM" ]
+ }
if (is_fuchsia) {
if (using_fuchsia_sdk) {
extra_deps += [ "$fuchsia_sdk_root/pkg:fdio" ]
diff --git a/runtime/bin/BUILD.gn b/runtime/bin/BUILD.gn
index dd9ea2c..4f60c40 100644
--- a/runtime/bin/BUILD.gn
+++ b/runtime/bin/BUILD.gn
@@ -266,12 +266,15 @@
if (is_fuchsia) {
if (using_fuchsia_sdk) {
- deps += [ "$fuchsia_sdk_root/pkg/lib/netstack/c" ]
+ deps += [
+ "$fuchsia_sdk_root/fidl:fuchsia.netstack",
+ "$fuchsia_sdk_root/pkg:sys_cpp",
+ ]
public_deps = [
"$fuchsia_sdk_root/pkg:fdio",
]
} else {
- deps += [ "//garnet/public/lib/netstack/c" ]
+ deps += [ "//sdk/fidl/fuchsia.netstack" ]
public_deps = [
"//zircon/public/lib/fdio",
]
@@ -388,12 +391,15 @@
if (is_fuchsia) {
if (using_fuchsia_sdk) {
- deps += [ "$fuchsia_sdk_root/pkg/lib/netstack/c" ]
+ deps += [
+ "$fuchsia_sdk_root/fidl:fuchsia.netstack",
+ "$fuchsia_sdk_root/pkg:sys_cpp",
+ ]
public_deps = [
"$fuchsia_sdk_root/pkg:fdio",
]
} else {
- deps += [ "//garnet/public/lib/netstack/c" ]
+ deps += [ "//sdk/fidl/fuchsia.netstack" ]
public_deps = [
"//zircon/public/lib/fdio",
]
diff --git a/runtime/bin/builtin_sources.gni b/runtime/bin/builtin_sources.gni
index c9edd40..8ed3c7d 100644
--- a/runtime/bin/builtin_sources.gni
+++ b/runtime/bin/builtin_sources.gni
@@ -1,6 +1,3 @@
# Copyright (c) 2017, 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.
-
-# This file contains all dart sources for the dart:_builtin library.
-builtin_sources = [ "builtin.dart" ]
diff --git a/runtime/bin/cli_sources.gni b/runtime/bin/cli_sources.gni
index ed72a04..cb2e6d6 100644
--- a/runtime/bin/cli_sources.gni
+++ b/runtime/bin/cli_sources.gni
@@ -2,5 +2,3 @@
# 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.
-# This file contains all sources for the dart:cli library.
-cli_runtime_dart_files = [ "cli_patch.dart" ]
diff --git a/runtime/bin/dart_embedder_api_impl.cc b/runtime/bin/dart_embedder_api_impl.cc
index cf2116a..a7fde47 100644
--- a/runtime/bin/dart_embedder_api_impl.cc
+++ b/runtime/bin/dart_embedder_api_impl.cc
@@ -88,8 +88,9 @@
Dart_EnterScope();
// Load embedder specific bits and return.
if (!bin::VmService::Setup(config.ip, config.port, config.dev_mode,
- config.disable_auth_codes, /*trace_loading=*/false,
- config.deterministic)) {
+ config.disable_auth_codes,
+ config.write_service_info_filename,
+ /*trace_loading=*/false, config.deterministic)) {
*error = strdup(bin::VmService::GetErrorMessage());
return nullptr;
}
diff --git a/runtime/bin/dfe.cc b/runtime/bin/dfe.cc
index 3e5eaf9..761c536 100644
--- a/runtime/bin/dfe.cc
+++ b/runtime/bin/dfe.cc
@@ -42,11 +42,23 @@
const char kSnapshotsDirectory[] = "snapshots";
static char* GetDirectoryPrefixFromExeName() {
- const char* name = Platform::GetExecutableName();
+ const char* name = nullptr;
+ const int kTargetSize = 4096;
+ char target[kTargetSize];
+ intptr_t target_size =
+ Platform::ResolveExecutablePathInto(target, kTargetSize);
+ if (target_size > 0 && target_size < kTargetSize - 1) {
+ target[target_size] = 0;
+ name = target;
+ }
+ if (name == nullptr) {
+ name = Platform::GetExecutableName();
+ target_size = strlen(name);
+ }
const char* sep = File::PathSeparator();
const intptr_t sep_length = strlen(sep);
- for (intptr_t i = strlen(name) - 1; i >= 0; --i) {
+ for (intptr_t i = target_size - 1; i >= 0; --i) {
const char* str = name + i;
if (strncmp(str, sep, sep_length) == 0
#if defined(HOST_OS_WINDOWS)
diff --git a/runtime/bin/file.h b/runtime/bin/file.h
index a3347c0..928fbdd 100644
--- a/runtime/bin/file.h
+++ b/runtime/bin/file.h
@@ -223,6 +223,9 @@
static const char* GetCanonicalPath(Namespace* namespc, const char* path);
// Link LinkTarget, but pathname must be absolute.
static const char* ReadLink(const char* pathname);
+ static intptr_t ReadLinkInto(const char* pathname,
+ char* result,
+ size_t result_size);
// Cleans an input path, transforming it to out, according to the rules
// defined by "Lexical File Names in Plan 9 or Getting Dot-Dot Right",
diff --git a/runtime/bin/file_android.cc b/runtime/bin/file_android.cc
index ef983f3..c634b0d 100644
--- a/runtime/bin/file_android.cc
+++ b/runtime/bin/file_android.cc
@@ -579,24 +579,34 @@
return ((pathname != NULL) && (pathname[0] == '/'));
}
-const char* File::ReadLink(const char* pathname) {
+intptr_t File::ReadLinkInto(const char* pathname,
+ char* result,
+ size_t result_size) {
ASSERT(pathname != NULL);
ASSERT(IsAbsolutePath(pathname));
struct stat link_stats;
if (TEMP_FAILURE_RETRY(lstat(pathname, &link_stats)) != 0) {
- return NULL;
+ return -1;
}
if (!S_ISLNK(link_stats.st_mode)) {
errno = ENOENT;
- return NULL;
+ return -1;
}
+ const size_t target_size =
+ TEMP_FAILURE_RETRY(readlink(pathname, result, result_size));
+ if (target_size <= 0) {
+ return -1;
+ }
+ return target_size;
+}
+
+const char* File::ReadLink(const char* pathname) {
// Don't rely on the link_stats.st_size for the size of the link
// target. For some filesystems, e.g. procfs, this value is always
// 0. Also the link might have changed before the readlink call.
const int kBufferSize = PATH_MAX + 1;
char target[kBufferSize];
- size_t target_size =
- TEMP_FAILURE_RETRY(readlink(pathname, target, kBufferSize));
+ size_t target_size = ReadLinkInto(pathname, target, kBufferSize);
if (target_size <= 0) {
return NULL;
}
diff --git a/runtime/bin/file_linux.cc b/runtime/bin/file_linux.cc
index f53d69a..e6db3ad 100644
--- a/runtime/bin/file_linux.cc
+++ b/runtime/bin/file_linux.cc
@@ -572,24 +572,34 @@
return (pathname != NULL) && (pathname[0] == '/');
}
-const char* File::ReadLink(const char* pathname) {
+intptr_t File::ReadLinkInto(const char* pathname,
+ char* result,
+ size_t result_size) {
ASSERT(pathname != NULL);
ASSERT(IsAbsolutePath(pathname));
struct stat64 link_stats;
if (TEMP_FAILURE_RETRY(lstat64(pathname, &link_stats)) != 0) {
- return NULL;
+ return -1;
}
if (!S_ISLNK(link_stats.st_mode)) {
errno = ENOENT;
- return NULL;
+ return -1;
}
+ const size_t target_size =
+ TEMP_FAILURE_RETRY(readlink(pathname, result, result_size));
+ if (target_size <= 0) {
+ return -1;
+ }
+ return target_size;
+}
+
+const char* File::ReadLink(const char* pathname) {
// Don't rely on the link_stats.st_size for the size of the link
// target. For some filesystems, e.g. procfs, this value is always
// 0. Also the link might have changed before the readlink call.
const int kBufferSize = PATH_MAX + 1;
char target[kBufferSize];
- size_t target_size =
- TEMP_FAILURE_RETRY(readlink(pathname, target, kBufferSize));
+ size_t target_size = ReadLinkInto(pathname, target, kBufferSize);
if (target_size <= 0) {
return NULL;
}
diff --git a/runtime/bin/io_sources.gni b/runtime/bin/io_sources.gni
index 56de0e7..8ed3c7d 100644
--- a/runtime/bin/io_sources.gni
+++ b/runtime/bin/io_sources.gni
@@ -1,21 +1,3 @@
# Copyright (c) 2017, 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.
-
-# This file contains all sources for the dart:io library.
-io_runtime_dart_files = [
- "common_patch.dart",
- "directory_patch.dart",
- "eventhandler_patch.dart",
- "file_patch.dart",
- "file_system_entity_patch.dart",
- "filter_patch.dart",
- "io_service_patch.dart",
- "namespace_patch.dart",
- "platform_patch.dart",
- "process_patch.dart",
- "socket_patch.dart",
- "stdio_patch.dart",
- "secure_socket_patch.dart",
- "sync_socket_patch.dart",
-]
diff --git a/runtime/bin/main.cc b/runtime/bin/main.cc
index 2ff8888..483368c 100644
--- a/runtime/bin/main.cc
+++ b/runtime/bin/main.cc
@@ -597,7 +597,8 @@
if (!VmService::Setup(
Options::vm_service_server_ip(), Options::vm_service_server_port(),
Options::vm_service_dev_mode(), Options::vm_service_auth_disabled(),
- Options::trace_loading(), Options::deterministic())) {
+ Options::vm_write_service_info_filename(), Options::trace_loading(),
+ Options::deterministic())) {
*error = strdup(VmService::GetErrorMessage());
return NULL;
}
@@ -1081,29 +1082,48 @@
}
vm_options.AddArgument("--new_gen_growth_factor=4");
- // Parse command line arguments.
- if (Options::ParseArguments(argc, argv, vm_run_app_snapshot, &vm_options,
- &script_name, &dart_options, &print_flags_seen,
- &verbose_debug_seen) < 0) {
- if (Options::help_option()) {
- Options::PrintUsage();
- Platform::Exit(0);
- } else if (Options::version_option()) {
- Options::PrintVersion();
- Platform::Exit(0);
- } else if (print_flags_seen) {
- // Will set the VM flags, print them out and then we exit as no
- // script was specified on the command line.
- char* error = Dart_SetVMFlags(vm_options.count(), vm_options.arguments());
- if (error != NULL) {
- Syslog::PrintErr("Setting VM flags failed: %s\n", error);
- free(error);
+ // If the executable binary contains the runtime together with an appended
+ // snapshot, load and run that.
+ // Any arguments passed to such an executable are meant for the actual
+ // application so skip all Dart VM flag parsing.
+ AppSnapshot* app_snapshot =
+ Snapshot::TryReadAppendedAppSnapshotBlobs(argv[0]);
+ if (app_snapshot != nullptr) {
+ script_name = argv[0];
+
+ // Store the executable name.
+ Platform::SetExecutableName(argv[0]);
+
+ // Parse out options to be passed to dart main.
+ for (int i = 1; i < argc; i++) {
+ dart_options.AddArgument(argv[i]);
+ }
+ } else {
+ // Parse command line arguments.
+ if (Options::ParseArguments(argc, argv, vm_run_app_snapshot, &vm_options,
+ &script_name, &dart_options, &print_flags_seen,
+ &verbose_debug_seen) < 0) {
+ if (Options::help_option()) {
+ Options::PrintUsage();
+ Platform::Exit(0);
+ } else if (Options::version_option()) {
+ Options::PrintVersion();
+ Platform::Exit(0);
+ } else if (print_flags_seen) {
+ // Will set the VM flags, print them out and then we exit as no
+ // script was specified on the command line.
+ char* error =
+ Dart_SetVMFlags(vm_options.count(), vm_options.arguments());
+ if (error != NULL) {
+ Syslog::PrintErr("Setting VM flags failed: %s\n", error);
+ free(error);
+ Platform::Exit(kErrorExitCode);
+ }
+ Platform::Exit(0);
+ } else {
+ Options::PrintUsage();
Platform::Exit(kErrorExitCode);
}
- Platform::Exit(0);
- } else {
- Options::PrintUsage();
- Platform::Exit(kErrorExitCode);
}
}
DartUtils::SetEnvironment(Options::environment());
@@ -1131,8 +1151,10 @@
shared_blobs->SetBuffers(&ignored, &ignored, &app_isolate_shared_data,
&app_isolate_shared_instructions);
}
- AppSnapshot* app_snapshot = Snapshot::TryReadAppSnapshot(script_name);
- if (app_snapshot != NULL) {
+ if (app_snapshot == nullptr) {
+ app_snapshot = Snapshot::TryReadAppSnapshot(script_name);
+ }
+ if (app_snapshot != nullptr) {
vm_run_app_snapshot = true;
app_snapshot->SetBuffers(&vm_snapshot_data, &vm_snapshot_instructions,
&app_isolate_snapshot_data,
diff --git a/runtime/bin/main_options.cc b/runtime/bin/main_options.cc
index ee4516e..38c26d7 100644
--- a/runtime/bin/main_options.cc
+++ b/runtime/bin/main_options.cc
@@ -147,6 +147,10 @@
" --warn-on-pause-with-no-debugger\n"
" This set is subject to change.\n"
" Please see these options (--help --verbose) for further documentation.\n"
+"--write-service-info=<file_name>\n"
+" Outputs information necessary to connect to the VM service to the\n"
+" specified file in JSON format. Useful for clients which are unable to\n"
+" listen to stdout for the Observatory listening message.\n"
"--snapshot-kind=<snapshot_kind>\n"
"--snapshot=<file_name>\n"
" These snapshot options are used to generate a snapshot of the loaded\n"
@@ -178,6 +182,10 @@
" --warn-on-pause-with-no-debugger\n"
" This set is subject to change.\n"
" Please see these options for further documentation.\n"
+"--write-service-info=<file_name>\n"
+" Outputs information necessary to connect to the VM service to the\n"
+" specified file in JSON format. Useful for clients which are unable to\n"
+" listen to stdout for the Observatory listening message.\n"
"--snapshot-kind=<snapshot_kind>\n"
"--snapshot=<file_name>\n"
" These snapshot options are used to generate a snapshot of the loaded\n"
diff --git a/runtime/bin/main_options.h b/runtime/bin/main_options.h
index 8513fe3..32c6d9c 100644
--- a/runtime/bin/main_options.h
+++ b/runtime/bin/main_options.h
@@ -30,7 +30,8 @@
V(load_type_feedback, load_type_feedback_filename) \
V(root_certs_file, root_certs_file) \
V(root_certs_cache, root_certs_cache) \
- V(namespace, namespc)
+ V(namespace, namespc) \
+ V(write_service_info, vm_write_service_info_filename)
// As STRING_OPTIONS_LIST but for boolean valued options. The default value is
// always false, and the presence of the flag switches the value to true.
diff --git a/runtime/bin/platform.h b/runtime/bin/platform.h
index 30d92ae7..b0b3aa2 100644
--- a/runtime/bin/platform.h
+++ b/runtime/bin/platform.h
@@ -64,6 +64,15 @@
static const char* ResolveExecutablePath();
+ // On Linux and Android this has the same effect as calling
+ // ResolveExecutablePath except that Dart_ScopeAllocate is not called and that
+ // the result goes into the given parameters.
+ // On all other platforms it returns -1, i.e. doesn't work.
+ // Note that `result` should be pre-allocated with size `result_size`.
+ // The return-value is the length read into `result` or -1 on failure.
+ // The content of `result` is not guranteed to be null-terminated.
+ static intptr_t ResolveExecutablePathInto(char* result, size_t result_size);
+
// Stores the executable name.
static void SetExecutableName(const char* executable_name) {
executable_name_ = executable_name;
diff --git a/runtime/bin/platform_android.cc b/runtime/bin/platform_android.cc
index 5fa361f..6555965 100644
--- a/runtime/bin/platform_android.cc
+++ b/runtime/bin/platform_android.cc
@@ -155,6 +155,10 @@
return File::ReadLink("/proc/self/exe");
}
+intptr_t Platform::ResolveExecutablePathInto(char* result, size_t result_size) {
+ return File::ReadLinkInto("/proc/self/exe", result, result_size);
+}
+
void Platform::Exit(int exit_code) {
Console::RestoreConfig();
Dart_PrepareToAbort();
diff --git a/runtime/bin/platform_fuchsia.cc b/runtime/bin/platform_fuchsia.cc
index 3f4d7a0..3fa55be 100644
--- a/runtime/bin/platform_fuchsia.cc
+++ b/runtime/bin/platform_fuchsia.cc
@@ -147,6 +147,10 @@
return NULL;
}
+intptr_t Platform::ResolveExecutablePathInto(char* result, size_t result_size) {
+ return -1;
+}
+
void Platform::Exit(int exit_code) {
Console::RestoreConfig();
Dart_PrepareToAbort();
diff --git a/runtime/bin/platform_linux.cc b/runtime/bin/platform_linux.cc
index b0fc285..e6571af 100644
--- a/runtime/bin/platform_linux.cc
+++ b/runtime/bin/platform_linux.cc
@@ -162,6 +162,10 @@
return File::ReadLink("/proc/self/exe");
}
+intptr_t Platform::ResolveExecutablePathInto(char* result, size_t result_size) {
+ return File::ReadLinkInto("/proc/self/exe", result, result_size);
+}
+
void Platform::Exit(int exit_code) {
Console::RestoreConfig();
Dart_PrepareToAbort();
diff --git a/runtime/bin/platform_macos.cc b/runtime/bin/platform_macos.cc
index 79ff679..2be3f30 100644
--- a/runtime/bin/platform_macos.cc
+++ b/runtime/bin/platform_macos.cc
@@ -251,6 +251,10 @@
return canon_path;
}
+intptr_t Platform::ResolveExecutablePathInto(char* result, size_t result_size) {
+ return -1;
+}
+
void Platform::Exit(int exit_code) {
Console::RestoreConfig();
Dart_PrepareToAbort();
diff --git a/runtime/bin/platform_win.cc b/runtime/bin/platform_win.cc
index c5820b8..e4f20a2 100644
--- a/runtime/bin/platform_win.cc
+++ b/runtime/bin/platform_win.cc
@@ -285,6 +285,10 @@
return canon_path;
}
+intptr_t Platform::ResolveExecutablePathInto(char* result, size_t result_size) {
+ return -1;
+}
+
void Platform::Exit(int exit_code) {
// Restore the console's output code page
Console::RestoreConfig();
diff --git a/runtime/bin/run_vm_tests.cc b/runtime/bin/run_vm_tests.cc
index 694577e..24626af 100644
--- a/runtime/bin/run_vm_tests.cc
+++ b/runtime/bin/run_vm_tests.cc
@@ -151,6 +151,7 @@
// Load embedder specific bits and return.
if (!bin::VmService::Setup("127.0.0.1", 0,
/*dev_mode=*/false, /*auth_disabled=*/true,
+ /*write_service_info_filename*/ "",
/*trace_loading=*/false, /*deterministic=*/true)) {
*error = strdup(bin::VmService::GetErrorMessage());
return nullptr;
diff --git a/runtime/bin/snapshot_utils.cc b/runtime/bin/snapshot_utils.cc
index 58407ce..673e556 100644
--- a/runtime/bin/snapshot_utils.cc
+++ b/runtime/bin/snapshot_utils.cc
@@ -75,24 +75,21 @@
MappedMemory* isolate_instructions_mapping_;
};
-static AppSnapshot* TryReadAppSnapshotBlobs(const char* script_name) {
- File* file = File::Open(NULL, script_name, File::kRead);
- if (file == NULL) {
- return NULL;
+static AppSnapshot* TryReadAppSnapshotBlobs(const char* script_name,
+ File* file) {
+ if ((file->Length() - file->Position()) < kAppSnapshotHeaderSize) {
+ return nullptr;
}
- RefCntReleaseScope<File> rs(file);
- if (file->Length() < kAppSnapshotHeaderSize) {
- return NULL;
- }
+
int64_t header[5];
ASSERT(sizeof(header) == kAppSnapshotHeaderSize);
if (!file->ReadFully(&header, kAppSnapshotHeaderSize)) {
- return NULL;
+ return nullptr;
}
ASSERT(sizeof(header[0]) == appjit_magic_number.length);
if (memcmp(&header[0], appjit_magic_number.bytes,
appjit_magic_number.length) != 0) {
- return NULL;
+ return nullptr;
}
int64_t vm_data_size = header[1];
@@ -115,39 +112,39 @@
Utils::RoundUp(isolate_instructions_position, kAppSnapshotPageSize);
}
- MappedMemory* vm_data_mapping = NULL;
+ MappedMemory* vm_data_mapping = nullptr;
if (vm_data_size != 0) {
vm_data_mapping =
file->Map(File::kReadOnly, vm_data_position, vm_data_size);
- if (vm_data_mapping == NULL) {
+ if (vm_data_mapping == nullptr) {
FATAL1("Failed to memory map snapshot: %s\n", script_name);
}
}
- MappedMemory* vm_instr_mapping = NULL;
+ MappedMemory* vm_instr_mapping = nullptr;
if (vm_instructions_size != 0) {
vm_instr_mapping = file->Map(File::kReadExecute, vm_instructions_position,
vm_instructions_size);
- if (vm_instr_mapping == NULL) {
+ if (vm_instr_mapping == nullptr) {
FATAL1("Failed to memory map snapshot: %s\n", script_name);
}
}
- MappedMemory* isolate_data_mapping = NULL;
+ MappedMemory* isolate_data_mapping = nullptr;
if (isolate_data_size != 0) {
isolate_data_mapping =
file->Map(File::kReadOnly, isolate_data_position, isolate_data_size);
- if (isolate_data_mapping == NULL) {
+ if (isolate_data_mapping == nullptr) {
FATAL1("Failed to memory map snapshot: %s\n", script_name);
}
}
- MappedMemory* isolate_instr_mapping = NULL;
+ MappedMemory* isolate_instr_mapping = nullptr;
if (isolate_instructions_size != 0) {
isolate_instr_mapping =
file->Map(File::kReadExecute, isolate_instructions_position,
isolate_instructions_size);
- if (isolate_instr_mapping == NULL) {
+ if (isolate_instr_mapping == nullptr) {
FATAL1("Failed to memory map snapshot: %s\n", script_name);
}
}
@@ -156,6 +153,41 @@
isolate_data_mapping, isolate_instr_mapping);
}
+static AppSnapshot* TryReadAppSnapshotBlobs(const char* script_name) {
+ File* file = File::Open(NULL, script_name, File::kRead);
+ if (file == nullptr) {
+ return nullptr;
+ }
+ RefCntReleaseScope<File> rs(file);
+ return TryReadAppSnapshotBlobs(script_name, file);
+}
+
+AppSnapshot* Snapshot::TryReadAppendedAppSnapshotBlobs(
+ const char* container_path) {
+ File* file = File::Open(NULL, container_path, File::kRead);
+ if (file == nullptr) {
+ return nullptr;
+ }
+ RefCntReleaseScope<File> rs(file);
+
+ // Check for payload appended at the end of the container file.
+ // If header is found, jump to payload offset.
+ int64_t appended_header[2];
+ if (!file->SetPosition(file->Length() - sizeof(appended_header))) {
+ return nullptr;
+ }
+ if (!file->ReadFully(&appended_header, sizeof(appended_header))) {
+ return nullptr;
+ }
+ if (memcmp(&appended_header[1], appjit_magic_number.bytes,
+ appjit_magic_number.length) != 0 ||
+ appended_header[0] <= 0 || !file->SetPosition(appended_header[0])) {
+ return nullptr;
+ }
+
+ return TryReadAppSnapshotBlobs(container_path, file);
+}
+
#if defined(DART_PRECOMPILED_RUNTIME)
class DylibAppSnapshot : public AppSnapshot {
public:
diff --git a/runtime/bin/snapshot_utils.h b/runtime/bin/snapshot_utils.h
index 8f5bb1b..5b7cf82 100644
--- a/runtime/bin/snapshot_utils.h
+++ b/runtime/bin/snapshot_utils.h
@@ -37,6 +37,8 @@
const uint8_t* shared_instructions);
static void GenerateAppAOTAsAssembly(const char* snapshot_filename);
+ static AppSnapshot* TryReadAppendedAppSnapshotBlobs(
+ const char* container_path);
static AppSnapshot* TryReadAppSnapshot(const char* script_name);
static void WriteAppSnapshot(const char* filename,
uint8_t* vm_data_buffer,
diff --git a/runtime/bin/socket_base_fuchsia.cc b/runtime/bin/socket_base_fuchsia.cc
index a08257d..65a44805 100644
--- a/runtime/bin/socket_base_fuchsia.cc
+++ b/runtime/bin/socket_base_fuchsia.cc
@@ -7,20 +7,18 @@
#include "bin/socket_base.h"
-// TODO(ZX-766): If/when Fuchsia adds getifaddrs(), use that instead of the
-// ioctl in netconfig.h.
-#include <errno.h> // NOLINT
-#include <fcntl.h> // NOLINT
-#include <ifaddrs.h> // NOLINT
-#include <lib/netstack/c/netconfig.h>
-#include <net/if.h> // NOLINT
-#include <netinet/tcp.h> // NOLINT
-#include <stdio.h> // NOLINT
-#include <stdlib.h> // NOLINT
-#include <string.h> // NOLINT
-#include <sys/ioctl.h> // NOLINT
-#include <sys/stat.h> // NOLINT
-#include <unistd.h> // NOLINT
+#include <errno.h>
+#include <fuchsia/netstack/cpp/fidl.h>
+#include <ifaddrs.h>
+#include <lib/sys/cpp/service_directory.h>
+#include <net/if.h>
+#include <netinet/tcp.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <vector>
#include "bin/eventhandler.h"
#include "bin/fdutils.h"
@@ -66,9 +64,20 @@
memmove(reinterpret_cast<void*>(&addr_), sa, salen);
}
+static fidl::SynchronousInterfacePtr<fuchsia::netstack::Netstack> netstack;
+static std::once_flag once;
+
bool SocketBase::Initialize() {
- // Nothing to do on Fuchsia.
- return true;
+ static zx_status_t status;
+ std::call_once(once, [&]() {
+ auto directory = sys::ServiceDirectory::CreateFromNamespace();
+ status = directory->Connect(netstack.NewRequest());
+ if (status != ZX_OK) {
+ LOG_ERR("Initialize: connecting to fuchsia.netstack failed: %s\n",
+ zx_status_get_string(status));
+ }
+ });
+ return status == ZX_OK;
}
bool SocketBase::FormatNumericAddress(const RawAddr& addr,
@@ -264,13 +273,6 @@
return (result == 1);
}
-static bool ShouldIncludeIfaAddrs(netc_if_info_t* if_info, int lookup_family) {
- const int family = if_info->addr.ss_family;
- return ((lookup_family == family) ||
- (((lookup_family == AF_UNSPEC) &&
- ((family == AF_INET) || (family == AF_INET6)))));
-}
-
bool SocketBase::ListInterfacesSupported() {
return true;
}
@@ -278,54 +280,59 @@
AddressList<InterfaceSocketAddress>* SocketBase::ListInterfaces(
int type,
OSError** os_error) {
- // We need a dummy socket.
- const int fd = socket(AF_INET6, SOCK_STREAM, 0);
- if (fd < 0) {
- LOG_ERR("ListInterfaces: socket(AF_INET, SOCK_DGRAM, 0) failed\n");
+ std::vector<fuchsia::netstack::NetInterface2> interfaces;
+ zx_status_t status = netstack->GetInterfaces2(&interfaces);
+ if (status != ZX_OK) {
+ LOG_ERR("ListInterfaces: fuchsia.netstack.GetInterfaces2 failed: %s\n",
+ zx_status_get_string(status));
+ errno = EIO;
return NULL;
}
- // Call the ioctls.
- netc_get_if_info_t get_if_info;
- const ssize_t size = ioctl_netc_get_num_ifs(fd, &get_if_info.n_info);
- if (size < 0) {
- LOG_ERR("ListInterfaces: ioctl_netc_get_num_ifs() failed");
- close(fd);
- return NULL;
- }
- for (uint32_t i = 0; i < get_if_info.n_info; i++) {
- const ssize_t size =
- ioctl_netc_get_if_info_at(fd, &i, &get_if_info.info[i]);
- if (size < 0) {
- LOG_ERR("ListInterfaces: ioctl_netc_get_if_info_at() failed");
- close(fd);
- return NULL;
- }
- }
-
// Process the results.
const int lookup_family = SocketAddress::FromType(type);
- intptr_t count = 0;
- for (intptr_t i = 0; i < get_if_info.n_info; i++) {
- if (ShouldIncludeIfaAddrs(&get_if_info.info[i], lookup_family)) {
- count++;
- }
- }
- AddressList<InterfaceSocketAddress>* addresses =
- new AddressList<InterfaceSocketAddress>(count);
+ std::remove_if(
+ interfaces.begin(), interfaces.end(),
+ [lookup_family](const auto& interface) {
+ switch (interface.addr.Which()) {
+ case fuchsia::net::IpAddress::Tag::kIpv4:
+ return !(lookup_family == AF_UNSPEC || lookup_family == AF_INET);
+ case fuchsia::net::IpAddress::Tag::kIpv6:
+ return !(lookup_family == AF_UNSPEC || lookup_family == AF_INET6);
+ case fuchsia::net::IpAddress::Tag::Invalid:
+ return true;
+ }
+ });
+
+ auto addresses = new AddressList<InterfaceSocketAddress>(interfaces.size());
int addresses_idx = 0;
- for (intptr_t i = 0; i < get_if_info.n_info; i++) {
- if (ShouldIncludeIfaAddrs(&get_if_info.info[i], lookup_family)) {
- char* ifa_name = DartUtils::ScopedCopyCString(get_if_info.info[i].name);
- InterfaceSocketAddress* isa = new InterfaceSocketAddress(
- reinterpret_cast<struct sockaddr*>(&get_if_info.info[i].addr),
- ifa_name, if_nametoindex(get_if_info.info[i].name));
- addresses->SetAt(addresses_idx, isa);
- addresses_idx++;
+ for (const auto& interface : interfaces) {
+ struct sockaddr_storage addr = {};
+ auto addr_in = reinterpret_cast<struct sockaddr_in*>(&addr);
+ auto addr_in6 = reinterpret_cast<struct sockaddr_in6*>(&addr);
+ switch (interface.addr.Which()) {
+ case fuchsia::net::IpAddress::Tag::kIpv4:
+ addr_in->sin_family = AF_INET;
+ memmove(&addr_in->sin_addr, interface.addr.ipv4().addr.data(),
+ sizeof(addr_in->sin_addr));
+ break;
+ case fuchsia::net::IpAddress::Tag::kIpv6:
+ addr_in6->sin6_family = AF_INET6;
+ memmove(&addr_in6->sin6_addr, interface.addr.ipv6().addr.data(),
+ sizeof(addr_in6->sin6_addr));
+ break;
+ case fuchsia::net::IpAddress::Tag::Invalid:
+ // Should have been filtered out above.
+ UNREACHABLE();
}
+ addresses->SetAt(addresses_idx,
+ new InterfaceSocketAddress(
+ reinterpret_cast<sockaddr*>(&addr),
+ DartUtils::ScopedCopyCString(interface.name.c_str()),
+ if_nametoindex(interface.name.c_str())));
+ addresses_idx++;
}
- close(fd);
return addresses;
}
diff --git a/runtime/bin/vmservice/server.dart b/runtime/bin/vmservice/server.dart
index 748ee68..8bae36d 100644
--- a/runtime/bin/vmservice/server.dart
+++ b/runtime/bin/vmservice/server.dart
@@ -148,6 +148,7 @@
final int _port;
final bool _originCheckDisabled;
final bool _authCodesDisabled;
+ final String _serviceInfoFilename;
HttpServer _server;
bool get running => _server != null;
@@ -165,7 +166,7 @@
// On Fuchsia, authentication codes are disabled by default. To enable, the authentication token
// would have to be written into the hub alongside the port number.
Server(this._service, this._ip, this._port, this._originCheckDisabled,
- bool authCodesDisabled)
+ bool authCodesDisabled, this._serviceInfoFilename)
: _authCodesDisabled = (authCodesDisabled || Platform.isFuchsia);
bool _isAllowedOrigin(String origin) {
@@ -369,6 +370,14 @@
client.onRequest(message); // exception free, no need to try catch
}
+ Future<void> _dumpServiceInfoToFile() async {
+ final serviceInfo = <String, dynamic>{
+ 'uri': serverAddress.toString(),
+ };
+ final file = File(_serviceInfoFilename);
+ file.writeAsString(json.encode(serviceInfo));
+ }
+
Future startup() async {
if (_server != null) {
// Already running.
@@ -426,6 +435,9 @@
serverPrint("Creating $path");
new File(path)..createSync(recursive: true);
}
+ if (_serviceInfoFilename != null && _serviceInfoFilename.isNotEmpty) {
+ _dumpServiceInfoToFile();
+ }
// Server is up and running.
_notifyServerState(serverAddress.toString());
onServerAddressChange('$serverAddress');
diff --git a/runtime/bin/vmservice/vmservice_io.dart b/runtime/bin/vmservice/vmservice_io.dart
index 6d7c55f..393f1f3 100644
--- a/runtime/bin/vmservice/vmservice_io.dart
+++ b/runtime/bin/vmservice/vmservice_io.dart
@@ -29,6 +29,9 @@
// Should the HTTP server run in devmode?
@pragma("vm:entry-point")
bool _originCheckDisabled;
+// Location of file to output VM service connection info.
+@pragma("vm:entry-point")
+String _serviceInfoFilename;
@pragma("vm:entry-point")
bool _isWindows = false;
@pragma("vm:entry-point")
@@ -48,8 +51,8 @@
// Lazily create service.
var service = new VMService();
// Lazily create server.
- server =
- new Server(service, _ip, _port, _originCheckDisabled, _authCodesDisabled);
+ server = new Server(service, _ip, _port, _originCheckDisabled,
+ _authCodesDisabled, _serviceInfoFilename);
}
Future cleanupCallback() async {
diff --git a/runtime/bin/vmservice_impl.cc b/runtime/bin/vmservice_impl.cc
index 683d4b4..b5387a7 100644
--- a/runtime/bin/vmservice_impl.cc
+++ b/runtime/bin/vmservice_impl.cc
@@ -114,6 +114,7 @@
intptr_t server_port,
bool dev_mode_server,
bool auth_codes_disabled,
+ const char* write_service_info_filename,
bool trace_loading,
bool deterministic) {
Dart_Isolate isolate = Dart_CurrentIsolate();
@@ -176,6 +177,11 @@
Dart_NewBoolean(auth_codes_disabled));
SHUTDOWN_ON_ERROR(result);
+ if (write_service_info_filename != nullptr) {
+ result = DartUtils::SetStringField(library, "_serviceInfoFilename",
+ write_service_info_filename);
+ SHUTDOWN_ON_ERROR(result);
+ }
// Are we running on Windows?
#if defined(HOST_OS_WINDOWS)
Dart_Handle is_windows = Dart_True();
diff --git a/runtime/bin/vmservice_impl.h b/runtime/bin/vmservice_impl.h
index 51e9bfc..17ec55a 100644
--- a/runtime/bin/vmservice_impl.h
+++ b/runtime/bin/vmservice_impl.h
@@ -18,6 +18,7 @@
intptr_t server_port,
bool dev_mode_server,
bool auth_codes_disabled,
+ const char* write_service_info_filename,
bool trace_loading,
bool deterministic);
diff --git a/runtime/include/dart_embedder_api.h b/runtime/include/dart_embedder_api.h
index 61b54fd..5b283ca 100644
--- a/runtime/include/dart_embedder_api.h
+++ b/runtime/include/dart_embedder_api.h
@@ -60,6 +60,10 @@
// Default port. See enum above for special values.
int port;
+ // If non-null, connection information for the VM service will be output to a
+ // file in JSON format at the location specified.
+ const char* write_service_info_filename;
+
// TODO(vegorov) document these ones.
bool dev_mode;
bool deterministic;
diff --git a/runtime/lib/async_sources.gni b/runtime/lib/async_sources.gni
index d3fef9a..86abf92 100644
--- a/runtime/lib/async_sources.gni
+++ b/runtime/lib/async_sources.gni
@@ -5,10 +5,3 @@
# This file contains all sources for the dart:async library.
async_runtime_cc_files = [ "async.cc" ]
-
-async_runtime_dart_files = [
- "async_patch.dart",
- "deferred_load_patch.dart",
- "schedule_microtask_patch.dart",
- "timer_patch.dart",
-]
diff --git a/runtime/lib/collection_sources.gni b/runtime/lib/collection_sources.gni
index c3c15fc..6a81dd3 100644
--- a/runtime/lib/collection_sources.gni
+++ b/runtime/lib/collection_sources.gni
@@ -3,10 +3,3 @@
# BSD-style license that can be found in the LICENSE file.
collection_runtime_cc_files = [ "linked_hash_map.cc" ]
-
-collection_runtime_dart_files = [
- # collection_patch.dart needs to be the first dart file because it contains
- # imports.
- "collection_patch.dart",
- "compact_hash.dart",
-]
diff --git a/runtime/lib/core_sources.gni b/runtime/lib/core_sources.gni
index 825663a..7e18428 100644
--- a/runtime/lib/core_sources.gni
+++ b/runtime/lib/core_sources.gni
@@ -24,38 +24,3 @@
"uri.cc",
"weak_property.cc",
]
-
-core_runtime_dart_files = [
- "core_patch.dart",
-
- # The above file needs to be first as it imports required libraries.
- "array.dart",
- "array_patch.dart",
- "bigint_patch.dart",
- "bool_patch.dart",
- "date_patch.dart",
- "double.dart",
- "double_patch.dart",
- "errors_patch.dart",
- "expando_patch.dart",
- "function.dart",
- "function_patch.dart",
- "growable_array.dart",
- "identical_patch.dart",
- "immutable_map.dart",
- "integers.dart",
- "integers_patch.dart",
- "invocation_mirror_patch.dart",
- "lib_prefix.dart",
- "map_patch.dart",
- "null_patch.dart",
- "object_patch.dart",
- "regexp_patch.dart",
- "stacktrace.dart",
- "stopwatch_patch.dart",
- "string_buffer_patch.dart",
- "string_patch.dart",
- "type_patch.dart",
- "uri_patch.dart",
- "weak_property.dart",
-]
diff --git a/runtime/lib/developer_sources.gni b/runtime/lib/developer_sources.gni
index a613da7..9d1260f 100644
--- a/runtime/lib/developer_sources.gni
+++ b/runtime/lib/developer_sources.gni
@@ -8,11 +8,3 @@
"profiler.cc",
"timeline.cc",
]
-
-developer_runtime_dart_files = [
- # developer.dart needs to be the first dart file because it contains
- # imports.
- "developer.dart",
- "profiler.dart",
- "timeline.dart",
-]
diff --git a/runtime/lib/ffi_sources.gni b/runtime/lib/ffi_sources.gni
index 9936dd2..85c8ef4 100644
--- a/runtime/lib/ffi_sources.gni
+++ b/runtime/lib/ffi_sources.gni
@@ -7,9 +7,3 @@
"ffi.cc",
"ffi_dynamic_library.cc",
]
-
-ffi_runtime_dart_files = [
- "ffi_patch.dart",
- "ffi_dynamic_library_patch.dart",
- "ffi_native_type_patch.dart",
-]
diff --git a/runtime/lib/internal_sources.gni b/runtime/lib/internal_sources.gni
index 7c173ab..b16eafe 100644
--- a/runtime/lib/internal_sources.gni
+++ b/runtime/lib/internal_sources.gni
@@ -4,12 +4,3 @@
# Sources that patch the library "dart:_internal".
internal_runtime_cc_files = [ "class_id.cc" ]
-
-internal_runtime_dart_files = [
- "internal_patch.dart",
-
- # The above file needs to be first as it imports required libraries.
- "class_id.dart",
- "print_patch.dart",
- "symbol_patch.dart",
-]
diff --git a/runtime/lib/isolate_sources.gni b/runtime/lib/isolate_sources.gni
index 1495aaf..be6661d 100644
--- a/runtime/lib/isolate_sources.gni
+++ b/runtime/lib/isolate_sources.gni
@@ -4,8 +4,3 @@
# This file contains all sources for the dart:isolate library.
isolate_runtime_cc_files = [ "isolate.cc" ]
-
-isolate_runtime_dart_files = [
- "isolate_patch.dart",
- "timer_impl.dart",
-]
diff --git a/runtime/lib/math_sources.gni b/runtime/lib/math_sources.gni
index 986010d..1155ac4 100644
--- a/runtime/lib/math_sources.gni
+++ b/runtime/lib/math_sources.gni
@@ -3,5 +3,3 @@
# BSD-style license that can be found in the LICENSE file.
math_runtime_cc_files = [ "math.cc" ]
-
-math_runtime_dart_files = [ "math_patch.dart" ]
diff --git a/runtime/lib/mirrors.cc b/runtime/lib/mirrors.cc
index a76d721..846e8ab 100644
--- a/runtime/lib/mirrors.cc
+++ b/runtime/lib/mirrors.cc
@@ -177,7 +177,7 @@
args.SetAt(6, is_final);
args.SetAt(7, default_value);
args.SetAt(8, metadata);
- param = CreateMirror(Symbols::_LocalParameterMirror(), args);
+ param = CreateMirror(Symbols::_ParameterMirror(), args);
results.SetAt(i, param);
}
results.MakeImmutable();
@@ -190,7 +190,7 @@
args.SetAt(0, param);
args.SetAt(1, String::Handle(param.name()));
args.SetAt(2, owner_mirror);
- return CreateMirror(Symbols::_LocalTypeVariableMirror(), args);
+ return CreateMirror(Symbols::_TypeVariableMirror(), args);
}
// We create a list in native code and let Dart code create the type mirror
@@ -225,7 +225,7 @@
args.SetAt(3, Bool::Get(cls.IsGeneric()));
args.SetAt(4, cls.IsGeneric() ? is_declaration : Bool::False());
args.SetAt(5, owner_mirror);
- return CreateMirror(Symbols::_LocalTypedefMirror(), args);
+ return CreateMirror(Symbols::_TypedefMirror(), args);
}
static RawInstance* CreateFunctionTypeMirror(const AbstractType& type) {
@@ -236,7 +236,7 @@
args.SetAt(0, MirrorReference::Handle(MirrorReference::New(cls)));
args.SetAt(1, MirrorReference::Handle(MirrorReference::New(func)));
args.SetAt(2, type);
- return CreateMirror(Symbols::_LocalFunctionTypeMirror(), args);
+ return CreateMirror(Symbols::_FunctionTypeMirror(), args);
}
static RawInstance* CreateMethodMirror(const Function& func,
@@ -276,7 +276,7 @@
kind_flags |= (static_cast<intptr_t>(is_synthetic) << Mirrors::kSynthetic);
args.SetAt(5, Smi::Handle(Smi::New(kind_flags)));
- return CreateMirror(Symbols::_LocalMethodMirror(), args);
+ return CreateMirror(Symbols::_MethodMirror(), args);
}
static RawInstance* CreateVariableMirror(const Field& field,
@@ -295,7 +295,7 @@
args.SetAt(5, Bool::Get(field.is_final()));
args.SetAt(6, Bool::Get(field.is_const()));
- return CreateMirror(Symbols::_LocalVariableMirror(), args);
+ return CreateMirror(Symbols::_VariableMirror(), args);
}
static RawInstance* CreateClassMirror(const Class& cls,
@@ -326,7 +326,7 @@
args.SetAt(6, Bool::Get(cls.is_transformed_mixin_application()));
args.SetAt(7, cls.NumTypeParameters() == 0 ? Bool::False() : is_declaration);
args.SetAt(8, Bool::Get(cls.is_enum_class()));
- return CreateMirror(Symbols::_LocalClassMirror(), args);
+ return CreateMirror(Symbols::_ClassMirror(), args);
}
static bool IsCensoredLibrary(const String& url) {
@@ -360,7 +360,7 @@
return Instance::null();
}
args.SetAt(2, str);
- return CreateMirror(Symbols::_LocalLibraryMirror(), args);
+ return CreateMirror(Symbols::_LibraryMirror(), args);
}
static RawInstance* CreateCombinatorMirror(const Object& identifiers,
@@ -368,7 +368,7 @@
const Array& args = Array::Handle(Array::New(2));
args.SetAt(0, identifiers);
args.SetAt(1, Bool::Get(is_show));
- return CreateMirror(Symbols::_LocalCombinatorMirror(), args);
+ return CreateMirror(Symbols::_CombinatorMirror(), args);
}
static RawInstance* CreateLibraryDependencyMirror(Thread* thread,
@@ -419,7 +419,7 @@
args.SetAt(4, Bool::Get(is_import));
args.SetAt(5, Bool::Get(is_deferred));
args.SetAt(6, metadata);
- return CreateMirror(Symbols::_LocalLibraryDependencyMirror(), args);
+ return CreateMirror(Symbols::_LibraryDependencyMirror(), args);
}
static RawInstance* CreateLibraryDependencyMirror(Thread* thread,
@@ -644,7 +644,7 @@
const Array& args = Array::Handle(Array::New(2));
args.SetAt(0, debug_name);
args.SetAt(1, root_library_mirror);
- return CreateMirror(Symbols::_LocalIsolateMirror(), args);
+ return CreateMirror(Symbols::_IsolateMirror(), args);
}
static void VerifyMethodKindShifts() {
@@ -653,7 +653,7 @@
Zone* zone = thread->zone();
const Library& lib = Library::Handle(zone, Library::MirrorsLibrary());
const Class& cls = Class::Handle(
- zone, lib.LookupClassAllowPrivate(Symbols::_LocalMethodMirror()));
+ zone, lib.LookupClassAllowPrivate(Symbols::_MethodMirror()));
Error& error = Error::Handle(zone);
error ^= cls.EnsureIsFinalized(thread);
ASSERT(error.IsNull());
diff --git a/runtime/lib/mirrors_sources.gni b/runtime/lib/mirrors_sources.gni
index e92dcf0..3b237a2 100644
--- a/runtime/lib/mirrors_sources.gni
+++ b/runtime/lib/mirrors_sources.gni
@@ -7,11 +7,3 @@
"mirrors.cc",
"mirrors.h",
]
-
-mirrors_runtime_dart_files = [
- # mirrors_patch.dart needs to be the first dart file because it contains
- # imports.
- "mirrors_patch.dart",
- "mirrors_impl.dart",
- "mirror_reference.dart",
-]
diff --git a/runtime/lib/typed_data_sources.gni b/runtime/lib/typed_data_sources.gni
index b10a829..feebd40 100644
--- a/runtime/lib/typed_data_sources.gni
+++ b/runtime/lib/typed_data_sources.gni
@@ -7,5 +7,3 @@
"typed_data.cc",
"simd128.cc",
]
-
-typed_data_runtime_dart_files = [ "typed_data_patch.dart" ]
diff --git a/runtime/lib/wasm.cc b/runtime/lib/wasm.cc
index 7d0c06f..d4f315d 100644
--- a/runtime/lib/wasm.cc
+++ b/runtime/lib/wasm.cc
@@ -2,27 +2,661 @@
// 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.
+#ifdef DART_ENABLE_WASM
+
+#include <memory>
+#include <sstream>
+
#include "platform/unicode.h"
+#include "third_party/wasmer/wasmer.hh"
#include "vm/bootstrap_natives.h"
+#include "vm/dart_api_state.h"
#include "vm/dart_entry.h"
+#include "vm/exceptions.h"
namespace dart {
-int callWasm(const char* name, int n) {
- return 100 * n;
+static void ThrowWasmerError() {
+ TransitionNativeToVM transition(Thread::Current());
+ String& error = String::Handle();
+ {
+ int len = wasmer_last_error_length();
+ auto raw_error = std::unique_ptr<char[]>(new char[len]);
+ int read_len = wasmer_last_error_message(raw_error.get(), len);
+ ASSERT(read_len == len);
+ error = String::NewFormatted("Wasmer error: %s", raw_error.get());
+ }
+ Exceptions::ThrowArgumentError(error);
}
-// This is a temporary API for prototyping.
+template <typename T>
+static void Finalize(void* isolate_callback_data,
+ Dart_WeakPersistentHandle handle,
+ void* peer) {
+ delete reinterpret_cast<T*>(peer);
+}
+
+static void FinalizeWasmModule(void* isolate_callback_data,
+ Dart_WeakPersistentHandle handle,
+ void* module) {
+ wasmer_module_destroy(reinterpret_cast<wasmer_module_t*>(module));
+}
+
+static void FinalizeWasmMemory(void* isolate_callback_data,
+ Dart_WeakPersistentHandle handle,
+ void* memory) {
+ wasmer_memory_destroy(reinterpret_cast<wasmer_memory_t*>(memory));
+}
+
+static std::unique_ptr<char[]> ToUTF8(const String& str) {
+ const intptr_t str_size = Utf8::Length(str);
+ auto str_raw = std::unique_ptr<char[]>(new char[str_size + 1]);
+ str.ToUTF8(reinterpret_cast<uint8_t*>(str_raw.get()), str_size);
+ str_raw[str_size] = '\0';
+ return str_raw;
+}
+
+static bool ToWasmValue(const Number& value,
+ classid_t type,
+ wasmer_value_t* out) {
+ switch (type) {
+ case kWasmInt32Cid:
+ if (!value.IsInteger()) return false;
+ out->tag = wasmer_value_tag::WASM_I32;
+ out->value.I32 = Integer::Cast(value).AsInt64Value();
+ return true;
+ case kWasmInt64Cid:
+ if (!value.IsInteger()) return false;
+ out->tag = wasmer_value_tag::WASM_I64;
+ out->value.I64 = Integer::Cast(value).AsInt64Value();
+ return true;
+ case kWasmFloatCid:
+ if (!value.IsDouble()) return false;
+ out->tag = wasmer_value_tag::WASM_F32;
+ out->value.F32 = Double::Cast(value).value();
+ return true;
+ case kWasmDoubleCid:
+ if (!value.IsDouble()) return false;
+ out->tag = wasmer_value_tag::WASM_F64;
+ out->value.F64 = Double::Cast(value).value();
+ return true;
+ default:
+ return false;
+ }
+}
+
+static RawObject* ToDartObject(wasmer_value_t ret) {
+ switch (ret.tag) {
+ case wasmer_value_tag::WASM_I32:
+ return Integer::New(ret.value.I32);
+ case wasmer_value_tag::WASM_I64:
+ return Integer::New(ret.value.I64);
+ case wasmer_value_tag::WASM_F32:
+ return Double::New(ret.value.F32);
+ case wasmer_value_tag::WASM_F64:
+ return Double::New(ret.value.F64);
+ default:
+ FATAL("Unknown WASM type");
+ return nullptr;
+ }
+}
+
+RawExternalTypedData* WasmMemoryToExternalTypedData(wasmer_memory_t* memory) {
+ uint8_t* data = wasmer_memory_data(memory);
+ uint32_t size = wasmer_memory_data_length(memory);
+ return ExternalTypedData::New(kExternalTypedDataUint8ArrayCid, data, size);
+}
+
+class WasmImports {
+ public:
+ explicit WasmImports(std::unique_ptr<char[]> module_name)
+ : _module_name(std::move(module_name)) {}
+
+ ~WasmImports() {
+ for (wasmer_global_t* global : _globals) {
+ wasmer_global_destroy(global);
+ }
+ for (const char* name : _import_names) {
+ delete[] name;
+ }
+ }
+
+ size_t NumImports() const { return _imports.length(); }
+ wasmer_import_t* RawImports() { return _imports.data(); }
+
+ void AddMemory(std::unique_ptr<char[]> name, wasmer_memory_t* memory) {
+ AddImport(std::move(name), wasmer_import_export_kind::WASM_MEMORY)->memory =
+ memory;
+ }
+
+ void AddGlobal(std::unique_ptr<char[]> name,
+ wasmer_value_t value,
+ bool mutable_) {
+ wasmer_global_t* global = wasmer_global_new(value, mutable_);
+ _globals.Add(global);
+ AddImport(std::move(name), wasmer_import_export_kind::WASM_GLOBAL)->global =
+ global;
+ }
+
+ private:
+ std::unique_ptr<char[]> _module_name;
+ MallocGrowableArray<const char*> _import_names;
+ MallocGrowableArray<wasmer_global_t*> _globals;
+ MallocGrowableArray<wasmer_import_t> _imports;
+
+ wasmer_import_export_value* AddImport(std::unique_ptr<char[]> name,
+ wasmer_import_export_kind tag) {
+ wasmer_import_t import;
+ import.module_name.bytes =
+ reinterpret_cast<const uint8_t*>(_module_name.get());
+ import.module_name.bytes_len = (uint32_t)strlen(_module_name.get());
+ import.import_name.bytes = reinterpret_cast<const uint8_t*>(name.get());
+ import.import_name.bytes_len = (uint32_t)strlen(name.get());
+ import.tag = tag;
+ _import_names.Add(name.release());
+ _imports.Add(import);
+ return &_imports.Last().value;
+ }
+
+ DISALLOW_COPY_AND_ASSIGN(WasmImports);
+};
+
+class WasmFunction {
+ public:
+ WasmFunction(MallocGrowableArray<classid_t> args,
+ classid_t ret,
+ const wasmer_export_func_t* fn)
+ : _args(std::move(args)), _ret(ret), _fn(fn) {}
+ bool IsVoid() const { return _ret == kWasmVoidCid; }
+ const MallocGrowableArray<classid_t>& args() const { return _args; }
+
+ bool SignatureMatches(const MallocGrowableArray<classid_t>& dart_args,
+ classid_t dart_ret) {
+ if (dart_args.length() != _args.length()) {
+ return false;
+ }
+ for (intptr_t i = 0; i < dart_args.length(); ++i) {
+ if (dart_args[i] != _args[i]) {
+ return false;
+ }
+ }
+ return dart_ret == _ret;
+ }
+
+ bool Call(const wasmer_value_t* params, wasmer_value_t* result) {
+ return wasmer_export_func_call(_fn, params, _args.length(), result,
+ IsVoid() ? 0 : 1) ==
+ wasmer_result_t::WASMER_OK;
+ }
+
+ void Print(std::ostream& o, const char* name) const {
+ PrintDartType(o, _ret);
+ o << ' ' << name << '(';
+ for (intptr_t i = 0; i < _args.length(); ++i) {
+ if (i > 0) o << ", ";
+ PrintDartType(o, _args[i]);
+ }
+ o << ')';
+ }
+
+ private:
+ MallocGrowableArray<classid_t> _args;
+ const classid_t _ret;
+ const wasmer_export_func_t* _fn;
+
+ static void PrintDartType(std::ostream& o, classid_t type) {
+ switch (type) {
+ case kWasmInt32Cid:
+ o << "i32";
+ break;
+ case kWasmInt64Cid:
+ o << "i64";
+ break;
+ case kWasmFloatCid:
+ o << "f32";
+ break;
+ case kWasmDoubleCid:
+ o << "f64";
+ break;
+ case kWasmVoidCid:
+ o << "void";
+ break;
+ }
+ }
+};
+
+class WasmInstance {
+ public:
+ WasmInstance() : _instance(nullptr), _exports(nullptr) {}
+
+ bool Instantiate(wasmer_module_t* module, WasmImports* imports) {
+ // Instantiate module.
+ if (wasmer_module_instantiate(module, &_instance, imports->RawImports(),
+ imports->NumImports()) !=
+ wasmer_result_t::WASMER_OK) {
+ return false;
+ }
+
+ // Load all functions.
+ wasmer_instance_exports(_instance, &_exports);
+ intptr_t num_exports = wasmer_exports_len(_exports);
+ for (intptr_t i = 0; i < num_exports; ++i) {
+ wasmer_export_t* exp = wasmer_exports_get(_exports, i);
+ if (wasmer_export_kind(exp) == wasmer_import_export_kind::WASM_FUNCTION) {
+ if (!AddFunction(exp)) {
+ return false;
+ }
+ }
+ }
+
+ return true;
+ }
+
+ ~WasmInstance() {
+ auto it = _functions.GetIterator();
+ for (auto* kv = it.Next(); kv; kv = it.Next()) {
+ delete[] kv->key;
+ delete kv->value;
+ }
+ if (_exports != nullptr) {
+ wasmer_exports_destroy(_exports);
+ }
+ if (_instance != nullptr) {
+ wasmer_instance_destroy(_instance);
+ }
+ }
+
+ WasmFunction* GetFunction(const char* name,
+ const MallocGrowableArray<classid_t>& dart_args,
+ classid_t dart_ret,
+ String* error) {
+ WasmFunction* fn = _functions.LookupValue(name);
+ if (fn == nullptr) {
+ *error = String::NewFormatted(
+ "Couldn't find a function called %s in the WASM module's exports",
+ name);
+ return nullptr;
+ }
+ if (!fn->SignatureMatches(dart_args, dart_ret)) {
+ std::stringstream sig;
+ fn->Print(sig, name);
+ *error = String::NewFormatted("Function signature doesn't match: %s",
+ sig.str().c_str());
+ return nullptr;
+ }
+ return fn;
+ }
+
+ void PrintFunctions(std::ostream& o) const {
+ o << '{' << std::endl;
+ auto it = _functions.GetIterator();
+ for (auto* kv = it.Next(); kv; kv = it.Next()) {
+ kv->value->Print(o, kv->key);
+ o << std::endl;
+ }
+ o << '}' << std::endl;
+ }
+
+ private:
+ wasmer_instance_t* _instance;
+ wasmer_exports_t* _exports;
+ MallocDirectChainedHashMap<CStringKeyValueTrait<WasmFunction*>> _functions;
+
+ static classid_t ToDartType(wasmer_value_tag wasm_type) {
+ switch (wasm_type) {
+ case wasmer_value_tag::WASM_I32:
+ return kWasmInt32Cid;
+ case wasmer_value_tag::WASM_I64:
+ return kWasmInt64Cid;
+ case wasmer_value_tag::WASM_F32:
+ return kWasmFloatCid;
+ case wasmer_value_tag::WASM_F64:
+ return kWasmDoubleCid;
+ }
+ FATAL("Unknown WASM type");
+ return 0;
+ }
+
+ bool AddFunction(wasmer_export_t* exp) {
+ const wasmer_export_func_t* fn = wasmer_export_to_func(exp);
+
+ uint32_t num_rets;
+ if (wasmer_export_func_returns_arity(fn, &num_rets) !=
+ wasmer_result_t::WASMER_OK) {
+ return false;
+ }
+ ASSERT(num_rets <= 1);
+ wasmer_value_tag wasm_ret;
+ if (wasmer_export_func_returns(fn, &wasm_ret, num_rets) !=
+ wasmer_result_t::WASMER_OK) {
+ return false;
+ }
+ classid_t ret = num_rets == 0 ? kWasmVoidCid : ToDartType(wasm_ret);
+
+ uint32_t num_args;
+ if (wasmer_export_func_params_arity(fn, &num_args) !=
+ wasmer_result_t::WASMER_OK) {
+ return false;
+ }
+ auto wasm_args =
+ std::unique_ptr<wasmer_value_tag[]>(new wasmer_value_tag[num_args]);
+ if (wasmer_export_func_params(fn, wasm_args.get(), num_args) !=
+ wasmer_result_t::WASMER_OK) {
+ return false;
+ }
+ MallocGrowableArray<classid_t> args;
+ for (intptr_t i = 0; i < num_args; ++i) {
+ args.Add(ToDartType(wasm_args[i]));
+ }
+
+ wasmer_byte_array name_bytes = wasmer_export_name(exp);
+ char* name = new char[name_bytes.bytes_len + 1];
+ for (size_t i = 0; i < name_bytes.bytes_len; ++i) {
+ name[i] = name_bytes.bytes[i];
+ }
+ name[name_bytes.bytes_len] = '\0';
+
+ _functions.Insert({name, new WasmFunction(std::move(args), ret, fn)});
+ return true;
+ }
+
+ DISALLOW_COPY_AND_ASSIGN(WasmInstance);
+};
+
+DEFINE_NATIVE_ENTRY(Wasm_initModule, 0, 2) {
+ GET_NON_NULL_NATIVE_ARGUMENT(Instance, mod_wrap, arguments->NativeArgAt(0));
+ GET_NON_NULL_NATIVE_ARGUMENT(TypedDataBase, data, arguments->NativeArgAt(1));
+
+ ASSERT(mod_wrap.NumNativeFields() == 1);
+
+ std::unique_ptr<uint8_t[]> data_copy;
+ intptr_t len;
+ {
+ NoSafepointScope scope(thread);
+ len = data.LengthInBytes();
+ data_copy = std::unique_ptr<uint8_t[]>(new uint8_t[len]);
+ // The memory does not overlap.
+ memcpy(data_copy.get(), data.DataAddr(0), len); // NOLINT
+ }
+
+ wasmer_module_t* module;
+ {
+ TransitionVMToNative transition(thread);
+ if (wasmer_compile(&module, data_copy.get(), len) !=
+ wasmer_result_t::WASMER_OK) {
+ data_copy.reset();
+ ThrowWasmerError();
+ }
+ }
+
+ mod_wrap.SetNativeField(0, reinterpret_cast<intptr_t>(module));
+ FinalizablePersistentHandle::New(thread->isolate(), mod_wrap, module,
+ FinalizeWasmModule, len);
+
+ return Object::null();
+}
+
+DEFINE_NATIVE_ENTRY(Wasm_initImports, 0, 2) {
+ GET_NON_NULL_NATIVE_ARGUMENT(Instance, imp_wrap, arguments->NativeArgAt(0));
+ GET_NON_NULL_NATIVE_ARGUMENT(String, module_name, arguments->NativeArgAt(1));
+
+ ASSERT(imp_wrap.NumNativeFields() == 1);
+
+ WasmImports* imports = new WasmImports(ToUTF8(module_name));
+
+ imp_wrap.SetNativeField(0, reinterpret_cast<intptr_t>(imports));
+ FinalizablePersistentHandle::New(thread->isolate(), imp_wrap, imports,
+ Finalize<WasmImports>, sizeof(WasmImports));
+
+ return Object::null();
+}
+
+DEFINE_NATIVE_ENTRY(Wasm_addMemoryImport, 0, 3) {
+ GET_NON_NULL_NATIVE_ARGUMENT(Instance, imp_wrap, arguments->NativeArgAt(0));
+ GET_NON_NULL_NATIVE_ARGUMENT(String, name, arguments->NativeArgAt(1));
+ GET_NON_NULL_NATIVE_ARGUMENT(Instance, mem_wrap, arguments->NativeArgAt(2));
+
+ ASSERT(imp_wrap.NumNativeFields() == 1);
+ ASSERT(mem_wrap.NumNativeFields() == 1);
+
+ WasmImports* imports =
+ reinterpret_cast<WasmImports*>(imp_wrap.GetNativeField(0));
+ wasmer_memory_t* memory =
+ reinterpret_cast<wasmer_memory_t*>(mem_wrap.GetNativeField(0));
+
+ imports->AddMemory(ToUTF8(name), memory);
+
+ return Object::null();
+}
+
+DEFINE_NATIVE_ENTRY(Wasm_addGlobalImport, 0, 5) {
+ GET_NON_NULL_NATIVE_ARGUMENT(Instance, imp_wrap, arguments->NativeArgAt(0));
+ GET_NON_NULL_NATIVE_ARGUMENT(String, name, arguments->NativeArgAt(1));
+ GET_NON_NULL_NATIVE_ARGUMENT(Number, value, arguments->NativeArgAt(2));
+ GET_NON_NULL_NATIVE_ARGUMENT(Type, type, arguments->NativeArgAt(3));
+ GET_NON_NULL_NATIVE_ARGUMENT(Bool, mutable_, arguments->NativeArgAt(4));
+
+ ASSERT(imp_wrap.NumNativeFields() == 1);
+
+ WasmImports* imports =
+ reinterpret_cast<WasmImports*>(imp_wrap.GetNativeField(0));
+ wasmer_value_t wasm_value;
+ if (!ToWasmValue(value, type.type_class_id(), &wasm_value)) {
+ Exceptions::ThrowArgumentError(String::Handle(String::NewFormatted(
+ "Can't convert dart value to WASM global variable")));
+ }
+
+ imports->AddGlobal(ToUTF8(name), wasm_value, mutable_.value());
+
+ return Object::null();
+}
+
+DEFINE_NATIVE_ENTRY(Wasm_initMemory, 0, 3) {
+ GET_NON_NULL_NATIVE_ARGUMENT(Instance, mem_wrap, arguments->NativeArgAt(0));
+ GET_NON_NULL_NATIVE_ARGUMENT(Integer, init, arguments->NativeArgAt(1));
+ GET_NATIVE_ARGUMENT(Integer, max, arguments->NativeArgAt(2));
+
+ ASSERT(mem_wrap.NumNativeFields() == 1);
+ const int64_t init_size = init.AsInt64Value();
+ const int64_t max_size = max.AsInt64Value();
+
+ wasmer_memory_t* memory;
+ wasmer_limits_t descriptor;
+ descriptor.min = init_size;
+ if (max_size < 0) {
+ descriptor.max.has_some = false;
+ } else {
+ descriptor.max.has_some = true;
+ descriptor.max.some = max_size;
+ }
+ if (wasmer_memory_new(&memory, descriptor) != wasmer_result_t::WASMER_OK) {
+ ThrowWasmerError();
+ }
+ mem_wrap.SetNativeField(0, reinterpret_cast<intptr_t>(memory));
+ FinalizablePersistentHandle::New(thread->isolate(), mem_wrap, memory,
+ FinalizeWasmMemory, init_size);
+ return WasmMemoryToExternalTypedData(memory);
+}
+
+DEFINE_NATIVE_ENTRY(Wasm_growMemory, 0, 2) {
+ GET_NON_NULL_NATIVE_ARGUMENT(Instance, mem_wrap, arguments->NativeArgAt(0));
+ GET_NON_NULL_NATIVE_ARGUMENT(Integer, delta, arguments->NativeArgAt(1));
+
+ ASSERT(mem_wrap.NumNativeFields() == 1);
+
+ wasmer_memory_t* memory =
+ reinterpret_cast<wasmer_memory_t*>(mem_wrap.GetNativeField(0));
+ if (wasmer_memory_grow(memory, delta.AsInt64Value()) !=
+ wasmer_result_t::WASMER_OK) {
+ ThrowWasmerError();
+ }
+ return WasmMemoryToExternalTypedData(memory);
+}
+
+DEFINE_NATIVE_ENTRY(Wasm_initInstance, 0, 3) {
+ GET_NON_NULL_NATIVE_ARGUMENT(Instance, inst_wrap, arguments->NativeArgAt(0));
+ GET_NON_NULL_NATIVE_ARGUMENT(Instance, mod_wrap, arguments->NativeArgAt(1));
+ GET_NON_NULL_NATIVE_ARGUMENT(Instance, imp_wrap, arguments->NativeArgAt(2));
+
+ ASSERT(inst_wrap.NumNativeFields() == 1);
+ ASSERT(mod_wrap.NumNativeFields() == 1);
+ ASSERT(imp_wrap.NumNativeFields() == 1);
+
+ wasmer_module_t* module =
+ reinterpret_cast<wasmer_module_t*>(mod_wrap.GetNativeField(0));
+ WasmImports* imports =
+ reinterpret_cast<WasmImports*>(imp_wrap.GetNativeField(0));
+
+ WasmInstance* inst = nullptr;
+ {
+ TransitionVMToNative transition(thread);
+ inst = new WasmInstance();
+ if (!inst->Instantiate(module, imports)) {
+ delete inst;
+ inst = nullptr;
+ }
+ }
+ if (inst == nullptr) {
+ ThrowWasmerError();
+ }
+
+ inst_wrap.SetNativeField(0, reinterpret_cast<intptr_t>(inst));
+ FinalizablePersistentHandle::New(thread->isolate(), inst_wrap, inst,
+ Finalize<WasmInstance>,
+ sizeof(WasmInstance));
+
+ return Object::null();
+}
+
+DEFINE_NATIVE_ENTRY(Wasm_initFunction, 0, 4) {
+ GET_NON_NULL_NATIVE_ARGUMENT(Instance, fn_wrap, arguments->NativeArgAt(0));
+ GET_NON_NULL_NATIVE_ARGUMENT(Instance, inst_wrap, arguments->NativeArgAt(1));
+ GET_NON_NULL_NATIVE_ARGUMENT(String, name, arguments->NativeArgAt(2));
+ GET_NON_NULL_NATIVE_ARGUMENT(Type, fn_type, arguments->NativeArgAt(3));
+
+ ASSERT(fn_wrap.NumNativeFields() == 1);
+ ASSERT(inst_wrap.NumNativeFields() == 1);
+
+ WasmInstance* inst =
+ reinterpret_cast<WasmInstance*>(inst_wrap.GetNativeField(0));
+
+ WasmFunction* fn;
+ String& error = String::Handle(zone);
+
+ {
+ Function& sig = Function::Handle(fn_type.signature());
+ Array& args = Array::Handle(sig.parameter_types());
+ MallocGrowableArray<classid_t> dart_args;
+ for (intptr_t i = sig.NumImplicitParameters(); i < args.Length(); ++i) {
+ dart_args.Add(
+ AbstractType::Cast(Object::Handle(args.At(i))).type_class_id());
+ }
+ classid_t dart_ret =
+ AbstractType::Handle(sig.result_type()).type_class_id();
+
+ std::unique_ptr<char[]> name_raw = ToUTF8(name);
+ fn = inst->GetFunction(name_raw.get(), dart_args, dart_ret, &error);
+ }
+
+ if (fn == nullptr) {
+ Exceptions::ThrowArgumentError(error);
+ }
+
+ fn_wrap.SetNativeField(0, reinterpret_cast<intptr_t>(fn));
+ // Don't need a finalizer because WasmFunctions are owned their WasmInstance.
+
+ return Object::null();
+}
+
DEFINE_NATIVE_ENTRY(Wasm_callFunction, 0, 2) {
- GET_NON_NULL_NATIVE_ARGUMENT(String, fn_name, arguments->NativeArgAt(0));
- GET_NON_NULL_NATIVE_ARGUMENT(Integer, arg, arguments->NativeArgAt(1));
+ GET_NON_NULL_NATIVE_ARGUMENT(Instance, fn_wrap, arguments->NativeArgAt(0));
+ GET_NON_NULL_NATIVE_ARGUMENT(Array, args, arguments->NativeArgAt(1));
- intptr_t len = Utf8::Length(fn_name);
- std::unique_ptr<char> name = std::unique_ptr<char>(new char[len + 1]);
- fn_name.ToUTF8(reinterpret_cast<uint8_t*>(name.get()), len);
- name.get()[len] = 0;
+ ASSERT(fn_wrap.NumNativeFields() == 1);
+ WasmFunction* fn = reinterpret_cast<WasmFunction*>(fn_wrap.GetNativeField(0));
- return Smi::New(callWasm(name.get(), arg.AsInt64Value()));
+ if (args.Length() != fn->args().length()) {
+ Exceptions::ThrowArgumentError(String::Handle(String::NewFormatted(
+ "Wrong number of args. Expected %" Pu " but found %" Pd ".",
+ fn->args().length(), args.Length())));
+ }
+ auto params = std::unique_ptr<wasmer_value_t[]>(
+ new wasmer_value_t[fn->args().length()]);
+ for (intptr_t i = 0; i < args.Length(); ++i) {
+ if (!ToWasmValue(Number::Cast(Object::Handle(args.At(i))), fn->args()[i],
+ ¶ms[i])) {
+ params.reset();
+ Exceptions::ThrowArgumentError(String::Handle(
+ String::NewFormatted("Arg %" Pd " is the wrong type.", i)));
+ }
+ }
+
+ wasmer_value_t ret;
+ {
+ TransitionVMToNative transition(thread);
+ if (!fn->Call(params.get(), &ret)) {
+ params.reset();
+ ThrowWasmerError();
+ }
+ }
+ return fn->IsVoid() ? Object::null() : ToDartObject(ret);
}
} // namespace dart
+
+#else // DART_ENABLE_WASM
+
+#include "vm/bootstrap_natives.h"
+#include "vm/dart_entry.h"
+#include "vm/exceptions.h"
+
+namespace dart {
+
+DEFINE_NATIVE_ENTRY(Wasm_initModule, 0, 2) {
+ Exceptions::ThrowUnsupportedError("WASM is disabled");
+ return nullptr;
+}
+
+DEFINE_NATIVE_ENTRY(Wasm_initImports, 0, 2) {
+ Exceptions::ThrowUnsupportedError("WASM is disabled");
+ return nullptr;
+}
+
+DEFINE_NATIVE_ENTRY(Wasm_addMemoryImport, 0, 3) {
+ Exceptions::ThrowUnsupportedError("WASM is disabled");
+ return nullptr;
+}
+
+DEFINE_NATIVE_ENTRY(Wasm_addGlobalImport, 0, 5) {
+ Exceptions::ThrowUnsupportedError("WASM is disabled");
+ return nullptr;
+}
+
+DEFINE_NATIVE_ENTRY(Wasm_initMemory, 0, 3) {
+ Exceptions::ThrowUnsupportedError("WASM is disabled");
+ return nullptr;
+}
+
+DEFINE_NATIVE_ENTRY(Wasm_growMemory, 0, 3) {
+ Exceptions::ThrowUnsupportedError("WASM is disabled");
+ return nullptr;
+}
+
+DEFINE_NATIVE_ENTRY(Wasm_initInstance, 0, 3) {
+ Exceptions::ThrowUnsupportedError("WASM is disabled");
+ return nullptr;
+}
+
+DEFINE_NATIVE_ENTRY(Wasm_initFunction, 0, 4) {
+ Exceptions::ThrowUnsupportedError("WASM is disabled");
+ return nullptr;
+}
+
+DEFINE_NATIVE_ENTRY(Wasm_callFunction, 0, 2) {
+ Exceptions::ThrowUnsupportedError("WASM is disabled");
+ return nullptr;
+}
+
+} // namespace dart
+
+#endif // DART_ENABLE_WASM
diff --git a/runtime/lib/wasm_sources.gni b/runtime/lib/wasm_sources.gni
index 6067612..2e7faff 100644
--- a/runtime/lib/wasm_sources.gni
+++ b/runtime/lib/wasm_sources.gni
@@ -3,5 +3,3 @@
# BSD-style license that can be found in the LICENSE file.
wasm_runtime_cc_files = [ "wasm.cc" ]
-
-wasm_runtime_dart_files = [ "wasm_patch.dart" ]
diff --git a/runtime/observatory/lib/src/elements/native_memory_profiler.dart b/runtime/observatory/lib/src/elements/native_memory_profiler.dart
index 4d874b5..dfbe459 100644
--- a/runtime/observatory/lib/src/elements/native_memory_profiler.dart
+++ b/runtime/observatory/lib/src/elements/native_memory_profiler.dart
@@ -145,6 +145,11 @@
}
Future _request({bool forceFetch: false}) async {
+ if (forceFetch) {
+ for (M.Isolate isolate in _vm.isolates) {
+ await isolate.collectAllGarbage();
+ }
+ }
_progress = null;
_progressStream = _profiles.get(_vm, _tag, forceFetch: forceFetch);
_r.dirty();
diff --git a/runtime/observatory/lib/src/models/objects/isolate.dart b/runtime/observatory/lib/src/models/objects/isolate.dart
index f1d1147..039e0bd 100644
--- a/runtime/observatory/lib/src/models/objects/isolate.dart
+++ b/runtime/observatory/lib/src/models/objects/isolate.dart
@@ -14,6 +14,9 @@
/// A name identifying this isolate. Not guaranteed to be unique.
String get name;
+
+ /// Trigger a full GC, collecting all unreachable or weakly reachable objects.
+ Future collectAllGarbage();
}
enum IsolateStatus { loading, idle, running, paused }
diff --git a/runtime/observatory/lib/src/service/object.dart b/runtime/observatory/lib/src/service/object.dart
index afbb7cc..fffb41c 100644
--- a/runtime/observatory/lib/src/service/object.dart
+++ b/runtime/observatory/lib/src/service/object.dart
@@ -1330,6 +1330,10 @@
}
}
+ Future collectAllGarbage() {
+ return invokeRpc('_collectAllGarbage', {});
+ }
+
/// Fetches and builds the class hierarchy for this isolate. Returns the
/// Object class object.
Future<Class> getClassHierarchy() async {
diff --git a/runtime/observatory/tests/service/add_breakpoint_rpc_test.dart b/runtime/observatory/tests/service/add_breakpoint_rpc_test.dart
deleted file mode 100644
index 4c2c388..0000000
--- a/runtime/observatory/tests/service/add_breakpoint_rpc_test.dart
+++ /dev/null
@@ -1,139 +0,0 @@
-// Copyright (c) 2015, 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.
-
-import 'package:observatory/service_io.dart';
-import 'package:unittest/unittest.dart';
-import 'service_test_common.dart';
-import 'test_helper.dart';
-import 'dart:async';
-
-const int LINE_A = 22;
-const int LINE_B = 24;
-
-int value = 0;
-
-int incValue(int amount) {
- value += amount;
- return amount;
-}
-
-Future testMain() async {
- incValue(incValue(1)); // line A.
-
- incValue(incValue(1)); // line B.
-}
-
-var tests = <IsolateTest>[
- hasPausedAtStart,
-
- // Test future breakpoints.
- (Isolate isolate) async {
- var rootLib = isolate.rootLibrary;
- await rootLib.load();
- var script = rootLib.scripts[0];
-
- // Future breakpoint.
- var futureBpt1 = await isolate.addBreakpoint(script, LINE_A);
- expect(futureBpt1.number, equals(1));
- expect(futureBpt1.resolved, isFalse);
- expect(await futureBpt1.location.getLine(), equals(LINE_A));
- expect(await futureBpt1.location.getColumn(), equals(null));
-
- // Future breakpoint with specific column.
- var futureBpt2 = await isolate.addBreakpoint(script, LINE_A, 3);
- expect(futureBpt2.number, equals(2));
- expect(futureBpt2.resolved, isFalse);
- expect(await futureBpt2.location.getLine(), equals(LINE_A));
- expect(await futureBpt2.location.getColumn(), equals(3));
-
- var stream = await isolate.vm.getEventStream(VM.kDebugStream);
- Completer completer = new Completer();
- var subscription;
- var resolvedCount = 0;
- subscription = stream.listen((ServiceEvent event) async {
- if (event.kind == ServiceEvent.kBreakpointResolved) {
- resolvedCount++;
- }
- if (event.kind == ServiceEvent.kPauseBreakpoint) {
- subscription.cancel();
- completer.complete();
- }
- });
- await isolate.resume();
- await completer.future;
-
- // After resolution the breakpoints have assigned line & column.
- expect(resolvedCount, equals(2));
- expect(futureBpt1.resolved, isTrue);
- expect(await futureBpt1.location.getLine(), equals(LINE_A));
- expect(await futureBpt1.location.getColumn(), equals(12));
- expect(futureBpt2.resolved, isTrue);
- expect(await futureBpt2.location.getLine(), equals(LINE_A));
- expect(await futureBpt2.location.getColumn(), equals(3));
-
- // The first breakpoint hits before value is modified.
- expect(((await rootLib.evaluate('value')) as Instance).valueAsString,
- equals('0'));
-
- stream = await isolate.vm.getEventStream(VM.kDebugStream);
- completer = new Completer();
- subscription = stream.listen((ServiceEvent event) async {
- if (event.kind == ServiceEvent.kPauseBreakpoint) {
- subscription.cancel();
- completer.complete();
- }
- });
- await isolate.resume();
- await completer.future;
-
- // The second breakpoint hits after value has been modified once.
- expect(((await rootLib.evaluate('value')) as Instance).valueAsString,
- equals('1'));
-
- // Remove the breakpoints.
- expect(
- (await isolate.removeBreakpoint(futureBpt1)).type, equals('Success'));
- expect(
- (await isolate.removeBreakpoint(futureBpt2)).type, equals('Success'));
- },
-
- // Test resolution of column breakpoints.
- (Isolate isolate) async {
- var script = isolate.rootLibrary.scripts[0];
- // Try all columns, including some columns that are too big.
- for (int col = 1; col <= 50; col++) {
- var bpt = await isolate.addBreakpoint(script, LINE_A, col);
- expect(bpt.resolved, isTrue);
- int resolvedLine = await bpt.location.getLine();
- int resolvedCol = await bpt.location.getColumn();
- print('20:${col} -> ${resolvedLine}:${resolvedCol}');
- if (col <= 12) {
- expect(resolvedLine, equals(LINE_A));
- expect(resolvedCol, equals(3));
- } else if (col <= 36) {
- expect(resolvedLine, equals(LINE_A));
- expect(resolvedCol, equals(12));
- } else {
- expect(resolvedLine, equals(LINE_B));
- expect(resolvedCol, equals(12));
- }
- expect((await isolate.removeBreakpoint(bpt)).type, equals('Success'));
- }
-
- // Make sure that a zero column is an error.
- var caughtException = false;
- try {
- await isolate.addBreakpoint(script, 20, 0);
- expect(false, isTrue, reason: 'Unreachable');
- } on ServerRpcException catch (e) {
- caughtException = true;
- expect(e.code, equals(ServerRpcException.kInvalidParams));
- expect(e.message, "addBreakpoint: invalid 'column' parameter: 0");
- }
- expect(caughtException, isTrue);
- },
-];
-
-main(args) => runIsolateTests(args, tests,
- testeeConcurrent: testMain, pause_on_start: true);
diff --git a/runtime/observatory/tests/service/collect_all_garbage_test.dart b/runtime/observatory/tests/service/collect_all_garbage_test.dart
new file mode 100644
index 0000000..8db2921
--- /dev/null
+++ b/runtime/observatory/tests/service/collect_all_garbage_test.dart
@@ -0,0 +1,17 @@
+// Copyright (c) 2017, 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.
+
+import 'package:observatory/service_io.dart';
+import 'package:unittest/unittest.dart';
+
+import 'test_helper.dart';
+
+var tests = <IsolateTest>[
+ (Isolate isolate) async {
+ var result = await isolate.invokeRpcNoUpgrade('_collectAllGarbage', {});
+ expect(result['type'], equals('Success'));
+ },
+];
+
+main(args) async => runIsolateTests(args, tests);
diff --git a/runtime/observatory/tests/service/coverage_const_field_test.dart b/runtime/observatory/tests/service/coverage_const_field_test.dart
new file mode 100644
index 0000000..9184a23
--- /dev/null
+++ b/runtime/observatory/tests/service/coverage_const_field_test.dart
@@ -0,0 +1,66 @@
+// Copyright (c) 2019, 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.
+
+import 'dart:developer';
+import 'package:observatory/service_io.dart';
+import 'package:unittest/unittest.dart';
+import 'service_test_common.dart';
+import 'test_helper.dart';
+
+const int LINE = 14;
+
+class Bar {
+ static const String field = "field"; // LINE
+}
+
+void testFunction() {
+ debugger();
+}
+
+var tests = <IsolateTest>[
+ hasStoppedAtBreakpoint,
+ (Isolate isolate) async {
+ var stack = await isolate.getStack();
+
+ // Make sure we are in the right place.
+ expect(stack.type, 'Stack');
+ expect(stack['frames'].length, greaterThanOrEqualTo(1));
+ expect(stack['frames'][0].function.name, 'testFunction');
+
+ var root = isolate.rootLibrary;
+ await root.load();
+ Script script = root.scripts.first;
+ await script.load();
+
+ var params = {
+ 'reports': ['Coverage'],
+ 'scriptId': script.id,
+ 'forceCompile': true
+ };
+ var report = await isolate.invokeRpcNoUpgrade('getSourceReport', params);
+ List<dynamic> ranges = report['ranges'];
+
+ int match = 0;
+ for (var range in ranges) {
+ for (int i in range["coverage"]["hits"]) {
+ int line = script.tokenToLine(i);
+ if (line == null) {
+ throw FormatException('token ${i} was missing source location');
+ }
+ // Check LINE.
+ if (line == LINE) {
+ match = (match | 1);
+ } else if (line == LINE - 3) {
+ // static const field LINE is defined at LINE - 3.
+ match = (match | 2);
+ }
+ }
+ }
+ // Neither LINE nor Bar.field should be added into coverage.
+ expect(match, 0);
+ },
+ resumeIsolate
+];
+
+main(args) => runIsolateTests(args, tests, testeeConcurrent: testFunction);
diff --git a/runtime/observatory/tests/service/coverage_leaf_function_test.dart b/runtime/observatory/tests/service/coverage_leaf_function_test.dart
index f178426..a90ec86 100644
--- a/runtime/observatory/tests/service/coverage_leaf_function_test.dart
+++ b/runtime/observatory/tests/service/coverage_leaf_function_test.dart
@@ -44,12 +44,12 @@
var expectedRange = {
'scriptIndex': 0,
- 'startPos': ifKernel(392, 26),
- 'endPos': ifKernel(442, 38),
+ 'startPos': 392,
+ 'endPos': 442,
'compiled': true,
'coverage': {
- 'hits': ifKernel([], []),
- 'misses': ifKernel([392], [26])
+ 'hits': [],
+ 'misses': [392]
}
};
@@ -85,12 +85,12 @@
var expectedRange = {
'scriptIndex': 0,
- 'startPos': ifKernel(392, 26),
- 'endPos': ifKernel(442, 38),
+ 'startPos': 392,
+ 'endPos': 442,
'compiled': true,
'coverage': {
- 'hits': ifKernel([392], [26]),
- 'misses': ifKernel([], [])
+ 'hits': [392],
+ 'misses': []
}
};
diff --git a/runtime/observatory/tests/service/coverage_optimized_function_test.dart b/runtime/observatory/tests/service/coverage_optimized_function_test.dart
index e7a38e7..8d68907 100644
--- a/runtime/observatory/tests/service/coverage_optimized_function_test.dart
+++ b/runtime/observatory/tests/service/coverage_optimized_function_test.dart
@@ -37,12 +37,12 @@
var expectedRange = {
'scriptIndex': 0,
- 'startPos': ifKernel(469, 26),
- 'endPos': ifKernel(536, 51),
+ 'startPos': 469,
+ 'endPos': 536,
'compiled': true,
'coverage': {
- 'hits': ifKernel([469, 509, 520, 524], [26, 37, 41, 45]),
- 'misses': ifKernel([], [])
+ 'hits': [469, 509, 520, 524],
+ 'misses': []
}
};
diff --git a/runtime/observatory/tests/service/get_object_rpc_test.dart b/runtime/observatory/tests/service/get_object_rpc_test.dart
index 3f0ff6c..de51a71 100644
--- a/runtime/observatory/tests/service/get_object_rpc_test.dart
+++ b/runtime/observatory/tests/service/get_object_rpc_test.dart
@@ -703,7 +703,7 @@
expect(result['id'], startsWith('libraries/'));
expect(result['uri'], startsWith('file:'));
expect(result['uri'], endsWith('get_object_rpc_test.dart'));
- expect(result['_kind'], equals(ifKernel('kernel', 'script')));
+ expect(result['_kind'], equals('kernel'));
expect(result['library']['type'], equals('@Library'));
expect(result['source'], startsWith('// Copyright (c)'));
expect(result['tokenPosTable'].length, isPositive);
diff --git a/runtime/observatory/tests/service/get_source_report_test.dart b/runtime/observatory/tests/service/get_source_report_test.dart
index 7627ef3..7abd05e 100644
--- a/runtime/observatory/tests/service/get_source_report_test.dart
+++ b/runtime/observatory/tests/service/get_source_report_test.dart
@@ -73,12 +73,12 @@
var expectedRange = {
'scriptIndex': 0,
- 'startPos': ifKernel(432, 40),
- 'endPos': ifKernel(576, 89),
+ 'startPos': 432,
+ 'endPos': 576,
'compiled': true,
'coverage': {
- 'hits': ifKernel([432, 482, 533, 562], [40, 55, 73, 83]),
- 'misses': ifKernel([495], [61])
+ 'hits': [432, 482, 533, 562],
+ 'misses': [495],
}
};
diff --git a/runtime/observatory/tests/service/service.status b/runtime/observatory/tests/service/service.status
index 0cdbc33..ea1e417 100644
--- a/runtime/observatory/tests/service/service.status
+++ b/runtime/observatory/tests/service/service.status
@@ -20,11 +20,6 @@
developer_extension_test: SkipByDesign
get_isolate_after_language_error_test: SkipByDesign
-# Kernel version of tests
-[ $compiler != dartk ]
-add_breakpoint_rpc_kernel_test: SkipByDesign # kernel specific version of add_breakpoint_rpc_test
-evaluate_function_type_parameters_test: SkipByDesign # only supported in kernel
-
# Service protocol is not supported in product mode.
[ $mode == product ]
*: SkipByDesign
diff --git a/runtime/observatory/tests/service/service_kernel.status b/runtime/observatory/tests/service/service_kernel.status
index 4a4cf8f..316e3f2 100644
--- a/runtime/observatory/tests/service/service_kernel.status
+++ b/runtime/observatory/tests/service/service_kernel.status
@@ -3,7 +3,6 @@
# BSD-style license that can be found in the LICENSE file.
[ $compiler == app_jitk ]
-add_breakpoint_rpc_test: SkipByDesign # non-kernel specific version of add_breakpoint_rpc_kernel_test.
async_generator_breakpoint_test: SkipByDesign # No incremental compiler available.
bad_reload_test: RuntimeError
break_on_activation_test: SkipByDesign # No incremental compiler available.
@@ -158,10 +157,7 @@
simple_reload_test: RuntimeError, Timeout
valid_source_locations_test: Pass, Slow, Timeout # Issue 34736
-# Kernel works slightly different. There are kernel specific versions.
-# These are the non-kernel specific versions so skip tests and allow errors.
[ $compiler == dartk || $compiler == dartkb ]
-add_breakpoint_rpc_test: SkipByDesign # non-kernel specific version of add_breakpoint_rpc_kernel_test.
bad_reload_test: RuntimeError # Issue 34025
coverage_optimized_function_test: Pass, Slow
evaluate_activation_in_method_class_test: RuntimeError # Issue 35505
diff --git a/runtime/observatory/tests/service/service_test_common.dart b/runtime/observatory/tests/service/service_test_common.dart
index 87893bc..e7f831f 100644
--- a/runtime/observatory/tests/service/service_test_common.dart
+++ b/runtime/observatory/tests/service/service_test_common.dart
@@ -579,36 +579,3 @@
}
return result;
}
-
-bool isKernel() {
- for (String argument in Platform.executableArguments) {
- if (argument.startsWith("--no-preview_dart_2")) return false;
- if (argument.startsWith("--no-preview-dart-2")) return false;
- }
- return true;
-}
-
-E ifKernel<E>(E then, E otherwise) {
- if (isKernel()) return then;
- return otherwise;
-}
-
-void ifKernelExecute(Function kernelFunction, Function nonKernelFunction) {
- if (isKernel()) {
- kernelFunction();
- } else {
- nonKernelFunction();
- }
-}
-
-void nonKernelExecute(Function nonKernelFunction) {
- if (!isKernel()) {
- nonKernelFunction();
- }
-}
-
-void kernelExecute(Function kernelFunction) {
- if (isKernel()) {
- kernelFunction();
- }
-}
diff --git a/runtime/observatory/tests/service/yield_positions_with_finally_test.dart b/runtime/observatory/tests/service/yield_positions_with_finally_test.dart
new file mode 100644
index 0000000..af9643b
--- /dev/null
+++ b/runtime/observatory/tests/service/yield_positions_with_finally_test.dart
@@ -0,0 +1,212 @@
+// Copyright (c) 2019, 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.
+import 'dart:developer';
+import 'package:observatory/service_io.dart';
+import 'package:unittest/unittest.dart';
+import 'service_test_common.dart';
+import 'test_helper.dart';
+
+const int LINE = 106;
+const int LINE_A = 23;
+const int LINE_B = 36;
+const int LINE_C = 47;
+const int LINE_D = 61;
+const int LINE_E = 78;
+const int LINE_F = 93;
+
+// break statement
+Stream<int> testBreak() async* {
+ for (int t = 0; t < 10; t++) {
+ try {
+ if (t == 1) break;
+ await throwException(); // LINE_A
+ } catch (e) {} finally {
+ yield t;
+ }
+ }
+}
+
+// return statement
+Stream<int> testReturn() async* {
+ for (int t = 0; t < 10; t++) {
+ try {
+ yield t;
+ if (t == 1) return;
+ await throwException(); // LINE_B
+ } catch (e) {} finally {
+ yield t;
+ }
+ }
+}
+
+// Multiple functions
+Stream<int> testMultipleFunctions() async* {
+ try {
+ yield 0;
+ await throwException(); // LINE_C
+ } catch (e) {} finally {
+ yield 1;
+ }
+}
+
+// continue statement
+Stream<int> testContinueSwitch() async* {
+ int currentState = 0;
+ switch (currentState) {
+ case 0:
+ {
+ try {
+ if (currentState == 1) continue label;
+ await throwException(); // LINE_D
+ } catch (e) {} finally {
+ yield 0;
+ }
+ yield 1;
+ break;
+ }
+ label:
+ case 1:
+ break;
+ }
+}
+
+Stream<int> testNestFinally() async* {
+ int i = 0;
+ try {
+ if (i == 1) return;
+ await throwException(); //LINE_E
+ } catch (e) {} finally {
+ try {
+ yield i;
+ } finally {
+ yield 1;
+ }
+ yield 1;
+ }
+}
+
+Stream<int> testAsyncClosureInFinally() async* {
+ int i = 0;
+ try {
+ if (i == 1) return;
+ await throwException(); //LINE_F
+ } catch (e) {} finally {
+ inner() async {
+ await Future.delayed(Duration(milliseconds: 10));
+ }
+
+ await inner;
+ yield 1;
+ }
+}
+
+Future<void> throwException() async {
+ await Future.delayed(Duration(milliseconds: 10));
+ throw new Exception(""); // LINE
+}
+
+code() async {
+ await for (var x in testBreak()) {}
+ await for (var x in testReturn()) {}
+ await for (var x in testMultipleFunctions()) {}
+ await for (var x in testContinueSwitch()) {}
+ await for (var x in testNestFinally()) {}
+ await for (var x in testAsyncClosureInFinally()) {}
+}
+
+var tests = <IsolateTest>[
+ hasPausedAtStart,
+ setBreakpointAtLine(LINE),
+ resumeIsolate,
+ hasStoppedAtBreakpoint,
+ stoppedAtLine(LINE),
+ (Isolate isolate) async {
+ // test break statement
+ ServiceMap stack = await isolate.getStack();
+ expect(stack['awaiterFrames'], isNotNull);
+ expect(stack['awaiterFrames'].length, greaterThanOrEqualTo(2));
+
+ // Check second top frame contains correct line number
+ Script script = stack['awaiterFrames'][1].location.script;
+ expect(script.tokenToLine(stack['awaiterFrames'][1].location.tokenPos),
+ equals(LINE_A));
+ },
+ resumeIsolate,
+ hasStoppedAtBreakpoint,
+ stoppedAtLine(LINE),
+ (Isolate isolate) async {
+ // test return statement
+ ServiceMap stack = await isolate.getStack();
+ expect(stack['awaiterFrames'], isNotNull);
+ expect(stack['awaiterFrames'].length, greaterThanOrEqualTo(2));
+
+ // Check second top frame contains correct line number
+ Script script = stack['awaiterFrames'][1].location.script;
+ expect(script.tokenToLine(stack['awaiterFrames'][1].location.tokenPos),
+ equals(LINE_B));
+ },
+ resumeIsolate,
+ hasStoppedAtBreakpoint,
+ stoppedAtLine(LINE),
+ (Isolate isolate) async {
+ // test break statement
+ ServiceMap stack = await isolate.getStack();
+ expect(stack['awaiterFrames'], isNotNull);
+ expect(stack['awaiterFrames'].length, greaterThanOrEqualTo(2));
+
+ // Check second top frame contains correct line number
+ Script script = stack['awaiterFrames'][1].location.script;
+ expect(script.tokenToLine(stack['awaiterFrames'][1].location.tokenPos),
+ equals(LINE_C));
+ },
+ resumeIsolate,
+ hasStoppedAtBreakpoint,
+ stoppedAtLine(LINE),
+ (Isolate isolate) async {
+ // test break statement
+ ServiceMap stack = await isolate.getStack();
+ expect(stack['awaiterFrames'], isNotNull);
+ expect(stack['awaiterFrames'].length, greaterThanOrEqualTo(2));
+
+ // Check second top frame contains correct line number
+ Script script = stack['awaiterFrames'][1].location.script;
+ expect(script.tokenToLine(stack['awaiterFrames'][1].location.tokenPos),
+ equals(LINE_D));
+ },
+ resumeIsolate,
+ hasStoppedAtBreakpoint,
+ stoppedAtLine(LINE),
+ (Isolate isolate) async {
+ // test nested finally statement
+ ServiceMap stack = await isolate.getStack();
+ expect(stack['awaiterFrames'], isNotNull);
+ expect(stack['awaiterFrames'].length, greaterThanOrEqualTo(2));
+
+ // Check second top frame contains correct line number
+ Script script = stack['awaiterFrames'][1].location.script;
+ expect(script.tokenToLine(stack['awaiterFrames'][1].location.tokenPos),
+ equals(LINE_E));
+ },
+ resumeIsolate,
+ hasStoppedAtBreakpoint,
+ stoppedAtLine(LINE),
+ (Isolate isolate) async {
+ // test async closure within finally block
+ ServiceMap stack = await isolate.getStack();
+ expect(stack['awaiterFrames'], isNotNull);
+ expect(stack['awaiterFrames'].length, greaterThanOrEqualTo(2));
+
+ // Check second top frame contains correct line number
+ Script script = stack['awaiterFrames'][1].location.script;
+ expect(script.tokenToLine(stack['awaiterFrames'][1].location.tokenPos),
+ equals(LINE_F));
+ },
+ resumeIsolate,
+ hasStoppedAtExit
+];
+
+main(args) {
+ runIsolateTestsSynchronous(args, tests,
+ testeeConcurrent: code, pause_on_start: true, pause_on_exit: true);
+}
diff --git a/runtime/platform/globals.h b/runtime/platform/globals.h
index 0803ea3..2dd7547 100644
--- a/runtime/platform/globals.h
+++ b/runtime/platform/globals.h
@@ -605,40 +605,6 @@
template <typename T>
static inline void USE(T) {}
-// Use implicit_cast as a safe version of static_cast or const_cast
-// for upcasting in the type hierarchy (i.e. casting a pointer to Foo
-// to a pointer to SuperclassOfFoo or casting a pointer to Foo to
-// a const pointer to Foo).
-// When you use implicit_cast, the compiler checks that the cast is safe.
-// Such explicit implicit_casts are necessary in surprisingly many
-// situations where C++ demands an exact type match instead of an
-// argument type convertible to a target type.
-//
-// The From type can be inferred, so the preferred syntax for using
-// implicit_cast is the same as for static_cast etc.:
-//
-// implicit_cast<ToType>(expr)
-//
-// implicit_cast would have been part of the C++ standard library,
-// but the proposal was submitted too late. It will probably make
-// its way into the language in the future.
-template <typename To, typename From>
-inline To implicit_cast(From const& f) {
- return f;
-}
-
-// Use like this: down_cast<T*>(foo);
-template <typename To, typename From> // use like this: down_cast<T*>(foo);
-inline To down_cast(From* f) { // so we only accept pointers
- // Ensures that To is a sub-type of From *. This test is here only
- // for compile-time type checking, and has no overhead in an
- // optimized build at run-time, as it will be optimized away completely.
- if (false) {
- implicit_cast<From, To>(0);
- }
- return static_cast<To>(f);
-}
-
// The type-based aliasing rule allows the compiler to assume that
// pointers of different types (for some definition of different)
// never alias each other. Thus the following code does not work:
diff --git a/runtime/platform/growable_array.h b/runtime/platform/growable_array.h
index 75922621e..615b616 100644
--- a/runtime/platform/growable_array.h
+++ b/runtime/platform/growable_array.h
@@ -29,8 +29,34 @@
}
}
+ BaseGrowableArray(BaseGrowableArray&& other)
+ : length_(other.length_),
+ capacity_(other.capacity_),
+ data_(other.data_),
+ allocator_(other.allocator_) {
+ other.length_ = 0;
+ other.capacity_ = 0;
+ other.data_ = NULL;
+ }
+
~BaseGrowableArray() { allocator_->template Free<T>(data_, capacity_); }
+ BaseGrowableArray& operator=(BaseGrowableArray&& other) {
+ intptr_t temp = other.length_;
+ other.length_ = length_;
+ length_ = temp;
+ temp = other.capacity_;
+ other.capacity_ = capacity_;
+ capacity_ = temp;
+ T* temp_data = other.data_;
+ other.data_ = data_;
+ data_ = temp_data;
+ Allocator* temp_allocator = other.allocator_;
+ other.allocator_ = allocator_;
+ allocator_ = temp_allocator;
+ return *this;
+ }
+
intptr_t length() const { return length_; }
T* data() const { return data_; }
bool is_empty() const { return length_ == 0; }
diff --git a/runtime/runtime_args.gni b/runtime/runtime_args.gni
index cf9e71d..35e6e7c 100644
--- a/runtime/runtime_args.gni
+++ b/runtime/runtime_args.gni
@@ -80,8 +80,8 @@
dart_component_kind = "static_library"
}
- # Whether the VM's platform dill file contains bytecode.
- dart_platform_bytecode = false
+ # Controls whether the VM uses bytecode.
+ dart_platform_bytecode = true
# Whether the VM includes the kernel service in all modes (debug, release,
# product).
@@ -89,6 +89,9 @@
# Whether libdart should export the symbols of the Dart API.
dart_lib_export_symbols = true
+
+ # Whether dart:wasm should be enabled.
+ dart_enable_wasm = false
}
declare_args() {
diff --git a/runtime/tests/vm/dart/regress_38182_test.dart b/runtime/tests/vm/dart/regress_38182_test.dart
new file mode 100644
index 0000000..952bee4
--- /dev/null
+++ b/runtime/tests/vm/dart/regress_38182_test.dart
@@ -0,0 +1,35 @@
+// Copyright (c) 2019, 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.
+
+// VMOptions=--stacktrace_every=1 --deterministic
+
+void foo1(par) {
+ try {
+ () {
+ // The parameter `par` has to be captured within a closure, but it doesn't
+ // matter whether or not it's actually used.
+ print(par.runtimeType);
+ };
+ // We need to throw, otherwise the crash doesn't happen. We don't need to
+ // catch it explicitly, however.
+ throw '';
+ } finally {
+ // We need to trigger a lot of stack overflow checks. Somewhere around
+ // 20000 seems to work.
+ int x = 0;
+ for (int loc1 = 0; loc1 < 20000; loc1++) {
+ x += loc1;
+ }
+ print(x);
+ }
+}
+
+main() {
+ try {
+ // Parameter isn't important.
+ foo1(null);
+ } catch (e) {
+ print('foo1 threw');
+ }
+}
diff --git a/runtime/tests/vm/dart/regress_merge_blocks_with_phis_test.dart b/runtime/tests/vm/dart/regress_merge_blocks_with_phis_test.dart
index a3edcce..606e4c5 100644
--- a/runtime/tests/vm/dart/regress_merge_blocks_with_phis_test.dart
+++ b/runtime/tests/vm/dart/regress_merge_blocks_with_phis_test.dart
@@ -2,7 +2,7 @@
// 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.
//
-// VMOptions=--deterministic --optimization-counter-threshold=5 --use-bytecode-compiler
+// VMOptions=--optimization-counter-threshold=5 --use-bytecode-compiler
//
// Test that block merging takes phis into account.
//
diff --git a/runtime/tests/vm/dart/run_appended_aot_snapshot_test.dart b/runtime/tests/vm/dart/run_appended_aot_snapshot_test.dart
new file mode 100644
index 0000000..b0b2736
--- /dev/null
+++ b/runtime/tests/vm/dart/run_appended_aot_snapshot_test.dart
@@ -0,0 +1,74 @@
+// Copyright (c) 2019, 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.
+
+import "dart:async";
+import "dart:io";
+import 'dart:typed_data';
+
+import "package:path/path.dart" as path;
+
+import "snapshot_test_helper.dart";
+
+final appSnapshotPageSize = 4096;
+const appjitMagicNumber = <int>[0xdc, 0xdc, 0xf6, 0xf6, 0, 0, 0, 0];
+
+Future writeAppendedExecutable(runtimePath, payloadPath, outputPath) async {
+ final runtime = File(runtimePath);
+ final int runtimeLength = runtime.lengthSync();
+
+ final padding = (appSnapshotPageSize - (runtimeLength % appSnapshotPageSize));
+ final padBytes = new List<int>.filled(padding, 0);
+ final offset = runtimeLength + padding;
+
+ final offsetBytes = new ByteData(8) // 64 bit in bytes.
+ ..setUint64(0, offset, Endian.little);
+
+ final outputFile = File(outputPath).openWrite();
+ outputFile.add(runtime.readAsBytesSync());
+ outputFile.add(padBytes);
+ outputFile.add(File(payloadPath).readAsBytesSync());
+ outputFile.add(offsetBytes.buffer.asUint8List());
+ outputFile.add(appjitMagicNumber);
+ await outputFile.close();
+}
+
+Future<void> main(List<String> args) async {
+ if (args.length == 1 && args[0] == "--child") {
+ print("Hello, Appended AOT");
+ return;
+ }
+
+ await withTempDir((String tmp) async {
+ final String dillPath = path.join(tmp, "test.dill");
+ final String aotPath = path.join(tmp, "test.aot");
+ final String exePath = path.join(tmp, "test.exe");
+
+ final dillResult = await runGenKernel("generate dill", [
+ "--aot",
+ "-o",
+ dillPath,
+ "runtime/tests/vm/dart/run_appended_aot_snapshot_test.dart",
+ ]);
+ expectOutput("", dillResult);
+
+ final aotResult = await runGenSnapshot("generate aot", [
+ "--snapshot-kind=app-aot-blobs",
+ "--blobs_container_filename=$aotPath",
+ dillPath,
+ ]);
+ expectOutput("", aotResult);
+
+ await writeAppendedExecutable(dartPrecompiledRuntime, aotPath, exePath);
+
+ if (Platform.isLinux || Platform.isMacOS) {
+ final execResult =
+ await runBinary("make executable", "chmod", ["+x", exePath]);
+ expectOutput("", execResult);
+ }
+
+ final runResult =
+ await runBinary("run appended aot snapshot", exePath, ["--child"]);
+ expectOutput("Hello, Appended AOT", runResult);
+ });
+}
diff --git a/runtime/tests/vm/dart/snapshot_test_helper.dart b/runtime/tests/vm/dart/snapshot_test_helper.dart
index 5c63da1..6f42b07 100644
--- a/runtime/tests/vm/dart/snapshot_test_helper.dart
+++ b/runtime/tests/vm/dart/snapshot_test_helper.dart
@@ -46,8 +46,11 @@
final String buildDir = p.dirname(Platform.executable);
final String platformDill = p.join(buildDir, "vm_platform_strong.dill");
final String genSnapshot = p.join(buildDir, "gen_snapshot${executableSuffix}");
-final String genKernel =
- p.join("pkg", "vm", "tool", "gen_kernel${scriptSuffix}");
+final String dartPrecompiledRuntime =
+ p.join(buildDir, "dart_precompiled_runtime${executableSuffix}");
+final String genKernel = p.join("pkg", "vm", "bin", "gen_kernel.dart");
+final String checkedInDartVM =
+ p.join("tools", "sdks", "dart-sdk", "bin", "dart${executableSuffix}");
Future<Result> runDart(String prefix, List<String> arguments) {
final augmentedArguments = <String>[]
@@ -58,10 +61,11 @@
Future<Result> runGenKernel(String prefix, List<String> arguments) {
final augmentedArguments = <String>[]
+ ..add(genKernel)
..add("--platform")
..add(platformDill)
..addAll(arguments);
- return runBinary(prefix, genKernel, augmentedArguments);
+ return runBinary(prefix, checkedInDartVM, augmentedArguments);
}
Future<Result> runGenSnapshot(String prefix, List<String> arguments) {
diff --git a/runtime/tests/vm/vm.status b/runtime/tests/vm/vm.status
index 22c5b32..d653126 100644
--- a/runtime/tests/vm/vm.status
+++ b/runtime/tests/vm/vm.status
@@ -231,6 +231,9 @@
[ $builder_tag == bytecode_interpreter || $builder_tag == bytecode_mixed || $builder_tag == optimization_counter_threshold || $hot_reload || $hot_reload_rollback || $arch != arm && $arch != simarm && $arch != x64 || $compiler != dartk && $compiler != dartkb && $compiler != dartkp ]
dart/entrypoints/*: SkipByDesign # These tests are for compiler optimizations and very sensible to when functions are optimized, so they are disabled on hotreload, optcounter and bytecode interpreter bots.
+[ $builder_tag == crossword || $compiler != dartkp || $system != linux && $system != macos && $system != windows ]
+dart/run_appended_aot_snapshot_test: SkipByDesign # Tests the precompiled runtime.
+
[ $compiler == dart2analyzer || $compiler == dart2js ]
dart/data_uri*test: Skip # Data uri's not supported by dart2js or the analyzer.
diff --git a/runtime/tools/dartfuzz/README.md b/runtime/tools/dartfuzz/README.md
index 0002b65..35accd4 100644
--- a/runtime/tools/dartfuzz/README.md
+++ b/runtime/tools/dartfuzz/README.md
@@ -51,7 +51,7 @@
--dart-top : sets DART_TOP explicitly through command line
--mode1 : m1
--mode2 : m2, and values one of
- jit-[debug-][ia32|x64|arm32|arm64|dbc32|dbc64] = Dart JIT
+ jit-[debug-][ia32|x64|arm32|arm64] = Dart JIT
aot-[debug-][x64|arm32|arm64] = Dart AOT
kbc-[int|mix|cmp]-[debug-][ia32|x64|arm32|arm64] = Dart KBC
(interpreted/
diff --git a/runtime/tools/dartfuzz/dartfuzz.dart b/runtime/tools/dartfuzz/dartfuzz.dart
index 8a02ff3..ba9b779 100644
--- a/runtime/tools/dartfuzz/dartfuzz.dart
+++ b/runtime/tools/dartfuzz/dartfuzz.dart
@@ -14,12 +14,18 @@
// Version of DartFuzz. Increase this each time changes are made
// to preserve the property that a given version of DartFuzz yields
// the same fuzzed program for a deterministic random seed.
-const String version = '1.42';
+const String version = '1.49';
// Restriction on statements and expressions.
-const int stmtLength = 2;
const int stmtDepth = 1;
const int exprDepth = 2;
+const int numStatements = 2;
+const int numGlobalVars = 4;
+const int numLocalVars = 4;
+const int numGlobalMethods = 4;
+const int numClassMethods = 3;
+const int numMethodParams = 4;
+const int numClasses = 4;
// Naming conventions.
const varName = 'var';
@@ -28,6 +34,32 @@
const fieldName = 'fld';
const methodName = 'foo';
+// Class that tracks the state of the filter applied to the
+// right-hand-side of an assignment in order to avoid generating
+// left-hand-side variables.
+class RhsFilter {
+ RhsFilter(this._remaining, this.lhsVar);
+ factory RhsFilter.fromDartType(DartType tp, String lhsVar) {
+ if (tp == DartType.STRING ||
+ tp == DartType.INT_LIST ||
+ tp == DartType.INT_SET ||
+ tp == DartType.INT_STRING_MAP) {
+ return RhsFilter(1, lhsVar);
+ }
+ return null;
+ }
+ // Clone the current RhsFilter instance and set remaining to 0.
+ // This is used for parameter expressions.
+ factory RhsFilter.cloneEmpty(RhsFilter rhsFilter) =>
+ rhsFilter == null ? null : RhsFilter(0, rhsFilter.lhsVar);
+ void consume() => _remaining--;
+ bool get shouldFilter => _remaining <= 0;
+ // Number of times the lhs variable can still be used on the rhs.
+ int _remaining;
+ // The name of the lhs variable to be filtered from the rhs.
+ final String lhsVar;
+}
+
/// Class that specifies the api for calling library and ffi functions (if
/// enabled).
class DartApi {
@@ -97,16 +129,22 @@
// Setup the types.
localVars = <DartType>[];
iterVars = <String>[];
- globalVars = fillTypes1();
+
+ globalVars = fillTypes1(limit: numGlobalVars);
globalVars.addAll(DartType.allTypes); // always one each
- globalMethods = fillTypes2();
- classFields = fillTypes2(limit: 8);
- classMethods = fillTypes3(classFields.length);
+ globalMethods =
+ fillTypes2(limit2: numGlobalMethods, limit1: numMethodParams);
+ classFields = fillTypes2(limit2: numClasses, limit1: numLocalVars);
+ classMethods = fillTypes3(classFields.length,
+ limit2: numClassMethods, limit1: numMethodParams);
+
+ virtualClassMethods = <Map<int, List<int>>>[];
classParents = <int>[];
// Setup optional ffi methods and types.
final ffiStatus = <bool>[for (final _ in globalMethods) false];
if (ffi) {
- List<List<DartType>> globalMethodsFfi = fillTypes2(isFfi: true);
+ List<List<DartType>> globalMethodsFfi = fillTypes2(
+ limit2: numGlobalMethods, limit1: numMethodParams, isFfi: true);
for (var m in globalMethodsFfi) {
globalMethods.add(m);
ffiStatus.add(true);
@@ -214,14 +252,17 @@
void emitVirtualMethods() {
final currentClassTmp = currentClass;
int parentClass = classParents[currentClass];
+ final vcm = <int, List<int>>{};
// Chase randomly up in class hierarchy.
while (parentClass >= 0) {
+ vcm[parentClass] = <int>[];
for (int j = 0, n = classMethods[parentClass].length; j < n; j++) {
if (rand.nextInt(8) == 0) {
currentClass = parentClass;
currentMethod = j;
emitMethod('$methodName${parentClass}_', j,
classMethods[parentClass][j], false);
+ vcm[parentClass].add(currentMethod);
currentMethod = null;
currentClass = null;
}
@@ -233,6 +274,7 @@
}
}
currentClass = currentClassTmp;
+ virtualClassMethods.add(vcm);
}
void emitClasses() {
@@ -296,6 +338,27 @@
}
}
+ void emitTryCatchFinally(Function tryBody, Function catchBody,
+ {Function finallyBody}) {
+ emitLn('try {');
+ indent += 2;
+ emitLn("", newline: false);
+ tryBody();
+ emit(";", newline: true);
+ indent -= 2;
+ emitLn('} catch (e, st) {');
+ indent += 2;
+ catchBody();
+ indent -= 2;
+ if (finallyBody != null) {
+ emitLn('} finally {');
+ indent += 2;
+ finallyBody();
+ indent -= 2;
+ }
+ emitLn('}');
+ }
+
void emitMain() {
emitLn('main() {');
indent += 2;
@@ -304,53 +367,51 @@
// Call each global method once.
for (int i = 0; i < globalMethods.length; i++) {
- emitLn('try {');
- indent += 2;
- emitLn("", newline: false);
- emitCall(1, "$methodName${i}", globalMethods[i]);
- emit(";", newline: true);
- indent -= 2;
- emitLn('} catch (exception, stackTrace) {');
- indent += 2;
- emitLn("print('$methodName$i throws');");
- indent -= 2;
- emitLn('}');
+ emitTryCatchFinally(() {
+ emitCall(1, "$methodName${i}", globalMethods[i]);
+ }, () {
+ emitLn("print('$methodName$i throws');");
+ });
}
// Call each class method once.
for (int i = 0; i < classMethods.length; i++) {
for (int j = 0; j < classMethods[i].length; j++) {
- emitLn('try {');
- indent += 2;
- emitLn("", newline: false);
- emitCall(1, "X${i}().$methodName${i}_${j}", classMethods[i][j]);
- emit(";", newline: true);
- indent -= 2;
- emitLn('} catch (exception, stackTrace) {');
- indent += 2;
- emitLn("print('X${i}().$methodName${i}_${j}() throws');");
- indent -= 2;
- emitLn('}');
+ emitTryCatchFinally(() {
+ emitCall(1, "X${i}().$methodName${i}_${j}", classMethods[i][j]);
+ }, () {
+ emitLn("print('X${i}().$methodName${i}_${j}() throws');");
+ });
+ }
+ // Call each virtual class method once.
+ int parentClass = classParents[i];
+ while (parentClass >= 0) {
+ if (virtualClassMethods[i].containsKey(parentClass)) {
+ for (int j = 0; j < virtualClassMethods[i][parentClass].length; j++) {
+ emitTryCatchFinally(() {
+ emitCall(1, "X${i}().$methodName${parentClass}_${j}",
+ classMethods[parentClass][j]);
+ }, () {
+ emitLn(
+ "print('X${i}().$methodName${parentClass}_${j}() throws');");
+ });
+ }
+ }
+ parentClass = classParents[parentClass];
}
}
- emitLn('try {');
- indent += 2;
- emitLn('X${classFields.length - 1}().run();');
- indent -= 2;
- emitLn('} catch (exception, stackTrace) {');
- indent += 2;
- emitLn("print('X${classFields.length - 1}().run() throws');");
- indent -= 2;
- emitLn('} finally {');
- indent += 2;
- emitLn("print('", newline: false);
- for (int i = 0; i < globalVars.length; i++) {
- emit('\$$varName$i\\n');
- }
- emit("');", newline: true);
- indent -= 2;
- emitLn('}');
+ emitTryCatchFinally(() {
+ emit('X${classFields.length - 1}().run()');
+ }, () {
+ emitLn("print('X${classFields.length - 1}().run() throws');");
+ }, finallyBody: () {
+ emitLn("print('", newline: false);
+ for (int i = 0; i < globalVars.length; i++) {
+ emit('\$$varName$i\\n');
+ }
+ emit("');", newline: true);
+ });
indent -= 2;
emitLn('}');
}
@@ -415,9 +476,13 @@
bool emitAssign() {
DartType tp = getType();
emitLn('', newline: false);
- emitVar(0, tp, isLhs: true);
- emitAssignOp(tp);
- emitExpr(0, tp);
+ final emittedVar = emitVar(0, tp, isLhs: true);
+ RhsFilter rhsFilter = RhsFilter.fromDartType(tp, emittedVar);
+ final assignOp = emitAssignOp(tp);
+ if ({'*=', '+='}.contains(assignOp)) {
+ rhsFilter?.consume();
+ }
+ emitExpr(0, tp, rhsFilter: rhsFilter);
emit(';', newline: true);
return true;
}
@@ -504,7 +569,9 @@
bool emitForIn(int depth) {
final int i = localVars.length;
emitLn('for (int $localName$i in ', newline: false);
+ localVars.add(null); // declared, but don't use
emitExpr(0, rand.nextBool() ? DartType.INT_LIST : DartType.INT_SET);
+ localVars.removeLast(); // will get type
emit(') {', newline: true);
indent += 2;
nest++;
@@ -520,10 +587,11 @@
// Emit a simple membership forEach loop.
bool emitForEach(int depth) {
final int i = localVars.length;
+ final int j = i + 1;
emitLn("", newline: false);
final emittedVar = emitScalarVar(DartType.INT_STRING_MAP, isLhs: false);
iterVars.add(emittedVar);
- emit('.forEach(($localName$i, $localName${i + 1}) {\n');
+ emit('.forEach(($localName$i, $localName$j) {\n');
indent += 2;
final int nestTmp = nest;
// Reset, since forEach cannot break out of own or enclosing context.
@@ -628,8 +696,11 @@
// Emit a new program scope that introduces a new local variable.
bool emitScope(int depth) {
DartType tp = getType();
- emitLn('{ ${tp.name} $localName${localVars.length} = ', newline: false);
+ final int i = localVars.length;
+ emitLn('{ ${tp.name} $localName$i = ', newline: false);
+ localVars.add(null); // declared, but don't use
emitExpr(0, tp);
+ localVars.removeLast(); // will get type
emit(';', newline: true);
indent += 2;
localVars.add(tp);
@@ -709,7 +780,7 @@
// Emit statements. Returns true if code may fall-through.
bool emitStatements(int depth) {
- int s = 1 + rand.nextInt(stmtLength);
+ int s = 1 + rand.nextInt(numStatements);
for (int i = 0; i < s; i++) {
if (!emitStatement(depth)) {
return false; // rest would be dead code
@@ -726,8 +797,8 @@
emit(rand.nextInt(2) == 0 ? 'true' : 'false');
}
- void emitSmallPositiveInt() {
- emit('${rand.nextInt(100)}');
+ void emitSmallPositiveInt({int limit = 100}) {
+ emit('${rand.nextInt(limit)}');
}
void emitSmallNegativeInt() {
@@ -778,25 +849,25 @@
emit("'");
}
- void emitElementExpr(int depth, DartType tp) {
+ void emitElementExpr(int depth, DartType tp, {RhsFilter rhsFilter}) {
if (currentMethod != null) {
- emitExpr(depth, tp);
+ emitExpr(depth, tp, rhsFilter: rhsFilter);
} else {
- emitLiteral(depth, tp);
+ emitLiteral(depth, tp, rhsFilter: rhsFilter);
}
}
- void emitElement(int depth, DartType tp) {
+ void emitElement(int depth, DartType tp, {RhsFilter rhsFilter}) {
if (tp == DartType.INT_STRING_MAP) {
emitSmallPositiveInt();
emit(' : ');
- emitElementExpr(depth, DartType.STRING);
+ emitElementExpr(depth, DartType.STRING, rhsFilter: rhsFilter);
} else {
- emitElementExpr(depth, DartType.INT);
+ emitElementExpr(depth, DartType.INT, rhsFilter: rhsFilter);
}
}
- void emitCollectionElement(int depth, DartType tp) {
+ void emitCollectionElement(int depth, DartType tp, {RhsFilter rhsFilter}) {
int r = depth <= exprDepth ? rand.nextInt(10) : 10;
switch (r) {
// Favors elements over control-flow collections.
@@ -804,19 +875,19 @@
// TODO (ajcbik): Remove restriction once compiler is fixed.
if (depth < 2) {
emit('...'); // spread
- emitCollection(depth + 1, tp);
+ emitCollection(depth + 1, tp, rhsFilter: rhsFilter);
} else {
- emitElement(depth, tp);
+ emitElement(depth, tp, rhsFilter: rhsFilter);
}
break;
case 1:
emit('if (');
- emitElementExpr(depth + 1, DartType.BOOL);
+ emitElementExpr(depth + 1, DartType.BOOL, rhsFilter: rhsFilter);
emit(') ');
- emitCollectionElement(depth + 1, tp);
+ emitCollectionElement(depth + 1, tp, rhsFilter: rhsFilter);
if (rand.nextBool()) {
emit(' else ');
- emitCollectionElement(depth + 1, tp);
+ emitCollectionElement(depth + 1, tp, rhsFilter: rhsFilter);
}
break;
case 2:
@@ -824,40 +895,45 @@
final int i = localVars.length;
emit('for (int $localName$i ');
// For-loop (induction, list, set).
+ localVars.add(null); // declared, but don't use
switch (rand.nextInt(3)) {
case 0:
emit('= 0; $localName$i < ');
- emitSmallPositiveInt();
+ emitSmallPositiveInt(limit: 16);
emit('; $localName$i++) ');
break;
case 1:
emit('in ');
- emitCollection(depth + 1, DartType.INT_LIST);
+ emitCollection(depth + 1, DartType.INT_LIST,
+ rhsFilter: rhsFilter);
emit(') ');
break;
default:
emit('in ');
- emitCollection(depth + 1, DartType.INT_SET);
+ emitCollection(depth + 1, DartType.INT_SET, rhsFilter: rhsFilter);
emit(') ');
break;
}
+ localVars.removeLast(); // will get type
nest++;
+ iterVars.add("$localName$i");
localVars.add(DartType.INT);
- emitCollectionElement(depth + 1, tp);
+ emitCollectionElement(depth + 1, tp, rhsFilter: rhsFilter);
localVars.removeLast();
+ iterVars.removeLast();
nest--;
break;
}
default:
- emitElement(depth, tp);
+ emitElement(depth, tp, rhsFilter: rhsFilter);
break;
}
}
- void emitCollection(int depth, DartType tp) {
+ void emitCollection(int depth, DartType tp, {RhsFilter rhsFilter}) {
emit(tp == DartType.INT_LIST ? '[ ' : '{ ');
for (int i = 0, n = 1 + rand.nextInt(8); i < n; i++) {
- emitCollectionElement(depth, tp);
+ emitCollectionElement(depth, tp, rhsFilter: rhsFilter);
if (i != (n - 1)) {
emit(', ');
}
@@ -865,7 +941,8 @@
emit(tp == DartType.INT_LIST ? ' ]' : ' }');
}
- void emitLiteral(int depth, DartType tp, {bool smallPositiveValue = false}) {
+ void emitLiteral(int depth, DartType tp,
+ {bool smallPositiveValue = false, RhsFilter rhsFilter}) {
if (tp == DartType.BOOL) {
emitBool();
} else if (tp == DartType.INT) {
@@ -881,13 +958,13 @@
} else if (tp == DartType.INT_LIST ||
tp == DartType.INT_SET ||
tp == DartType.INT_STRING_MAP) {
- emitCollection(depth, tp);
+ emitCollection(depth, tp, rhsFilter: RhsFilter.cloneEmpty(rhsFilter));
} else {
assert(false);
}
}
- String emitScalarVar(DartType tp, {bool isLhs = false}) {
+ String emitScalarVar(DartType tp, {bool isLhs = false, RhsFilter rhsFilter}) {
// Collect all choices from globals, fields, locals, and parameters.
Set<String> choices = <String>{};
for (int i = 0; i < globalVars.length; i++) {
@@ -918,55 +995,84 @@
}
}
}
+ // Filter out the current lhs of the expression to avoid recursive
+ // assignments of the form x = x * x.
+ if (rhsFilter != null && rhsFilter.shouldFilter) {
+ Set<String> cleanChoices = choices.difference({rhsFilter.lhsVar});
+ // If we have other choices of variables, use those.
+ if (cleanChoices.isNotEmpty) {
+ choices = cleanChoices;
+ } else if (!isLhs) {
+ // If we are emitting an RHS variable, we can emit a terminal.
+ // note that if the variable type is a collection, this might
+ // still result in a recursion.
+ emitLiteral(0, tp);
+ return null;
+ }
+ // Otherwise we have to risk creating a recursion.
+ }
// Then pick one.
- assert(choices.isNotEmpty);
+ if (choices.isEmpty) {
+ throw 'No variable to emit for type ${tp.name}';
+ }
final emittedVar = '${choices.elementAt(rand.nextInt(choices.length))}';
+ if (rhsFilter != null && (emittedVar == rhsFilter.lhsVar)) {
+ rhsFilter.consume();
+ }
emit(emittedVar);
return emittedVar;
}
- void emitSubscriptedVar(int depth, DartType tp, {bool isLhs = false}) {
+ String emitSubscriptedVar(int depth, DartType tp,
+ {bool isLhs = false, RhsFilter rhsFilter}) {
+ String ret;
if (tp == DartType.INT) {
- emitScalarVar(DartType.INT_LIST, isLhs: isLhs);
+ ret =
+ emitScalarVar(DartType.INT_LIST, isLhs: isLhs, rhsFilter: rhsFilter);
emit('[');
emitExpr(depth + 1, DartType.INT);
emit(']');
} else if (tp == DartType.STRING) {
- emitScalarVar(DartType.INT_STRING_MAP, isLhs: isLhs);
+ ret = emitScalarVar(DartType.INT_STRING_MAP,
+ isLhs: isLhs, rhsFilter: rhsFilter);
emit('[');
emitExpr(depth + 1, DartType.INT);
emit(']');
} else {
- emitScalarVar(tp, isLhs: isLhs); // resort to scalar
+ ret = emitScalarVar(tp,
+ isLhs: isLhs, rhsFilter: rhsFilter); // resort to scalar
}
+ return ret;
}
- void emitVar(int depth, DartType tp, {bool isLhs = false}) {
+ String emitVar(int depth, DartType tp,
+ {bool isLhs = false, RhsFilter rhsFilter}) {
switch (rand.nextInt(2)) {
case 0:
- emitScalarVar(tp, isLhs: isLhs);
+ return emitScalarVar(tp, isLhs: isLhs, rhsFilter: rhsFilter);
break;
default:
- emitSubscriptedVar(depth, tp, isLhs: isLhs);
+ return emitSubscriptedVar(depth, tp,
+ isLhs: isLhs, rhsFilter: rhsFilter);
break;
}
}
- void emitTerminal(int depth, DartType tp) {
+ void emitTerminal(int depth, DartType tp, {RhsFilter rhsFilter}) {
switch (rand.nextInt(2)) {
case 0:
- emitLiteral(depth, tp);
+ emitLiteral(depth, tp, rhsFilter: rhsFilter);
break;
default:
- emitVar(depth, tp);
+ emitVar(depth, tp, rhsFilter: rhsFilter);
break;
}
}
- void emitExprList(int depth, List<DartType> proto) {
+ void emitExprList(int depth, List<DartType> proto, {RhsFilter rhsFilter}) {
emit('(');
for (int i = 1; i < proto.length; i++) {
- emitExpr(depth, proto[i]);
+ emitExpr(depth, proto[i], rhsFilter: rhsFilter);
if (i != (proto.length - 1)) {
emit(', ');
}
@@ -975,62 +1081,52 @@
}
// Emit expression with unary operator: (~(x))
- void emitUnaryExpr(int depth, DartType tp) {
+ void emitUnaryExpr(int depth, DartType tp, {RhsFilter rhsFilter}) {
if (tp == DartType.BOOL || tp == DartType.INT || tp == DartType.DOUBLE) {
emit('(');
emitUnaryOp(tp);
emit('(');
- emitExpr(depth + 1, tp);
+ emitExpr(depth + 1, tp, rhsFilter: rhsFilter);
emit('))');
} else {
- emitTerminal(depth, tp); // resort to terminal
+ emitTerminal(depth, tp, rhsFilter: rhsFilter); // resort to terminal
}
}
// Emit expression with binary operator: (x + y)
- void emitBinaryExpr(int depth, DartType tp) {
+ void emitBinaryExpr(int depth, DartType tp, {RhsFilter rhsFilter}) {
if (tp == DartType.BOOL) {
// For boolean, allow type switch with relational op.
if (rand.nextInt(2) == 0) {
DartType deeper_tp = getType();
emit('(');
- emitExpr(depth + 1, deeper_tp);
+ emitExpr(depth + 1, deeper_tp, rhsFilter: rhsFilter);
emitRelOp(deeper_tp);
- emitExpr(depth + 1, deeper_tp);
+ emitExpr(depth + 1, deeper_tp, rhsFilter: rhsFilter);
emit(')');
return;
}
- } else if (tp == DartType.STRING || tp == DartType.INT_LIST) {
- // For strings and lists, a construct like x = x + x; inside a loop
- // yields an exponentially growing data structure. We avoid this
- // situation by forcing a literal on the rhs of each +.
- emit('(');
- emitExpr(depth + 1, tp);
- emitBinaryOp(tp);
- emitLiteral(depth + 1, tp);
- emit(')');
- return;
}
emit('(');
- emitExpr(depth + 1, tp);
+ emitExpr(depth + 1, tp, rhsFilter: rhsFilter);
emitBinaryOp(tp);
- emitExpr(depth + 1, tp);
+ emitExpr(depth + 1, tp, rhsFilter: rhsFilter);
emit(')');
}
// Emit expression with ternary operator: (b ? x : y)
- void emitTernaryExpr(int depth, DartType tp) {
+ void emitTernaryExpr(int depth, DartType tp, {RhsFilter rhsFilter}) {
emit('(');
- emitExpr(depth + 1, DartType.BOOL);
+ emitExpr(depth + 1, DartType.BOOL, rhsFilter: rhsFilter);
emit(' ? ');
- emitExpr(depth + 1, tp);
+ emitExpr(depth + 1, tp, rhsFilter: rhsFilter);
emit(' : ');
- emitExpr(depth + 1, tp);
+ emitExpr(depth + 1, tp, rhsFilter: rhsFilter);
emit(')');
}
// Emit expression with pre/post-increment/decrement operator: (x++)
- void emitPreOrPostExpr(int depth, DartType tp) {
+ void emitPreOrPostExpr(int depth, DartType tp, {RhsFilter rhsFilter}) {
if (tp == DartType.INT) {
int r = rand.nextInt(2);
emit('(');
@@ -1039,18 +1135,18 @@
if (r == 1) emitPreOrPostOp(tp);
emit(')');
} else {
- emitTerminal(depth, tp); // resort to terminal
+ emitTerminal(depth, tp, rhsFilter: rhsFilter); // resort to terminal
}
}
// Emit library call.
- void emitLibraryCall(int depth, DartType tp) {
+ void emitLibraryCall(int depth, DartType tp, {RhsFilter rhsFilter}) {
DartLib lib = getLibraryMethod(tp);
final String proto = lib.proto;
// Receiver.
if (proto[0] != 'V') {
emit('(');
- emitArg(depth + 1, proto[0]);
+ emitArg(depth + 1, proto[0], rhsFilter: rhsFilter);
emit(').');
}
// Call.
@@ -1060,7 +1156,7 @@
emit('(');
if (proto[1] != 'V') {
for (int i = 1; i < proto.length; i++) {
- emitArg(depth + 1, proto[i]);
+ emitArg(depth + 1, proto[i], rhsFilter: rhsFilter);
if (i != (proto.length - 1)) {
emit(', ');
}
@@ -1071,17 +1167,19 @@
}
// Emit call to a specific method.
- void emitCall(int depth, String name, List<DartType> proto) {
+ void emitCall(int depth, String name, List<DartType> proto,
+ {RhsFilter rhsFilter}) {
emit(name);
- emitExprList(depth + 1, proto);
+ emitExprList(depth + 1, proto, rhsFilter: rhsFilter);
}
// Helper for a method call.
bool pickedCall(
- int depth, DartType tp, String name, List<List<DartType>> protos, int m) {
+ int depth, DartType tp, String name, List<List<DartType>> protos, int m,
+ {RhsFilter rhsFilter}) {
for (int i = m - 1; i >= 0; i--) {
if (tp == protos[i][0]) {
- emitCall(depth + 1, "$name$i", protos[i]);
+ emitCall(depth + 1, "$name$i", protos[i], rhsFilter: rhsFilter);
return true;
}
}
@@ -1089,12 +1187,13 @@
}
// Emit method call within the program.
- void emitMethodCall(int depth, DartType tp) {
+ void emitMethodCall(int depth, DartType tp, {RhsFilter rhsFilter}) {
// Only call backward to avoid infinite recursion.
if (currentClass == null) {
// Outside a class but inside a method: call backward in global methods.
if (currentMethod != null &&
- pickedCall(depth, tp, methodName, globalMethods, currentMethod)) {
+ pickedCall(depth, tp, methodName, globalMethods, currentMethod,
+ rhsFilter: rhsFilter)) {
return;
}
} else {
@@ -1121,43 +1220,44 @@
}
final int m2 = globalMethods.length;
if (pickedCall(depth, tp, '$methodName${classIndex}_',
- classMethods[classIndex], m1) ||
- pickedCall(depth, tp, methodName, globalMethods, m2)) {
+ classMethods[classIndex], m1, rhsFilter: rhsFilter) ||
+ pickedCall(depth, tp, methodName, globalMethods, m2,
+ rhsFilter: rhsFilter)) {
return;
}
}
- emitTerminal(depth, tp); // resort to terminal.
+ emitTerminal(depth, tp, rhsFilter: rhsFilter); // resort to terminal.
}
// Emit expression.
- void emitExpr(int depth, DartType tp) {
+ void emitExpr(int depth, DartType tp, {RhsFilter rhsFilter}) {
// Continuing nested expressions becomes less likely as the depth grows.
if (rand.nextInt(depth + 1) > exprDepth) {
- emitTerminal(depth, tp);
+ emitTerminal(depth, tp, rhsFilter: rhsFilter);
return;
}
// Possibly nested expression.
switch (rand.nextInt(7)) {
case 0:
- emitUnaryExpr(depth, tp);
+ emitUnaryExpr(depth, tp, rhsFilter: rhsFilter);
break;
case 1:
- emitBinaryExpr(depth, tp);
+ emitBinaryExpr(depth, tp, rhsFilter: rhsFilter);
break;
case 2:
- emitTernaryExpr(depth, tp);
+ emitTernaryExpr(depth, tp, rhsFilter: rhsFilter);
break;
case 3:
- emitPreOrPostExpr(depth, tp);
+ emitPreOrPostExpr(depth, tp, rhsFilter: rhsFilter);
break;
case 4:
- emitLibraryCall(depth, tp);
+ emitLibraryCall(depth, tp, rhsFilter: RhsFilter.cloneEmpty(rhsFilter));
break;
case 5:
- emitMethodCall(depth, tp);
+ emitMethodCall(depth, tp, rhsFilter: RhsFilter.cloneEmpty(rhsFilter));
break;
default:
- emitTerminal(depth, tp);
+ emitTerminal(depth, tp, rhsFilter: rhsFilter);
break;
}
}
@@ -1167,9 +1267,9 @@
//
// Emit same type in-out assignment operator.
- void emitAssignOp(DartType tp) {
+ String emitAssignOp(DartType tp) {
if (tp == DartType.INT) {
- emit(oneOf(const <String>[
+ final assignOp = oneOf(const <String>[
' += ',
' -= ',
' *= ',
@@ -1182,12 +1282,18 @@
' <<= ',
' ??= ',
' = '
- ]));
+ ]);
+ emit(assignOp);
+ return assignOp;
} else if (tp == DartType.DOUBLE) {
- emit(oneOf(
- const <String>[' += ', ' -= ', ' *= ', ' /= ', ' ??= ', ' = ']));
+ final assignOp =
+ oneOf(const <String>[' += ', ' -= ', ' *= ', ' /= ', ' ??= ', ' = ']);
+ emit(assignOp);
+ return assignOp;
} else {
- emit(oneOf(const <String>[' ??= ', ' = ']));
+ final assignOp = oneOf(const <String>[' ??= ', ' = ']);
+ emit(assignOp);
+ return assignOp;
}
}
@@ -1274,7 +1380,7 @@
}
// Emit a library argument, possibly subject to restrictions.
- void emitArg(int depth, String p) {
+ void emitArg(int depth, String p, {RhsFilter rhsFilter}) {
switch (p) {
case 'B':
emitExpr(depth, DartType.BOOL);
@@ -1289,19 +1395,19 @@
emitExpr(depth, fp ? DartType.DOUBLE : DartType.INT);
break;
case 'S':
- emitExpr(depth, DartType.STRING);
+ emitExpr(depth, DartType.STRING, rhsFilter: rhsFilter);
break;
case 's': // emit small string
emitString(length: 2);
break;
case 'L':
- emitExpr(depth, DartType.INT_LIST);
+ emitExpr(depth, DartType.INT_LIST, rhsFilter: rhsFilter);
break;
case 'X':
- emitExpr(depth, DartType.INT_SET);
+ emitExpr(depth, DartType.INT_SET, rhsFilter: rhsFilter);
break;
case 'M':
- emitExpr(depth, DartType.INT_STRING_MAP);
+ emitExpr(depth, DartType.INT_STRING_MAP, rhsFilter: rhsFilter);
break;
default:
throw ArgumentError('Invalid p value: $p');
@@ -1332,9 +1438,9 @@
}
}
- List<DartType> fillTypes1({bool isFfi = false}) {
+ List<DartType> fillTypes1({int limit = 4, bool isFfi = false}) {
final list = <DartType>[];
- for (int i = 0, n = 1 + rand.nextInt(4); i < n; i++) {
+ for (int i = 0, n = 1 + rand.nextInt(limit); i < n; i++) {
if (isFfi) {
list.add(fp ? oneOf([DartType.INT, DartType.DOUBLE]) : DartType.INT);
} else {
@@ -1344,18 +1450,20 @@
return list;
}
- List<List<DartType>> fillTypes2({bool isFfi = false, int limit = 4}) {
+ List<List<DartType>> fillTypes2(
+ {bool isFfi = false, int limit2 = 4, int limit1 = 4}) {
final list = <List<DartType>>[];
- for (int i = 0, n = 1 + rand.nextInt(limit); i < n; i++) {
- list.add(fillTypes1(isFfi: isFfi));
+ for (int i = 0, n = 1 + rand.nextInt(limit2); i < n; i++) {
+ list.add(fillTypes1(limit: limit1, isFfi: isFfi));
}
return list;
}
- List<List<List<DartType>>> fillTypes3(int n) {
+ List<List<List<DartType>>> fillTypes3(int n,
+ {int limit2 = 4, int limit1 = 4}) {
final list = <List<List<DartType>>>[];
for (int i = 0; i < n; i++) {
- list.add(fillTypes2());
+ list.add(fillTypes2(limit2: limit2, limit1: limit1));
}
return list;
}
@@ -1453,7 +1561,7 @@
// Types of global variables.
List<DartType> globalVars;
- // Names of currenty active iterator variables.
+ // Names of currently active iterator variables.
// These are tracked to avoid modifications within the loop body,
// which can lead to infinite loops.
List<String> iterVars;
@@ -1467,6 +1575,10 @@
// Prototypes of all methods over all classes (first element is return type).
List<List<List<DartType>>> classMethods;
+ // List of virtual functions per class. Map is from parent class index to List
+ // of overloaded functions from that parent.
+ List<Map<int, List<int>>> virtualClassMethods;
+
// Parent class indices for all classes.
List<int> classParents;
}
diff --git a/runtime/tools/dartfuzz/dartfuzz_test.dart b/runtime/tools/dartfuzz/dartfuzz_test.dart
index 3dc78e3..c1fcbe7 100644
--- a/runtime/tools/dartfuzz/dartfuzz_test.dart
+++ b/runtime/tools/dartfuzz/dartfuzz_test.dart
@@ -138,14 +138,10 @@
if (mode.endsWith('debug-x64')) return 'DebugX64';
if (mode.endsWith('debug-arm32')) return 'DebugSIMARM';
if (mode.endsWith('debug-arm64')) return 'DebugSIMARM64';
- if (mode.endsWith('debug-dbc32')) return 'DebugSIMDBC';
- if (mode.endsWith('debug-dbc64')) return 'DebugSIMDBC64';
if (mode.endsWith('ia32')) return 'ReleaseIA32';
if (mode.endsWith('x64')) return 'ReleaseX64';
if (mode.endsWith('arm32')) return 'ReleaseSIMARM';
if (mode.endsWith('arm64')) return 'ReleaseSIMARM64';
- if (mode.endsWith('dbc32')) return 'ReleaseSIMDBC';
- if (mode.endsWith('dbc64')) return 'ReleaseSIMDBC64';
throw ('unknown tag in mode: $mode');
}
@@ -315,6 +311,14 @@
print('\n${isolate}: done');
showStatistics();
print('');
+ if (timeoutSeeds.isNotEmpty) {
+ print('\n${isolate} timeout: ' + timeoutSeeds.join(", "));
+ print('');
+ }
+ if (skippedSeeds.isNotEmpty) {
+ print('\n${isolate} skipped: ' + skippedSeeds.join(", "));
+ print('');
+ }
cleanup();
return numDivergences;
@@ -348,6 +352,8 @@
numRerun = 0;
numTimeout = 0;
numDivergences = 0;
+ timeoutSeeds = {};
+ skippedSeeds = {};
}
bool samePrecision(String mode1, String mode2) =>
@@ -427,10 +433,12 @@
case -sigkill:
// Both had a time out.
numTimeout++;
+ timeoutSeeds.add(seed);
break;
default:
// Both had an error.
numSkipped++;
+ skippedSeeds.add(seed);
break;
}
} else {
@@ -440,6 +448,7 @@
// with at least one time out is treated as a regular time out.
if (result1.exitCode == -sigkill || result2.exitCode == -sigkill) {
numTimeout++;
+ timeoutSeeds.add(seed);
return ReportStatus.ignored;
}
}
@@ -531,6 +540,8 @@
int numRerun;
int numTimeout;
int numDivergences;
+ Set<int> timeoutSeeds;
+ Set<int> skippedSeeds;
}
/// Class to start fuzz testing session.
@@ -686,11 +697,6 @@
// Modes not used on cluster runs because they have outstanding issues.
static const List<String> nonClusterModes = [
- // Deprecated.
- 'jit-debug-dbc32',
- 'jit-debug-dbc64',
- 'jit-dbc32',
- 'jit-dbc64',
// Times out often:
'aot-debug-arm32',
'aot-debug-arm64',
diff --git a/runtime/tools/dartfuzz/gen_api_table.dart b/runtime/tools/dartfuzz/gen_api_table.dart
index 1231006..e4a55d6 100644
--- a/runtime/tools/dartfuzz/gen_api_table.dart
+++ b/runtime/tools/dartfuzz/gen_api_table.dart
@@ -56,6 +56,7 @@
final provider = PhysicalResourceProvider.INSTANCE;
final collection = AnalysisContextCollectionImpl(
includedPaths: <String>[packageRoot],
+ excludedPaths: <String>[packageRoot + "/pkg/front_end/test"],
resourceProvider: provider,
sdkPath: sdkPath);
final AnalysisSession session = collection.contexts[0].currentSession;
diff --git a/runtime/tools/dartfuzz/list_dartfuzz_versions.sh b/runtime/tools/dartfuzz/list_dartfuzz_versions.sh
new file mode 100755
index 0000000..5181ca9
--- /dev/null
+++ b/runtime/tools/dartfuzz/list_dartfuzz_versions.sh
@@ -0,0 +1,12 @@
+#!/usr/bin/env bash
+#
+# Copyright (c) 2019, 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.
+
+for i in $(git log --oneline | grep -- '\[vm/fuzzer\]' | awk '{print $1}')
+do
+ echo $i
+ git show $i:runtime/tools/dartfuzz/dartfuzz.dart | grep 'const String version = ' | awk '{print $NF}'
+done
+
diff --git a/runtime/vm/BUILD.gn b/runtime/vm/BUILD.gn
index a526aec..5850a97 100644
--- a/runtime/vm/BUILD.gn
+++ b/runtime/vm/BUILD.gn
@@ -13,7 +13,6 @@
import("../../sdk/lib/isolate/isolate_sources.gni")
import("../../sdk/lib/math/math_sources.gni")
import("../../sdk/lib/mirrors/mirrors_sources.gni")
-import("../../sdk/lib/profiler/profiler_sources.gni")
import("../../sdk/lib/typed_data/typed_data_sources.gni")
import("../../sdk/lib/vmservice/vmservice_sources.gni")
import("../../sdk/lib/wasm/wasm_sources.gni")
@@ -69,7 +68,7 @@
extra_deps = [ "//third_party/icu" ]
if (is_fuchsia) {
if (using_fuchsia_sdk) {
- extra_deps += [ "$fuchsia_sdk_root/pkg/lib/sys/cpp" ]
+ extra_deps += [ "$fuchsia_sdk_root/pkg:sys_cpp" ]
} else {
extra_deps += [
# TODO(US-399): Remove time_service specific code when it is no longer
@@ -102,6 +101,9 @@
]
}
}
+ if (dart_enable_wasm) {
+ defines = [ "DART_ENABLE_WASM" ]
+ }
include_dirs = [ ".." ]
allsources = async_runtime_cc_files + collection_runtime_cc_files +
core_runtime_cc_files + developer_runtime_cc_files +
diff --git a/runtime/vm/bootstrap_natives.cc b/runtime/vm/bootstrap_natives.cc
index f733331..f8030dc 100644
--- a/runtime/vm/bootstrap_natives.cc
+++ b/runtime/vm/bootstrap_natives.cc
@@ -127,11 +127,6 @@
library.set_native_entry_symbol_resolver(symbol_resolver);
#endif
- library = Library::ProfilerLibrary();
- ASSERT(!library.IsNull());
- library.set_native_entry_resolver(resolver);
- library.set_native_entry_symbol_resolver(symbol_resolver);
-
library = Library::TypedDataLibrary();
ASSERT(!library.IsNull());
library.set_native_entry_resolver(resolver);
diff --git a/runtime/vm/bootstrap_natives.h b/runtime/vm/bootstrap_natives.h
index efccf88..c947c02 100644
--- a/runtime/vm/bootstrap_natives.h
+++ b/runtime/vm/bootstrap_natives.h
@@ -391,6 +391,14 @@
V(Ffi_dl_executableLibrary, 0) \
V(TransferableTypedData_factory, 2) \
V(TransferableTypedData_materialize, 1) \
+ V(Wasm_initModule, 2) \
+ V(Wasm_initImports, 2) \
+ V(Wasm_addMemoryImport, 3) \
+ V(Wasm_addGlobalImport, 5) \
+ V(Wasm_initMemory, 3) \
+ V(Wasm_growMemory, 2) \
+ V(Wasm_initInstance, 3) \
+ V(Wasm_initFunction, 4) \
V(Wasm_callFunction, 2)
// List of bootstrap native entry points used in the dart:mirror library.
diff --git a/runtime/vm/class_id.h b/runtime/vm/class_id.h
index 7c129c1..69d6487 100644
--- a/runtime/vm/class_id.h
+++ b/runtime/vm/class_id.h
@@ -131,6 +131,13 @@
V(DynamicLibrary) \
V(Struct)
+#define CLASS_LIST_WASM(V) \
+ V(WasmInt32) \
+ V(WasmInt64) \
+ V(WasmFloat) \
+ V(WasmDouble) \
+ V(WasmVoid)
+
#define DART_CLASS_LIST_TYPED_DATA(V) \
V(Int8) \
V(Uint8) \
@@ -182,6 +189,10 @@
CLASS_LIST_FFI(DEFINE_OBJECT_KIND)
#undef DEFINE_OBJECT_KIND
+#define DEFINE_OBJECT_KIND(clazz) k##clazz##Cid,
+ CLASS_LIST_WASM(DEFINE_OBJECT_KIND)
+#undef DEFINE_OBJECT_KIND
+
#define DEFINE_OBJECT_KIND(clazz) \
kTypedData##clazz##Cid, \
kTypedData##clazz##ViewCid, \
diff --git a/runtime/vm/clustered_snapshot.cc b/runtime/vm/clustered_snapshot.cc
index a5958d6..70459fd 100644
--- a/runtime/vm/clustered_snapshot.cc
+++ b/runtime/vm/clustered_snapshot.cc
@@ -300,7 +300,7 @@
objects_.Add(type_args);
s->Push(type_args->ptr()->instantiations_);
- intptr_t length = Smi::Value(type_args->ptr()->length_);
+ const intptr_t length = Smi::Value(type_args->ptr()->length_);
for (intptr_t i = 0; i < length; i++) {
s->Push(type_args->ptr()->types()[i]);
}
@@ -308,23 +308,23 @@
void WriteAlloc(Serializer* s) {
s->WriteCid(kTypeArgumentsCid);
- intptr_t count = objects_.length();
+ const intptr_t count = objects_.length();
s->WriteUnsigned(count);
for (intptr_t i = 0; i < count; i++) {
RawTypeArguments* type_args = objects_[i];
s->AssignRef(type_args);
AutoTraceObject(type_args);
- intptr_t length = Smi::Value(type_args->ptr()->length_);
+ const intptr_t length = Smi::Value(type_args->ptr()->length_);
s->WriteUnsigned(length);
}
}
void WriteFill(Serializer* s) {
- intptr_t count = objects_.length();
+ const intptr_t count = objects_.length();
for (intptr_t i = 0; i < count; i++) {
RawTypeArguments* type_args = objects_[i];
AutoTraceObject(type_args);
- intptr_t length = Smi::Value(type_args->ptr()->length_);
+ const intptr_t length = Smi::Value(type_args->ptr()->length_);
s->WriteUnsigned(length);
s->Write<bool>(type_args->IsCanonical());
intptr_t hash = Smi::Value(type_args->ptr()->hash_);
@@ -349,9 +349,9 @@
void ReadAlloc(Deserializer* d) {
start_index_ = d->next_index();
PageSpace* old_space = d->heap()->old_space();
- intptr_t count = d->ReadUnsigned();
+ const intptr_t count = d->ReadUnsigned();
for (intptr_t i = 0; i < count; i++) {
- intptr_t length = d->ReadUnsigned();
+ const intptr_t length = d->ReadUnsigned();
d->AssignRef(AllocateUninitialized(old_space,
TypeArguments::InstanceSize(length)));
}
@@ -362,7 +362,7 @@
for (intptr_t id = start_index_; id < stop_index_; id++) {
RawTypeArguments* type_args =
reinterpret_cast<RawTypeArguments*>(d->Ref(id));
- intptr_t length = d->ReadUnsigned();
+ const intptr_t length = d->ReadUnsigned();
bool is_canonical = d->Read<bool>();
Deserializer::InitializeHeader(type_args, kTypeArgumentsCid,
TypeArguments::InstanceSize(length),
@@ -393,7 +393,7 @@
void WriteAlloc(Serializer* s) {
s->WriteCid(kPatchClassCid);
- intptr_t count = objects_.length();
+ const intptr_t count = objects_.length();
s->WriteUnsigned(count);
for (intptr_t i = 0; i < count; i++) {
RawPatchClass* cls = objects_[i];
@@ -402,7 +402,7 @@
}
void WriteFill(Serializer* s) {
- intptr_t count = objects_.length();
+ const intptr_t count = objects_.length();
for (intptr_t i = 0; i < count; i++) {
RawPatchClass* cls = objects_[i];
AutoTraceObject(cls);
@@ -426,7 +426,7 @@
void ReadAlloc(Deserializer* d) {
start_index_ = d->next_index();
PageSpace* old_space = d->heap()->old_space();
- intptr_t count = d->ReadUnsigned();
+ const intptr_t count = d->ReadUnsigned();
for (intptr_t i = 0; i < count; i++) {
d->AssignRef(
AllocateUninitialized(old_space, PatchClass::InstanceSize()));
@@ -475,7 +475,7 @@
void WriteAlloc(Serializer* s) {
s->WriteCid(kFunctionCid);
- intptr_t count = objects_.length();
+ const intptr_t count = objects_.length();
s->WriteUnsigned(count);
for (intptr_t i = 0; i < count; i++) {
RawFunction* func = objects_[i];
@@ -485,7 +485,7 @@
void WriteFill(Serializer* s) {
Snapshot::Kind kind = s->kind();
- intptr_t count = objects_.length();
+ const intptr_t count = objects_.length();
for (intptr_t i = 0; i < count; i++) {
RawFunction* func = objects_[i];
AutoTraceObjectName(func, func->ptr()->name_);
@@ -501,13 +501,12 @@
WriteField(func, ic_data_array_);
}
-#if !defined(DART_PRECOMPILED_RUNTIME)
if (kind != Snapshot::kFullAOT) {
s->WriteTokenPosition(func->ptr()->token_pos_);
s->WriteTokenPosition(func->ptr()->end_token_pos_);
s->Write<uint32_t>(func->ptr()->binary_declaration_);
}
-#endif
+
s->Write<uint32_t>(func->ptr()->packed_fields_);
s->Write<uint32_t>(func->ptr()->kind_tag_);
}
@@ -526,7 +525,7 @@
void ReadAlloc(Deserializer* d) {
start_index_ = d->next_index();
PageSpace* old_space = d->heap()->old_space();
- intptr_t count = d->ReadUnsigned();
+ const intptr_t count = d->ReadUnsigned();
for (intptr_t i = 0; i < count; i++) {
d->AssignRef(AllocateUninitialized(old_space, Function::InstanceSize()));
}
@@ -649,7 +648,7 @@
void WriteAlloc(Serializer* s) {
s->WriteCid(kClosureDataCid);
- intptr_t count = objects_.length();
+ const intptr_t count = objects_.length();
s->WriteUnsigned(count);
for (intptr_t i = 0; i < count; i++) {
RawClosureData* data = objects_[i];
@@ -658,7 +657,7 @@
}
void WriteFill(Serializer* s) {
- intptr_t count = objects_.length();
+ const intptr_t count = objects_.length();
for (intptr_t i = 0; i < count; i++) {
RawClosureData* data = objects_[i];
AutoTraceObject(data);
@@ -684,7 +683,7 @@
void ReadAlloc(Deserializer* d) {
start_index_ = d->next_index();
PageSpace* old_space = d->heap()->old_space();
- intptr_t count = d->ReadUnsigned();
+ const intptr_t count = d->ReadUnsigned();
for (intptr_t i = 0; i < count; i++) {
d->AssignRef(
AllocateUninitialized(old_space, ClosureData::InstanceSize()));
@@ -724,7 +723,7 @@
void WriteAlloc(Serializer* s) {
s->WriteCid(kSignatureDataCid);
- intptr_t count = objects_.length();
+ const intptr_t count = objects_.length();
s->WriteUnsigned(count);
for (intptr_t i = 0; i < count; i++) {
RawSignatureData* data = objects_[i];
@@ -733,7 +732,7 @@
}
void WriteFill(Serializer* s) {
- intptr_t count = objects_.length();
+ const intptr_t count = objects_.length();
for (intptr_t i = 0; i < count; i++) {
RawSignatureData* data = objects_[i];
AutoTraceObject(data);
@@ -754,7 +753,7 @@
void ReadAlloc(Deserializer* d) {
start_index_ = d->next_index();
PageSpace* old_space = d->heap()->old_space();
- intptr_t count = d->ReadUnsigned();
+ const intptr_t count = d->ReadUnsigned();
for (intptr_t i = 0; i < count; i++) {
d->AssignRef(
AllocateUninitialized(old_space, SignatureData::InstanceSize()));
@@ -795,7 +794,7 @@
}
void WriteFill(Serializer* s) {
- intptr_t count = objects_.length();
+ const intptr_t count = objects_.length();
for (intptr_t i = 0; i < count; i++) {
RawFfiTrampolineData* const data = objects_[i];
AutoTraceObject(data);
@@ -823,7 +822,7 @@
void ReadAlloc(Deserializer* d) {
start_index_ = d->next_index();
PageSpace* old_space = d->heap()->old_space();
- intptr_t count = d->ReadUnsigned();
+ const intptr_t count = d->ReadUnsigned();
for (intptr_t i = 0; i < count; i++) {
d->AssignRef(
AllocateUninitialized(old_space, FfiTrampolineData::InstanceSize()));
@@ -859,7 +858,7 @@
void WriteAlloc(Serializer* s) {
s->WriteCid(kRedirectionDataCid);
- intptr_t count = objects_.length();
+ const intptr_t count = objects_.length();
s->WriteUnsigned(count);
for (intptr_t i = 0; i < count; i++) {
RawRedirectionData* data = objects_[i];
@@ -868,7 +867,7 @@
}
void WriteFill(Serializer* s) {
- intptr_t count = objects_.length();
+ const intptr_t count = objects_.length();
for (intptr_t i = 0; i < count; i++) {
RawRedirectionData* data = objects_[i];
AutoTraceObject(data);
@@ -889,7 +888,7 @@
void ReadAlloc(Deserializer* d) {
start_index_ = d->next_index();
PageSpace* old_space = d->heap()->old_space();
- intptr_t count = d->ReadUnsigned();
+ const intptr_t count = d->ReadUnsigned();
for (intptr_t i = 0; i < count; i++) {
d->AssignRef(
AllocateUninitialized(old_space, RedirectionData::InstanceSize()));
@@ -956,7 +955,7 @@
void WriteAlloc(Serializer* s) {
s->WriteCid(kFieldCid);
- intptr_t count = objects_.length();
+ const intptr_t count = objects_.length();
s->WriteUnsigned(count);
for (intptr_t i = 0; i < count; i++) {
RawField* field = objects_[i];
@@ -966,7 +965,7 @@
void WriteFill(Serializer* s) {
Snapshot::Kind kind = s->kind();
- intptr_t count = objects_.length();
+ const intptr_t count = objects_.length();
for (intptr_t i = 0; i < count; i++) {
RawField* field = objects_[i];
AutoTraceObjectName(field, field->ptr()->name_);
@@ -1030,7 +1029,7 @@
void ReadAlloc(Deserializer* d) {
start_index_ = d->next_index();
PageSpace* old_space = d->heap()->old_space();
- intptr_t count = d->ReadUnsigned();
+ const intptr_t count = d->ReadUnsigned();
for (intptr_t i = 0; i < count; i++) {
d->AssignRef(AllocateUninitialized(old_space, Field::InstanceSize()));
}
@@ -1094,7 +1093,7 @@
void WriteAlloc(Serializer* s) {
s->WriteCid(kScriptCid);
- intptr_t count = objects_.length();
+ const intptr_t count = objects_.length();
s->WriteUnsigned(count);
for (intptr_t i = 0; i < count; i++) {
RawScript* script = objects_[i];
@@ -1103,14 +1102,14 @@
}
void WriteFill(Serializer* s) {
- intptr_t count = objects_.length();
+ const intptr_t count = objects_.length();
for (intptr_t i = 0; i < count; i++) {
RawScript* script = objects_[i];
AutoTraceObjectName(script, script->ptr()->url_);
WriteFromTo(script);
s->Write<int32_t>(script->ptr()->line_offset_);
s->Write<int32_t>(script->ptr()->col_offset_);
- s->Write<int8_t>(script->ptr()->kind_);
+ s->Write<uint8_t>(script->ptr()->kind_and_tags_);
s->Write<int32_t>(script->ptr()->kernel_script_index_);
}
}
@@ -1128,7 +1127,7 @@
void ReadAlloc(Deserializer* d) {
start_index_ = d->next_index();
PageSpace* old_space = d->heap()->old_space();
- intptr_t count = d->ReadUnsigned();
+ const intptr_t count = d->ReadUnsigned();
for (intptr_t i = 0; i < count; i++) {
d->AssignRef(AllocateUninitialized(old_space, Script::InstanceSize()));
}
@@ -1143,7 +1142,7 @@
ReadFromTo(script);
script->ptr()->line_offset_ = d->Read<int32_t>();
script->ptr()->col_offset_ = d->Read<int32_t>();
- script->ptr()->kind_ = d->Read<int8_t>();
+ script->ptr()->kind_and_tags_ = d->Read<uint8_t>();
script->ptr()->kernel_script_index_ = d->Read<int32_t>();
script->ptr()->load_timestamp_ = 0;
}
@@ -1164,7 +1163,7 @@
void WriteAlloc(Serializer* s) {
s->WriteCid(kLibraryCid);
- intptr_t count = objects_.length();
+ const intptr_t count = objects_.length();
s->WriteUnsigned(count);
for (intptr_t i = 0; i < count; i++) {
RawLibrary* lib = objects_[i];
@@ -1173,7 +1172,7 @@
}
void WriteFill(Serializer* s) {
- intptr_t count = objects_.length();
+ const intptr_t count = objects_.length();
for (intptr_t i = 0; i < count; i++) {
RawLibrary* lib = objects_[i];
AutoTraceObjectName(lib, lib->ptr()->url_);
@@ -1202,7 +1201,7 @@
void ReadAlloc(Deserializer* d) {
start_index_ = d->next_index();
PageSpace* old_space = d->heap()->old_space();
- intptr_t count = d->ReadUnsigned();
+ const intptr_t count = d->ReadUnsigned();
for (intptr_t i = 0; i < count; i++) {
d->AssignRef(AllocateUninitialized(old_space, Library::InstanceSize()));
}
@@ -1245,7 +1244,7 @@
void WriteAlloc(Serializer* s) {
s->WriteCid(kNamespaceCid);
- intptr_t count = objects_.length();
+ const intptr_t count = objects_.length();
s->WriteUnsigned(count);
for (intptr_t i = 0; i < count; i++) {
RawNamespace* ns = objects_[i];
@@ -1254,7 +1253,7 @@
}
void WriteFill(Serializer* s) {
- intptr_t count = objects_.length();
+ const intptr_t count = objects_.length();
for (intptr_t i = 0; i < count; i++) {
RawNamespace* ns = objects_[i];
AutoTraceObject(ns);
@@ -1275,7 +1274,7 @@
void ReadAlloc(Deserializer* d) {
start_index_ = d->next_index();
PageSpace* old_space = d->heap()->old_space();
- intptr_t count = d->ReadUnsigned();
+ const intptr_t count = d->ReadUnsigned();
for (intptr_t i = 0; i < count; i++) {
d->AssignRef(AllocateUninitialized(old_space, Namespace::InstanceSize()));
}
@@ -1308,7 +1307,7 @@
void WriteAlloc(Serializer* s) {
s->WriteCid(kKernelProgramInfoCid);
- intptr_t count = objects_.length();
+ const intptr_t count = objects_.length();
s->WriteUnsigned(count);
for (intptr_t i = 0; i < count; i++) {
RawKernelProgramInfo* info = objects_[i];
@@ -1317,7 +1316,7 @@
}
void WriteFill(Serializer* s) {
- intptr_t count = objects_.length();
+ const intptr_t count = objects_.length();
for (intptr_t i = 0; i < count; i++) {
RawKernelProgramInfo* info = objects_[i];
AutoTraceObject(info);
@@ -1340,7 +1339,7 @@
void ReadAlloc(Deserializer* d) {
start_index_ = d->next_index();
PageSpace* old_space = d->heap()->old_space();
- intptr_t count = d->ReadUnsigned();
+ const intptr_t count = d->ReadUnsigned();
for (intptr_t i = 0; i < count; i++) {
d->AssignRef(
AllocateUninitialized(old_space, KernelProgramInfo::InstanceSize()));
@@ -1404,7 +1403,7 @@
void WriteAlloc(Serializer* s) {
s->WriteCid(kCodeCid);
- intptr_t count = objects_.length();
+ const intptr_t count = objects_.length();
s->WriteUnsigned(count);
for (intptr_t i = 0; i < count; i++) {
RawCode* code = objects_[i];
@@ -1414,7 +1413,7 @@
void WriteFill(Serializer* s) {
Snapshot::Kind kind = s->kind();
- intptr_t count = objects_.length();
+ const intptr_t count = objects_.length();
for (intptr_t i = 0; i < count; i++) {
RawCode* code = objects_[i];
AutoTraceObject(code);
@@ -1610,7 +1609,7 @@
void WriteAlloc(Serializer* s) {
s->WriteCid(kBytecodeCid);
- intptr_t count = objects_.length();
+ const intptr_t count = objects_.length();
s->WriteUnsigned(count);
for (intptr_t i = 0; i < count; i++) {
RawBytecode* bytecode = objects_[i];
@@ -1620,7 +1619,7 @@
void WriteFill(Serializer* s) {
ASSERT(s->kind() != Snapshot::kFullAOT);
- intptr_t count = objects_.length();
+ const intptr_t count = objects_.length();
for (intptr_t i = 0; i < count; i++) {
RawBytecode* bytecode = objects_[i];
s->Write<int32_t>(bytecode->ptr()->instructions_size_);
@@ -1643,7 +1642,7 @@
void ReadAlloc(Deserializer* d) {
start_index_ = d->next_index();
PageSpace* old_space = d->heap()->old_space();
- intptr_t count = d->ReadUnsigned();
+ const intptr_t count = d->ReadUnsigned();
for (intptr_t i = 0; i < count; i++) {
d->AssignRef(AllocateUninitialized(old_space, Bytecode::InstanceSize()));
}
@@ -1688,7 +1687,7 @@
RawObjectPool* pool = ObjectPool::RawCast(object);
objects_.Add(pool);
- intptr_t length = pool->ptr()->length_;
+ const intptr_t length = pool->ptr()->length_;
uint8_t* entry_bits = pool->ptr()->entry_bits();
for (intptr_t i = 0; i < length; i++) {
auto entry_type = ObjectPool::TypeBits::decode(entry_bits[i]);
@@ -1701,23 +1700,23 @@
void WriteAlloc(Serializer* s) {
s->WriteCid(kObjectPoolCid);
- intptr_t count = objects_.length();
+ const intptr_t count = objects_.length();
s->WriteUnsigned(count);
for (intptr_t i = 0; i < count; i++) {
RawObjectPool* pool = objects_[i];
s->AssignRef(pool);
AutoTraceObject(pool);
- intptr_t length = pool->ptr()->length_;
+ const intptr_t length = pool->ptr()->length_;
s->WriteUnsigned(length);
}
}
void WriteFill(Serializer* s) {
- intptr_t count = objects_.length();
+ const intptr_t count = objects_.length();
for (intptr_t i = 0; i < count; i++) {
RawObjectPool* pool = objects_[i];
AutoTraceObject(pool);
- intptr_t length = pool->ptr()->length_;
+ const intptr_t length = pool->ptr()->length_;
s->WriteUnsigned(length);
uint8_t* entry_bits = pool->ptr()->entry_bits();
for (intptr_t j = 0; j < length; j++) {
@@ -1783,9 +1782,9 @@
void ReadAlloc(Deserializer* d) {
start_index_ = d->next_index();
PageSpace* old_space = d->heap()->old_space();
- intptr_t count = d->ReadUnsigned();
+ const intptr_t count = d->ReadUnsigned();
for (intptr_t i = 0; i < count; i++) {
- intptr_t length = d->ReadUnsigned();
+ const intptr_t length = d->ReadUnsigned();
d->AssignRef(
AllocateUninitialized(old_space, ObjectPool::InstanceSize(length)));
}
@@ -1794,7 +1793,7 @@
void ReadFill(Deserializer* d) {
for (intptr_t id = start_index_; id < stop_index_; id += 1) {
- intptr_t length = d->ReadUnsigned();
+ const intptr_t length = d->ReadUnsigned();
RawObjectPool* pool = reinterpret_cast<RawObjectPool*>(d->Ref(id + 0));
Deserializer::InitializeHeader(pool, kObjectPoolCid,
ObjectPool::InstanceSize(length));
@@ -1834,6 +1833,77 @@
};
#if !defined(DART_PRECOMPILED_RUNTIME)
+class PcDescriptorsSerializationCluster : public SerializationCluster {
+ public:
+ PcDescriptorsSerializationCluster() : SerializationCluster("PcDescriptors") {}
+ ~PcDescriptorsSerializationCluster() {}
+
+ void Trace(Serializer* s, RawObject* object) {
+ RawPcDescriptors* desc = PcDescriptors::RawCast(object);
+ objects_.Add(desc);
+ }
+
+ void WriteAlloc(Serializer* s) {
+ s->WriteCid(kPcDescriptorsCid);
+ const intptr_t count = objects_.length();
+ s->WriteUnsigned(count);
+ for (intptr_t i = 0; i < count; i++) {
+ RawPcDescriptors* desc = objects_[i];
+ s->AssignRef(desc);
+ AutoTraceObject(desc);
+ const intptr_t length = desc->ptr()->length_;
+ s->WriteUnsigned(length);
+ }
+ }
+
+ void WriteFill(Serializer* s) {
+ const intptr_t count = objects_.length();
+ for (intptr_t i = 0; i < count; i++) {
+ RawPcDescriptors* desc = objects_[i];
+ AutoTraceObject(desc);
+ const intptr_t length = desc->ptr()->length_;
+ s->WriteUnsigned(length);
+ uint8_t* cdata = reinterpret_cast<uint8_t*>(desc->ptr()->data());
+ s->WriteBytes(cdata, length);
+ }
+ }
+
+ private:
+ GrowableArray<RawPcDescriptors*> objects_;
+};
+#endif // !DART_PRECOMPILED_RUNTIME
+
+class PcDescriptorsDeserializationCluster : public DeserializationCluster {
+ public:
+ PcDescriptorsDeserializationCluster() {}
+ ~PcDescriptorsDeserializationCluster() {}
+
+ void ReadAlloc(Deserializer* d) {
+ start_index_ = d->next_index();
+ PageSpace* old_space = d->heap()->old_space();
+ const intptr_t count = d->ReadUnsigned();
+ for (intptr_t i = 0; i < count; i++) {
+ const intptr_t length = d->ReadUnsigned();
+ d->AssignRef(AllocateUninitialized(old_space,
+ PcDescriptors::InstanceSize(length)));
+ }
+ stop_index_ = d->next_index();
+ }
+
+ void ReadFill(Deserializer* d) {
+ for (intptr_t id = start_index_; id < stop_index_; id += 1) {
+ const intptr_t length = d->ReadUnsigned();
+ RawPcDescriptors* desc = reinterpret_cast<RawPcDescriptors*>(d->Ref(id));
+ Deserializer::InitializeHeader(desc, kPcDescriptorsCid,
+ PcDescriptors::InstanceSize(length));
+ desc->ptr()->length_ = length;
+ uint8_t* cdata = reinterpret_cast<uint8_t*>(desc->ptr()->data());
+ d->ReadBytes(cdata, length);
+ }
+ }
+};
+
+#if !defined(DART_PRECOMPILED_RUNTIME)
// PcDescriptor, StackMap, OneByteString, TwoByteString
class RODataSerializationCluster : public SerializationCluster {
public:
@@ -1951,23 +2021,23 @@
void WriteAlloc(Serializer* s) {
s->WriteCid(kExceptionHandlersCid);
- intptr_t count = objects_.length();
+ const intptr_t count = objects_.length();
s->WriteUnsigned(count);
for (intptr_t i = 0; i < count; i++) {
RawExceptionHandlers* handlers = objects_[i];
s->AssignRef(handlers);
AutoTraceObject(handlers);
- intptr_t length = handlers->ptr()->num_entries_;
+ const intptr_t length = handlers->ptr()->num_entries_;
s->WriteUnsigned(length);
}
}
void WriteFill(Serializer* s) {
- intptr_t count = objects_.length();
+ const intptr_t count = objects_.length();
for (intptr_t i = 0; i < count; i++) {
RawExceptionHandlers* handlers = objects_[i];
AutoTraceObject(handlers);
- intptr_t length = handlers->ptr()->num_entries_;
+ const intptr_t length = handlers->ptr()->num_entries_;
s->WriteUnsigned(length);
WriteField(handlers, handled_types_data_);
for (intptr_t j = 0; j < length; j++) {
@@ -1994,9 +2064,9 @@
void ReadAlloc(Deserializer* d) {
start_index_ = d->next_index();
PageSpace* old_space = d->heap()->old_space();
- intptr_t count = d->ReadUnsigned();
+ const intptr_t count = d->ReadUnsigned();
for (intptr_t i = 0; i < count; i++) {
- intptr_t length = d->ReadUnsigned();
+ const intptr_t length = d->ReadUnsigned();
d->AssignRef(AllocateUninitialized(
old_space, ExceptionHandlers::InstanceSize(length)));
}
@@ -2007,7 +2077,7 @@
for (intptr_t id = start_index_; id < stop_index_; id++) {
RawExceptionHandlers* handlers =
reinterpret_cast<RawExceptionHandlers*>(d->Ref(id));
- intptr_t length = d->ReadUnsigned();
+ const intptr_t length = d->ReadUnsigned();
Deserializer::InitializeHeader(handlers, kExceptionHandlersCid,
ExceptionHandlers::InstanceSize(length));
handlers->ptr()->num_entries_ = length;
@@ -2036,7 +2106,7 @@
objects_.Add(context);
s->Push(context->ptr()->parent_);
- intptr_t length = context->ptr()->num_variables_;
+ const intptr_t length = context->ptr()->num_variables_;
for (intptr_t i = 0; i < length; i++) {
s->Push(context->ptr()->data()[i]);
}
@@ -2044,23 +2114,23 @@
void WriteAlloc(Serializer* s) {
s->WriteCid(kContextCid);
- intptr_t count = objects_.length();
+ const intptr_t count = objects_.length();
s->WriteUnsigned(count);
for (intptr_t i = 0; i < count; i++) {
RawContext* context = objects_[i];
s->AssignRef(context);
AutoTraceObject(context);
- intptr_t length = context->ptr()->num_variables_;
+ const intptr_t length = context->ptr()->num_variables_;
s->WriteUnsigned(length);
}
}
void WriteFill(Serializer* s) {
- intptr_t count = objects_.length();
+ const intptr_t count = objects_.length();
for (intptr_t i = 0; i < count; i++) {
RawContext* context = objects_[i];
AutoTraceObject(context);
- intptr_t length = context->ptr()->num_variables_;
+ const intptr_t length = context->ptr()->num_variables_;
s->WriteUnsigned(length);
WriteField(context, parent_);
for (intptr_t j = 0; j < length; j++) {
@@ -2082,9 +2152,9 @@
void ReadAlloc(Deserializer* d) {
start_index_ = d->next_index();
PageSpace* old_space = d->heap()->old_space();
- intptr_t count = d->ReadUnsigned();
+ const intptr_t count = d->ReadUnsigned();
for (intptr_t i = 0; i < count; i++) {
- intptr_t length = d->ReadUnsigned();
+ const intptr_t length = d->ReadUnsigned();
d->AssignRef(
AllocateUninitialized(old_space, Context::InstanceSize(length)));
}
@@ -2094,7 +2164,7 @@
void ReadFill(Deserializer* d) {
for (intptr_t id = start_index_; id < stop_index_; id++) {
RawContext* context = reinterpret_cast<RawContext*>(d->Ref(id));
- intptr_t length = d->ReadUnsigned();
+ const intptr_t length = d->ReadUnsigned();
Deserializer::InitializeHeader(context, kContextCid,
Context::InstanceSize(length));
context->ptr()->num_variables_ = length;
@@ -2116,29 +2186,29 @@
RawContextScope* scope = ContextScope::RawCast(object);
objects_.Add(scope);
- intptr_t length = scope->ptr()->num_variables_;
+ const intptr_t length = scope->ptr()->num_variables_;
PushFromTo(scope, length);
}
void WriteAlloc(Serializer* s) {
s->WriteCid(kContextScopeCid);
- intptr_t count = objects_.length();
+ const intptr_t count = objects_.length();
s->WriteUnsigned(count);
for (intptr_t i = 0; i < count; i++) {
RawContextScope* scope = objects_[i];
s->AssignRef(scope);
AutoTraceObject(scope);
- intptr_t length = scope->ptr()->num_variables_;
+ const intptr_t length = scope->ptr()->num_variables_;
s->WriteUnsigned(length);
}
}
void WriteFill(Serializer* s) {
- intptr_t count = objects_.length();
+ const intptr_t count = objects_.length();
for (intptr_t i = 0; i < count; i++) {
RawContextScope* scope = objects_[i];
AutoTraceObject(scope);
- intptr_t length = scope->ptr()->num_variables_;
+ const intptr_t length = scope->ptr()->num_variables_;
s->WriteUnsigned(length);
s->Write<bool>(scope->ptr()->is_implicit_);
WriteFromTo(scope, length);
@@ -2158,9 +2228,9 @@
void ReadAlloc(Deserializer* d) {
start_index_ = d->next_index();
PageSpace* old_space = d->heap()->old_space();
- intptr_t count = d->ReadUnsigned();
+ const intptr_t count = d->ReadUnsigned();
for (intptr_t i = 0; i < count; i++) {
- intptr_t length = d->ReadUnsigned();
+ const intptr_t length = d->ReadUnsigned();
d->AssignRef(
AllocateUninitialized(old_space, ContextScope::InstanceSize(length)));
}
@@ -2170,7 +2240,7 @@
void ReadFill(Deserializer* d) {
for (intptr_t id = start_index_; id < stop_index_; id++) {
RawContextScope* scope = reinterpret_cast<RawContextScope*>(d->Ref(id));
- intptr_t length = d->ReadUnsigned();
+ const intptr_t length = d->ReadUnsigned();
Deserializer::InitializeHeader(scope, kContextScopeCid,
ContextScope::InstanceSize(length));
scope->ptr()->num_variables_ = length;
@@ -2195,7 +2265,7 @@
void WriteAlloc(Serializer* s) {
s->WriteCid(kParameterTypeCheckCid);
- intptr_t count = objects_.length();
+ const intptr_t count = objects_.length();
s->WriteUnsigned(count);
for (intptr_t i = 0; i < count; i++) {
RawParameterTypeCheck* check = objects_[i];
@@ -2204,7 +2274,7 @@
}
void WriteFill(Serializer* s) {
- intptr_t count = objects_.length();
+ const intptr_t count = objects_.length();
for (intptr_t i = 0; i < count; i++) {
RawParameterTypeCheck* check = objects_[i];
s->Write<intptr_t>(check->ptr()->index_);
@@ -2225,7 +2295,7 @@
void ReadAlloc(Deserializer* d) {
start_index_ = d->next_index();
PageSpace* old_space = d->heap()->old_space();
- intptr_t count = d->ReadUnsigned();
+ const intptr_t count = d->ReadUnsigned();
for (intptr_t i = 0; i < count; i++) {
d->AssignRef(
AllocateUninitialized(old_space, ParameterTypeCheck::InstanceSize()));
@@ -2259,7 +2329,7 @@
void WriteAlloc(Serializer* s) {
s->WriteCid(kUnlinkedCallCid);
- intptr_t count = objects_.length();
+ const intptr_t count = objects_.length();
s->WriteUnsigned(count);
for (intptr_t i = 0; i < count; i++) {
RawUnlinkedCall* unlinked = objects_[i];
@@ -2268,7 +2338,7 @@
}
void WriteFill(Serializer* s) {
- intptr_t count = objects_.length();
+ const intptr_t count = objects_.length();
for (intptr_t i = 0; i < count; i++) {
RawUnlinkedCall* unlinked = objects_[i];
AutoTraceObjectName(unlinked, unlinked->ptr()->target_name_);
@@ -2289,7 +2359,7 @@
void ReadAlloc(Deserializer* d) {
start_index_ = d->next_index();
PageSpace* old_space = d->heap()->old_space();
- intptr_t count = d->ReadUnsigned();
+ const intptr_t count = d->ReadUnsigned();
for (intptr_t i = 0; i < count; i++) {
d->AssignRef(
AllocateUninitialized(old_space, UnlinkedCall::InstanceSize()));
@@ -2322,7 +2392,7 @@
void WriteAlloc(Serializer* s) {
s->WriteCid(kICDataCid);
- intptr_t count = objects_.length();
+ const intptr_t count = objects_.length();
s->WriteUnsigned(count);
for (intptr_t i = 0; i < count; i++) {
RawICData* ic = objects_[i];
@@ -2332,7 +2402,7 @@
void WriteFill(Serializer* s) {
Snapshot::Kind kind = s->kind();
- intptr_t count = objects_.length();
+ const intptr_t count = objects_.length();
for (intptr_t i = 0; i < count; i++) {
RawICData* ic = objects_[i];
AutoTraceObjectName(ic, ic->ptr()->target_name_);
@@ -2357,7 +2427,7 @@
void ReadAlloc(Deserializer* d) {
start_index_ = d->next_index();
PageSpace* old_space = d->heap()->old_space();
- intptr_t count = d->ReadUnsigned();
+ const intptr_t count = d->ReadUnsigned();
for (intptr_t i = 0; i < count; i++) {
d->AssignRef(AllocateUninitialized(old_space, ICData::InstanceSize()));
}
@@ -2390,7 +2460,7 @@
void WriteAlloc(Serializer* s) {
s->WriteCid(kMegamorphicCacheCid);
- intptr_t count = objects_.length();
+ const intptr_t count = objects_.length();
s->WriteUnsigned(count);
for (intptr_t i = 0; i < count; i++) {
RawMegamorphicCache* cache = objects_[i];
@@ -2399,7 +2469,7 @@
}
void WriteFill(Serializer* s) {
- intptr_t count = objects_.length();
+ const intptr_t count = objects_.length();
for (intptr_t i = 0; i < count; i++) {
RawMegamorphicCache* cache = objects_[i];
AutoTraceObjectName(cache, cache->ptr()->target_name_);
@@ -2421,7 +2491,7 @@
void ReadAlloc(Deserializer* d) {
start_index_ = d->next_index();
PageSpace* old_space = d->heap()->old_space();
- intptr_t count = d->ReadUnsigned();
+ const intptr_t count = d->ReadUnsigned();
for (intptr_t i = 0; i < count; i++) {
d->AssignRef(
AllocateUninitialized(old_space, MegamorphicCache::InstanceSize()));
@@ -2482,7 +2552,7 @@
void WriteAlloc(Serializer* s) {
s->WriteCid(kSubtypeTestCacheCid);
- intptr_t count = objects_.length();
+ const intptr_t count = objects_.length();
s->WriteUnsigned(count);
for (intptr_t i = 0; i < count; i++) {
RawSubtypeTestCache* cache = objects_[i];
@@ -2491,7 +2561,7 @@
}
void WriteFill(Serializer* s) {
- intptr_t count = objects_.length();
+ const intptr_t count = objects_.length();
for (intptr_t i = 0; i < count; i++) {
RawSubtypeTestCache* cache = objects_[i];
AutoTraceObject(cache);
@@ -2512,7 +2582,7 @@
void ReadAlloc(Deserializer* d) {
start_index_ = d->next_index();
PageSpace* old_space = d->heap()->old_space();
- intptr_t count = d->ReadUnsigned();
+ const intptr_t count = d->ReadUnsigned();
for (intptr_t i = 0; i < count; i++) {
d->AssignRef(
AllocateUninitialized(old_space, SubtypeTestCache::InstanceSize()));
@@ -2545,7 +2615,7 @@
void WriteAlloc(Serializer* s) {
s->WriteCid(kLanguageErrorCid);
- intptr_t count = objects_.length();
+ const intptr_t count = objects_.length();
s->WriteUnsigned(count);
for (intptr_t i = 0; i < count; i++) {
RawLanguageError* error = objects_[i];
@@ -2554,7 +2624,7 @@
}
void WriteFill(Serializer* s) {
- intptr_t count = objects_.length();
+ const intptr_t count = objects_.length();
for (intptr_t i = 0; i < count; i++) {
RawLanguageError* error = objects_[i];
AutoTraceObject(error);
@@ -2578,7 +2648,7 @@
void ReadAlloc(Deserializer* d) {
start_index_ = d->next_index();
PageSpace* old_space = d->heap()->old_space();
- intptr_t count = d->ReadUnsigned();
+ const intptr_t count = d->ReadUnsigned();
for (intptr_t i = 0; i < count; i++) {
d->AssignRef(
AllocateUninitialized(old_space, LanguageError::InstanceSize()));
@@ -2614,7 +2684,7 @@
void WriteAlloc(Serializer* s) {
s->WriteCid(kUnhandledExceptionCid);
- intptr_t count = objects_.length();
+ const intptr_t count = objects_.length();
s->WriteUnsigned(count);
for (intptr_t i = 0; i < count; i++) {
RawUnhandledException* exception = objects_[i];
@@ -2623,7 +2693,7 @@
}
void WriteFill(Serializer* s) {
- intptr_t count = objects_.length();
+ const intptr_t count = objects_.length();
for (intptr_t i = 0; i < count; i++) {
RawUnhandledException* exception = objects_[i];
AutoTraceObject(exception);
@@ -2644,7 +2714,7 @@
void ReadAlloc(Deserializer* d) {
start_index_ = d->next_index();
PageSpace* old_space = d->heap()->old_space();
- intptr_t count = d->ReadUnsigned();
+ const intptr_t count = d->ReadUnsigned();
for (intptr_t i = 0; i < count; i++) {
d->AssignRef(
AllocateUninitialized(old_space, UnhandledException::InstanceSize()));
@@ -2692,7 +2762,7 @@
void WriteAlloc(Serializer* s) {
s->WriteCid(cid_);
- intptr_t count = objects_.length();
+ const intptr_t count = objects_.length();
s->WriteUnsigned(count);
s->Write<int32_t>(next_field_offset_in_words_);
@@ -2706,7 +2776,7 @@
void WriteFill(Serializer* s) {
intptr_t next_field_offset = next_field_offset_in_words_ << kWordSizeLog2;
- intptr_t count = objects_.length();
+ const intptr_t count = objects_.length();
for (intptr_t i = 0; i < count; i++) {
RawInstance* instance = objects_[i];
AutoTraceObject(instance);
@@ -2737,7 +2807,7 @@
void ReadAlloc(Deserializer* d) {
start_index_ = d->next_index();
PageSpace* old_space = d->heap()->old_space();
- intptr_t count = d->ReadUnsigned();
+ const intptr_t count = d->ReadUnsigned();
next_field_offset_in_words_ = d->Read<int32_t>();
instance_size_in_words_ = d->Read<int32_t>();
intptr_t instance_size =
@@ -2795,7 +2865,7 @@
void WriteAlloc(Serializer* s) {
s->WriteCid(kLibraryPrefixCid);
- intptr_t count = objects_.length();
+ const intptr_t count = objects_.length();
s->WriteUnsigned(count);
for (intptr_t i = 0; i < count; i++) {
RawLibraryPrefix* prefix = objects_[i];
@@ -2804,7 +2874,7 @@
}
void WriteFill(Serializer* s) {
- intptr_t count = objects_.length();
+ const intptr_t count = objects_.length();
for (intptr_t i = 0; i < count; i++) {
RawLibraryPrefix* prefix = objects_[i];
AutoTraceObject(prefix);
@@ -2827,7 +2897,7 @@
void ReadAlloc(Deserializer* d) {
start_index_ = d->next_index();
PageSpace* old_space = d->heap()->old_space();
- intptr_t count = d->ReadUnsigned();
+ const intptr_t count = d->ReadUnsigned();
for (intptr_t i = 0; i < count; i++) {
d->AssignRef(
AllocateUninitialized(old_space, LibraryPrefix::InstanceSize()));
@@ -3011,7 +3081,7 @@
void WriteAlloc(Serializer* s) {
s->WriteCid(kTypeRefCid);
- intptr_t count = objects_.length();
+ const intptr_t count = objects_.length();
s->WriteUnsigned(count);
for (intptr_t i = 0; i < count; i++) {
RawTypeRef* type = objects_[i];
@@ -3020,7 +3090,7 @@
}
void WriteFill(Serializer* s) {
- intptr_t count = objects_.length();
+ const intptr_t count = objects_.length();
for (intptr_t i = 0; i < count; i++) {
RawTypeRef* type = objects_[i];
AutoTraceObject(type);
@@ -3041,7 +3111,7 @@
void ReadAlloc(Deserializer* d) {
start_index_ = d->next_index();
PageSpace* old_space = d->heap()->old_space();
- intptr_t count = d->ReadUnsigned();
+ const intptr_t count = d->ReadUnsigned();
for (intptr_t i = 0; i < count; i++) {
d->AssignRef(AllocateUninitialized(old_space, TypeRef::InstanceSize()));
}
@@ -3094,7 +3164,7 @@
void WriteAlloc(Serializer* s) {
s->WriteCid(kTypeParameterCid);
- intptr_t count = objects_.length();
+ const intptr_t count = objects_.length();
s->WriteUnsigned(count);
for (intptr_t i = 0; i < count; i++) {
RawTypeParameter* type = objects_[i];
@@ -3103,7 +3173,7 @@
}
void WriteFill(Serializer* s) {
- intptr_t count = objects_.length();
+ const intptr_t count = objects_.length();
for (intptr_t i = 0; i < count; i++) {
RawTypeParameter* type = objects_[i];
AutoTraceObject(type);
@@ -3128,7 +3198,7 @@
void ReadAlloc(Deserializer* d) {
start_index_ = d->next_index();
PageSpace* old_space = d->heap()->old_space();
- intptr_t count = d->ReadUnsigned();
+ const intptr_t count = d->ReadUnsigned();
for (intptr_t i = 0; i < count; i++) {
d->AssignRef(
AllocateUninitialized(old_space, TypeParameter::InstanceSize()));
@@ -3184,7 +3254,7 @@
void WriteAlloc(Serializer* s) {
s->WriteCid(kClosureCid);
- intptr_t count = objects_.length();
+ const intptr_t count = objects_.length();
s->WriteUnsigned(count);
for (intptr_t i = 0; i < count; i++) {
RawClosure* closure = objects_[i];
@@ -3193,7 +3263,7 @@
}
void WriteFill(Serializer* s) {
- intptr_t count = objects_.length();
+ const intptr_t count = objects_.length();
for (intptr_t i = 0; i < count; i++) {
RawClosure* closure = objects_[i];
AutoTraceObject(closure);
@@ -3215,7 +3285,7 @@
void ReadAlloc(Deserializer* d) {
start_index_ = d->next_index();
PageSpace* old_space = d->heap()->old_space();
- intptr_t count = d->ReadUnsigned();
+ const intptr_t count = d->ReadUnsigned();
for (intptr_t i = 0; i < count; i++) {
d->AssignRef(AllocateUninitialized(old_space, Closure::InstanceSize()));
}
@@ -3286,7 +3356,7 @@
PageSpace* old_space = d->heap()->old_space();
start_index_ = d->next_index();
- intptr_t count = d->ReadUnsigned();
+ const intptr_t count = d->ReadUnsigned();
for (intptr_t i = 0; i < count; i++) {
bool is_canonical = d->Read<bool>();
int64_t value = d->Read<int64_t>();
@@ -3333,7 +3403,7 @@
void WriteAlloc(Serializer* s) {
s->WriteCid(kDoubleCid);
- intptr_t count = objects_.length();
+ const intptr_t count = objects_.length();
s->WriteUnsigned(count);
for (intptr_t i = 0; i < count; i++) {
RawDouble* dbl = objects_[i];
@@ -3342,7 +3412,7 @@
}
void WriteFill(Serializer* s) {
- intptr_t count = objects_.length();
+ const intptr_t count = objects_.length();
for (intptr_t i = 0; i < count; i++) {
RawDouble* dbl = objects_[i];
AutoTraceObject(dbl);
@@ -3364,7 +3434,7 @@
void ReadAlloc(Deserializer* d) {
start_index_ = d->next_index();
PageSpace* old_space = d->heap()->old_space();
- intptr_t count = d->ReadUnsigned();
+ const intptr_t count = d->ReadUnsigned();
for (intptr_t i = 0; i < count; i++) {
d->AssignRef(AllocateUninitialized(old_space, Double::InstanceSize()));
}
@@ -3397,7 +3467,7 @@
void WriteAlloc(Serializer* s) {
s->WriteCid(kGrowableObjectArrayCid);
- intptr_t count = objects_.length();
+ const intptr_t count = objects_.length();
s->WriteUnsigned(count);
for (intptr_t i = 0; i < count; i++) {
RawGrowableObjectArray* array = objects_[i];
@@ -3406,7 +3476,7 @@
}
void WriteFill(Serializer* s) {
- intptr_t count = objects_.length();
+ const intptr_t count = objects_.length();
for (intptr_t i = 0; i < count; i++) {
RawGrowableObjectArray* array = objects_[i];
AutoTraceObject(array);
@@ -3429,7 +3499,7 @@
void ReadAlloc(Deserializer* d) {
start_index_ = d->next_index();
PageSpace* old_space = d->heap()->old_space();
- intptr_t count = d->ReadUnsigned();
+ const intptr_t count = d->ReadUnsigned();
for (intptr_t i = 0; i < count; i++) {
d->AssignRef(AllocateUninitialized(old_space,
GrowableObjectArray::InstanceSize()));
@@ -3464,24 +3534,24 @@
void WriteAlloc(Serializer* s) {
s->WriteCid(cid_);
- intptr_t count = objects_.length();
+ const intptr_t count = objects_.length();
s->WriteUnsigned(count);
for (intptr_t i = 0; i < count; i++) {
RawTypedData* data = objects_[i];
s->AssignRef(data);
AutoTraceObject(data);
- intptr_t length = Smi::Value(data->ptr()->length_);
+ const intptr_t length = Smi::Value(data->ptr()->length_);
s->WriteUnsigned(length);
}
}
void WriteFill(Serializer* s) {
- intptr_t count = objects_.length();
+ const intptr_t count = objects_.length();
intptr_t element_size = TypedData::ElementSizeInBytes(cid_);
for (intptr_t i = 0; i < count; i++) {
RawTypedData* data = objects_[i];
AutoTraceObject(data);
- intptr_t length = Smi::Value(data->ptr()->length_);
+ const intptr_t length = Smi::Value(data->ptr()->length_);
s->WriteUnsigned(length);
s->Write<bool>(data->IsCanonical());
uint8_t* cdata = reinterpret_cast<uint8_t*>(data->ptr()->data());
@@ -3503,10 +3573,10 @@
void ReadAlloc(Deserializer* d) {
start_index_ = d->next_index();
PageSpace* old_space = d->heap()->old_space();
- intptr_t count = d->ReadUnsigned();
+ const intptr_t count = d->ReadUnsigned();
intptr_t element_size = TypedData::ElementSizeInBytes(cid_);
for (intptr_t i = 0; i < count; i++) {
- intptr_t length = d->ReadUnsigned();
+ const intptr_t length = d->ReadUnsigned();
d->AssignRef(AllocateUninitialized(
old_space, TypedData::InstanceSize(length * element_size)));
}
@@ -3518,9 +3588,9 @@
for (intptr_t id = start_index_; id < stop_index_; id++) {
RawTypedData* data = reinterpret_cast<RawTypedData*>(d->Ref(id));
- intptr_t length = d->ReadUnsigned();
+ const intptr_t length = d->ReadUnsigned();
bool is_canonical = d->Read<bool>();
- intptr_t length_in_bytes = length * element_size;
+ const intptr_t length_in_bytes = length * element_size;
Deserializer::InitializeHeader(
data, cid_, TypedData::InstanceSize(length_in_bytes), is_canonical);
data->ptr()->length_ = Smi::New(length);
@@ -3627,7 +3697,7 @@
void WriteAlloc(Serializer* s) {
s->WriteCid(cid_);
- intptr_t count = objects_.length();
+ const intptr_t count = objects_.length();
s->WriteUnsigned(count);
for (intptr_t i = 0; i < count; i++) {
RawExternalTypedData* data = objects_[i];
@@ -3636,12 +3706,12 @@
}
void WriteFill(Serializer* s) {
- intptr_t count = objects_.length();
+ const intptr_t count = objects_.length();
intptr_t element_size = ExternalTypedData::ElementSizeInBytes(cid_);
for (intptr_t i = 0; i < count; i++) {
RawExternalTypedData* data = objects_[i];
AutoTraceObject(data);
- intptr_t length = Smi::Value(data->ptr()->length_);
+ const intptr_t length = Smi::Value(data->ptr()->length_);
s->WriteUnsigned(length);
uint8_t* cdata = reinterpret_cast<uint8_t*>(data->ptr()->data_);
s->Align(ExternalTypedData::kDataSerializationAlignment);
@@ -3663,7 +3733,7 @@
void ReadAlloc(Deserializer* d) {
start_index_ = d->next_index();
PageSpace* old_space = d->heap()->old_space();
- intptr_t count = d->ReadUnsigned();
+ const intptr_t count = d->ReadUnsigned();
for (intptr_t i = 0; i < count; i++) {
d->AssignRef(
AllocateUninitialized(old_space, ExternalTypedData::InstanceSize()));
@@ -3677,7 +3747,7 @@
for (intptr_t id = start_index_; id < stop_index_; id++) {
RawExternalTypedData* data =
reinterpret_cast<RawExternalTypedData*>(d->Ref(id));
- intptr_t length = d->ReadUnsigned();
+ const intptr_t length = d->ReadUnsigned();
Deserializer::InitializeHeader(data, cid_,
ExternalTypedData::InstanceSize());
data->ptr()->length_ = Smi::New(length);
@@ -3706,7 +3776,7 @@
void WriteAlloc(Serializer* s) {
s->WriteCid(kStackTraceCid);
- intptr_t count = objects_.length();
+ const intptr_t count = objects_.length();
s->WriteUnsigned(count);
for (intptr_t i = 0; i < count; i++) {
RawStackTrace* trace = objects_[i];
@@ -3715,7 +3785,7 @@
}
void WriteFill(Serializer* s) {
- intptr_t count = objects_.length();
+ const intptr_t count = objects_.length();
for (intptr_t i = 0; i < count; i++) {
RawStackTrace* trace = objects_[i];
AutoTraceObject(trace);
@@ -3736,7 +3806,7 @@
void ReadAlloc(Deserializer* d) {
start_index_ = d->next_index();
PageSpace* old_space = d->heap()->old_space();
- intptr_t count = d->ReadUnsigned();
+ const intptr_t count = d->ReadUnsigned();
for (intptr_t i = 0; i < count; i++) {
d->AssignRef(
AllocateUninitialized(old_space, StackTrace::InstanceSize()));
@@ -3768,7 +3838,7 @@
void WriteAlloc(Serializer* s) {
s->WriteCid(kRegExpCid);
- intptr_t count = objects_.length();
+ const intptr_t count = objects_.length();
s->WriteUnsigned(count);
for (intptr_t i = 0; i < count; i++) {
RawRegExp* regexp = objects_[i];
@@ -3777,7 +3847,7 @@
}
void WriteFill(Serializer* s) {
- intptr_t count = objects_.length();
+ const intptr_t count = objects_.length();
for (intptr_t i = 0; i < count; i++) {
RawRegExp* regexp = objects_[i];
AutoTraceObject(regexp);
@@ -3801,7 +3871,7 @@
void ReadAlloc(Deserializer* d) {
start_index_ = d->next_index();
PageSpace* old_space = d->heap()->old_space();
- intptr_t count = d->ReadUnsigned();
+ const intptr_t count = d->ReadUnsigned();
for (intptr_t i = 0; i < count; i++) {
d->AssignRef(AllocateUninitialized(old_space, RegExp::InstanceSize()));
}
@@ -3835,7 +3905,7 @@
void WriteAlloc(Serializer* s) {
s->WriteCid(kWeakPropertyCid);
- intptr_t count = objects_.length();
+ const intptr_t count = objects_.length();
s->WriteUnsigned(count);
for (intptr_t i = 0; i < count; i++) {
RawWeakProperty* property = objects_[i];
@@ -3844,7 +3914,7 @@
}
void WriteFill(Serializer* s) {
- intptr_t count = objects_.length();
+ const intptr_t count = objects_.length();
for (intptr_t i = 0; i < count; i++) {
RawWeakProperty* property = objects_[i];
AutoTraceObject(property);
@@ -3865,7 +3935,7 @@
void ReadAlloc(Deserializer* d) {
start_index_ = d->next_index();
PageSpace* old_space = d->heap()->old_space();
- intptr_t count = d->ReadUnsigned();
+ const intptr_t count = d->ReadUnsigned();
for (intptr_t i = 0; i < count; i++) {
d->AssignRef(
AllocateUninitialized(old_space, WeakProperty::InstanceSize()));
@@ -3911,7 +3981,7 @@
void WriteAlloc(Serializer* s) {
s->WriteCid(kLinkedHashMapCid);
- intptr_t count = objects_.length();
+ const intptr_t count = objects_.length();
s->WriteUnsigned(count);
for (intptr_t i = 0; i < count; i++) {
RawLinkedHashMap* map = objects_[i];
@@ -3920,7 +3990,7 @@
}
void WriteFill(Serializer* s) {
- intptr_t count = objects_.length();
+ const intptr_t count = objects_.length();
for (intptr_t i = 0; i < count; i++) {
RawLinkedHashMap* map = objects_[i];
AutoTraceObject(map);
@@ -3961,7 +4031,7 @@
void ReadAlloc(Deserializer* d) {
start_index_ = d->next_index();
PageSpace* old_space = d->heap()->old_space();
- intptr_t count = d->ReadUnsigned();
+ const intptr_t count = d->ReadUnsigned();
for (intptr_t i = 0; i < count; i++) {
d->AssignRef(
AllocateUninitialized(old_space, LinkedHashMap::InstanceSize()));
@@ -4021,7 +4091,7 @@
objects_.Add(array);
s->Push(array->ptr()->type_arguments_);
- intptr_t length = Smi::Value(array->ptr()->length_);
+ const intptr_t length = Smi::Value(array->ptr()->length_);
for (intptr_t i = 0; i < length; i++) {
s->Push(array->ptr()->data()[i]);
}
@@ -4029,23 +4099,23 @@
void WriteAlloc(Serializer* s) {
s->WriteCid(cid_);
- intptr_t count = objects_.length();
+ const intptr_t count = objects_.length();
s->WriteUnsigned(count);
for (intptr_t i = 0; i < count; i++) {
RawArray* array = objects_[i];
s->AssignRef(array);
AutoTraceObject(array);
- intptr_t length = Smi::Value(array->ptr()->length_);
+ const intptr_t length = Smi::Value(array->ptr()->length_);
s->WriteUnsigned(length);
}
}
void WriteFill(Serializer* s) {
- intptr_t count = objects_.length();
+ const intptr_t count = objects_.length();
for (intptr_t i = 0; i < count; i++) {
RawArray* array = objects_[i];
AutoTraceObject(array);
- intptr_t length = Smi::Value(array->ptr()->length_);
+ const intptr_t length = Smi::Value(array->ptr()->length_);
s->WriteUnsigned(length);
s->Write<bool>(array->IsCanonical());
WriteField(array, type_arguments_);
@@ -4069,9 +4139,9 @@
void ReadAlloc(Deserializer* d) {
start_index_ = d->next_index();
PageSpace* old_space = d->heap()->old_space();
- intptr_t count = d->ReadUnsigned();
+ const intptr_t count = d->ReadUnsigned();
for (intptr_t i = 0; i < count; i++) {
- intptr_t length = d->ReadUnsigned();
+ const intptr_t length = d->ReadUnsigned();
d->AssignRef(
AllocateUninitialized(old_space, Array::InstanceSize(length)));
}
@@ -4081,7 +4151,7 @@
void ReadFill(Deserializer* d) {
for (intptr_t id = start_index_; id < stop_index_; id++) {
RawArray* array = reinterpret_cast<RawArray*>(d->Ref(id));
- intptr_t length = d->ReadUnsigned();
+ const intptr_t length = d->ReadUnsigned();
bool is_canonical = d->Read<bool>();
Deserializer::InitializeHeader(array, cid_, Array::InstanceSize(length),
is_canonical);
@@ -4111,23 +4181,23 @@
void WriteAlloc(Serializer* s) {
s->WriteCid(kOneByteStringCid);
- intptr_t count = objects_.length();
+ const intptr_t count = objects_.length();
s->WriteUnsigned(count);
for (intptr_t i = 0; i < count; i++) {
RawOneByteString* str = objects_[i];
s->AssignRef(str);
AutoTraceObject(str);
- intptr_t length = Smi::Value(str->ptr()->length_);
+ const intptr_t length = Smi::Value(str->ptr()->length_);
s->WriteUnsigned(length);
}
}
void WriteFill(Serializer* s) {
- intptr_t count = objects_.length();
+ const intptr_t count = objects_.length();
for (intptr_t i = 0; i < count; i++) {
RawOneByteString* str = objects_[i];
AutoTraceObject(str);
- intptr_t length = Smi::Value(str->ptr()->length_);
+ const intptr_t length = Smi::Value(str->ptr()->length_);
s->WriteUnsigned(length);
s->Write<bool>(str->IsCanonical());
intptr_t hash = String::GetCachedHash(str);
@@ -4149,9 +4219,9 @@
void ReadAlloc(Deserializer* d) {
start_index_ = d->next_index();
PageSpace* old_space = d->heap()->old_space();
- intptr_t count = d->ReadUnsigned();
+ const intptr_t count = d->ReadUnsigned();
for (intptr_t i = 0; i < count; i++) {
- intptr_t length = d->ReadUnsigned();
+ const intptr_t length = d->ReadUnsigned();
d->AssignRef(AllocateUninitialized(old_space,
OneByteString::InstanceSize(length)));
}
@@ -4161,7 +4231,7 @@
void ReadFill(Deserializer* d) {
for (intptr_t id = start_index_; id < stop_index_; id++) {
RawOneByteString* str = reinterpret_cast<RawOneByteString*>(d->Ref(id));
- intptr_t length = d->ReadUnsigned();
+ const intptr_t length = d->ReadUnsigned();
bool is_canonical = d->Read<bool>();
Deserializer::InitializeHeader(str, kOneByteStringCid,
OneByteString::InstanceSize(length),
@@ -4188,23 +4258,23 @@
void WriteAlloc(Serializer* s) {
s->WriteCid(kTwoByteStringCid);
- intptr_t count = objects_.length();
+ const intptr_t count = objects_.length();
s->WriteUnsigned(count);
for (intptr_t i = 0; i < count; i++) {
RawTwoByteString* str = objects_[i];
s->AssignRef(str);
AutoTraceObject(str);
- intptr_t length = Smi::Value(str->ptr()->length_);
+ const intptr_t length = Smi::Value(str->ptr()->length_);
s->WriteUnsigned(length);
}
}
void WriteFill(Serializer* s) {
- intptr_t count = objects_.length();
+ const intptr_t count = objects_.length();
for (intptr_t i = 0; i < count; i++) {
RawTwoByteString* str = objects_[i];
AutoTraceObject(str);
- intptr_t length = Smi::Value(str->ptr()->length_);
+ const intptr_t length = Smi::Value(str->ptr()->length_);
s->WriteUnsigned(length);
s->Write<bool>(str->IsCanonical());
intptr_t hash = String::GetCachedHash(str);
@@ -4226,9 +4296,9 @@
void ReadAlloc(Deserializer* d) {
start_index_ = d->next_index();
PageSpace* old_space = d->heap()->old_space();
- intptr_t count = d->ReadUnsigned();
+ const intptr_t count = d->ReadUnsigned();
for (intptr_t i = 0; i < count; i++) {
- intptr_t length = d->ReadUnsigned();
+ const intptr_t length = d->ReadUnsigned();
d->AssignRef(AllocateUninitialized(old_space,
TwoByteString::InstanceSize(length)));
}
@@ -4238,7 +4308,7 @@
void ReadFill(Deserializer* d) {
for (intptr_t id = start_index_; id < stop_index_; id++) {
RawTwoByteString* str = reinterpret_cast<RawTwoByteString*>(d->Ref(id));
- intptr_t length = d->ReadUnsigned();
+ const intptr_t length = d->ReadUnsigned();
bool is_canonical = d->Read<bool>();
Deserializer::InitializeHeader(str, kTwoByteStringCid,
TwoByteString::InstanceSize(length),
@@ -4413,12 +4483,12 @@
return new (Z) KernelProgramInfoSerializationCluster();
case kCodeCid:
return new (Z) CodeSerializationCluster();
-#if !defined(DART_PRECOMPILED_RUNTIME)
case kBytecodeCid:
return new (Z) BytecodeSerializationCluster();
-#endif // !DART_PRECOMPILED_RUNTIME
case kObjectPoolCid:
return new (Z) ObjectPoolSerializationCluster();
+ case kPcDescriptorsCid:
+ return new (Z) PcDescriptorsSerializationCluster();
case kExceptionHandlersCid:
return new (Z) ExceptionHandlersSerializationCluster();
case kContextCid:
@@ -4998,6 +5068,17 @@
return new (Z) TypedDataDeserializationCluster(cid);
}
+ if (Snapshot::IncludesCode(kind_)) {
+ switch (cid) {
+ case kPcDescriptorsCid:
+ case kCodeSourceMapCid:
+ case kStackMapCid:
+ case kOneByteStringCid:
+ case kTwoByteStringCid:
+ return new (Z) RODataDeserializationCluster();
+ }
+ }
+
switch (cid) {
case kClassCid:
return new (Z) ClassDeserializationCluster();
@@ -5036,9 +5117,7 @@
case kObjectPoolCid:
return new (Z) ObjectPoolDeserializationCluster();
case kPcDescriptorsCid:
- case kCodeSourceMapCid:
- case kStackMapCid:
- return new (Z) RODataDeserializationCluster();
+ return new (Z) PcDescriptorsDeserializationCluster();
case kExceptionHandlersCid:
return new (Z) ExceptionHandlersDeserializationCluster();
case kContextCid:
@@ -5087,20 +5166,10 @@
return new (Z) ArrayDeserializationCluster(kArrayCid);
case kImmutableArrayCid:
return new (Z) ArrayDeserializationCluster(kImmutableArrayCid);
- case kOneByteStringCid: {
- if (Snapshot::IncludesCode(kind_)) {
- return new (Z) RODataDeserializationCluster();
- } else {
- return new (Z) OneByteStringDeserializationCluster();
- }
- }
- case kTwoByteStringCid: {
- if (Snapshot::IncludesCode(kind_)) {
- return new (Z) RODataDeserializationCluster();
- } else {
- return new (Z) TwoByteStringDeserializationCluster();
- }
- }
+ case kOneByteStringCid:
+ return new (Z) OneByteStringDeserializationCluster();
+ case kTwoByteStringCid:
+ return new (Z) TwoByteStringDeserializationCluster();
default:
break;
}
diff --git a/runtime/vm/code_descriptors.cc b/runtime/vm/code_descriptors.cc
index 149de08..0d4bd00 100644
--- a/runtime/vm/code_descriptors.cc
+++ b/runtime/vm/code_descriptors.cc
@@ -102,13 +102,13 @@
(list_[i].pc_offset == ExceptionHandlers::kInvalidPcOffset));
handlers.SetHandlerInfo(i, list_[i].outer_try_index, list_[i].pc_offset,
list_[i].needs_stacktrace, has_catch_all,
- list_[i].token_pos, list_[i].is_generated);
+ list_[i].is_generated);
handlers.SetHandledTypes(i, Array::empty_array());
} else {
const bool has_catch_all = ContainsDynamic(*list_[i].handler_types);
handlers.SetHandlerInfo(i, list_[i].outer_try_index, list_[i].pc_offset,
list_[i].needs_stacktrace, has_catch_all,
- list_[i].token_pos, list_[i].is_generated);
+ list_[i].is_generated);
handlers.SetHandledTypes(i, *list_[i].handler_types);
}
}
diff --git a/runtime/vm/code_descriptors.h b/runtime/vm/code_descriptors.h
index 45c7435..5e2a52f 100644
--- a/runtime/vm/code_descriptors.h
+++ b/runtime/vm/code_descriptors.h
@@ -74,7 +74,6 @@
struct HandlerDesc {
intptr_t outer_try_index; // Try block in which this try block is nested.
intptr_t pc_offset; // Handler PC offset value.
- TokenPosition token_pos; // Token position of handler.
bool is_generated; // False if this is directly from Dart code.
const Array* handler_types; // Catch clause guards.
bool needs_stacktrace;
@@ -88,7 +87,6 @@
struct HandlerDesc data;
data.outer_try_index = -1;
data.pc_offset = ExceptionHandlers::kInvalidPcOffset;
- data.token_pos = TokenPosition::kNoSource;
data.is_generated = true;
data.handler_types = NULL;
data.needs_stacktrace = false;
@@ -98,7 +96,6 @@
void AddHandler(intptr_t try_index,
intptr_t outer_try_index,
intptr_t pc_offset,
- TokenPosition token_pos,
bool is_generated,
const Array& handler_types,
bool needs_stacktrace) {
@@ -109,7 +106,6 @@
list_[try_index].outer_try_index = outer_try_index;
ASSERT(list_[try_index].pc_offset == ExceptionHandlers::kInvalidPcOffset);
list_[try_index].pc_offset = pc_offset;
- list_[try_index].token_pos = token_pos;
list_[try_index].is_generated = is_generated;
ASSERT(handler_types.IsZoneHandle());
list_[try_index].handler_types = &handler_types;
diff --git a/runtime/vm/code_patcher_ia32.cc b/runtime/vm/code_patcher_ia32.cc
index 81fa738..7e97f67 100644
--- a/runtime/vm/code_patcher_ia32.cc
+++ b/runtime/vm/code_patcher_ia32.cc
@@ -64,8 +64,10 @@
}
void set_native_function(NativeFunction func) const {
- WritableInstructionsScope writable(start_ + 1, sizeof(func));
- *reinterpret_cast<NativeFunction*>(start_ + 1) = func;
+ Thread::Current()->isolate_group()->RunWithStoppedMutators([&]() {
+ WritableInstructionsScope writable(start_ + 1, sizeof(func));
+ *reinterpret_cast<NativeFunction*>(start_ + 1) = func;
+ });
}
private:
@@ -179,11 +181,15 @@
void CodePatcher::PatchStaticCallAt(uword return_address,
const Code& code,
const Code& new_target) {
- const Instructions& instrs = Instructions::Handle(code.instructions());
- WritableInstructionsScope writable(instrs.PayloadStart(), instrs.Size());
- ASSERT(code.ContainsInstructionAt(return_address));
- StaticCall call(return_address);
- call.set_target(new_target);
+ auto thread = Thread::Current();
+ auto zone = thread->zone();
+ const Instructions& instrs = Instructions::Handle(zone, code.instructions());
+ thread->isolate_group()->RunWithStoppedMutators([&]() {
+ WritableInstructionsScope writable(instrs.PayloadStart(), instrs.Size());
+ ASSERT(code.ContainsInstructionAt(return_address));
+ StaticCall call(return_address);
+ call.set_target(new_target);
+ });
}
void CodePatcher::InsertDeoptimizationCallAt(uword start) {
@@ -205,12 +211,17 @@
const Code& caller_code,
const Object& data,
const Code& target) {
+ auto thread = Thread::Current();
+ auto zone = thread->zone();
ASSERT(caller_code.ContainsInstructionAt(return_address));
- const Instructions& instrs = Instructions::Handle(caller_code.instructions());
- WritableInstructionsScope writable(instrs.PayloadStart(), instrs.Size());
- InstanceCall call(return_address);
- call.set_data(data);
- call.set_target(target);
+ const Instructions& instrs =
+ Instructions::Handle(zone, caller_code.instructions());
+ thread->isolate_group()->RunWithStoppedMutators([&]() {
+ WritableInstructionsScope writable(instrs.PayloadStart(), instrs.Size());
+ InstanceCall call(return_address);
+ call.set_data(data);
+ call.set_target(target);
+ });
}
RawFunction* CodePatcher::GetUnoptimizedStaticCallAt(uword return_address,
diff --git a/runtime/vm/compiler/aot/precompiler.cc b/runtime/vm/compiler/aot/precompiler.cc
index 3e9c86ea..b92b714 100644
--- a/runtime/vm/compiler/aot/precompiler.cc
+++ b/runtime/vm/compiler/aot/precompiler.cc
@@ -4,6 +4,8 @@
#include "vm/compiler/aot/precompiler.h"
+#ifndef DART_PRECOMPILED_RUNTIME
+
#include "platform/unicode.h"
#include "vm/class_finalizer.h"
#include "vm/code_patcher.h"
@@ -2892,3 +2894,5 @@
// !defined(TARGET_ARCH_IA32)
} // namespace dart
+
+#endif // DART_PRECOMPILED_RUNTIME
diff --git a/runtime/vm/compiler/aot/precompiler.h b/runtime/vm/compiler/aot/precompiler.h
index a6ceb59..545f193 100644
--- a/runtime/vm/compiler/aot/precompiler.h
+++ b/runtime/vm/compiler/aot/precompiler.h
@@ -5,6 +5,8 @@
#ifndef RUNTIME_VM_COMPILER_AOT_PRECOMPILER_H_
#define RUNTIME_VM_COMPILER_AOT_PRECOMPILER_H_
+#ifndef DART_PRECOMPILED_RUNTIME
+
#include "vm/allocation.h"
#include "vm/compiler/assembler/assembler.h"
#include "vm/hash_map.h"
@@ -96,13 +98,11 @@
static Value ValueOf(Pair kv) { return kv; }
static inline intptr_t Hashcode(Key key) {
- // We are using pointer hash for objects originating from Kernel because
- // Fasta currently does not assign any position information to them.
- if (key->kernel_offset() > 0) {
- return key->kernel_offset();
- } else {
- return key->token_pos().value();
+ const TokenPosition token_pos = key->token_pos();
+ if (token_pos.IsReal()) {
+ return token_pos.value();
}
+ return key->binary_declaration_offset();
}
static inline bool IsKeyEqual(Pair pair, Key key) {
@@ -557,4 +557,6 @@
} // namespace dart
+#endif // DART_PRECOMPILED_RUNTIME
+
#endif // RUNTIME_VM_COMPILER_AOT_PRECOMPILER_H_
diff --git a/runtime/vm/compiler/assembler/assembler_arm.cc b/runtime/vm/compiler/assembler/assembler_arm.cc
index 6958b22..0902183 100644
--- a/runtime/vm/compiler/assembler/assembler_arm.cc
+++ b/runtime/vm/compiler/assembler/assembler_arm.cc
@@ -546,34 +546,35 @@
}
void Assembler::EnterSafepoint(Register addr, Register state) {
+ // We generate the same number of instructions whether or not the slow-path is
+ // forced. This simplifies GenerateJitCallbackTrampolines.
+ Label slow_path, done, retry;
if (FLAG_use_slow_path || TargetCPUFeatures::arm_version() == ARMv5TE) {
- EnterSafepointSlowly();
- } else {
- Label slow_path, done, retry;
- LoadImmediate(addr, target::Thread::safepoint_state_offset());
- add(addr, THR, Operand(addr));
- Bind(&retry);
- ldrex(state, addr);
- cmp(state, Operand(target::Thread::safepoint_state_unacquired()));
- b(&slow_path, NE);
-
- mov(state, Operand(target::Thread::safepoint_state_acquired()));
- strex(TMP, state, addr);
- cmp(TMP, Operand(0)); // 0 means strex was successful.
- b(&done, EQ);
- b(&retry);
-
- Bind(&slow_path);
- EnterSafepointSlowly();
-
- Bind(&done);
+ b(&slow_path);
}
-}
-void Assembler::EnterSafepointSlowly() {
+ LoadImmediate(addr, target::Thread::safepoint_state_offset());
+ add(addr, THR, Operand(addr));
+ Bind(&retry);
+ ldrex(state, addr);
+ cmp(state, Operand(target::Thread::safepoint_state_unacquired()));
+ b(&slow_path, NE);
+
+ mov(state, Operand(target::Thread::safepoint_state_acquired()));
+ strex(TMP, state, addr);
+ cmp(TMP, Operand(0)); // 0 means strex was successful.
+ b(&done, EQ);
+
+ if (!FLAG_use_slow_path && TargetCPUFeatures::arm_version() != ARMv5TE) {
+ b(&retry);
+ }
+
+ Bind(&slow_path);
ldr(TMP, Address(THR, target::Thread::enter_safepoint_stub_offset()));
ldr(TMP, FieldAddress(TMP, target::Code::entry_point_offset()));
blx(TMP);
+
+ Bind(&done);
}
void Assembler::TransitionGeneratedToNative(Register destination_address,
@@ -597,34 +598,35 @@
}
void Assembler::ExitSafepoint(Register addr, Register state) {
+ // We generate the same number of instructions whether or not the slow-path is
+ // forced, for consistency with EnterSafepoint.
+ Label slow_path, done, retry;
if (FLAG_use_slow_path || TargetCPUFeatures::arm_version() == ARMv5TE) {
- ExitSafepointSlowly();
- } else {
- Label slow_path, done, retry;
- LoadImmediate(addr, target::Thread::safepoint_state_offset());
- add(addr, THR, Operand(addr));
- Bind(&retry);
- ldrex(state, addr);
- cmp(state, Operand(target::Thread::safepoint_state_acquired()));
- b(&slow_path, NE);
-
- mov(state, Operand(target::Thread::safepoint_state_unacquired()));
- strex(TMP, state, addr);
- cmp(TMP, Operand(0)); // 0 means strex was successful.
- b(&done, EQ);
- b(&retry);
-
- Bind(&slow_path);
- ExitSafepointSlowly();
-
- Bind(&done);
+ b(&slow_path);
}
-}
-void Assembler::ExitSafepointSlowly() {
+ LoadImmediate(addr, target::Thread::safepoint_state_offset());
+ add(addr, THR, Operand(addr));
+ Bind(&retry);
+ ldrex(state, addr);
+ cmp(state, Operand(target::Thread::safepoint_state_acquired()));
+ b(&slow_path, NE);
+
+ mov(state, Operand(target::Thread::safepoint_state_unacquired()));
+ strex(TMP, state, addr);
+ cmp(TMP, Operand(0)); // 0 means strex was successful.
+ b(&done, EQ);
+
+ if (!FLAG_use_slow_path && TargetCPUFeatures::arm_version() != ARMv5TE) {
+ b(&retry);
+ }
+
+ Bind(&slow_path);
ldr(TMP, Address(THR, target::Thread::exit_safepoint_stub_offset()));
ldr(TMP, FieldAddress(TMP, target::Code::entry_point_offset()));
blx(TMP);
+
+ Bind(&done);
}
void Assembler::TransitionNativeToGenerated(Register addr,
diff --git a/runtime/vm/compiler/assembler/assembler_arm.h b/runtime/vm/compiler/assembler/assembler_arm.h
index 667f8a5..904890d 100644
--- a/runtime/vm/compiler/assembler/assembler_arm.h
+++ b/runtime/vm/compiler/assembler/assembler_arm.h
@@ -1337,9 +1337,6 @@
CanBeSmi can_be_smi,
BarrierFilterMode barrier_filter_mode);
- void EnterSafepointSlowly();
- void ExitSafepointSlowly();
-
friend class dart::FlowGraphCompiler;
std::function<void(Condition, Register)>
generate_invoke_write_barrier_wrapper_;
diff --git a/runtime/vm/compiler/assembler/assembler_arm64.cc b/runtime/vm/compiler/assembler/assembler_arm64.cc
index e75fcc9..d973ac9 100644
--- a/runtime/vm/compiler/assembler/assembler_arm64.cc
+++ b/runtime/vm/compiler/assembler/assembler_arm64.cc
@@ -1307,21 +1307,29 @@
}
void Assembler::EnterSafepoint(Register state) {
+ // We generate the same number of instructions whether or not the slow-path is
+ // forced. This simplifies GenerateJitCallbackTrampolines.
+
Register addr = TMP2;
ASSERT(addr != state);
Label slow_path, done, retry;
- if (!FLAG_use_slow_path) {
- movz(addr, Immediate(target::Thread::safepoint_state_offset()), 0);
- add(addr, THR, Operand(addr));
- Bind(&retry);
- ldxr(state, addr);
- cmp(state, Operand(target::Thread::safepoint_state_unacquired()));
- b(&slow_path, NE);
+ if (FLAG_use_slow_path) {
+ b(&slow_path);
+ }
- movz(state, Immediate(target::Thread::safepoint_state_acquired()), 0);
- stxr(TMP, state, addr);
- cbz(&done, TMP); // 0 means stxr was successful.
+ movz(addr, Immediate(target::Thread::safepoint_state_offset()), 0);
+ add(addr, THR, Operand(addr));
+ Bind(&retry);
+ ldxr(state, addr);
+ cmp(state, Operand(target::Thread::safepoint_state_unacquired()));
+ b(&slow_path, NE);
+
+ movz(state, Immediate(target::Thread::safepoint_state_acquired()), 0);
+ stxr(TMP, state, addr);
+ cbz(&done, TMP); // 0 means stxr was successful.
+
+ if (!FLAG_use_slow_path) {
b(&retry);
}
@@ -1352,21 +1360,28 @@
}
void Assembler::ExitSafepoint(Register state) {
+ // We generate the same number of instructions whether or not the slow-path is
+ // forced, for consistency with EnterSafepoint.
Register addr = TMP2;
ASSERT(addr != state);
Label slow_path, done, retry;
- if (!FLAG_use_slow_path) {
- movz(addr, Immediate(target::Thread::safepoint_state_offset()), 0);
- add(addr, THR, Operand(addr));
- Bind(&retry);
- ldxr(state, addr);
- cmp(state, Operand(target::Thread::safepoint_state_acquired()));
- b(&slow_path, NE);
+ if (FLAG_use_slow_path) {
+ b(&slow_path);
+ }
- movz(state, Immediate(target::Thread::safepoint_state_unacquired()), 0);
- stxr(TMP, state, addr);
- cbz(&done, TMP); // 0 means stxr was successful.
+ movz(addr, Immediate(target::Thread::safepoint_state_offset()), 0);
+ add(addr, THR, Operand(addr));
+ Bind(&retry);
+ ldxr(state, addr);
+ cmp(state, Operand(target::Thread::safepoint_state_acquired()));
+ b(&slow_path, NE);
+
+ movz(state, Immediate(target::Thread::safepoint_state_unacquired()), 0);
+ stxr(TMP, state, addr);
+ cbz(&done, TMP); // 0 means stxr was successful.
+
+ if (!FLAG_use_slow_path) {
b(&retry);
}
diff --git a/runtime/vm/compiler/assembler/assembler_arm64.h b/runtime/vm/compiler/assembler/assembler_arm64.h
index 315e72f..972b1dc 100644
--- a/runtime/vm/compiler/assembler/assembler_arm64.h
+++ b/runtime/vm/compiler/assembler/assembler_arm64.h
@@ -1542,8 +1542,8 @@
// Emit code to transition between generated mode and native mode.
//
- // These require that CSP and SP are equal and aligned and require a scratch
- // register (in addition to TMP/TMP2).
+ // These require and ensure that CSP and SP are equal and aligned and require
+ // a scratch register (in addition to TMP/TMP2).
void TransitionGeneratedToNative(Register destination_address,
Register new_exit_frame,
diff --git a/runtime/vm/compiler/assembler/assembler_ia32.cc b/runtime/vm/compiler/assembler/assembler_ia32.cc
index 4943f780..63cab25 100644
--- a/runtime/vm/compiler/assembler/assembler_ia32.cc
+++ b/runtime/vm/compiler/assembler/assembler_ia32.cc
@@ -1499,6 +1499,13 @@
EmitUint8(0xD0 | reg);
}
+void Assembler::bsfl(Register dst, Register src) {
+ AssemblerBuffer::EnsureCapacity ensured(&buffer_);
+ EmitUint8(0x0F);
+ EmitUint8(0xBC);
+ EmitRegisterOperand(dst, src);
+}
+
void Assembler::bsrl(Register dst, Register src) {
AssemblerBuffer::EnsureCapacity ensured(&buffer_);
EmitUint8(0x0F);
@@ -1506,6 +1513,24 @@
EmitRegisterOperand(dst, src);
}
+void Assembler::popcntl(Register dst, Register src) {
+ ASSERT(TargetCPUFeatures::popcnt_supported());
+ AssemblerBuffer::EnsureCapacity ensured(&buffer_);
+ EmitUint8(0xF3);
+ EmitUint8(0x0F);
+ EmitUint8(0xB8);
+ EmitRegisterOperand(dst, src);
+}
+
+void Assembler::lzcntl(Register dst, Register src) {
+ ASSERT(TargetCPUFeatures::abm_supported());
+ AssemblerBuffer::EnsureCapacity ensured(&buffer_);
+ EmitUint8(0xF3);
+ EmitUint8(0x0F);
+ EmitUint8(0xBD);
+ EmitRegisterOperand(dst, src);
+}
+
void Assembler::bt(Register base, Register offset) {
AssemblerBuffer::EnsureCapacity ensured(&buffer_);
EmitUint8(0x0F);
@@ -2142,21 +2167,29 @@
}
void Assembler::EnterSafepoint(Register scratch) {
+ // We generate the same number of instructions whether or not the slow-path is
+ // forced. This simplifies GenerateJitCallbackTrampolines.
+
// Compare and swap the value at Thread::safepoint_state from unacquired to
// acquired. On success, jump to 'success'; otherwise, fallthrough.
- Label done;
+ Label done, slow_path;
+ if (FLAG_use_slow_path) {
+ jmp(&slow_path);
+ }
+
+ pushl(EAX);
+ movl(EAX, Immediate(target::Thread::safepoint_state_unacquired()));
+ movl(scratch, Immediate(target::Thread::safepoint_state_acquired()));
+ LockCmpxchgl(Address(THR, target::Thread::safepoint_state_offset()), scratch);
+ movl(scratch, EAX);
+ popl(EAX);
+ cmpl(scratch, Immediate(target::Thread::safepoint_state_unacquired()));
+
if (!FLAG_use_slow_path) {
- pushl(EAX);
- movl(EAX, Immediate(target::Thread::safepoint_state_unacquired()));
- movl(scratch, Immediate(target::Thread::safepoint_state_acquired()));
- LockCmpxchgl(Address(THR, target::Thread::safepoint_state_offset()),
- scratch);
- movl(scratch, EAX);
- popl(EAX);
- cmpl(scratch, Immediate(target::Thread::safepoint_state_unacquired()));
j(EQUAL, &done);
}
+ Bind(&slow_path);
movl(scratch, Address(THR, target::Thread::enter_safepoint_stub_offset()));
movl(scratch, FieldAddress(scratch, target::Code::entry_point_offset()));
call(scratch);
@@ -2183,21 +2216,29 @@
}
void Assembler::ExitSafepoint(Register scratch) {
+ // We generate the same number of instructions whether or not the slow-path is
+ // forced, for consistency with EnterSafepoint.
+
// Compare and swap the value at Thread::safepoint_state from acquired to
// unacquired. On success, jump to 'success'; otherwise, fallthrough.
- Label done;
+ Label done, slow_path;
+ if (FLAG_use_slow_path) {
+ jmp(&slow_path);
+ }
+
+ pushl(EAX);
+ movl(EAX, Immediate(target::Thread::safepoint_state_acquired()));
+ movl(scratch, Immediate(target::Thread::safepoint_state_unacquired()));
+ LockCmpxchgl(Address(THR, target::Thread::safepoint_state_offset()), scratch);
+ movl(scratch, EAX);
+ popl(EAX);
+ cmpl(scratch, Immediate(target::Thread::safepoint_state_acquired()));
+
if (!FLAG_use_slow_path) {
- pushl(EAX);
- movl(EAX, Immediate(target::Thread::safepoint_state_acquired()));
- movl(scratch, Immediate(target::Thread::safepoint_state_unacquired()));
- LockCmpxchgl(Address(THR, target::Thread::safepoint_state_offset()),
- scratch);
- movl(scratch, EAX);
- popl(EAX);
- cmpl(scratch, Immediate(target::Thread::safepoint_state_acquired()));
j(EQUAL, &done);
}
+ Bind(&slow_path);
movl(scratch, Address(THR, target::Thread::exit_safepoint_stub_offset()));
movl(scratch, FieldAddress(scratch, target::Code::entry_point_offset()));
call(scratch);
diff --git a/runtime/vm/compiler/assembler/assembler_ia32.h b/runtime/vm/compiler/assembler/assembler_ia32.h
index 8321841..e4e86c1 100644
--- a/runtime/vm/compiler/assembler/assembler_ia32.h
+++ b/runtime/vm/compiler/assembler/assembler_ia32.h
@@ -527,7 +527,10 @@
void negl(Register reg);
void notl(Register reg);
+ void bsfl(Register dst, Register src);
void bsrl(Register dst, Register src);
+ void popcntl(Register dst, Register src);
+ void lzcntl(Register dst, Register src);
void bt(Register base, Register offset);
void bt(Register base, int bit);
diff --git a/runtime/vm/compiler/assembler/assembler_ia32_test.cc b/runtime/vm/compiler/assembler/assembler_ia32_test.cc
index ca0ab3a..3bfccc0 100644
--- a/runtime/vm/compiler/assembler/assembler_ia32_test.cc
+++ b/runtime/vm/compiler/assembler/assembler_ia32_test.cc
@@ -326,6 +326,84 @@
"ret\n");
}
+ASSEMBLER_TEST_GENERATE(Bsf, assembler) {
+ __ movl(ECX, Immediate(12));
+ __ bsfl(EAX, ECX);
+ __ ret();
+}
+
+ASSEMBLER_TEST_RUN(Bsf, test) {
+ typedef int (*BsfCode)();
+ EXPECT_EQ(2, reinterpret_cast<BsfCode>(test->entry())());
+ EXPECT_DISASSEMBLY(
+ "mov ecx,0xc\n"
+ "bsf eax,ecx\n"
+ "ret\n");
+}
+
+ASSEMBLER_TEST_GENERATE(Bsr, assembler) {
+ __ movl(ECX, Immediate(12));
+ __ bsrl(EAX, ECX);
+ __ ret();
+}
+
+ASSEMBLER_TEST_RUN(Bsr, test) {
+ typedef int (*BsrCode)();
+ EXPECT_EQ(3, reinterpret_cast<BsrCode>(test->entry())());
+ EXPECT_DISASSEMBLY(
+ "mov ecx,0xc\n"
+ "bsr eax,ecx\n"
+ "ret\n");
+}
+
+ASSEMBLER_TEST_GENERATE(Popcnt, assembler) {
+ __ movl(ECX, Immediate(-1));
+ __ popcntl(EAX, ECX);
+ __ movl(ECX, Immediate(0xf));
+ __ popcntl(ECX, ECX);
+ __ addl(EAX, ECX);
+ __ ret();
+}
+
+ASSEMBLER_TEST_RUN(Popcnt, test) {
+ if (!HostCPUFeatures::popcnt_supported()) {
+ return;
+ }
+ typedef int (*PopcntCode)();
+ EXPECT_EQ(36, reinterpret_cast<PopcntCode>(test->entry())());
+ EXPECT_DISASSEMBLY(
+ "mov ecx,0x........\n"
+ "popcnt eax,ecx\n"
+ "mov ecx,0xf\n"
+ "popcnt ecx,ecx\n"
+ "add eax,ecx\n"
+ "ret\n");
+}
+
+ASSEMBLER_TEST_GENERATE(Lzcnt, assembler) {
+ __ movl(ECX, Immediate(0x0f00));
+ __ lzcntl(EAX, ECX);
+ __ movl(ECX, Immediate(0x00f0));
+ __ lzcntl(ECX, ECX);
+ __ addl(EAX, ECX);
+ __ ret();
+}
+
+ASSEMBLER_TEST_RUN(Lzcnt, test) {
+ if (!HostCPUFeatures::abm_supported()) {
+ return;
+ }
+ typedef int (*LzcntCode)();
+ EXPECT_EQ(44, reinterpret_cast<LzcntCode>(test->entry())());
+ EXPECT_DISASSEMBLY(
+ "mov ecx,0x...\n"
+ "lzcnt eax,ecx\n"
+ "mov ecx,0xf0\n"
+ "lzcnt ecx,ecx\n"
+ "add eax,ecx\n"
+ "ret\n");
+}
+
struct JumpAddress {
uword filler1;
uword filler2;
diff --git a/runtime/vm/compiler/assembler/assembler_x64.cc b/runtime/vm/compiler/assembler/assembler_x64.cc
index 9c1cb4f..c9e1299 100644
--- a/runtime/vm/compiler/assembler/assembler_x64.cc
+++ b/runtime/vm/compiler/assembler/assembler_x64.cc
@@ -161,20 +161,28 @@
}
void Assembler::EnterSafepoint() {
+ // We generate the same number of instructions whether or not the slow-path is
+ // forced, to simplify GenerateJitCallbackTrampolines.
+ Label done, slow_path;
+ if (FLAG_use_slow_path) {
+ jmp(&slow_path);
+ }
+
// Compare and swap the value at Thread::safepoint_state from unacquired to
// acquired. If the CAS fails, go to a slow-path stub.
- Label done;
+ pushq(RAX);
+ movq(RAX, Immediate(target::Thread::safepoint_state_unacquired()));
+ movq(TMP, Immediate(target::Thread::safepoint_state_acquired()));
+ LockCmpxchgq(Address(THR, target::Thread::safepoint_state_offset()), TMP);
+ movq(TMP, RAX);
+ popq(RAX);
+ cmpq(TMP, Immediate(target::Thread::safepoint_state_unacquired()));
+
if (!FLAG_use_slow_path) {
- pushq(RAX);
- movq(RAX, Immediate(target::Thread::safepoint_state_unacquired()));
- movq(TMP, Immediate(target::Thread::safepoint_state_acquired()));
- LockCmpxchgq(Address(THR, target::Thread::safepoint_state_offset()), TMP);
- movq(TMP, RAX);
- popq(RAX);
- cmpq(TMP, Immediate(target::Thread::safepoint_state_unacquired()));
j(EQUAL, &done);
}
+ Bind(&slow_path);
movq(TMP, Address(THR, target::Thread::enter_safepoint_stub_offset()));
movq(TMP, FieldAddress(TMP, target::Code::entry_point_offset()));
@@ -203,20 +211,29 @@
}
void Assembler::LeaveSafepoint() {
+ // We generate the same number of instructions whether or not the slow-path is
+ // forced, for consistency with EnterSafepoint.
+ Label done, slow_path;
+ if (FLAG_use_slow_path) {
+ jmp(&slow_path);
+ }
+
// Compare and swap the value at Thread::safepoint_state from acquired to
// unacquired. On success, jump to 'success'; otherwise, fallthrough.
- Label done;
+
+ pushq(RAX);
+ movq(RAX, Immediate(target::Thread::safepoint_state_acquired()));
+ movq(TMP, Immediate(target::Thread::safepoint_state_unacquired()));
+ LockCmpxchgq(Address(THR, target::Thread::safepoint_state_offset()), TMP);
+ movq(TMP, RAX);
+ popq(RAX);
+ cmpq(TMP, Immediate(target::Thread::safepoint_state_acquired()));
+
if (!FLAG_use_slow_path) {
- pushq(RAX);
- movq(RAX, Immediate(target::Thread::safepoint_state_acquired()));
- movq(TMP, Immediate(target::Thread::safepoint_state_unacquired()));
- LockCmpxchgq(Address(THR, target::Thread::safepoint_state_offset()), TMP);
- movq(TMP, RAX);
- popq(RAX);
- cmpq(TMP, Immediate(target::Thread::safepoint_state_acquired()));
j(EQUAL, &done);
}
+ Bind(&slow_path);
movq(TMP, Address(THR, target::Thread::exit_safepoint_stub_offset()));
movq(TMP, FieldAddress(TMP, target::Code::entry_point_offset()));
diff --git a/runtime/vm/compiler/assembler/assembler_x64.h b/runtime/vm/compiler/assembler/assembler_x64.h
index 4065bdd..0c4a5e6 100644
--- a/runtime/vm/compiler/assembler/assembler_x64.h
+++ b/runtime/vm/compiler/assembler/assembler_x64.h
@@ -334,7 +334,10 @@
REGULAR_INSTRUCTION(test, 0x85)
REGULAR_INSTRUCTION(xchg, 0x87)
REGULAR_INSTRUCTION(imul, 0xAF, 0x0F)
+ REGULAR_INSTRUCTION(bsf, 0xBC, 0x0F)
REGULAR_INSTRUCTION(bsr, 0xBD, 0x0F)
+ REGULAR_INSTRUCTION(popcnt, 0xB8, 0x0F, 0xF3)
+ REGULAR_INSTRUCTION(lzcnt, 0xBD, 0x0F, 0xF3)
#undef REGULAR_INSTRUCTION
RA(Q, movsxd, 0x63)
RR(Q, movsxd, 0x63)
diff --git a/runtime/vm/compiler/assembler/assembler_x64_test.cc b/runtime/vm/compiler/assembler/assembler_x64_test.cc
index 2e4609f..ef0619a 100644
--- a/runtime/vm/compiler/assembler/assembler_x64_test.cc
+++ b/runtime/vm/compiler/assembler/assembler_x64_test.cc
@@ -6,6 +6,7 @@
#if defined(TARGET_ARCH_X64)
#include "vm/compiler/assembler/assembler.h"
+#include "vm/cpu.h"
#include "vm/os.h"
#include "vm/unit_test.h"
#include "vm/virtual_memory.h"
@@ -552,7 +553,7 @@
}
ASSEMBLER_TEST_GENERATE(Testb2, assembler) {
- Label done, ok1, ok2, ok3, ok4, ok5, ok6;
+ Label done, ok1, ok2, ok3, ok4, ok5, ok6, ok7;
__ movq(RAX, Immediate(0xffffefff));
__ bsrq(RCX, RAX);
@@ -593,6 +594,13 @@
__ int3();
__ Bind(&ok6);
+ __ movq(RAX, Immediate(0x0fffeff0));
+ __ bsfq(RCX, RAX);
+ __ cmpq(RCX, Immediate(4));
+ __ j(EQUAL, &ok7);
+ __ int3();
+ __ Bind(&ok7);
+
__ movq(RAX, Immediate(42));
__ ret();
}
@@ -634,6 +642,12 @@
"jz 0x................\n"
"int3\n"
+ "movl rax,0x........\n"
+ "bsfq rcx,rax\n"
+ "cmpq rcx,4\n"
+ "jz 0x................\n"
+ "int3\n"
+
"movl rax,0x2a\n"
"ret\n");
}
@@ -670,6 +684,54 @@
"ret\n");
}
+ASSEMBLER_TEST_GENERATE(Popcnt, assembler) {
+ __ movq(RCX, Immediate(-1));
+ __ popcntq(RAX, RCX);
+ __ movq(RCX, Immediate(0xf));
+ __ popcntq(RCX, RCX);
+ __ addq(RAX, RCX);
+ __ ret();
+}
+
+ASSEMBLER_TEST_RUN(Popcnt, test) {
+ if (!HostCPUFeatures::popcnt_supported()) {
+ return;
+ }
+ typedef int64_t (*PopcntCode)();
+ EXPECT_EQ(68, reinterpret_cast<PopcntCode>(test->entry())());
+ EXPECT_DISASSEMBLY(
+ "movq rcx,-1\n"
+ "popcntq rax,rcx\n"
+ "movl rcx,0xf\n"
+ "popcntq rcx,rcx\n"
+ "addq rax,rcx\n"
+ "ret\n");
+}
+
+ASSEMBLER_TEST_GENERATE(Lzcnt, assembler) {
+ __ movq(RCX, Immediate(0x0f00));
+ __ lzcntq(RAX, RCX);
+ __ movq(RCX, Immediate(0x00f0));
+ __ lzcntq(RCX, RCX);
+ __ addq(RAX, RCX);
+ __ ret();
+}
+
+ASSEMBLER_TEST_RUN(Lzcnt, test) {
+ if (!HostCPUFeatures::abm_supported()) {
+ return;
+ }
+ typedef int64_t (*LzcntCode)();
+ EXPECT_EQ(108, reinterpret_cast<LzcntCode>(test->entry())());
+ EXPECT_DISASSEMBLY(
+ "movl rcx,0x...\n"
+ "lzcntq rax,rcx\n"
+ "movl rcx,0xf0\n"
+ "lzcntq rcx,rcx\n"
+ "addq rax,rcx\n"
+ "ret\n");
+}
+
struct JumpAddress {
uword filler1;
uword filler2;
diff --git a/runtime/vm/compiler/assembler/disassembler_x86.cc b/runtime/vm/compiler/assembler/disassembler_x86.cc
index 6fd177e..b51f464 100644
--- a/runtime/vm/compiler/assembler/disassembler_x86.cc
+++ b/runtime/vm/compiler/assembler/disassembler_x86.cc
@@ -1442,6 +1442,12 @@
get_modrm(*current, &mod, ®op, &rm);
Print("cvtdq2pd %s,", NameOfXMMRegister(regop));
current += PrintRightXMMOperand(current);
+ } else if (opcode == 0xB8) {
+ // POPCNT.
+ current += PrintOperands(mnemonic, REG_OPER_OP_ORDER, current);
+ } else if (opcode == 0xBD) {
+ // LZCNT (rep BSR encoding).
+ current += PrintOperands("lzcnt", REG_OPER_OP_ORDER, current);
} else {
UnimplementedInstruction();
}
@@ -1585,7 +1591,7 @@
"cpuid", "bt", "shld", "shld", NULL, NULL,
NULL, NULL, NULL, "bts", "shrd", "shrd",
NULL, "imul", "cmpxchg", "cmpxchg", NULL, NULL,
- NULL, NULL, "movzxb", "movzxw", NULL, NULL,
+ NULL, NULL, "movzxb", "movzxw", "popcnt", NULL,
NULL, NULL, "bsf", "bsr", "movsxb", "movsxw"};
return mnemonics[opcode - 0xA2];
}
diff --git a/runtime/vm/compiler/backend/constant_propagator.cc b/runtime/vm/compiler/backend/constant_propagator.cc
index 27cdef7..7447b7e 100644
--- a/runtime/vm/compiler/backend/constant_propagator.cc
+++ b/runtime/vm/compiler/backend/constant_propagator.cc
@@ -780,7 +780,7 @@
Instance& obj = Instance::Handle(Z, field.StaticValue());
if (field.is_final() && (obj.raw() != Object::sentinel().raw()) &&
(obj.raw() != Object::transition_sentinel().raw())) {
- if (obj.IsSmi() || obj.IsOld()) {
+ if (obj.IsSmi() || (obj.IsOld() && obj.IsCanonical())) {
SetValue(instr, obj);
return;
}
diff --git a/runtime/vm/compiler/backend/flow_graph.cc b/runtime/vm/compiler/backend/flow_graph.cc
index c883852..7c52d628 100644
--- a/runtime/vm/compiler/backend/flow_graph.cc
+++ b/runtime/vm/compiler/backend/flow_graph.cc
@@ -989,20 +989,10 @@
// Add global constants to the initial definitions.
CreateCommonConstants();
- // During regular execution, only the direct parameters appear in
- // the fixed part of the environment. During OSR, however, all
- // variables and possibly a non-empty stack are passed as
- // parameters. The latter mimics the incoming expression stack
- // that was set up prior to triggering OSR.
- const intptr_t parameter_count =
- IsCompiledForOsr() ? osr_variable_count() : num_direct_parameters_;
-
// Initial renaming environment.
- GrowableArray<Definition*> env(parameter_count + num_stack_locals());
- env.FillWith(constant_dead(), 0, parameter_count);
- if (!IsCompiledForOsr()) {
- env.FillWith(constant_null(), parameter_count, num_stack_locals());
- }
+ GrowableArray<Definition*> env(variable_count());
+ env.FillWith(constant_dead(), 0, num_direct_parameters());
+ env.FillWith(constant_null(), num_direct_parameters(), num_stack_locals());
if (entry->catch_entries().length() > 0) {
// Functions with try-catch have a fixed area of stack slots reserved
@@ -1013,6 +1003,21 @@
ASSERT(entry->unchecked_entry() != nullptr ? entry->SuccessorCount() == 2
: entry->SuccessorCount() == 1);
}
+
+ // For OSR on a non-empty stack, insert synthetic phis on the joining entry.
+ // These phis are synthetic since they are not driven by live variable
+ // analysis, but merely serve the purpose of merging stack slots from
+ // parameters and other predecessors at the block in which OSR occurred.
+ if (IsCompiledForOsr()) {
+ JoinEntryInstr* join =
+ entry->osr_entry()->last_instruction()->SuccessorAt(0)->AsJoinEntry();
+ ASSERT(join != nullptr);
+ const intptr_t parameter_count = osr_variable_count();
+ for (intptr_t i = variable_count(); i < parameter_count; i++) {
+ join->InsertPhi(i, parameter_count)->mark_alive();
+ }
+ }
+
RenameRecursive(entry, &env, live_phis, variable_liveness,
inlining_parameters);
}
@@ -1088,26 +1093,18 @@
OsrEntryInstr* osr_entry,
GrowableArray<Definition*>* env) {
ASSERT(IsCompiledForOsr());
+ // During OSR, all variables and possibly a non-empty stack are
+ // passed as parameters. The latter mimics the incoming expression
+ // stack that was set up prior to triggering OSR.
const intptr_t parameter_count = osr_variable_count();
- // Initialize the initial enviroment.
- ASSERT(parameter_count <= env->length());
+ ASSERT(env->length() == (parameter_count - osr_entry->stack_depth()));
+ env->EnsureLength(parameter_count, constant_dead());
for (intptr_t i = 0; i < parameter_count; i++) {
ParameterInstr* param = new (zone()) ParameterInstr(i, osr_entry);
param->set_ssa_temp_index(alloc_ssa_temp_index());
AddToInitialDefinitions(osr_entry, param);
(*env)[i] = param;
}
- // For OSR on a non-emtpy stack, insert synthetic phis on the joining entry.
- // These phis are synthetic since they are not driven by live variable
- // analysis, but merely serve the purpose of merging stack slots from
- // parameters and other predecessors at the block in which OSR occurred.
- JoinEntryInstr* join =
- osr_entry->last_instruction()->SuccessorAt(0)->AsJoinEntry();
- ASSERT(join != nullptr);
- for (intptr_t i = variable_count(); i < parameter_count; i++) {
- PhiInstr* phi = join->InsertPhi(i, parameter_count);
- phi->mark_alive();
- }
}
void FlowGraph::PopulateEnvironmentFromCatchEntry(
@@ -1292,6 +1289,8 @@
ASSERT(push_arg->IsPushArgument());
ASSERT(reaching_defn->ssa_temp_index() != -1);
ASSERT(reaching_defn->IsPhi());
+ push_arg->ReplaceUsesWith(push_arg->InputAt(0)->definition());
+ push_arg->UnuseAllInputs();
push_arg->previous()->LinkTo(push_arg->next());
push_arg->set_previous(nullptr);
push_arg->set_next(nullptr);
@@ -1395,6 +1394,13 @@
env->Add(current->Cast<PushArgumentInstr>());
continue;
+ case Instruction::kCheckStackOverflow:
+ // Assert environment integrity at checkpoints.
+ ASSERT((variable_count() +
+ current->AsCheckStackOverflow()->stack_depth()) ==
+ env->length());
+ continue;
+
default:
// Other definitions directly go into the environment.
if (Definition* definition = current->AsDefinition()) {
@@ -1417,10 +1423,23 @@
}
// 3. Process dominated blocks.
+ BlockEntryInstr* osr_succ =
+ (block_entry == graph_entry() && IsCompiledForOsr())
+ ? graph_entry()->osr_entry()->last_instruction()->SuccessorAt(0)
+ : nullptr;
for (intptr_t i = 0; i < block_entry->dominated_blocks().length(); ++i) {
BlockEntryInstr* block = block_entry->dominated_blocks()[i];
GrowableArray<Definition*> new_env(env->length());
new_env.AddArray(*env);
+ ASSERT(block != nullptr);
+ if (block == osr_succ) {
+ // During OSR, when visiting the successor block of the OSR entry from
+ // the graph entry (rather than going through the OSR entry first), we
+ // must adjust the environment to mimic a non-empty incoming expression
+ // stack to ensure temporaries refer to the right stack items.
+ new_env.FillWith(constant_dead(), new_env.length(),
+ graph_entry()->osr_entry()->stack_depth());
+ }
RenameRecursive(block, &new_env, live_phis, variable_liveness,
inlining_parameters);
}
@@ -1436,9 +1455,17 @@
if (successor->phis() != NULL) {
for (intptr_t i = 0; i < successor->phis()->length(); ++i) {
PhiInstr* phi = (*successor->phis())[i];
- if (phi != NULL) {
+ if (phi != nullptr) {
// Rename input operand.
- Value* use = new (zone()) Value((*env)[i]);
+ Definition* input = (*env)[i];
+ ASSERT(input != nullptr);
+ if (input->IsPushArgument()) {
+ // A push argument left on expression stack
+ // requires the variable name in SSA phis.
+ ASSERT(IsCompiledForOsr());
+ input = input->InputAt(0)->definition();
+ }
+ Value* use = new (zone()) Value(input);
phi->SetInputAt(pred_index, use);
}
}
diff --git a/runtime/vm/compiler/backend/flow_graph_checker.cc b/runtime/vm/compiler/backend/flow_graph_checker.cc
index bde8521..54a3630 100644
--- a/runtime/vm/compiler/backend/flow_graph_checker.cc
+++ b/runtime/vm/compiler/backend/flow_graph_checker.cc
@@ -325,6 +325,10 @@
} else {
ASSERT(instruction->InputAt(use->use_index()) == use);
}
+ // Make sure the reaching type, if any, has an owner consistent with this use.
+ if (auto const type = use->reaching_type()) {
+ ASSERT(type->owner() == nullptr || type->owner() == def);
+ }
// Make sure each use appears in the graph and is properly dominated
// by the definition (note that the proper dominance relation on the
// input values of Phis is checked by the Phi visitor below).
@@ -368,6 +372,7 @@
ASSERT(phi->InputCount() == current_block_->PredecessorCount());
for (intptr_t i = 0, n = phi->InputCount(); i < n; ++i) {
Definition* def = phi->InputAt(i)->definition();
+ ASSERT(def->HasSSATemp()); // phis have SSA defs
BlockEntryInstr* edge = current_block_->PredecessorAt(i);
ASSERT(DefDominatesUse(def, edge->last_instruction()));
}
diff --git a/runtime/vm/compiler/backend/flow_graph_compiler.cc b/runtime/vm/compiler/backend/flow_graph_compiler.cc
index 49597bb9..27600c2 100644
--- a/runtime/vm/compiler/backend/flow_graph_compiler.cc
+++ b/runtime/vm/compiler/backend/flow_graph_compiler.cc
@@ -722,12 +722,11 @@
void FlowGraphCompiler::AddExceptionHandler(intptr_t try_index,
intptr_t outer_try_index,
intptr_t pc_offset,
- TokenPosition token_pos,
bool is_generated,
const Array& handler_types,
bool needs_stacktrace) {
exception_handlers_list_->AddHandler(try_index, outer_try_index, pc_offset,
- token_pos, is_generated, handler_types,
+ is_generated, handler_types,
needs_stacktrace);
}
diff --git a/runtime/vm/compiler/backend/flow_graph_compiler.h b/runtime/vm/compiler/backend/flow_graph_compiler.h
index f07d8d7..4c26d2b 100644
--- a/runtime/vm/compiler/backend/flow_graph_compiler.h
+++ b/runtime/vm/compiler/backend/flow_graph_compiler.h
@@ -730,7 +730,6 @@
void AddExceptionHandler(intptr_t try_index,
intptr_t outer_try_index,
intptr_t pc_offset,
- TokenPosition token_pos,
bool is_generated,
const Array& handler_types,
bool needs_stacktrace);
diff --git a/runtime/vm/compiler/backend/flow_graph_compiler_arm.cc b/runtime/vm/compiler/backend/flow_graph_compiler_arm.cc
index af3e2f5..7db6c39 100644
--- a/runtime/vm/compiler/backend/flow_graph_compiler_arm.cc
+++ b/runtime/vm/compiler/backend/flow_graph_compiler_arm.cc
@@ -952,7 +952,9 @@
VisitBlocks();
+#if defined(DEBUG)
__ bkpt(0);
+#endif
if (!skip_body_compilation()) {
ASSERT(assembler()->constant_pool_allowed());
diff --git a/runtime/vm/compiler/backend/flow_graph_compiler_arm64.cc b/runtime/vm/compiler/backend/flow_graph_compiler_arm64.cc
index 8c9f45d..2e8362a 100644
--- a/runtime/vm/compiler/backend/flow_graph_compiler_arm64.cc
+++ b/runtime/vm/compiler/backend/flow_graph_compiler_arm64.cc
@@ -920,7 +920,9 @@
VisitBlocks();
+#if defined(DEBUG)
__ brk(0);
+#endif
if (!skip_body_compilation()) {
ASSERT(assembler()->constant_pool_allowed());
diff --git a/runtime/vm/compiler/backend/flow_graph_compiler_ia32.cc b/runtime/vm/compiler/backend/flow_graph_compiler_ia32.cc
index 5b1a9c3..f311a34 100644
--- a/runtime/vm/compiler/backend/flow_graph_compiler_ia32.cc
+++ b/runtime/vm/compiler/backend/flow_graph_compiler_ia32.cc
@@ -839,7 +839,9 @@
VisitBlocks();
if (!skip_body_compilation()) {
+#if defined(DEBUG)
__ int3();
+#endif
GenerateDeferredCode();
}
}
diff --git a/runtime/vm/compiler/backend/flow_graph_compiler_x64.cc b/runtime/vm/compiler/backend/flow_graph_compiler_x64.cc
index 78987ee..fe4eace 100644
--- a/runtime/vm/compiler/backend/flow_graph_compiler_x64.cc
+++ b/runtime/vm/compiler/backend/flow_graph_compiler_x64.cc
@@ -935,7 +935,9 @@
ASSERT(!block_order().is_empty());
VisitBlocks();
+#if defined(DEBUG)
__ int3();
+#endif
if (!skip_body_compilation()) {
ASSERT(assembler()->constant_pool_allowed());
diff --git a/runtime/vm/compiler/backend/il.cc b/runtime/vm/compiler/backend/il.cc
index e3479a4..2b1152a 100644
--- a/runtime/vm/compiler/backend/il.cc
+++ b/runtime/vm/compiler/backend/il.cc
@@ -767,6 +767,30 @@
return TargetAt(0)->exactness;
}
+const char* AssertAssignableInstr::KindToCString(Kind kind) {
+ switch (kind) {
+#define KIND_CASE(name) \
+ case k##name: \
+ return #name;
+ FOR_EACH_ASSERT_ASSIGNABLE_KIND(KIND_CASE)
+#undef KIND_CASE
+ default:
+ UNREACHABLE();
+ return nullptr;
+ }
+}
+
+bool AssertAssignableInstr::ParseKind(const char* str, Kind* out) {
+#define KIND_CASE(name) \
+ if (strcmp(str, #name) == 0) { \
+ *out = Kind::k##name; \
+ return true; \
+ }
+ FOR_EACH_ASSERT_ASSIGNABLE_KIND(KIND_CASE)
+#undef KIND_CASE
+ return false;
+}
+
CheckClassInstr::CheckClassInstr(Value* value,
intptr_t deopt_id,
const Cids& cids,
@@ -1027,8 +1051,38 @@
: value_(value), token_pos_(token_pos) {
// Check that the value is not an incorrect Integer representation.
ASSERT(!value.IsMint() || !Smi::IsValid(Mint::Cast(value).AsInt64Value()));
+ // Check that clones of fields are not stored as constants.
ASSERT(!value.IsField() || Field::Cast(value).IsOriginal());
+ // Check that all non-Smi objects are heap allocated and in old space.
ASSERT(value.IsSmi() || value.IsOld());
+#if defined(DEBUG)
+ // Generally, instances in the flow graph should be canonical. Smis and
+ // null values are canonical by construction and so we skip them here.
+ if (!value.IsNull() && !value.IsSmi() && value.IsInstance() &&
+ !value.IsCanonical()) {
+ // The only allowed type for which IsCanonical() never answers true is
+ // TypeParameter. (They are treated as canonical due to how they are
+ // created, but there is no way to canonicalize a new TypeParameter
+ // instance containing the same information as an existing instance.)
+ //
+ // Arrays in ConstantInstrs are usually immutable and canonicalized, but
+ // there are at least a couple of cases where one or both is not true:
+ //
+ // * The Arrays created as backing for ArgumentsDescriptors may not be
+ // canonicalized for space reasons when inlined in the IL. However, they
+ // are still immutable.
+ // * The backtracking stack for IRRegExps is put into a ConstantInstr for
+ // immediate use as an argument to the operations on that stack. In this
+ // case, the Array representing it is neither immutable or canonical.
+ //
+ // In addition to complicating the story for Arrays, IRRegExp compilation
+ // also uses other non-canonical values as "constants". For example, the bit
+ // tables used for certain character classes are represented as TypedData,
+ // and so those values are also neither immutable (as there are no immutable
+ // TypedData values) or canonical.
+ ASSERT(value.IsTypeParameter() || value.IsArray() || value.IsTypedData());
+ }
+#endif
}
bool ConstantInstr::AttributesEqual(Instruction* other) const {
@@ -1302,8 +1356,7 @@
} else if (this == def->env_use_list()) {
def->set_env_use_list(next);
if (next != NULL) next->set_previous_use(NULL);
- } else {
- Value* prev = previous_use();
+ } else if (Value* prev = previous_use()) {
prev->set_next_use(next);
if (next != NULL) next->set_previous_use(prev);
}
@@ -4283,8 +4336,8 @@
return nullptr;
}
-bool SpecialParameterInstr::KindFromCString(const char* str,
- SpecialParameterKind* out) {
+bool SpecialParameterInstr::ParseKind(const char* str,
+ SpecialParameterKind* out) {
ASSERT(str != nullptr && out != nullptr);
#define KIND_CASE(Name) \
if (strcmp(str, #Name) == 0) { \
diff --git a/runtime/vm/compiler/backend/il.h b/runtime/vm/compiler/backend/il.h
index fb2fc75..8128fb9 100644
--- a/runtime/vm/compiler/backend/il.h
+++ b/runtime/vm/compiler/backend/il.h
@@ -87,7 +87,12 @@
reaching_type_(NULL) {}
Definition* definition() const { return definition_; }
- void set_definition(Definition* definition) { definition_ = definition; }
+ void set_definition(Definition* definition) {
+ definition_ = definition;
+ // Clone the reaching type if there was one and the owner no longer matches
+ // this value's definition.
+ SetReachingType(reaching_type_);
+ }
Value* previous_use() const { return previous_use_; }
void set_previous_use(Value* previous) { previous_use_ = previous; }
@@ -156,6 +161,7 @@
private:
friend class FlowGraphPrinter;
+ friend class FlowGraphDeserializer; // For setting reaching_type_ directly.
Definition* definition_;
Value* previous_use_;
@@ -1862,8 +1868,7 @@
class CatchBlockEntryInstr : public BlockEntryWithInitialDefs {
public:
- CatchBlockEntryInstr(TokenPosition handler_token_pos,
- bool is_generated,
+ CatchBlockEntryInstr(bool is_generated,
intptr_t block_id,
intptr_t try_index,
GraphEntryInstr* graph_entry,
@@ -1885,7 +1890,6 @@
raw_exception_var_(raw_exception_var),
raw_stacktrace_var_(raw_stacktrace_var),
needs_stacktrace_(needs_stacktrace),
- handler_token_pos_(handler_token_pos),
is_generated_(is_generated) {}
DECLARE_INSTRUCTION(CatchBlockEntry)
@@ -1911,7 +1915,6 @@
bool needs_stacktrace() const { return needs_stacktrace_; }
bool is_generated() const { return is_generated_; }
- TokenPosition handler_token_pos() const { return handler_token_pos_; }
// Returns try index for the try block to which this catch handler
// corresponds.
@@ -1938,7 +1941,6 @@
const LocalVariable* raw_exception_var_;
const LocalVariable* raw_stacktrace_var_;
const bool needs_stacktrace_;
- TokenPosition handler_token_pos_;
bool is_generated_;
DISALLOW_COPY_AND_ASSIGN(CatchBlockEntryInstr);
@@ -3269,7 +3271,18 @@
class AssertAssignableInstr : public TemplateDefinition<3, Throws, Pure> {
public:
- enum Kind { kParameterCheck, kInsertedByFrontend, kFromSource, kUnknown };
+#define FOR_EACH_ASSERT_ASSIGNABLE_KIND(V) \
+ V(ParameterCheck) \
+ V(InsertedByFrontend) \
+ V(FromSource) \
+ V(Unknown)
+
+#define KIND_DEFN(name) k##name,
+ enum Kind { FOR_EACH_ASSERT_ASSIGNABLE_KIND(KIND_DEFN) };
+#undef KIND_DEFN
+
+ static const char* KindToCString(Kind kind);
+ static bool ParseKind(const char* str, Kind* out);
AssertAssignableInstr(TokenPosition token_pos,
Value* value,
@@ -3326,6 +3339,7 @@
virtual Value* RedefinedValue() const;
PRINT_OPERANDS_TO_SUPPORT
+ ADD_EXTRA_INFO_TO_S_EXPRESSION_SUPPORT
private:
const TokenPosition token_pos_;
@@ -3385,7 +3399,7 @@
#undef KIND_INC
static const char* KindToCString(SpecialParameterKind k);
- static bool KindFromCString(const char* str, SpecialParameterKind* out);
+ static bool ParseKind(const char* str, SpecialParameterKind* out);
SpecialParameterInstr(SpecialParameterKind kind,
intptr_t deopt_id,
@@ -3666,6 +3680,7 @@
PRINT_OPERANDS_TO_SUPPORT
ADD_OPERANDS_TO_S_EXPRESSION_SUPPORT
+ ADD_EXTRA_INFO_TO_S_EXPRESSION_SUPPORT
bool MatchesCoreName(const String& name);
@@ -4438,6 +4453,7 @@
PRINT_OPERANDS_TO_SUPPORT
ADD_OPERANDS_TO_S_EXPRESSION_SUPPORT
+ ADD_EXTRA_INFO_TO_S_EXPRESSION_SUPPORT
private:
void set_native_c_function(NativeFunction value) {
@@ -5512,6 +5528,8 @@
return other->AsLoadUntagged()->offset_ == offset_;
}
+ PRINT_OPERANDS_TO_SUPPORT
+
private:
intptr_t offset_;
diff --git a/runtime/vm/compiler/backend/il_arm.cc b/runtime/vm/compiler/backend/il_arm.cc
index 6f00a18..b6e2166 100644
--- a/runtime/vm/compiler/backend/il_arm.cc
+++ b/runtime/vm/compiler/backend/il_arm.cc
@@ -510,7 +510,9 @@
compiler->GenerateRuntimeCall(token_pos, deopt_id,
kNonBoolTypeErrorRuntimeEntry, 1, locs);
// We should never return here.
+#if defined(DEBUG)
__ bkpt(0);
+#endif
__ Bind(&done);
}
@@ -3237,10 +3239,9 @@
void CatchBlockEntryInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
__ Bind(compiler->GetJumpLabel(this));
- compiler->AddExceptionHandler(catch_try_index(), try_index(),
- compiler->assembler()->CodeSize(),
- handler_token_pos(), is_generated(),
- catch_handler_types_, needs_stacktrace());
+ compiler->AddExceptionHandler(
+ catch_try_index(), try_index(), compiler->assembler()->CodeSize(),
+ is_generated(), catch_handler_types_, needs_stacktrace());
// On lazy deoptimization we patch the optimized code here to enter the
// deoptimization stub.
const intptr_t deopt_id = DeoptId::ToDeoptAfter(GetDeoptId());
diff --git a/runtime/vm/compiler/backend/il_arm64.cc b/runtime/vm/compiler/backend/il_arm64.cc
index 3359f05..74c983d 100644
--- a/runtime/vm/compiler/backend/il_arm64.cc
+++ b/runtime/vm/compiler/backend/il_arm64.cc
@@ -499,7 +499,9 @@
compiler->GenerateRuntimeCall(token_pos, deopt_id,
kNonBoolTypeErrorRuntimeEntry, 1, locs);
// We should never return here.
+#if defined(DEBUG)
__ brk(0);
+#endif
__ Bind(&done);
}
@@ -2861,10 +2863,9 @@
void CatchBlockEntryInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
__ Bind(compiler->GetJumpLabel(this));
- compiler->AddExceptionHandler(catch_try_index(), try_index(),
- compiler->assembler()->CodeSize(),
- handler_token_pos(), is_generated(),
- catch_handler_types_, needs_stacktrace());
+ compiler->AddExceptionHandler(
+ catch_try_index(), try_index(), compiler->assembler()->CodeSize(),
+ is_generated(), catch_handler_types_, needs_stacktrace());
// On lazy deoptimization we patch the optimized code here to enter the
// deoptimization stub.
const intptr_t deopt_id = DeoptId::ToDeoptAfter(GetDeoptId());
diff --git a/runtime/vm/compiler/backend/il_dbc.cc b/runtime/vm/compiler/backend/il_dbc.cc
index 7ac0079..bd859e9 100644
--- a/runtime/vm/compiler/backend/il_dbc.cc
+++ b/runtime/vm/compiler/backend/il_dbc.cc
@@ -1245,10 +1245,9 @@
EMIT_NATIVE_CODE(CatchBlockEntry, 0) {
__ Bind(compiler->GetJumpLabel(this));
- compiler->AddExceptionHandler(catch_try_index(), try_index(),
- compiler->assembler()->CodeSize(),
- handler_token_pos(), is_generated(),
- catch_handler_types_, needs_stacktrace());
+ compiler->AddExceptionHandler(
+ catch_try_index(), try_index(), compiler->assembler()->CodeSize(),
+ is_generated(), catch_handler_types_, needs_stacktrace());
// On lazy deoptimization we patch the optimized code here to enter the
// deoptimization stub.
const intptr_t deopt_id = DeoptId::ToDeoptAfter(GetDeoptId());
@@ -1455,7 +1454,7 @@
void Environment::DropArguments(intptr_t argc) {
#if defined(DEBUG)
// Check that we are in the backend - register allocation has been run.
- ASSERT(locations_ != NULL);
+ ASSERT((Length() == 0) || (locations_ != nullptr));
// Check that we are only dropping a valid number of instructions from the
// environment.
diff --git a/runtime/vm/compiler/backend/il_deserializer.cc b/runtime/vm/compiler/backend/il_deserializer.cc
index f4bf535..97a98b1 100644
--- a/runtime/vm/compiler/backend/il_deserializer.cc
+++ b/runtime/vm/compiler/backend/il_deserializer.cc
@@ -44,6 +44,15 @@
THR_Print("Results of round trip serialization: {\"function\":\"%s\"",
results.function.ToFullyQualifiedCString());
THR_Print(",\"success\":%s", results.success ? "true" : "false");
+
+ // A few checks to make sure we'll print out enough info. First, if there are
+ // no unhandled instructions, then we should have serialized the flow graph.
+ ASSERT(!results.unhandled.is_empty() || results.serialized != nullptr);
+ // If we failed, then either there are unhandled instructions or we have
+ // an appropriate error message and sexp from the FlowGraphDeserializer.
+ ASSERT(results.success || !results.unhandled.is_empty() ||
+ (results.error_message != nullptr && results.error_sexp != nullptr));
+
if (!results.unhandled.is_empty()) {
CStringMap<intptr_t> count_map(zone);
for (auto inst : results.unhandled) {
@@ -146,7 +155,7 @@
} else {
if (FLAG_trace_round_trip_serialization) {
THR_Print("Successfully deserialized graph for %s\n",
- results.serialized->AsList()->At(0)->AsSymbol()->value());
+ results.serialized->AsList()->At(1)->AsSymbol()->value());
}
results.success = true;
}
@@ -256,9 +265,20 @@
pos++;
}
+ // The graph entry doesn't push any arguments onto the stack. Adding a
+ // pushed_stack_map_ entry for it allows us to unify how function entries
+ // are handled vs. other types of blocks with regards to incoming pushed
+ // argument stacks.
+ //
+ // We add this entry now so that ParseEnvironment can assume that there's
+ // always a current pushed_stack_map_ for current_block_.
+ auto const empty_stack = new (zone()) PushStack(zone(), 0);
+ pushed_stack_map_.Insert(0, empty_stack);
+
// The deopt environment for the graph entry may use entries from the
// constant pool, so that must be parsed first.
if (auto const env_sexp = CheckList(root->ExtraLookupValue("env"))) {
+ current_block_ = graph;
auto const env = ParseEnvironment(env_sexp);
if (env == nullptr) return nullptr;
env->DeepCopyTo(zone(), graph);
@@ -293,13 +313,6 @@
block_worklist.Add(normal_entry->block_id());
}
- // The graph entry doesn't push any arguments onto the stack. Adding a
- // pushed_stack_map_ entry for it allows us to unify how function entries
- // are handled vs. other types of blocks with regards to incoming pushed
- // argument stacks.
- auto const empty_stack = new (zone()) PushStack(zone(), 0);
- pushed_stack_map_.Insert(0, empty_stack);
-
if (!ParseBlocks(root, pos, &block_worklist)) return nullptr;
// Before we return the new graph, make sure all definitions were found for
@@ -307,10 +320,9 @@
if (values_map_.Length() > 0) {
auto it = values_map_.GetIterator();
auto const kv = it.Next();
- // TODO(sstrickl): This assumes SSA variables.
- auto const sym =
- new (zone()) SExpSymbol(OS::SCreate(zone(), "v%" Pd "", kv->key));
- StoreError(sym, "no definition found for variable index in flow graph");
+ ASSERT(kv->value->length() > 0);
+ const auto& value_info = kv->value->At(0);
+ StoreError(value_info.sexp, "no definition found for use in flow graph");
return nullptr;
}
@@ -336,6 +348,14 @@
// Since we will not be adding new definitions, we make the initial size of
// the worklist the number of definitions in the constant pool.
GrowableArray<SExpList*> worklist(zone(), pool->Length() - 1);
+ // In order to ensure that the definition order is the same in the original
+ // flow graph, we can't just simply call GetConstant() whenever we
+ // successfully parse a constant. Instead, we'll create a stand-in
+ // ConstantInstr that we can temporarily stick in the definition_map_, and
+ // then once finished we'll go back through, add the constants via
+ // GetConstant() and parse any extra information.
+ DirectChainedHashMap<RawPointerKeyValueTrait<SExpList, ConstantInstr*>>
+ parsed_constants(zone());
// We keep old_worklist in reverse order so that we can just RemoveLast
// to get elements in their original order.
for (intptr_t i = pool->Length() - 1; i > 0; i--) {
@@ -353,8 +373,16 @@
parse_failures.Add(def_sexp);
continue;
}
- ConstantInstr* def = flow_graph_->GetConstant(obj);
- if (!ParseDefinitionWithParsedBody(def_sexp, def)) return false;
+ ConstantInstr* def = new (zone()) ConstantInstr(obj);
+ // Instead of parsing the whole definition, just get the SSA index so
+ // we can insert it into the definition_map_.
+ intptr_t index;
+ auto const name_sexp = CheckSymbol(Retrieve(def_sexp, 1));
+ if (!ParseSSATemp(name_sexp, &index)) return false;
+ def->set_ssa_temp_index(index);
+ ASSERT(!definition_map_.HasKey(index));
+ definition_map_.Insert(index, def);
+ parsed_constants.Insert({def_sexp, def});
}
if (parse_failures.is_empty()) break;
// We've gone through the whole worklist without success, so return
@@ -366,6 +394,20 @@
worklist.Add(parse_failures.RemoveLast());
}
}
+ // Now loop back through the constant pool definition S-expressions and
+ // get the real ConstantInstrs the flow graph will be using and finish
+ // parsing.
+ for (intptr_t i = 1; i < pool->Length(); i++) {
+ auto const def_sexp = CheckTaggedList(pool->At(i));
+ auto const temp_def = parsed_constants.LookupValue(def_sexp);
+ ASSERT(temp_def != nullptr);
+ // Remove the temporary definition from definition_map_ so this doesn't get
+ // flagged as a redefinition.
+ definition_map_.Remove(temp_def->ssa_temp_index());
+ ConstantInstr* real_def = flow_graph_->GetConstant(temp_def->value());
+ if (!ParseDefinitionWithParsedBody(def_sexp, real_def)) return false;
+ ASSERT(temp_def->ssa_temp_index() == real_def->ssa_temp_index());
+ }
return true;
}
@@ -383,7 +425,7 @@
StoreError(entry->At(1), "multiple entries for block found");
return false;
}
- const auto tag = entry->At(0)->AsSymbol();
+ const auto tag = entry->Tag();
if (ParseBlockHeader(entry, block_id, tag) == nullptr) return false;
}
return true;
@@ -622,7 +664,7 @@
auto const entry = CheckTaggedList(Retrieve(list, i));
if (entry == nullptr) return false;
Instruction* inst = nullptr;
- if (strcmp(entry->At(0)->AsSymbol()->value(), "def") == 0) {
+ if (entry->Tag()->Equals("def")) {
inst = ParseDefinition(entry);
} else {
inst = ParseInstruction(entry);
@@ -673,7 +715,7 @@
}
definition_map_.Insert(index, def);
- FixPendingValues(index, def);
+ if (!FixPendingValues(index, def)) return false;
return true;
}
@@ -692,13 +734,18 @@
Instruction* FlowGraphDeserializer::ParseInstruction(SExpList* list) {
if (list == nullptr) return nullptr;
- auto const tag = list->At(0)->AsSymbol();
+ auto const tag = list->Tag();
intptr_t deopt_id = DeoptId::kNone;
if (auto const deopt_int = CheckInteger(list->ExtraLookupValue("deopt_id"))) {
deopt_id = deopt_int->value();
}
- InstrInfo common_info = {deopt_id, TokenPosition::kNoSource};
+ TokenPosition token_pos = TokenPosition::kNoSource;
+ if (auto const token_int =
+ CheckInteger(list->ExtraLookupValue("token_pos"))) {
+ token_pos = TokenPosition(token_int->value());
+ }
+ InstrInfo common_info = {deopt_id, token_pos};
// Parse the environment before handling the instruction, as we may have
// references to PushArguments and parsing the instruction may pop
@@ -777,7 +824,7 @@
const InstrInfo& info) {
auto& cls = Class::ZoneHandle(zone());
auto const cls_sexp = CheckTaggedList(Retrieve(sexp, 1), "Class");
- if (!ParseDartValue(cls_sexp, &cls)) return nullptr;
+ if (!ParseClass(cls_sexp, &cls)) return nullptr;
intptr_t args_len = 0;
if (auto const len_sexp = CheckInteger(sexp->ExtraLookupValue("args_len"))) {
@@ -792,13 +839,64 @@
if (auto const closure_sexp = CheckTaggedList(
sexp->ExtraLookupValue("closure_function"), "Function")) {
auto& closure_function = Function::Handle(zone());
- if (!ParseDartValue(closure_sexp, &closure_function)) return nullptr;
+ if (!ParseFunction(closure_sexp, &closure_function)) return nullptr;
inst->set_closure_function(closure_function);
}
return inst;
}
+AssertAssignableInstr* FlowGraphDeserializer::DeserializeAssertAssignable(
+ SExpList* sexp,
+ const InstrInfo& info) {
+ auto const val = ParseValue(Retrieve(sexp, 1));
+ if (val == nullptr) return nullptr;
+
+ auto const inst_type_args = ParseValue(Retrieve(sexp, 2));
+ if (inst_type_args == nullptr) return nullptr;
+
+ auto const func_type_args = ParseValue(Retrieve(sexp, 3));
+ if (func_type_args == nullptr) return nullptr;
+
+ auto& dst_type = AbstractType::Handle(zone());
+ auto const dst_type_sexp = Retrieve(sexp, "type");
+ if (!ParseDartValue(dst_type_sexp, &dst_type)) return nullptr;
+
+ auto& dst_name = String::ZoneHandle(zone());
+ auto const dst_name_sexp = Retrieve(sexp, "name");
+ if (!ParseDartValue(dst_name_sexp, &dst_name)) return nullptr;
+
+ auto kind = AssertAssignableInstr::Kind::kUnknown;
+ if (auto const kind_sexp = CheckSymbol(sexp->ExtraLookupValue("kind"))) {
+ if (!AssertAssignableInstr::ParseKind(kind_sexp->value(), &kind)) {
+ StoreError(kind_sexp, "unknown AssertAssignable kind");
+ return nullptr;
+ }
+ }
+
+ return new (zone())
+ AssertAssignableInstr(info.token_pos, val, inst_type_args, func_type_args,
+ dst_type, dst_name, info.deopt_id, kind);
+}
+
+AssertBooleanInstr* FlowGraphDeserializer::DeserializeAssertBoolean(
+ SExpList* sexp,
+ const InstrInfo& info) {
+ auto const val = ParseValue(Retrieve(sexp, 1));
+ if (val == nullptr) return nullptr;
+
+ return new (zone()) AssertBooleanInstr(info.token_pos, val, info.deopt_id);
+}
+
+BooleanNegateInstr* FlowGraphDeserializer::DeserializeBooleanNegate(
+ SExpList* sexp,
+ const InstrInfo& info) {
+ auto const value = ParseValue(Retrieve(sexp, 1));
+ if (value == nullptr) return nullptr;
+
+ return new (zone()) BooleanNegateInstr(value);
+}
+
BranchInstr* FlowGraphDeserializer::DeserializeBranch(SExpList* sexp,
const InstrInfo& info) {
auto const comp_sexp = CheckTaggedList(Retrieve(sexp, 1));
@@ -863,7 +961,7 @@
auto kind = CheckStackOverflowInstr::kOsrAndPreemption;
if (auto const kind_sexp = CheckSymbol(sexp->ExtraLookupValue("kind"))) {
- ASSERT(strcmp(kind_sexp->value(), "OsrOnly") == 0);
+ ASSERT(kind_sexp->Equals("OsrOnly"));
kind = CheckStackOverflowInstr::kOsrOnly;
}
@@ -884,7 +982,7 @@
const InstrInfo& info) {
auto kind = RawPcDescriptors::kAnyKind;
if (auto const kind_sexp = CheckSymbol(Retrieve(sexp, "stub_kind"))) {
- if (!RawPcDescriptors::KindFromCString(kind_sexp->value(), &kind)) {
+ if (!RawPcDescriptors::ParseKind(kind_sexp->value(), &kind)) {
StoreError(kind_sexp, "not a valid RawPcDescriptors::Kind name");
return nullptr;
}
@@ -903,6 +1001,67 @@
return new (zone()) GotoInstr(block->AsJoinEntry(), info.deopt_id);
}
+InstanceCallInstr* FlowGraphDeserializer::DeserializeInstanceCall(
+ SExpList* sexp,
+ const InstrInfo& info) {
+ auto& interface_target = Function::ZoneHandle(zone());
+ if (!ParseDartValue(Retrieve(sexp, 1), &interface_target)) return nullptr;
+
+ auto& function_name = String::ZoneHandle(zone());
+ // If we have an explicit function_name value, then use that value. Otherwise,
+ // if we have an non-null interface_target, use its name.
+ if (auto const name_sexp = sexp->ExtraLookupValue("function_name")) {
+ if (!ParseDartValue(name_sexp, &function_name)) return nullptr;
+ } else if (!interface_target.IsNull()) {
+ function_name = interface_target.name();
+ }
+
+ auto token_kind = Token::Kind::kILLEGAL;
+ if (auto const kind_sexp =
+ CheckSymbol(sexp->ExtraLookupValue("token_kind"))) {
+ if (!Token::FromStr(kind_sexp->value(), &token_kind)) {
+ StoreError(kind_sexp, "unexpected token kind");
+ return nullptr;
+ }
+ }
+
+ CallInfo call_info(zone());
+ if (!ParseCallInfo(sexp, &call_info)) return nullptr;
+
+ intptr_t checked_arg_count = 0;
+ if (auto const checked_sexp =
+ CheckInteger(sexp->ExtraLookupValue("checked_arg_count"))) {
+ checked_arg_count = checked_sexp->value();
+ }
+
+ auto const inst = new (zone()) InstanceCallInstr(
+ info.token_pos, function_name, token_kind, call_info.arguments,
+ call_info.type_args_len, call_info.argument_names, checked_arg_count,
+ info.deopt_id, interface_target);
+
+ if (call_info.result_type != nullptr) {
+ inst->SetResultType(zone(), *call_info.result_type);
+ }
+
+ inst->set_entry_kind(call_info.entry_kind);
+
+ if (auto const ic_data_sexp =
+ CheckTaggedList(Retrieve(sexp, "ic_data"), "ICData")) {
+ if (!CreateICData(ic_data_sexp, inst)) return nullptr;
+ }
+
+ return inst;
+}
+
+LoadClassIdInstr* FlowGraphDeserializer::DeserializeLoadClassId(
+ SExpList* sexp,
+ const InstrInfo& info) {
+ auto const val = ParseValue(Retrieve(sexp, 1));
+ if (val == nullptr) return nullptr;
+
+ return new (zone()) LoadClassIdInstr(val);
+}
+
LoadFieldInstr* FlowGraphDeserializer::DeserializeLoadField(
SExpList* sexp,
const InstrInfo& info) {
@@ -915,6 +1074,33 @@
return new (zone()) LoadFieldInstr(instance, *slot, info.token_pos);
}
+NativeCallInstr* FlowGraphDeserializer::DeserializeNativeCall(
+ SExpList* sexp,
+ const InstrInfo& info) {
+ auto& function = Function::ZoneHandle(zone());
+ if (!ParseDartValue(Retrieve(sexp, 1), &function)) return nullptr;
+ if (!function.IsFunction()) {
+ StoreError(sexp->At(1), "expected a Function value");
+ return nullptr;
+ }
+
+ auto const name_sexp = CheckString(Retrieve(sexp, "name"));
+ if (name_sexp == nullptr) return nullptr;
+ const auto& name =
+ String::ZoneHandle(zone(), String::New(name_sexp->value()));
+
+ bool link_lazily = false;
+ if (auto const link_sexp = CheckBool(sexp->ExtraLookupValue("link_lazily"))) {
+ link_lazily = link_sexp->value();
+ }
+
+ CallInfo call_info(zone());
+ if (!ParseCallInfo(sexp, &call_info)) return nullptr;
+
+ return new (zone()) NativeCallInstr(&name, &function, link_lazily,
+ info.token_pos, call_info.arguments);
+}
+
ParameterInstr* FlowGraphDeserializer::DeserializeParameter(
SExpList* sexp,
const InstrInfo& info) {
@@ -951,7 +1137,7 @@
auto const kind_sexp = CheckSymbol(Retrieve(sexp, 1));
if (kind_sexp == nullptr) return nullptr;
SpecialParameterInstr::SpecialParameterKind kind;
- if (!SpecialParameterInstr::KindFromCString(kind_sexp->value(), &kind)) {
+ if (!SpecialParameterInstr::ParseKind(kind_sexp->value(), &kind)) {
StoreError(kind_sexp, "unknown special parameter kind");
return nullptr;
}
@@ -964,37 +1150,10 @@
const InstrInfo& info) {
auto& function = Function::ZoneHandle(zone());
auto const function_sexp = CheckTaggedList(Retrieve(sexp, 1), "Function");
- if (!ParseDartValue(function_sexp, &function)) return nullptr;
+ if (!ParseFunction(function_sexp, &function)) return nullptr;
- intptr_t type_args_len = 0;
- if (auto const type_args_len_sexp =
- CheckInteger(sexp->ExtraLookupValue("type_args_len"))) {
- type_args_len = type_args_len_sexp->value();
- }
-
- Array& argument_names = Array::ZoneHandle(zone());
- if (auto const arg_names_sexp =
- CheckList(sexp->ExtraLookupValue("arg_names"))) {
- argument_names = Array::New(arg_names_sexp->Length(), Heap::kOld);
- for (intptr_t i = 0, n = arg_names_sexp->Length(); i < n; i++) {
- auto name_sexp = CheckString(Retrieve(arg_names_sexp, i));
- if (name_sexp == nullptr) return nullptr;
- tmp_string_ = String::New(name_sexp->value(), Heap::kOld);
- argument_names.SetAt(i, tmp_string_);
- }
- }
-
- intptr_t args_len = 0;
- if (auto const args_len_sexp =
- CheckInteger(sexp->ExtraLookupValue("args_len"))) {
- args_len = args_len_sexp->value();
- }
-
- // Type arguments are wrapped in a TypeArguments array, so no matter how
- // many there are, they are contained in a single pushed argument.
- auto const all_args_len = (type_args_len > 0 ? 1 : 0) + args_len;
- auto const arguments = FetchPushedArguments(sexp, all_args_len);
- if (arguments == nullptr) return nullptr;
+ CallInfo call_info(zone());
+ if (!ParseCallInfo(sexp, &call_info)) return nullptr;
intptr_t call_count = 0;
if (auto const call_count_sexp =
@@ -1002,18 +1161,32 @@
call_count = call_count_sexp->value();
}
- auto rebind_rule = ICData::kInstance;
+ auto rebind_rule = ICData::kStatic;
if (auto const rebind_sexp =
CheckSymbol(sexp->ExtraLookupValue("rebind_rule"))) {
- if (!ICData::RebindRuleFromCString(rebind_sexp->value(), &rebind_rule)) {
+ if (!ICData::ParseRebindRule(rebind_sexp->value(), &rebind_rule)) {
StoreError(rebind_sexp, "unknown rebind rule value");
return nullptr;
}
}
- return new (zone())
- StaticCallInstr(info.token_pos, function, type_args_len, argument_names,
- arguments, info.deopt_id, call_count, rebind_rule);
+ auto const inst = new (zone())
+ StaticCallInstr(info.token_pos, function, call_info.type_args_len,
+ call_info.argument_names, call_info.arguments,
+ info.deopt_id, call_count, rebind_rule);
+
+ if (call_info.result_type != nullptr) {
+ inst->SetResultType(zone(), *call_info.result_type);
+ }
+
+ inst->set_entry_kind(call_info.entry_kind);
+
+ if (auto const ic_data_sexp =
+ CheckTaggedList(sexp->ExtraLookupValue("ic_data"), "ICData")) {
+ if (!CreateICData(ic_data_sexp, inst)) return nullptr;
+ }
+
+ return inst;
}
StoreInstanceFieldInstr* FlowGraphDeserializer::DeserializeStoreInstanceField(
@@ -1067,18 +1240,74 @@
needs_check, info.deopt_id);
}
+ThrowInstr* FlowGraphDeserializer::DeserializeThrow(SExpList* sexp,
+ const InstrInfo& info) {
+ return new (zone()) ThrowInstr(info.token_pos, info.deopt_id);
+}
+
+bool FlowGraphDeserializer::ParseCallInfo(SExpList* call, CallInfo* out) {
+ ASSERT(out != nullptr);
+
+ if (auto const len_sexp =
+ CheckInteger(call->ExtraLookupValue("type_args_len"))) {
+ out->type_args_len = len_sexp->value();
+ }
+
+ if (auto const arg_names_sexp =
+ CheckList(call->ExtraLookupValue("arg_names"))) {
+ out->argument_names = Array::New(arg_names_sexp->Length(), Heap::kOld);
+ for (intptr_t i = 0, n = arg_names_sexp->Length(); i < n; i++) {
+ auto name_sexp = CheckString(Retrieve(arg_names_sexp, i));
+ if (name_sexp == nullptr) return false;
+ tmp_string_ = String::New(name_sexp->value(), Heap::kOld);
+ out->argument_names.SetAt(i, tmp_string_);
+ }
+ }
+
+ if (auto const args_len_sexp =
+ CheckInteger(call->ExtraLookupValue("args_len"))) {
+ out->args_len = args_len_sexp->value();
+ }
+
+ if (auto const result_sexp = CheckTaggedList(
+ call->ExtraLookupValue("result_type"), "CompileType")) {
+ out->result_type = ParseCompileType(result_sexp);
+ }
+
+ if (auto const kind_sexp =
+ CheckSymbol(call->ExtraLookupValue("entry_kind"))) {
+ if (!Code::ParseEntryKind(kind_sexp->value(), &out->entry_kind))
+ return false;
+ }
+
+ // Type arguments are wrapped in a TypeArguments array, so no matter how
+ // many there are, they are contained in a single pushed argument.
+ auto const all_args_len = (out->type_args_len > 0 ? 1 : 0) + out->args_len;
+ out->arguments = FetchPushedArguments(call, all_args_len);
+ if (out->arguments == nullptr) return false;
+
+ return true;
+}
+
Value* FlowGraphDeserializer::ParseValue(SExpression* sexp,
bool allow_pending) {
- auto name = sexp->AsSymbol();
CompileType* type = nullptr;
+ bool inherit_type = false;
+ auto name = sexp->AsSymbol();
if (name == nullptr) {
auto const list = CheckTaggedList(sexp, "value");
name = CheckSymbol(Retrieve(list, 1));
- if (name == nullptr) return nullptr;
if (auto const type_sexp =
CheckTaggedList(list->ExtraLookupValue("type"), "CompileType")) {
type = ParseCompileType(type_sexp);
if (type == nullptr) return nullptr;
+ } else if (auto const inherit_sexp =
+ CheckBool(list->ExtraLookupValue("inherit_type"))) {
+ inherit_type = inherit_sexp->value();
+ } else {
+ // We assume that the type should be inherited from the definition for
+ // for (value ...) forms without an explicit type.
+ inherit_type = true;
}
}
intptr_t index;
@@ -1090,9 +1319,17 @@
StoreError(sexp, "found use prior to definition");
return nullptr;
}
- val = AddNewPendingValue(index);
+ val = AddNewPendingValue(sexp, index, inherit_type);
} else {
val = new (zone()) Value(def);
+ if (inherit_type) {
+ if (def->HasType()) {
+ val->reaching_type_ = def->Type();
+ } else {
+ StoreError(sexp, "value inherits type, but no type found");
+ return nullptr;
+ }
+ }
}
if (type != nullptr) val->SetReachingType(type);
return val;
@@ -1108,22 +1345,17 @@
: CompileType::kNonNullable;
}
- // A cid as the second element means that the type is based off a concrete
- // class.
- intptr_t cid = kDynamicCid;
- if (sexp->Length() > 1) {
- if (auto const cid_sexp = CheckInteger(sexp->At(1))) {
- // TODO(sstrickl): Check that the cid is a valid cid.
- cid = cid_sexp->value();
- } else {
- return nullptr;
- }
+ intptr_t cid = kIllegalCid;
+ if (auto const cid_sexp = CheckInteger(sexp->ExtraLookupValue("cid"))) {
+ // TODO(sstrickl): Check that the cid is a valid concrete cid, or a cid
+ // otherwise found in CompileTypes like kIllegalCid or kDynamicCid.
+ cid = cid_sexp->value();
}
AbstractType* type = nullptr;
- if (auto const type_sexp = CheckTaggedList(sexp->ExtraLookupValue("type"))) {
+ if (auto const type_sexp = sexp->ExtraLookupValue("type")) {
auto& type_handle = AbstractType::ZoneHandle(zone());
- if (!ParseDartValue(type_sexp, &type_handle)) return nullptr;
+ if (!ParseAbstractType(type_sexp, &type_handle)) return nullptr;
type = &type_handle;
}
return new (zone()) CompileType(nullable, cid, type);
@@ -1146,6 +1378,7 @@
}
}
+ ASSERT(parsed_function_ != nullptr);
auto const env = new (zone()) Environment(list->Length(), fixed_param_count,
*parsed_function_, outer_env);
@@ -1181,7 +1414,7 @@
if (auto const sym = sexp->AsSymbol()) {
// We'll use the null value in *out as a marker later, so go ahead and exit
// early if we parse one.
- if (strcmp(sym->value(), "null") == 0) return true;
+ if (sym->Equals("null")) return true;
// The only other symbols that should appear in Dart value position are
// names of constant definitions.
@@ -1199,126 +1432,7 @@
// Other instance values may need to be canonicalized, so do that before
// returning.
- if (auto const list = CheckTaggedList(sexp)) {
- auto const tag = list->At(0)->AsSymbol();
- if (strcmp(tag->value(), "Class") == 0) {
- auto const cid_sexp = CheckInteger(Retrieve(list, 1));
- if (cid_sexp == nullptr) return false;
- ClassTable* table = thread()->isolate()->class_table();
- if (!table->HasValidClassAt(cid_sexp->value())) {
- StoreError(cid_sexp, "no valid class found for cid");
- return false;
- }
- *out = table->At(cid_sexp->value());
- } else if (strcmp(tag->value(), "Type") == 0) {
- if (const auto cls_sexp = CheckTaggedList(Retrieve(list, 1), "Class")) {
- auto& cls = Class::ZoneHandle(zone());
- if (!ParseDartValue(cls_sexp, &cls)) return false;
- auto& type_args = TypeArguments::ZoneHandle(zone());
- if (const auto ta_sexp = CheckTaggedList(
- list->ExtraLookupValue("type_args"), "TypeArguments")) {
- if (!ParseDartValue(ta_sexp, &type_args)) return false;
- }
- *out = Type::New(cls, type_args, TokenPosition::kNoSource, Heap::kOld);
- // Need to set this for canonicalization. We ensure in the serializer
- // that only finalized types are successfully serialized.
- Type::Cast(*out).SetIsFinalized();
- }
- // TODO(sstrickl): Handle types not derived from classes.
- } else if (strcmp(tag->value(), "TypeArguments") == 0) {
- *out = TypeArguments::New(list->Length() - 1, Heap::kOld);
- auto& type_args = TypeArguments::Cast(*out);
- for (intptr_t i = 1, n = list->Length(); i < n; i++) {
- if (!ParseDartValue(Retrieve(list, i), &value_type_)) return false;
- type_args.SetTypeAt(i - 1, value_type_);
- }
- } else if (strcmp(tag->value(), "Field") == 0) {
- auto const name_sexp = CheckSymbol(Retrieve(list, 1));
- if (!ParseCanonicalName(name_sexp, out)) return false;
- } else if (strcmp(tag->value(), "Function") == 0) {
- auto const name_sexp = CheckSymbol(Retrieve(list, 1));
- if (!ParseCanonicalName(name_sexp, out)) return false;
- // Check the kind expected by the S-expression if one was specified.
- if (auto const kind_sexp = CheckSymbol(list->ExtraLookupValue("kind"))) {
- RawFunction::Kind kind;
- if (!RawFunction::KindFromCString(kind_sexp->value(), &kind)) {
- StoreError(kind_sexp, "unexpected function kind");
- return false;
- }
- auto& function = Function::Cast(*out);
- if (function.kind() != kind) {
- auto const kind_str = RawFunction::KindToCString(function.kind());
- StoreError(list, "retrieved function has kind %s", kind_str);
- return false;
- }
- }
- } else if (strcmp(tag->value(), "TypeParameter") == 0) {
- ASSERT(parsed_function_ != nullptr);
- auto const name_sexp = CheckSymbol(Retrieve(list, 1));
- if (name_sexp == nullptr) return false;
- const auto& func = parsed_function_->function();
- tmp_string_ = String::New(name_sexp->value());
- *out = func.LookupTypeParameter(tmp_string_, nullptr);
- if (out->IsNull()) {
- // Check the owning class for the function as well.
- value_class_ = func.Owner();
- *out = value_class_.LookupTypeParameter(tmp_string_);
- }
- // We'll want a more specific error message than the generic unhandled
- // Dart value one if this failed.
- if (out->IsNull()) {
- StoreError(name_sexp, "no type parameter found for name");
- return false;
- }
- } else if (strcmp(tag->value(), "ImmutableList") == 0) {
- // Since arrays can contain arrays, we must allocate a new handle here.
- auto& arr =
- Array::Handle(zone(), Array::New(list->Length() - 1, Heap::kOld));
- for (intptr_t i = 1; i < list->Length(); i++) {
- if (!ParseDartValue(Retrieve(list, i), &value_object_)) return false;
- arr.SetAt(i - 1, value_object_);
- }
- if (auto type_args_sexp = CheckTaggedList(
- list->ExtraLookupValue("type_args"), "TypeArguments")) {
- if (!ParseDartValue(type_args_sexp, &value_type_args_)) return false;
- arr.SetTypeArguments(value_type_args_);
- }
- arr.MakeImmutable();
- *out = arr.raw();
- } else if (strcmp(tag->value(), "Instance") == 0) {
- if (!ParseInstance(list, reinterpret_cast<Instance*>(out))) return false;
- } else if (strcmp(tag->value(), "Closure") == 0) {
- auto& function = Function::ZoneHandle(zone());
- if (!ParseDartValue(Retrieve(list, 1), &function)) return false;
-
- auto& context = Context::ZoneHandle(zone());
- if (list->ExtraLookupValue("context") != nullptr) {
- StoreError(list, "closures with contexts currently unhandled");
- return false;
- }
-
- auto& inst_type_args = TypeArguments::ZoneHandle(zone());
- if (auto const type_args_sexp = CheckTaggedList(
- Retrieve(list, "inst_type_args"), "TypeArguments")) {
- if (!ParseDartValue(type_args_sexp, &inst_type_args)) return false;
- }
-
- auto& func_type_args = TypeArguments::ZoneHandle(zone());
- if (auto const type_args_sexp = CheckTaggedList(
- Retrieve(list, "func_type_args"), "TypeArguments")) {
- if (!ParseDartValue(type_args_sexp, &func_type_args)) return false;
- }
-
- auto& delayed_type_args = TypeArguments::ZoneHandle(zone());
- if (auto const type_args_sexp = CheckTaggedList(
- Retrieve(list, "delayed_type_args"), "TypeArguments")) {
- if (!ParseDartValue(type_args_sexp, &delayed_type_args)) return false;
- }
-
- *out = Closure::New(inst_type_args, func_type_args, delayed_type_args,
- function, context, Heap::kOld);
- }
- } else if (auto const b = sexp->AsBool()) {
+ if (auto const b = sexp->AsBool()) {
*out = Bool::Get(b->value()).raw();
} else if (auto const str = sexp->AsString()) {
*out = String::New(str->value(), Heap::kOld);
@@ -1326,6 +1440,29 @@
*out = Integer::New(i->value(), Heap::kOld);
} else if (auto const d = sexp->AsDouble()) {
*out = Double::New(d->value(), Heap::kOld);
+ } else if (auto const list = CheckTaggedList(sexp)) {
+ auto const tag = list->Tag();
+ if (tag->Equals("Class")) {
+ return ParseClass(list, out);
+ } else if (tag->Equals("Type")) {
+ return ParseType(list, out);
+ } else if (tag->Equals("TypeArguments")) {
+ return ParseTypeArguments(list, out);
+ } else if (tag->Equals("Field")) {
+ return ParseField(list, out);
+ } else if (tag->Equals("Function")) {
+ return ParseFunction(list, out);
+ } else if (tag->Equals("TypeParameter")) {
+ return ParseTypeParameter(list, out);
+ } else if (tag->Equals("ImmutableList")) {
+ return ParseImmutableList(list, out);
+ } else if (tag->Equals("Instance")) {
+ return ParseInstance(list, out);
+ } else if (tag->Equals("Closure")) {
+ return ParseClosure(list, out);
+ } else if (tag->Equals("TypeRef")) {
+ return ParseTypeRef(list, out);
+ }
}
// If we're here and still haven't gotten a non-null value, then something
@@ -1335,26 +1472,170 @@
return false;
}
- if (out->IsInstance()) {
- const char* error_str = nullptr;
- // CheckAndCanonicalize uses the current zone for the passed in thread,
- // not an explicitly provided zone. This means we cannot be run in a context
- // where [thread()->zone()] does not match [zone()] (e.g., due to StackZone)
- // until this is addressed.
- *out = Instance::Cast(*out).CheckAndCanonicalize(thread(), &error_str);
- if (out->IsNull()) {
- if (error_str != nullptr) {
- StoreError(sexp, "error during canonicalization: %s", error_str);
- } else {
- StoreError(sexp, "unexpected error during canonicalization");
- }
+ if (!out->IsInstance()) return true;
+ return CanonicalizeInstance(sexp, out);
+}
+
+bool FlowGraphDeserializer::CanonicalizeInstance(SExpression* sexp,
+ Object* out) {
+ ASSERT(out != nullptr);
+ if (!out->IsInstance()) return true;
+ const char* error_str = nullptr;
+ // CheckAndCanonicalize uses the current zone for the passed in thread,
+ // not an explicitly provided zone. This means we cannot be run in a context
+ // where [thread()->zone()] does not match [zone()] (e.g., due to StackZone)
+ // until this is addressed.
+ *out = Instance::Cast(*out).CheckAndCanonicalize(thread(), &error_str);
+ if (error_str != nullptr) {
+ StoreError(sexp, "error during canonicalization: %s", error_str);
+ return false;
+ }
+ return true;
+}
+
+bool FlowGraphDeserializer::ParseAbstractType(SExpression* sexp, Object* out) {
+ ASSERT(out != nullptr);
+ if (sexp == nullptr) return false;
+
+ // If it's a symbol, it should be a reference to a constant definition, which
+ // is handled in ParseType.
+ if (auto const sym = sexp->AsSymbol()) {
+ return ParseType(sexp, out);
+ } else if (auto const list = CheckTaggedList(sexp)) {
+ auto const tag = list->Tag();
+ if (tag->Equals("Type")) {
+ return ParseType(list, out);
+ } else if (tag->Equals("TypeParameter")) {
+ return ParseTypeParameter(list, out);
+ } else if (tag->Equals("TypeRef")) {
+ return ParseTypeRef(list, out);
+ }
+ }
+
+ StoreError(sexp, "not an AbstractType");
+ return false;
+}
+
+bool FlowGraphDeserializer::ParseClass(SExpList* list, Object* out) {
+ ASSERT(out != nullptr);
+ if (list == nullptr) return false;
+
+ auto const ref_sexp = Retrieve(list, 1);
+ if (ref_sexp == nullptr) return false;
+ if (auto const cid_sexp = ref_sexp->AsInteger()) {
+ ClassTable* table = thread()->isolate()->class_table();
+ if (!table->HasValidClassAt(cid_sexp->value())) {
+ StoreError(cid_sexp, "no valid class found for cid");
+ return false;
+ }
+ *out = table->At(cid_sexp->value());
+ } else if (auto const name_sexp = ref_sexp->AsSymbol()) {
+ if (!ParseCanonicalName(name_sexp, out)) return false;
+ if (!out->IsClass()) {
+ StoreError(name_sexp, "expected the name of a class");
return false;
}
}
return true;
}
-bool FlowGraphDeserializer::ParseInstance(SExpList* list, Instance* out) {
+bool FlowGraphDeserializer::ParseClosure(SExpList* list, Object* out) {
+ ASSERT(out != nullptr);
+ if (list == nullptr) return false;
+
+ auto& function = Function::ZoneHandle(zone());
+ auto const function_sexp = CheckTaggedList(Retrieve(list, 1), "Function");
+ if (!ParseFunction(function_sexp, &function)) return false;
+
+ auto& context = Context::ZoneHandle(zone());
+ if (list->ExtraLookupValue("context") != nullptr) {
+ StoreError(list, "closures with contexts currently unhandled");
+ return false;
+ }
+
+ auto& inst_type_args = TypeArguments::ZoneHandle(zone());
+ if (auto const type_args_sexp = Retrieve(list, "inst_type_args")) {
+ if (!ParseTypeArguments(type_args_sexp, &inst_type_args)) return false;
+ }
+
+ auto& func_type_args = TypeArguments::ZoneHandle(zone());
+ if (auto const type_args_sexp = Retrieve(list, "func_type_args")) {
+ if (!ParseTypeArguments(type_args_sexp, &func_type_args)) return false;
+ }
+
+ auto& delayed_type_args = TypeArguments::ZoneHandle(zone());
+ if (auto const type_args_sexp = Retrieve(list, "delayed_type_args")) {
+ if (!ParseTypeArguments(type_args_sexp, &delayed_type_args)) {
+ return false;
+ }
+ }
+
+ *out = Closure::New(inst_type_args, func_type_args, delayed_type_args,
+ function, context, Heap::kOld);
+ return CanonicalizeInstance(list, out);
+}
+
+bool FlowGraphDeserializer::ParseField(SExpList* list, Object* out) {
+ auto const name_sexp = CheckSymbol(Retrieve(list, 1));
+ if (!ParseCanonicalName(name_sexp, out)) return false;
+ if (!out->IsField()) {
+ StoreError(list, "expected a Field name");
+ return false;
+ }
+ return true;
+}
+
+bool FlowGraphDeserializer::ParseFunction(SExpList* list, Object* out) {
+ ASSERT(out != nullptr);
+ if (list == nullptr) return false;
+
+ auto const name_sexp = CheckSymbol(Retrieve(list, 1));
+ if (!ParseCanonicalName(name_sexp, out)) return false;
+ if (!out->IsFunction()) {
+ StoreError(list, "expected a Function name");
+ return false;
+ }
+ auto& function = Function::Cast(*out);
+ // Check the kind expected by the S-expression if one was specified.
+ if (auto const kind_sexp = CheckSymbol(list->ExtraLookupValue("kind"))) {
+ RawFunction::Kind kind;
+ if (!RawFunction::ParseKind(kind_sexp->value(), &kind)) {
+ StoreError(kind_sexp, "unexpected function kind");
+ return false;
+ }
+ if (function.kind() != kind) {
+ auto const kind_str = RawFunction::KindToCString(function.kind());
+ StoreError(list, "retrieved function has kind %s", kind_str);
+ return false;
+ }
+ }
+ return true;
+}
+
+bool FlowGraphDeserializer::ParseImmutableList(SExpList* list, Object* out) {
+ ASSERT(out != nullptr);
+ if (list == nullptr) return false;
+
+ *out = Array::New(list->Length() - 1, Heap::kOld);
+ auto& arr = Array::Cast(*out);
+ // Arrays may contain other arrays, so we'll need a new handle in which to
+ // store elements.
+ auto& elem = Object::Handle(zone());
+ for (intptr_t i = 1; i < list->Length(); i++) {
+ if (!ParseDartValue(Retrieve(list, i), &elem)) return false;
+ arr.SetAt(i - 1, elem);
+ }
+ if (auto type_args_sexp = list->ExtraLookupValue("type_args")) {
+ if (!ParseTypeArguments(type_args_sexp, &array_type_args_)) return false;
+ arr.SetTypeArguments(array_type_args_);
+ }
+ arr.MakeImmutable();
+ return CanonicalizeInstance(list, out);
+}
+
+bool FlowGraphDeserializer::ParseInstance(SExpList* list, Object* out) {
+ ASSERT(out != nullptr);
+ if (list == nullptr) return false;
auto const cid_sexp = CheckInteger(Retrieve(list, 1));
if (cid_sexp == nullptr) return false;
@@ -1366,34 +1647,310 @@
instance_class_ = table->At(cid_sexp->value());
*out = Instance::New(instance_class_, Heap::kOld);
+ auto& instance = Instance::Cast(*out);
- if (list->Length() > 2) {
- auto const fields_sexp = CheckTaggedList(Retrieve(list, 2), "Fields");
- if (fields_sexp == nullptr) return false;
- auto it = fields_sexp->ExtraIterator();
- while (auto kv = it.Next()) {
- tmp_string_ = String::New(kv->key);
- instance_field_ = instance_class_.LookupFieldAllowPrivate(
- tmp_string_, /*instance_only=*/true);
- if (instance_field_.IsNull()) {
- StoreError(list, "cannot find field %s", kv->key);
- return false;
- }
-
- if (auto const inst = CheckTaggedList(kv->value, "Instance")) {
- // Unsure if this will be necessary, so for now not doing fresh
- // Instance/Class handle allocations unless it is.
- StoreError(inst, "nested instances not handled yet");
- return false;
- }
- if (!ParseDartValue(kv->value, &instance_object_)) return false;
- out->SetField(instance_field_, instance_object_);
+ if (auto const type_args = list->ExtraLookupValue("type_args")) {
+ instance_type_args_ = TypeArguments::null();
+ if (!ParseTypeArguments(type_args, &instance_type_args_)) return false;
+ if (!instance_class_.IsGeneric()) {
+ StoreError(list,
+ "type arguments provided for an instance of a "
+ "non-generic class");
+ return false;
}
+ instance.SetTypeArguments(instance_type_args_);
}
+
+ // Pick out and store the final instance fields of the class, as values must
+ // be provided for them. Error if there are any non-final instance fields.
+ instance_fields_array_ = instance_class_.fields();
+ auto const field_count = instance_fields_array_.Length();
+ GrowableArray<const Field*> final_fields(zone(), field_count);
+ for (intptr_t i = 0, n = field_count; i < n; i++) {
+ instance_field_ = Field::RawCast(instance_fields_array_.At(i));
+ if (!instance_field_.is_instance()) continue;
+ if (!instance_field_.is_final()) {
+ StoreError(list, "class for instance has non-final instance fields");
+ return false;
+ }
+ auto& fresh_handle = Field::Handle(zone(), instance_field_.raw());
+ final_fields.Add(&fresh_handle);
+ }
+
+ // If there is no (Fields...) sub-expression or it has no extra info, then
+ // ensure there are no final fields before returning the canonicalized form.
+ SExpList* fields_sexp = nullptr;
+ bool fields_provided = list->Length() > 2;
+ if (fields_provided) {
+ fields_sexp = CheckTaggedList(Retrieve(list, 2), "Fields");
+ if (fields_sexp == nullptr) return false;
+ fields_provided = fields_sexp->ExtraLength() != 0;
+ }
+ if (!fields_provided) {
+ if (!final_fields.is_empty()) {
+ StoreError(list, "values not provided for final fields of instance");
+ return false;
+ }
+ return CanonicalizeInstance(list, out);
+ }
+
+ // At this point, we have final instance field values to set on the new
+ // instance before canonicalization. When setting instance fields, we may
+ // cause field guards to be invalidated. Because of this, we must either be
+ // running on the mutator thread or be at a safepoint when calling `SetField`.
+ //
+ // For IR round-trips, the constants we create have already existed before in
+ // the VM heap, which means field invalidation cannot occur. Thus, we create a
+ // closure that sets the fields of the instance and then conditionally run
+ // that closure at a safepoint if not in the mutator thread.
+ //
+ // TODO(dartbug.com/36882): When deserializing IR that was not generated
+ // during the RoundTripSerialization pass, we are no longer guaranteed that
+ // deserialization of instances will not invalidate field guards. Thus, we may
+ // need to support invalidating field guards on non-mutator threads or fall
+ // back onto forcing the deserialization to happen on the mutator thread.
+ auto set_instance_fields = [&]() {
+ auto& inst = Instance::Cast(*out);
+ // We'll need to allocate a handle for the parsed value as we may have
+ // instances as field values and so this function may be re-entered.
+ auto& value = Object::Handle(zone());
+ for (auto field : final_fields) {
+ tmp_string_ = field->UserVisibleName();
+ auto const name = tmp_string_.ToCString();
+ auto const value_sexp = Retrieve(fields_sexp, name);
+ if (value_sexp == nullptr) {
+ StoreError(list, "no value provided for final instance field %s", name);
+ return false;
+ }
+ if (!ParseDartValue(value_sexp, &value)) return false;
+ inst.SetField(*field, value);
+ }
+ return true;
+ };
+
+ auto const t = Thread::Current();
+ if (!t->IsMutatorThread()) {
+ SafepointOperationScope safepoint_scope(t);
+ if (!set_instance_fields()) return false;
+ } else {
+ if (!set_instance_fields()) return false;
+ }
+
+ return CanonicalizeInstance(list, out);
+}
+
+bool FlowGraphDeserializer::ParseType(SExpression* sexp, Object* out) {
+ ASSERT(out != nullptr);
+ if (sexp == nullptr) return false;
+
+ if (auto const sym = sexp->AsSymbol()) {
+ auto const val = ParseValue(sexp, /*allow_pending=*/false);
+ if (val == nullptr) {
+ StoreError(sexp, "expected type or reference to constant definition");
+ return false;
+ }
+ if (!val->BindsToConstant()) {
+ StoreError(sexp, "reference to non-constant definition");
+ return false;
+ }
+ *out = val->BoundConstant().raw();
+ if (!out->IsType()) {
+ StoreError(sexp, "expected Type constant");
+ return false;
+ }
+ return true;
+ }
+ auto const list = CheckTaggedList(sexp, "Type");
+ if (list == nullptr) return false;
+
+ const auto hash_sexp = CheckInteger(list->ExtraLookupValue("hash"));
+ const auto is_recursive = hash_sexp != nullptr;
+ // This isn't necessary the hash value we will have in the new FlowGraph, but
+ // it will be how this type is referred to by TypeRefs in the serialized one.
+ auto const old_hash = is_recursive ? hash_sexp->value() : 0;
+ ZoneGrowableArray<TypeRef*>* pending_typerefs;
+ if (is_recursive) {
+ if (pending_typeref_map_.LookupValue(old_hash) != nullptr) {
+ StoreError(sexp, "already parsing a type with hash %" Pd64 "",
+ hash_sexp->value());
+ return false;
+ }
+ pending_typerefs = new (zone()) ZoneGrowableArray<TypeRef*>(zone(), 2);
+ pending_typeref_map_.Insert(old_hash, pending_typerefs);
+ }
+
+ const auto cls_sexp = CheckTaggedList(Retrieve(list, 1), "Class");
+ if (cls_sexp == nullptr) {
+ // TODO(sstrickl): Handle types not derived from classes.
+ StoreError(list, "non-class types not currently handled");
+ return false;
+ }
+ auto& cls = Class::ZoneHandle(zone());
+ if (!ParseClass(cls_sexp, &cls)) return false;
+ auto& type_args = TypeArguments::ZoneHandle(zone());
+ if (const auto ta_sexp = list->ExtraLookupValue("type_args")) {
+ if (!ParseTypeArguments(ta_sexp, &type_args)) return false;
+ }
+ TokenPosition token_pos = TokenPosition::kNoSource;
+ if (const auto pos_sexp = CheckInteger(list->ExtraLookupValue("token_pos"))) {
+ token_pos = TokenPosition(pos_sexp->value());
+ }
+ *out = Type::New(cls, type_args, token_pos, Heap::kOld);
+ auto& type = Type::Cast(*out);
+ if (auto const sig_sexp = list->ExtraLookupValue("signature")) {
+ auto& function = Function::Handle(zone());
+ if (!ParseDartValue(sig_sexp, &function)) return false;
+ type.set_signature(function);
+ }
+ if (is_recursive) {
+ while (!pending_typerefs->is_empty()) {
+ auto const ref = pending_typerefs->RemoveLast();
+ ASSERT(ref != nullptr);
+ ref->set_type(type);
+ }
+ pending_typeref_map_.Remove(old_hash);
+
+ // If there are still pending typerefs, we can't canonicalize yet until
+ // an enclosing type where we have resolved them. This is a conservative
+ // check, as we do not ensure that any of the still-pending typerefs are
+ // found within this type.
+ //
+ // This is within the is_recursive check because if this type was
+ // non-recursive, then even if there are pending type refs, we are
+ // guaranteed that none of them are in this type.
+ if (ArePendingTypeRefs()) return true;
+ }
+
+ // Need to set this for canonicalization. We ensure in the serializer
+ // that only finalized types are successfully serialized.
+ type.SetIsFinalized();
+ return CanonicalizeInstance(list, out);
+}
+
+bool FlowGraphDeserializer::ParseTypeArguments(SExpression* sexp, Object* out) {
+ ASSERT(out != nullptr);
+ if (sexp == nullptr) return false;
+
+ if (auto const sym = sexp->AsSymbol()) {
+ auto const val = ParseValue(sexp, /*allow_pending=*/false);
+ if (val == nullptr) {
+ StoreError(sexp,
+ "expected type arguments or reference to constant definition");
+ return false;
+ }
+ if (!val->BindsToConstant()) {
+ StoreError(sexp, "reference to non-constant definition");
+ return false;
+ }
+ *out = val->BoundConstant().raw();
+ if (!out->IsTypeArguments()) {
+ StoreError(sexp, "expected TypeArguments constant");
+ return false;
+ }
+ return true;
+ }
+ auto const list = CheckTaggedList(sexp, "TypeArguments");
+ if (list == nullptr) return false;
+
+ *out = TypeArguments::New(list->Length() - 1, Heap::kOld);
+ auto& type_args = TypeArguments::Cast(*out);
+ // We may reenter ParseTypeArguments while parsing one of the elements, so we
+ // need a fresh handle here.
+ auto& elem = AbstractType::Handle(zone());
+ for (intptr_t i = 1, n = list->Length(); i < n; i++) {
+ if (!ParseAbstractType(Retrieve(list, i), &elem)) return false;
+ type_args.SetTypeAt(i - 1, elem);
+ }
+
+ // If there are still pending typerefs, we can't canonicalize yet.
+ if (ArePendingTypeRefs()) return true;
+
+ return CanonicalizeInstance(list, out);
+}
+
+bool FlowGraphDeserializer::ParseTypeParameter(SExpList* list, Object* out) {
+ ASSERT(out != nullptr);
+ if (list == nullptr) return false;
+
+ const Function* function = nullptr;
+ const Class* cls = nullptr;
+ if (auto const func_sexp = CheckSymbol(list->ExtraLookupValue("function"))) {
+ if (!ParseCanonicalName(func_sexp, &type_param_function_)) return false;
+ if (!type_param_function_.IsFunction() || type_param_function_.IsNull()) {
+ StoreError(func_sexp, "not a function name");
+ return false;
+ }
+ function = &type_param_function_;
+ } else if (auto const class_sexp =
+ CheckInteger(list->ExtraLookupValue("class"))) {
+ const intptr_t cid = class_sexp->value();
+ auto const table = thread()->isolate()->class_table();
+ if (!table->HasValidClassAt(cid)) {
+ StoreError(class_sexp, "not a valid class id");
+ return false;
+ }
+ type_param_class_ = table->At(cid);
+ cls = &type_param_class_;
+ } else {
+ ASSERT(parsed_function_ != nullptr);
+ // If we weren't given an explicit source, check in the flow graph's
+ // function and in its owning class.
+ function = &parsed_function_->function();
+ type_param_class_ = function->Owner();
+ cls = &type_param_class_;
+ }
+
+ auto const name_sexp = CheckSymbol(Retrieve(list, 1));
+ if (name_sexp == nullptr) return false;
+ tmp_string_ = String::New(name_sexp->value());
+
+ if (function != nullptr) {
+ *out = function->LookupTypeParameter(tmp_string_, nullptr);
+ }
+ if (cls != nullptr && out->IsNull()) {
+ *out = cls->LookupTypeParameter(tmp_string_);
+ }
+ if (out->IsNull()) {
+ StoreError(name_sexp, "no type parameter found for name");
+ return false;
+ }
+ return CanonicalizeInstance(list, out);
+}
+
+bool FlowGraphDeserializer::ParseTypeRef(SExpList* list, Object* out) {
+ ASSERT(out != nullptr);
+ if (list == nullptr) return false;
+
+ const bool contains_type = list->Length() > 1;
+ if (contains_type) {
+ auto& type = Type::Handle(zone());
+ if (!ParseAbstractType(Retrieve(list, 1), &type)) return false;
+ *out = TypeRef::New(type);
+ // If the TypeRef appears outside the referrent, then the referrent
+ // should be already canonicalized. This serves as a double-check that
+ // is the case.
+ return CanonicalizeInstance(list, out);
+ }
+ // If there is no type in the body, then this must be a referrent to
+ // a Type containing this TypeRef. That means we must have a hash value.
+ auto const hash_sexp = CheckInteger(Retrieve(list, "hash"));
+ if (hash_sexp == nullptr) return false;
+ auto const old_hash = hash_sexp->value();
+ auto const pending = pending_typeref_map_.LookupValue(old_hash);
+ if (pending == nullptr) {
+ StoreError(list, "reference to recursive type found outside type");
+ return false;
+ }
+ *out = TypeRef::New(Object::null_abstract_type());
+ pending->Add(static_cast<TypeRef*>(out));
+
+ // We can only canonicalize TypeRefs appearing within their referrent
+ // when its containing value is canonicalized.
return true;
}
bool FlowGraphDeserializer::ParseCanonicalName(SExpSymbol* sym, Object* obj) {
+ ASSERT(obj != nullptr);
if (sym == nullptr) return false;
auto const name = sym->value();
// TODO(sstrickl): No library URL, handle this better.
@@ -1496,7 +2053,8 @@
ASSERT(!tmp_string_.IsNull());
auto const parent_name = tmp_string_.ToCString();
// ImplicitClosureFunctions (tearoffs) have the same name as the Function
- // to which they are attached. We won't handle any further nesting.
+ // to which they are attached. We currently don't handle any other kinds
+ // of local functions.
if (name_function_.HasImplicitClosureFunction() && *func_end == '\0' &&
strncmp(parent_name, func_start, name_len) == 0) {
*obj = name_function_.ImplicitClosureFunction();
@@ -1506,6 +2064,16 @@
return false;
}
+ // Check for the prefix "<anonymous ..." in the name and fail if found,
+ // since we can't resolve these.
+ static auto const anon_prefix = "<anonymous ";
+ static const intptr_t prefix_len = strlen(anon_prefix);
+ if ((name_len > prefix_len) &&
+ strncmp(anon_prefix, func_start, prefix_len) == 0) {
+ StoreError(sym, "cannot resolve anonymous values");
+ return false;
+ }
+
tmp_string_ = String::FromUTF8(reinterpret_cast<const uint8_t*>(func_start),
name_len);
name_function_ = name_class_.LookupFunctionAllowPrivate(tmp_string_);
@@ -1533,7 +2101,7 @@
}
// Following the lead of BaseFlowGraphBuilder::MayCloneField here.
-const Field& FlowGraphDeserializer::MayCloneField(const Field& field) {
+const Field& FlowGraphDeserializer::MayCloneField(const Field& field) const {
if ((Compiler::IsBackgroundCompilation() ||
FLAG_force_clone_compiler_objects) &&
field.IsOriginal()) {
@@ -1552,7 +2120,7 @@
const auto kind_sexp = CheckSymbol(Retrieve(list, "kind"));
if (kind_sexp == nullptr) return false;
Slot::Kind kind;
- if (!Slot::KindFromCString(kind_sexp->value(), &kind)) {
+ if (!Slot::ParseKind(kind_sexp->value(), &kind)) {
StoreError(kind_sexp, "unknown Slot kind");
return false;
}
@@ -1562,6 +2130,7 @@
auto& field = Field::ZoneHandle(zone());
const auto field_sexp = CheckTaggedList(Retrieve(list, "field"), "Field");
if (!ParseDartValue(field_sexp, &field)) return false;
+ ASSERT(parsed_function_ != nullptr);
*out = &Slot::Get(MayCloneField(field), parsed_function_);
break;
}
@@ -1610,31 +2179,151 @@
return true;
}
-Value* FlowGraphDeserializer::AddNewPendingValue(intptr_t index) {
- ASSERT(flow_graph_ != nullptr);
- auto const val = new (zone()) Value(flow_graph_->constant_null());
- AddPendingValue(index, val);
- return val;
-}
-
-void FlowGraphDeserializer::AddPendingValue(intptr_t index, Value* val) {
- ASSERT(!definition_map_.HasKey(index));
- auto value_list = values_map_.LookupValue(index);
- if (value_list == nullptr) {
- value_list = new (zone()) ZoneGrowableArray<Value*>(zone(), 2);
- values_map_.Insert(index, value_list);
+bool FlowGraphDeserializer::ArePendingTypeRefs() const {
+ // We'll do a deep check, because while there may be recursive types still
+ // being parsed, if there are no pending type refs to those recursive types,
+ // we're still good to canonicalize.
+ if (pending_typeref_map_.IsEmpty()) return false;
+ auto it = pending_typeref_map_.GetIterator();
+ while (auto kv = it.Next()) {
+ if (!kv->value->is_empty()) return true;
}
- value_list->Add(val);
+ return false;
}
-void FlowGraphDeserializer::FixPendingValues(intptr_t index, Definition* def) {
+bool FlowGraphDeserializer::CreateICData(SExpList* list, Instruction* inst) {
+ ASSERT(inst != nullptr);
+ if (list == nullptr) return false;
+
+ const String* function_name = nullptr;
+ Array& arguments_descriptor = Array::Handle(zone());
+ intptr_t num_args_checked;
+ ICData::RebindRule rebind_rule;
+
+ if (auto const call = inst->AsInstanceCall()) {
+ function_name = &call->function_name();
+ arguments_descriptor = call->GetArgumentsDescriptor();
+ num_args_checked = call->checked_argument_count();
+ rebind_rule = ICData::RebindRule::kInstance;
+ } else if (auto const call = inst->AsStaticCall()) {
+ function_name = &String::Handle(zone(), call->function().name());
+ arguments_descriptor = call->GetArgumentsDescriptor();
+ num_args_checked =
+ MethodRecognizer::NumArgsCheckedForStaticCall(call->function());
+ rebind_rule = ICData::RebindRule::kStatic;
+ } else {
+ StoreError(list, "unexpected instruction type for ICData");
+ return false;
+ }
+
+ auto type_ptr = &Object::null_abstract_type();
+ if (auto const type_sexp = list->ExtraLookupValue("receivers_static_type")) {
+ auto& type = AbstractType::ZoneHandle(zone());
+ if (!ParseAbstractType(type_sexp, &type)) return false;
+ type_ptr = &type;
+ }
+
+ ASSERT(parsed_function_ != nullptr);
+ const auto& ic_data = ICData::ZoneHandle(
+ zone(), ICData::New(parsed_function_->function(), *function_name,
+ arguments_descriptor, inst->deopt_id(),
+ num_args_checked, rebind_rule, *type_ptr));
+
+ if (auto const is_mega_sexp =
+ CheckBool(list->ExtraLookupValue("is_megamorphic"))) {
+ ic_data.set_is_megamorphic(is_mega_sexp->value());
+ }
+
+ auto const class_table = thread()->isolate()->class_table();
+ GrowableArray<intptr_t> class_ids(zone(), 2);
+ for (intptr_t i = 1, n = list->Length(); i < n; i++) {
+ auto const entry = CheckList(Retrieve(list, i));
+ if (entry == nullptr) return false;
+ ASSERT(ic_data.NumArgsTested() == entry->Length());
+
+ intptr_t count = 0;
+ if (auto const count_sexp =
+ CheckInteger(entry->ExtraLookupValue("count"))) {
+ count = count_sexp->value();
+ }
+
+ auto& target = Function::ZoneHandle(zone());
+ if (!ParseDartValue(Retrieve(entry, "target"), &target)) return false;
+
+ // We can't use AddCheck for NumArgsTested < 2. We'll handle 0 here, and
+ // 1 after the for loop.
+ if (entry->Length() == 0) {
+ if (count != 0) {
+ StoreError(entry, "expected a zero count for no checked args");
+ return false;
+ }
+ ic_data.AddTarget(target);
+ continue;
+ }
+
+ class_ids.Clear();
+ for (intptr_t j = 0, num_cids = entry->Length(); j < num_cids; j++) {
+ auto const cid_sexp = CheckInteger(Retrieve(entry, j));
+ if (cid_sexp == nullptr) return false;
+ const intptr_t cid = cid_sexp->value();
+ // kObjectCid is a special case used for AddTarget() entries with
+ // a non-zero number of checked arguments.
+ if (cid != kObjectCid && !class_table->HasValidClassAt(cid)) {
+ StoreError(cid_sexp, "cid is not a valid class");
+ return false;
+ }
+ class_ids.Add(cid);
+ }
+
+ if (entry->Length() == 1) {
+ ic_data.AddReceiverCheck(class_ids.At(0), target, count);
+ } else {
+ ic_data.AddCheck(class_ids, target, count);
+ }
+ }
+
+ if (auto const call = inst->AsInstanceCall()) {
+ call->set_ic_data(&ic_data);
+ } else if (auto const call = inst->AsStaticCall()) {
+ call->set_ic_data(&ic_data);
+ }
+
+ return true;
+}
+
+Value* FlowGraphDeserializer::AddNewPendingValue(SExpression* sexp,
+ intptr_t index,
+ bool inherit_type) {
+ ASSERT(flow_graph_ != nullptr);
+ auto const value = new (zone()) Value(flow_graph_->constant_null());
+ ASSERT(!definition_map_.HasKey(index));
+ auto list = values_map_.LookupValue(index);
+ if (list == nullptr) {
+ list = new (zone()) ZoneGrowableArray<PendingValue>(zone(), 2);
+ values_map_.Insert(index, list);
+ }
+ list->Add({sexp, value, inherit_type});
+ return value;
+}
+
+bool FlowGraphDeserializer::FixPendingValues(intptr_t index, Definition* def) {
if (auto value_list = values_map_.LookupValue(index)) {
for (intptr_t i = 0; i < value_list->length(); i++) {
- auto const val = value_list->At(i);
- val->BindTo(def);
+ const auto& value_info = value_list->At(i);
+ auto const value = value_info.value;
+ const bool inherit_type = value_info.inherit_type;
+ value->BindTo(def);
+ if (!inherit_type) continue;
+ if (def->HasType()) {
+ value->reaching_type_ = def->Type();
+ } else {
+ StoreError(value_info.sexp, "value inherits type, but no type found");
+ return false;
+ }
}
values_map_.Remove(index);
}
+ return true;
}
PushArgumentsArray* FlowGraphDeserializer::FetchPushedArguments(SExpList* list,
@@ -1721,7 +2410,7 @@
bool FlowGraphDeserializer::IsTag(SExpression* sexp, const char* label) {
auto const sym = CheckSymbol(sexp);
if (sym == nullptr) return false;
- if (label != nullptr && strcmp(label, sym->value()) != 0) {
+ if (label != nullptr && !sym->Equals(label)) {
StoreError(sym, "expected symbol %s", label);
return false;
}
diff --git a/runtime/vm/compiler/backend/il_deserializer.h b/runtime/vm/compiler/backend/il_deserializer.h
index 2ebb507..2b0040a 100644
--- a/runtime/vm/compiler/backend/il_deserializer.h
+++ b/runtime/vm/compiler/backend/il_deserializer.h
@@ -47,21 +47,23 @@
zone_(ASSERT_NOTNULL(zone)),
root_sexp_(ASSERT_NOTNULL(root)),
parsed_function_(pf),
- block_map_(zone_),
- pushed_stack_map_(zone_),
- definition_map_(zone_),
- values_map_(zone_),
+ block_map_(zone),
+ pushed_stack_map_(zone),
+ definition_map_(zone),
+ values_map_(zone),
+ recursive_types_map_(zone),
+ pending_typeref_map_(zone),
+ array_type_args_(TypeArguments::Handle(zone)),
instance_class_(Class::Handle(zone)),
instance_field_(Field::Handle(zone)),
- instance_object_(Object::Handle(zone)),
+ instance_fields_array_(Array::Handle(zone)),
+ instance_type_args_(TypeArguments::Handle(zone)),
name_class_(Class::Handle(zone)),
name_field_(Field::Handle(zone)),
name_function_(Function::Handle(zone)),
name_library_(Library::Handle(zone)),
- value_class_(Class::Handle(zone)),
- value_object_(Object::Handle(zone)),
- value_type_(AbstractType::Handle(zone)),
- value_type_args_(TypeArguments::Handle(zone)),
+ type_param_class_(Class::Handle(zone)),
+ type_param_function_(Function::Handle(zone)),
tmp_string_(String::Handle(zone)) {
// See canonicalization comment in ParseDartValue as to why this is
// currently necessary.
@@ -86,20 +88,27 @@
#define FOR_EACH_HANDLED_INSTRUCTION_IN_DESERIALIZER(M) \
M(AllocateObject) \
+ M(AssertAssignable) \
+ M(AssertBoolean) \
+ M(BooleanNegate) \
M(Branch) \
M(CheckNull) \
M(CheckStackOverflow) \
M(Constant) \
M(DebugStepCheck) \
M(Goto) \
+ M(InstanceCall) \
+ M(LoadClassId) \
M(LoadField) \
+ M(NativeCall) \
M(Parameter) \
M(PushArgument) \
M(Return) \
M(SpecialParameter) \
M(StaticCall) \
M(StoreInstanceField) \
- M(StrictCompare)
+ M(StrictCompare) \
+ M(Throw)
// Helper methods for AllUnhandledInstructions.
static bool IsHandledInstruction(Instruction* inst);
@@ -214,6 +223,22 @@
#undef HANDLER_DECL
+ // Common information parsed from call instruction S-expressions.
+ struct CallInfo : public ValueObject {
+ explicit CallInfo(Zone* zone) : argument_names(Array::ZoneHandle(zone)) {}
+
+ Array& argument_names;
+ intptr_t type_args_len = 0;
+ intptr_t args_len = 0;
+ PushArgumentsArray* arguments = nullptr;
+ CompileType* result_type = nullptr;
+ Code::EntryKind entry_kind = Code::EntryKind::kNormal;
+ };
+
+ // Helper function for parsing call instructions that returns a structure
+ // of information common to all calls.
+ bool ParseCallInfo(SExpList* call, CallInfo* out);
+
// Parses [sexp] as a value form, that is, either the binding name for
// a definition as a symbol or the form (value <name> { ... }).
// If [allow_pending], then values for definitions not already in the
@@ -235,14 +260,34 @@
// Parses a Dart value and returns a canonicalized result.
bool ParseDartValue(SExpression* sexp, Object* out);
- // Helper function for ParseDartValue for parsing instances.
- // Does not canonicalize (that is currently done in ParseDartValue), so
- // do not call this method directly.
- bool ParseInstance(SExpList* list, Instance* out);
+ // Canonicalizes and replaces the original contents of the handle pointed to
+ // by [inst] if [inst] is an Instance (if not, it trivially succeeds). The
+ // replacement happens whether successful or not. [sexp] is the SExpression
+ // to be used for error reporting.
+ bool CanonicalizeInstance(SExpression* sexp, Object* inst);
+
+ // Helper functions for ParseDartValue for parsing particular type of values.
+ // If necessary, they canonicalize the returned value, and so may be used
+ // directly by other code as well. Helpers that take SExpression* take either
+ // serialized constants or references to constant definitions.
+ //
+ // Due to particulars of operator=() on non-Object values, for a given X,
+ // ParseX takes Object* instead of X* for the out parameter.
+ bool ParseAbstractType(SExpression* sexp, Object* out);
+ bool ParseClass(SExpList* list, Object* out);
+ bool ParseClosure(SExpList* list, Object* out);
+ bool ParseField(SExpList* list, Object* out);
+ bool ParseFunction(SExpList* list, Object* out);
+ bool ParseImmutableList(SExpList* list, Object* out);
+ bool ParseInstance(SExpList* list, Object* out);
+ bool ParseType(SExpression* sexp, Object* out);
+ bool ParseTypeParameter(SExpList* list, Object* out);
+ bool ParseTypeArguments(SExpression* sexp, Object* out);
+ bool ParseTypeRef(SExpList* list, Object* out);
bool ParseCanonicalName(SExpSymbol* sym, Object* out);
- const Field& MayCloneField(const Field& field);
+ const Field& MayCloneField(const Field& field) const;
bool ParseSlot(SExpList* list, const Slot** out);
bool ParseBlockId(SExpSymbol* sym, intptr_t* out);
@@ -250,16 +295,21 @@
bool ParseUse(SExpSymbol* sym, intptr_t* out);
bool ParseSymbolAsPrefixedInt(SExpSymbol* sym, char prefix, intptr_t* out);
+ bool ArePendingTypeRefs() const;
+
+ // Allocates a new ICData structure. [list] is the ICData S-expression, while
+ // [inst] is the Instruction generated from the instruction S-expression
+ // containing [list].
+ bool CreateICData(SExpList* list, Instruction* inst);
+
// Helper function for creating a placeholder value when the definition
- // has not yet been seen.
- Value* AddNewPendingValue(intptr_t index);
+ // with index [i] has not yet been seen. If [inherit_type], then the type of
+ // the definition should be used as the reaching type for the use. [s] is used
+ // for any errors that occur when resolving the pending value.
+ Value* AddNewPendingValue(SExpression* s, intptr_t i, bool inherit_type);
- // Similar helper, but where we already have a created value.
- void AddPendingValue(intptr_t index, Value* val);
-
- // Helper function for rebinding pending values once the definition has
- // been located.
- void FixPendingValues(intptr_t index, Definition* def);
+ // Helper function for rebinding values pending on this definition.
+ bool FixPendingValues(intptr_t index, Definition* def);
// Creates a PushArgumentsArray of size [len] from [pushed_stack_] if there
// are enough and pops the fetched arguments from the stack.
@@ -326,24 +376,46 @@
// Map from variable indexes to definitions.
IntMap<Definition*> definition_map_;
+ // Information needed to handle uses seen prior to their definitions.
+ struct PendingValue {
+ // SExpression used for error reporting.
+ SExpression* sexp;
+ // Value to be rebound once the right definition is found.
+ Value* value;
+ // Whether the type should inherit the type of the found definition.
+ bool inherit_type;
+ };
+
// Map from variable indices to lists of values. The list of values are
// values that were parsed prior to the corresponding definition being found.
- IntMap<ZoneGrowableArray<Value*>*> values_map_;
+ IntMap<ZoneGrowableArray<PendingValue>*> values_map_;
+
+ // Map from hash values to SExpLists. This is used by ParseTypeRef to
+ // determine whether or not the recursive type it refers to is being currently
+ // built. The SExpList can be used to report hash collisions.
+ IntMap<SExpList*> recursive_types_map_;
+
+ // Map from hash values to arrays of TypeRefs. This is used by ParseType and
+ // ParseTypeRef to store and later fill in TypeRefs pending on the type being
+ // constructed. Since entries are added at the start of parsing recursive
+ // Type S-exps and removed before the resulting Type is successfully returned,
+ // this map should be empty outside of parsing recursive types.
+ IntMap<ZoneGrowableArray<TypeRef*>*> pending_typeref_map_;
// Temporary handles used by functions that are not re-entrant or where the
// handle is not live after the re-entrant call. Comments show which handles
// are expected to only be used within a single method.
- Class& instance_class_; // ParseInstance
- Field& instance_field_; // ParseInstance
- Object& instance_object_; // ParseInstance
- Class& name_class_; // ParseCanonicalName
- Field& name_field_; // ParseCanonicalName
- Function& name_function_; // ParseCanonicalName
- Library& name_library_; // ParseCanonicalName
- Class& value_class_; // ParseDartValue
- Object& value_object_; // ParseDartValue
- AbstractType& value_type_; // ParseDartValue
- TypeArguments& value_type_args_; // ParseDartValue
+ TypeArguments& array_type_args_; // ParseImmutableList
+ Class& instance_class_; // ParseInstance
+ Field& instance_field_; // ParseInstance
+ Array& instance_fields_array_; // ParseInstance
+ TypeArguments& instance_type_args_; // ParseInstance
+ Class& name_class_; // ParseCanonicalName
+ Field& name_field_; // ParseCanonicalName
+ Function& name_function_; // ParseCanonicalName
+ Library& name_library_; // ParseCanonicalName
+ Class& type_param_class_; // ParseTypeParameter
+ Function& type_param_function_; // ParseTypeParameter
// Uses of string handles tend to be immediate, so we only need one.
String& tmp_string_;
diff --git a/runtime/vm/compiler/backend/il_ia32.cc b/runtime/vm/compiler/backend/il_ia32.cc
index 72bc6b3..a290225 100644
--- a/runtime/vm/compiler/backend/il_ia32.cc
+++ b/runtime/vm/compiler/backend/il_ia32.cc
@@ -392,7 +392,9 @@
compiler->GenerateRuntimeCall(token_pos, deopt_id,
kNonBoolTypeErrorRuntimeEntry, 1, locs);
// We should never return here.
+#if defined(DEBUG)
__ int3();
+#endif
__ Bind(&done);
}
@@ -2761,10 +2763,9 @@
void CatchBlockEntryInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
__ Bind(compiler->GetJumpLabel(this));
- compiler->AddExceptionHandler(catch_try_index(), try_index(),
- compiler->assembler()->CodeSize(),
- handler_token_pos(), is_generated(),
- catch_handler_types_, needs_stacktrace());
+ compiler->AddExceptionHandler(
+ catch_try_index(), try_index(), compiler->assembler()->CodeSize(),
+ is_generated(), catch_handler_types_, needs_stacktrace());
// On lazy deoptimization we patch the optimized code here to enter the
// deoptimization stub.
const intptr_t deopt_id = DeoptId::ToDeoptAfter(GetDeoptId());
diff --git a/runtime/vm/compiler/backend/il_printer.cc b/runtime/vm/compiler/backend/il_printer.cc
index 0dd6d6b..c8166bc 100644
--- a/runtime/vm/compiler/backend/il_printer.cc
+++ b/runtime/vm/compiler/backend/il_printer.cc
@@ -345,9 +345,7 @@
range_->PrintTo(f);
}
- if (type_ != NULL &&
- ((type_->ToNullableCid() != kDynamicCid) ||
- !type_->ToAbstractType()->IsDynamicType() || !type_->is_nullable())) {
+ if (type_ != NULL) {
f->Print(" ");
type_->PrintTo(f);
}
@@ -676,6 +674,11 @@
f->Print(" . %s%s", slot().Name(), slot().is_immutable() ? " {final}" : "");
}
+void LoadUntaggedInstr::PrintOperandsTo(BufferFormatter* f) const {
+ object()->PrintTo(f);
+ f->Print(", %" Pd, offset());
+}
+
void InstantiateTypeInstr::PrintOperandsTo(BufferFormatter* f) const {
const String& type_name = String::Handle(type().Name());
f->Print("%s,", type_name.ToCString());
diff --git a/runtime/vm/compiler/backend/il_serializer.cc b/runtime/vm/compiler/backend/il_serializer.cc
index 5369159..1ab17fd 100644
--- a/runtime/vm/compiler/backend/il_serializer.cc
+++ b/runtime/vm/compiler/backend/il_serializer.cc
@@ -268,6 +268,9 @@
AddSymbol(sexp, "FlowGraph");
sexp->Add(CanonicalNameToSExp(flow_graph()->function()));
AddExtraInteger(sexp, "deopt_id", start->deopt_id());
+ if (start->env() != nullptr) {
+ sexp->AddExtra("env", start->env()->ToSExpression(this));
+ }
if (start->IsCompiledForOsr()) {
AddExtraInteger(sexp, "osr_id", start->osr_id());
}
@@ -325,8 +328,7 @@
static bool ShouldSerializeType(CompileType* type) {
return (FLAG_verbose_flow_graph_serialization ||
FLAG_serialize_flow_graph_types) &&
- type != NULL &&
- (type->ToNullableCid() != kDynamicCid || !type->is_nullable());
+ type != nullptr;
}
SExpression* FlowGraphSerializer::FieldToSExp(const Field& field) {
@@ -343,19 +345,55 @@
SExpression* FlowGraphSerializer::AbstractTypeToSExp(const AbstractType& t) {
if (t.IsNull()) return nullptr;
+ ASSERT(t.IsFinalized());
auto sexp = new (zone()) SExpList(zone());
if (t.IsTypeParameter()) {
const auto& param = TypeParameter::Cast(t);
AddSymbol(sexp, "TypeParameter");
tmp_string_ = param.name();
AddSymbol(sexp, tmp_string_.ToCString());
+ if (param.IsFunctionTypeParameter()) {
+ if (param.parameterized_function() != flow_graph_->function().raw()) {
+ type_function_ = param.parameterized_function();
+ sexp->AddExtra("function", CanonicalNameToSExp(type_function_));
+ } else if (FLAG_verbose_flow_graph_serialization) {
+ sexp->AddExtra("function",
+ CanonicalNameToSExp(flow_graph_->function()));
+ }
+ } else if (param.IsClassTypeParameter()) {
+ if (param.parameterized_class() != flow_graph_->function().Owner()) {
+ type_class_ = param.parameterized_class();
+ AddExtraInteger(sexp, "class", type_class_.id());
+ } else if (FLAG_verbose_flow_graph_serialization) {
+ type_class_ = flow_graph_->function().Owner();
+ AddExtraInteger(sexp, "class", type_class_.id());
+ }
+ }
return sexp;
}
if (t.IsTypeRef()) {
const auto& ref = TypeRef::Cast(t);
AddSymbol(sexp, "TypeRef");
type_ref_type_ = ref.type();
- AddExtraInteger(sexp, "hash", type_ref_type_.Hash());
+ auto const hash = type_ref_type_.Hash();
+ // Check to see if this is a TypeRef to a type we're currently serializing.
+ // If it is not, then we need to serialize the underlying type, as it
+ // otherwise won't be available when deserializing.
+ auto const open_type = open_recursive_types_.LookupValue(hash);
+ if (open_type == nullptr) {
+ // Allocate a new handle as we may re-enter the TypeRef branch.
+ auto& type = AbstractType::Handle(zone(), ref.type());
+ sexp->Add(AbstractTypeToSExp(type));
+ // If we serialized the referrent, then we don't need this information,
+ // but it may be useful for debugging so add it in verbose mode.
+ if (FLAG_verbose_flow_graph_serialization) {
+ AddExtraInteger(sexp, "hash", hash);
+ }
+ } else {
+ // Make sure we didn't have a hash collision.
+ ASSERT(open_type->Equals(type_ref_type_));
+ AddExtraInteger(sexp, "hash", hash);
+ }
if (FLAG_verbose_flow_graph_serialization) {
AddExtraString(sexp, "type", type_ref_type_.ToCString());
}
@@ -363,28 +401,43 @@
}
ASSERT(t.IsType());
AddSymbol(sexp, "Type");
- const auto& typ = Type::Cast(t);
- ASSERT(typ.IsFinalized());
- if (typ.HasTypeClass()) {
- type_class_ = typ.type_class();
+ const auto& type = Type::Cast(t);
+ if (!type.token_pos().IsNoSource()) {
+ AddExtraInteger(sexp, "token_pos", type.token_pos().value());
+ }
+ // We want to check for the type being recursive before we may serialize
+ // any sub-parts that include possible TypeRefs to this type.
+ const bool is_recursive = type.IsRecursive();
+ intptr_t hash = 0;
+ if (is_recursive) {
+ hash = type.Hash();
+ AddExtraInteger(sexp, "hash", hash);
+ open_recursive_types_.Insert(hash, &type);
+ }
+ if (type.HasTypeClass()) {
+ type_class_ = type.type_class();
// This avoids re-entry as long as serializing a class doesn't involve
// serializing concrete (non-parameter, non-reference) types.
sexp->Add(DartValueToSExp(type_class_));
- if (typ.IsRecursive()) {
- AddExtraInteger(sexp, "hash", typ.Hash());
- }
- // Since type arguments may themselves be instantiations of generic
- // classes, we may call back into this function in the middle of printing
- // the TypeArguments and so we must allocate a fresh handle here.
- const auto& args = TypeArguments::Handle(zone(), typ.arguments());
- if (auto const args_sexp = NonEmptyTypeArgumentsToSExp(args)) {
- sexp->AddExtra("type_args", args_sexp);
- }
} else {
// TODO(dartbug.com/36882): Actually structure non-class types instead of
// just printing out this version.
- AddString(sexp, typ.ToCString());
+ AddExtraString(sexp, "name", type.ToCString());
}
+ if (type.IsFunctionType()) {
+ type_function_ = type.signature();
+ sexp->AddExtra("signature", DartValueToSExp(type_function_));
+ }
+ // Since type arguments may themselves be instantiations of generic
+ // types, we may call back into this function in the middle of printing
+ // the TypeArguments and so we must allocate a fresh handle here.
+ const auto& args = TypeArguments::Handle(zone(), type.arguments());
+ if (auto const args_sexp = NonEmptyTypeArgumentsToSExp(args)) {
+ sexp->AddExtra("type_args", args_sexp);
+ }
+ // If we were parsing a recursive type, we're now done building it, so
+ // remove it from the open recursive types.
+ if (is_recursive) open_recursive_types_.Remove(hash);
return sexp;
}
@@ -422,6 +475,9 @@
type_arguments_elem_ = ta.TypeAt(i);
sexp->Add(DartValueToSExp(type_arguments_elem_));
}
+ if (FLAG_verbose_flow_graph_serialization && ta.IsRecursive()) {
+ AddExtraInteger(sexp, "hash", ta.Hash());
+ }
return sexp;
}
@@ -634,15 +690,19 @@
AddSymbol(constant_list, "Constants");
for (intptr_t i = 0; i < initial_defs->length(); i++) {
ASSERT(initial_defs->At(i)->IsConstant());
- ConstantInstr* value = initial_defs->At(i)->AsConstant();
+ auto const definition = initial_defs->At(i)->AsDefinition();
auto elem = new (zone()) SExpList(zone());
AddSymbol(elem, "def");
- elem->Add(UseToSExp(value->AsDefinition()));
+ elem->Add(UseToSExp(definition));
// Use ObjectToSExp here, not DartValueToSExp!
- elem->Add(ObjectToSExp(value->value()));
- if (ShouldSerializeType(value->AsDefinition()->Type())) {
- auto const val = value->AsDefinition()->Type()->ToSExpression(this);
- elem->AddExtra("type", val);
+ elem->Add(ObjectToSExp(definition->AsConstant()->value()));
+ // Check this first, otherwise Type() can have the side effect of setting
+ // a new CompileType!
+ if (definition->HasType()) {
+ auto const type = definition->Type();
+ if (ShouldSerializeType(type)) {
+ elem->AddExtra("type", type->ToSExpression(this));
+ }
}
constant_list->Add(elem);
}
@@ -721,6 +781,9 @@
if (env() != nullptr) {
sexp->AddExtra("env", env()->ToSExpression(s));
}
+ if (!token_pos().IsNoSource()) {
+ s->AddExtraInteger(sexp, "token_pos", token_pos().value());
+ }
}
SExpression* Definition::ToSExpression(FlowGraphSerializer* s) const {
@@ -737,6 +800,14 @@
return sexp;
}
+void AssertAssignableInstr::AddExtraInfoToSExpression(
+ SExpList* sexp,
+ FlowGraphSerializer* s) const {
+ Instruction::AddExtraInfoToSExpression(sexp, s);
+ sexp->AddExtra("type", s->DartValueToSExp(dst_type()));
+ sexp->AddExtra("name", s->DartValueToSExp(dst_name()));
+}
+
void ConstantInstr::AddOperandsToSExpression(SExpList* sexp,
FlowGraphSerializer* s) const {
sexp->Add(s->DartValueToSExp(value()));
@@ -811,6 +882,7 @@
void StoreInstanceFieldInstr::AddExtraInfoToSExpression(
SExpList* sexp,
FlowGraphSerializer* s) const {
+ Instruction::AddExtraInfoToSExpression(sexp, s);
if (is_initialization_ || FLAG_verbose_flow_graph_serialization) {
s->AddExtraBool(sexp, "is_init", is_initialization_);
}
@@ -882,6 +954,7 @@
void DebugStepCheckInstr::AddExtraInfoToSExpression(
SExpList* sexp,
FlowGraphSerializer* s) const {
+ Instruction::AddExtraInfoToSExpression(sexp, s);
if (stub_kind_ != RawPcDescriptors::kAnyKind ||
FLAG_verbose_flow_graph_serialization) {
auto const stub_kind_name = RawPcDescriptors::KindToCString(stub_kind_);
@@ -890,6 +963,54 @@
}
}
+SExpression* FlowGraphSerializer::ICDataToSExp(const ICData* ic_data) {
+ auto const sexp = new (zone()) SExpList(zone());
+ AddSymbol(sexp, "ICData");
+
+ if (ic_data->is_tracking_exactness()) {
+ ic_data_type_ = ic_data->receivers_static_type();
+ sexp->AddExtra("receivers_static_type", AbstractTypeToSExp(ic_data_type_));
+ }
+
+ if (ic_data->is_megamorphic() || FLAG_verbose_flow_graph_serialization) {
+ AddExtraBool(sexp, "is_megamorphic", ic_data->is_megamorphic());
+ }
+
+ auto const num_checks = ic_data->NumberOfChecks();
+ GrowableArray<intptr_t> class_ids(zone(), 2);
+ for (intptr_t i = 0; i < num_checks; i++) {
+ auto const entry = new (zone()) SExpList(zone());
+
+ auto const count = ic_data->GetCountAt(i);
+ if (count > 0 || FLAG_verbose_flow_graph_serialization) {
+ AddExtraInteger(entry, "count", count);
+ }
+
+ class_ids.Clear();
+ ic_data->GetCheckAt(i, &class_ids, &ic_data_target_);
+ entry->AddExtra("target", DartValueToSExp(ic_data_target_));
+ for (auto const cid : class_ids) {
+ entry->Add(new (zone()) SExpInteger(cid));
+ }
+
+ sexp->Add(entry);
+ }
+
+ if (FLAG_verbose_flow_graph_serialization) {
+ AddExtraSymbol(sexp, "rebind_rule",
+ ICData::RebindRuleToCString(ic_data->rebind_rule()));
+ tmp_string_ = ic_data->target_name();
+ AddExtraString(sexp, "target_name", tmp_string_.ToCString());
+ ic_data_target_ = ic_data->Owner();
+ sexp->AddExtra("owner", DartValueToSExp(ic_data_target_));
+ AddExtraInteger(sexp, "num_args_tested", ic_data->NumArgsTested());
+ auto& args_desc = Array::Handle(zone(), ic_data->arguments_descriptor());
+ sexp->AddExtra("arguments_descriptor", DartValueToSExp(args_desc));
+ }
+
+ return sexp;
+}
+
void TailCallInstr::AddOperandsToSExpression(SExpList* sexp,
FlowGraphSerializer* s) const {
if (auto const code = s->DartValueToSExp(code_)) {
@@ -905,6 +1026,17 @@
}
}
+void NativeCallInstr::AddExtraInfoToSExpression(SExpList* sexp,
+ FlowGraphSerializer* s) const {
+ TemplateDartCall<0>::AddExtraInfoToSExpression(sexp, s);
+ if (!native_name().IsNull()) {
+ s->AddExtraString(sexp, "name", native_name().ToCString());
+ }
+ if (link_lazily() || FLAG_verbose_flow_graph_serialization) {
+ s->AddExtraBool(sexp, "link_lazily", link_lazily());
+ }
+}
+
template <intptr_t kInputCount>
void TemplateDartCall<kInputCount>::AddExtraInfoToSExpression(
SExpList* sexp,
@@ -914,9 +1046,7 @@
s->AddExtraInteger(sexp, "type_args_len", type_args_len());
}
s->AddExtraInteger(sexp, "args_len", ArgumentCountWithoutTypeArgs());
- if (this->CallCount() > 0 || FLAG_verbose_flow_graph_serialization) {
- s->AddExtraInteger(sexp, "call_count", this->CallCount());
- }
+
const auto& arg_names = argument_names();
if (!arg_names.IsNull()) {
auto arg_names_sexp = new (s->zone()) SExpList(s->zone());
@@ -947,12 +1077,28 @@
FlowGraphSerializer* s) const {
TemplateDartCall<0>::AddExtraInfoToSExpression(sexp, s);
- if (rebind_rule_ != ICData::kInstance ||
+ if (HasICData()) {
+ sexp->AddExtra("ic_data", s->ICDataToSExp(ic_data()));
+ } else if (CallCount() > 0 || FLAG_verbose_flow_graph_serialization) {
+ s->AddExtraInteger(sexp, "call_count", CallCount());
+ }
+
+ if (rebind_rule_ != ICData::kStatic ||
FLAG_verbose_flow_graph_serialization) {
auto const str = ICData::RebindRuleToCString(rebind_rule_);
ASSERT(str != nullptr);
s->AddExtraSymbol(sexp, "rebind_rule", str);
}
+
+ if (ShouldSerializeType(result_type())) {
+ sexp->AddExtra("result_type", result_type()->ToSExpression(s));
+ }
+
+ if (entry_kind() != Code::EntryKind::kNormal ||
+ FLAG_verbose_flow_graph_serialization) {
+ auto const kind_str = Code::EntryKindToCString(entry_kind());
+ s->AddExtraSymbol(sexp, "entry_kind", kind_str);
+ }
}
void InstanceCallInstr::AddOperandsToSExpression(SExpList* sexp,
@@ -962,17 +1108,54 @@
}
}
+void InstanceCallInstr::AddExtraInfoToSExpression(
+ SExpList* sexp,
+ FlowGraphSerializer* s) const {
+ TemplateDartCall<0>::AddExtraInfoToSExpression(sexp, s);
+
+ if (HasICData()) {
+ sexp->AddExtra("ic_data", s->ICDataToSExp(ic_data()));
+ }
+
+ if (function_name().IsNull()) {
+ if (!interface_target().IsNull()) {
+ s->AddExtraSymbol(sexp, "function_name", "null");
+ }
+ } else {
+ if (interface_target().IsNull() ||
+ function_name().raw() != interface_target().name()) {
+ s->AddExtraString(sexp, "function_name", function_name().ToCString());
+ }
+ }
+
+ if (token_kind() != Token::kILLEGAL) {
+ s->AddExtraSymbol(sexp, "token_kind", Token::Str(token_kind()));
+ }
+ if (checked_argument_count() > 0 || FLAG_verbose_flow_graph_serialization) {
+ s->AddExtraInteger(sexp, "checked_arg_count", checked_argument_count());
+ }
+
+ if (ShouldSerializeType(result_type())) {
+ sexp->AddExtra("result_type", result_type()->ToSExpression(s));
+ }
+
+ if (entry_kind() != Code::EntryKind::kNormal ||
+ FLAG_verbose_flow_graph_serialization) {
+ auto const kind_str = Code::EntryKindToCString(entry_kind());
+ s->AddExtraSymbol(sexp, "entry_kind", kind_str);
+ }
+}
+
void PolymorphicInstanceCallInstr::AddOperandsToSExpression(
SExpList* sexp,
FlowGraphSerializer* s) const {
- instance_call()->AddOperandsToSExpression(sexp, s);
+ sexp->Add(instance_call()->ToSExpression(s));
}
void PolymorphicInstanceCallInstr::AddExtraInfoToSExpression(
SExpList* sexp,
FlowGraphSerializer* s) const {
- ASSERT(deopt_id() == instance_call()->deopt_id());
- instance_call()->AddExtraInfoToSExpression(sexp, s);
+ Instruction::AddExtraInfoToSExpression(sexp, s);
if (targets().length() > 0 || FLAG_verbose_flow_graph_serialization) {
auto elem_list = new (s->zone()) SExpList(s->zone());
for (intptr_t i = 0; i < targets().length(); i++) {
@@ -1109,45 +1292,52 @@
SExpression* Value::ToSExpression(FlowGraphSerializer* s) const {
auto name = s->UseToSExp(definition());
- if (reaching_type_ == nullptr || reaching_type_ == definition()->type_ ||
- !ShouldSerializeType(reaching_type_)) {
- return name;
- }
+ // If we're not serializing types or there is no reaching type for this use,
+ // just serialize the use as the bound name.
+ if (!ShouldSerializeType(reaching_type_)) return name;
+
auto sexp = new (s->zone()) SExpList(s->zone());
s->AddSymbol(sexp, "value");
sexp->Add(name);
- sexp->AddExtra("type", reaching_type_->ToSExpression(s));
+ // If there is no owner for the type, then serialize the type in full.
+ // Otherwise the owner should be the definition, so we'll inherit the type
+ // from it. (That is, (value v<X>) with no explicit type info means the
+ // reaching type comes from the definition of v<X>.) We'll serialize an
+ // "inherit_type" extra info field to make this explicit when in verbose mode.
+ if (reaching_type_->owner() == nullptr) {
+ sexp->AddExtra("type", reaching_type_->ToSExpression(s));
+ } else {
+ ASSERT(reaching_type_->owner() == definition());
+ }
+ if (FLAG_verbose_flow_graph_serialization) {
+ s->AddExtraBool(sexp, "inherit_type",
+ reaching_type_->owner() == definition());
+ }
return sexp;
}
SExpression* CompileType::ToSExpression(FlowGraphSerializer* s) const {
ASSERT(FLAG_verbose_flow_graph_serialization ||
FLAG_serialize_flow_graph_types);
- ASSERT(cid_ != kDynamicCid || !is_nullable());
auto sexp = new (s->zone()) SExpList(s->zone());
s->AddSymbol(sexp, "CompileType");
- if (cid_ != kIllegalCid && cid_ != kDynamicCid) {
- s->AddInteger(sexp, cid_);
- }
AddExtraInfoToSExpression(sexp, s);
return sexp;
}
void CompileType::AddExtraInfoToSExpression(SExpList* sexp,
FlowGraphSerializer* s) const {
+ if (cid_ != kIllegalCid || FLAG_verbose_flow_graph_serialization) {
+ s->AddExtraInteger(sexp, "cid", cid_);
+ }
// TODO(sstrickl): Currently we only print out nullable if it's false
// (or during verbose printing). Switch this when NNBD is the standard.
if (!is_nullable() || FLAG_verbose_flow_graph_serialization) {
s->AddExtraBool(sexp, "nullable", is_nullable());
}
- if (cid_ == kIllegalCid || cid_ == kDynamicCid ||
- FLAG_verbose_flow_graph_serialization) {
- if (type_ != nullptr) {
- sexp->AddExtra("type", s->DartValueToSExp(*type_));
- } else {
- s->AddExtraString(sexp, "name", ToCString());
- }
+ if (type_ != nullptr) {
+ sexp->AddExtra("type", s->DartValueToSExp(*type_));
}
}
diff --git a/runtime/vm/compiler/backend/il_serializer.h b/runtime/vm/compiler/backend/il_serializer.h
index 753ce49..94945e0 100644
--- a/runtime/vm/compiler/backend/il_serializer.h
+++ b/runtime/vm/compiler/backend/il_serializer.h
@@ -95,6 +95,7 @@
// Methods for serializing IL-specific values.
SExpression* LocalVariableToSExp(const LocalVariable& v);
SExpression* SlotToSExp(const Slot& s);
+ SExpression* ICDataToSExp(const ICData* ic_data);
// Helper methods for adding atoms to S-expression lists
void AddBool(SExpList* sexp, bool b);
@@ -110,6 +111,7 @@
FlowGraphSerializer(Zone* zone, const FlowGraph* flow_graph)
: flow_graph_(ASSERT_NOTNULL(flow_graph)),
zone_(zone),
+ open_recursive_types_(zone_),
tmp_string_(String::Handle(zone_)),
array_type_args_((TypeArguments::Handle(zone_))),
closure_context_(Context::Handle(zone_)),
@@ -119,6 +121,8 @@
context_parent_(Context::Handle(zone_)),
context_elem_(Object::Handle(zone_)),
function_type_args_(TypeArguments::Handle(zone_)),
+ ic_data_target_(Function::Handle(zone_)),
+ ic_data_type_(AbstractType::Handle(zone_)),
instance_field_(Field::Handle(zone_)),
instance_type_args_(TypeArguments::Handle(zone_)),
serialize_library_(Library::Handle(zone_)),
@@ -126,6 +130,7 @@
serialize_parent_(Function::Handle(zone_)),
type_arguments_elem_(AbstractType::Handle(zone_)),
type_class_(Class::Handle(zone_)),
+ type_function_(Function::Handle(zone_)),
type_ref_type_(AbstractType::Handle(zone_)) {
// Double-check that the zone in the flow graph is a parent of the
// zone we'll be using for serialization.
@@ -143,6 +148,10 @@
const FlowGraph* const flow_graph_;
Zone* const zone_;
+ // A map of currently open (being serialized) recursive types. We use this
+ // to determine whether to serialize the referred types in TypeRefs.
+ IntMap<const Type*> open_recursive_types_;
+
// Handles used across functions, where the contained value is used
// immediately and does not need to live across calls to other serializer
// functions.
@@ -165,6 +174,8 @@
Context& context_parent_; // ContextToSExp
Object& context_elem_; // ContextToSExp
TypeArguments& function_type_args_; // FunctionToSExp
+ Function& ic_data_target_; // ICDataToSExp
+ AbstractType& ic_data_type_; // ICDataToSExp
Field& instance_field_; // InstanceToSExp
TypeArguments& instance_type_args_; // InstanceToSExp
Library& serialize_library_; // SerializeCanonicalName
@@ -172,6 +183,7 @@
Function& serialize_parent_; // SerializeCanonicalName
AbstractType& type_arguments_elem_; // TypeArgumentsToSExp
Class& type_class_; // AbstractTypeToSExp
+ Function& type_function_; // AbstractTypeToSExp
AbstractType& type_ref_type_; // AbstractTypeToSExp
};
diff --git a/runtime/vm/compiler/backend/il_test_helper.cc b/runtime/vm/compiler/backend/il_test_helper.cc
index bdc039a..9570fc9 100644
--- a/runtime/vm/compiler/backend/il_test_helper.cc
+++ b/runtime/vm/compiler/backend/il_test_helper.cc
@@ -46,8 +46,10 @@
void Invoke(const Library& lib, const char* name) {
// These tests rely on running unoptimized code to collect type feedback. The
- // interpreter does not collect type feedback for interface calls.
- SetFlagScope<bool> sfs(&FLAG_enable_interpreter, false);
+ // interpreter does not collect type feedback for interface calls, so set
+ // compilation threshold to 0 in order to compile invoked function
+ // immediately and execute compiled code.
+ SetFlagScope<int> sfs(&FLAG_compilation_counter_threshold, 0);
Thread* thread = Thread::Current();
Dart_Handle api_lib = Api::NewHandle(thread, lib.raw());
diff --git a/runtime/vm/compiler/backend/il_test_helper.h b/runtime/vm/compiler/backend/il_test_helper.h
index 019b0d5..bdb7be1 100644
--- a/runtime/vm/compiler/backend/il_test_helper.h
+++ b/runtime/vm/compiler/backend/il_test_helper.h
@@ -242,12 +242,11 @@
ConstantInstr* IntConstant(int64_t value) const {
return flow_graph_.GetConstant(
- Integer::Handle(Integer::New(value, Heap::kOld)));
+ Integer::Handle(Integer::NewCanonical(value)));
}
ConstantInstr* DoubleConstant(double value) {
- return flow_graph_.GetConstant(
- Double::Handle(Double::New(value, Heap::kOld)));
+ return flow_graph_.GetConstant(Double::Handle(Double::NewCanonical(value)));
}
PhiInstr* Phi(JoinEntryInstr* join,
diff --git a/runtime/vm/compiler/backend/il_x64.cc b/runtime/vm/compiler/backend/il_x64.cc
index c7612ed..b7cf98f 100644
--- a/runtime/vm/compiler/backend/il_x64.cc
+++ b/runtime/vm/compiler/backend/il_x64.cc
@@ -521,7 +521,9 @@
compiler->GenerateRuntimeCall(token_pos, deopt_id,
kNonBoolTypeErrorRuntimeEntry, 1, locs);
// We should never return here.
+#if defined(DEBUG)
__ int3();
+#endif
__ Bind(&done);
}
@@ -2893,10 +2895,9 @@
void CatchBlockEntryInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
__ Bind(compiler->GetJumpLabel(this));
- compiler->AddExceptionHandler(catch_try_index(), try_index(),
- compiler->assembler()->CodeSize(),
- handler_token_pos(), is_generated(),
- catch_handler_types_, needs_stacktrace());
+ compiler->AddExceptionHandler(
+ catch_try_index(), try_index(), compiler->assembler()->CodeSize(),
+ is_generated(), catch_handler_types_, needs_stacktrace());
// On lazy deoptimization we patch the optimized code here to enter the
// deoptimization stub.
const intptr_t deopt_id = DeoptId::ToDeoptAfter(GetDeoptId());
diff --git a/runtime/vm/compiler/backend/sexpression.cc b/runtime/vm/compiler/backend/sexpression.cc
index a314abf..241361e 100644
--- a/runtime/vm/compiler/backend/sexpression.cc
+++ b/runtime/vm/compiler/backend/sexpression.cc
@@ -30,8 +30,12 @@
}
bool SExpBool::Equals(SExpression* sexp) const {
- if (!sexp->IsBool()) return false;
- return this->value() == sexp->AsBool()->value();
+ if (auto const b = sexp->AsBool()) return b->Equals(value());
+ return false;
+}
+
+bool SExpBool::Equals(bool val) const {
+ return value() == val;
}
void SExpBool::SerializeToLine(TextBuffer* buffer) const {
@@ -40,8 +44,12 @@
}
bool SExpDouble::Equals(SExpression* sexp) const {
- if (!sexp->IsDouble()) return false;
- return this->value() == sexp->AsDouble()->value();
+ if (auto const d = sexp->AsDouble()) return d->Equals(value());
+ return false;
+}
+
+bool SExpDouble::Equals(double val) const {
+ return value() == val;
}
void SExpDouble::SerializeToLine(TextBuffer* buffer) const {
@@ -53,8 +61,12 @@
}
bool SExpInteger::Equals(SExpression* sexp) const {
- if (!sexp->IsInteger()) return false;
- return this->value() == sexp->AsInteger()->value();
+ if (auto const i = sexp->AsInteger()) return i->Equals(value());
+ return false;
+}
+
+bool SExpInteger::Equals(int64_t val) const {
+ return value() == val;
}
void SExpInteger::SerializeToLine(TextBuffer* buffer) const {
@@ -62,8 +74,12 @@
}
bool SExpString::Equals(SExpression* sexp) const {
- if (!sexp->IsString()) return false;
- return strcmp(this->value(), sexp->AsString()->value()) == 0;
+ if (auto const s = sexp->AsString()) return s->Equals(value());
+ return false;
+}
+
+bool SExpString::Equals(const char* str) const {
+ return strcmp(value(), str) == 0;
}
void SExpString::SerializeToLine(TextBuffer* buffer) const {
@@ -73,8 +89,12 @@
}
bool SExpSymbol::Equals(SExpression* sexp) const {
- if (!sexp->IsSymbol()) return false;
- return strcmp(this->value(), sexp->AsSymbol()->value()) == 0;
+ if (auto const s = sexp->AsSymbol()) return s->Equals(value());
+ return false;
+}
+
+bool SExpSymbol::Equals(const char* str) const {
+ return strcmp(value(), str) == 0;
}
void SExpSymbol::SerializeToLine(TextBuffer* buffer) const {
diff --git a/runtime/vm/compiler/backend/sexpression.h b/runtime/vm/compiler/backend/sexpression.h
index 4a7d67e..d1dfe7e 100644
--- a/runtime/vm/compiler/backend/sexpression.h
+++ b/runtime/vm/compiler/backend/sexpression.h
@@ -115,6 +115,7 @@
: SExpAtom(start), val_(val) {} \
value_type value() const { return val_; } \
virtual bool Equals(SExpression* sexp) const; \
+ bool Equals(value_type val) const; \
virtual void SerializeToLine(TextBuffer* buffer) const; \
DEFINE_S_EXPRESSION_TYPE_CHECK(name) \
private: \
@@ -149,6 +150,13 @@
return extra_info_.LookupValue(cstr);
}
+ // Shortcut for retrieving the tag from a tagged list (list that contains an
+ // initial symbol). Returns nullptr if the list is not a tagged list.
+ SExpSymbol* Tag() const {
+ if (Length() == 0 || !At(0)->IsSymbol()) return nullptr;
+ return At(0)->AsSymbol();
+ }
+
DEFINE_S_EXPRESSION_TYPE_CHECK(List)
virtual bool Equals(SExpression* sexp) const;
virtual void SerializeTo(Zone* zone,
diff --git a/runtime/vm/compiler/backend/slot.cc b/runtime/vm/compiler/backend/slot.cc
index d928420..4a26aa7 100644
--- a/runtime/vm/compiler/backend/slot.cc
+++ b/runtime/vm/compiler/backend/slot.cc
@@ -68,7 +68,7 @@
}
}
-bool Slot::KindFromCString(const char* str, Kind* out) {
+bool Slot::ParseKind(const char* str, Kind* out) {
ASSERT(str != nullptr && out != nullptr);
#define NATIVE_CASE(C, F, id, M) \
if (strcmp(str, NATIVE_TO_STR(C, F, id, M)) == 0) { \
diff --git a/runtime/vm/compiler/backend/slot.h b/runtime/vm/compiler/backend/slot.h
index 361532b..da23fbd 100644
--- a/runtime/vm/compiler/backend/slot.h
+++ b/runtime/vm/compiler/backend/slot.h
@@ -103,7 +103,7 @@
// clang-format on
static const char* KindToCString(Kind k);
- static bool KindFromCString(const char* str, Kind* k);
+ static bool ParseKind(const char* str, Kind* k);
// Returns a slot that represents length field for the given [array_cid].
static const Slot& GetLengthFieldForArrayCid(intptr_t array_cid);
diff --git a/runtime/vm/compiler/frontend/base_flow_graph_builder.cc b/runtime/vm/compiler/frontend/base_flow_graph_builder.cc
index 2b70b9d..c6ac8e4 100644
--- a/runtime/vm/compiler/frontend/base_flow_graph_builder.cc
+++ b/runtime/vm/compiler/frontend/base_flow_graph_builder.cc
@@ -951,6 +951,9 @@
function_name, String::Handle(Z, String::New("#tearoff", Heap::kNew)),
Heap::kOld);
}
+ if (!function_name.IsCanonical()) {
+ function_name = Symbols::New(thread_, function_name);
+ }
Fragment call_hook;
call_hook += Constant(closure);
diff --git a/runtime/vm/compiler/frontend/bytecode_flow_graph_builder.cc b/runtime/vm/compiler/frontend/bytecode_flow_graph_builder.cc
index a330e14..034716b 100644
--- a/runtime/vm/compiler/frontend/bytecode_flow_graph_builder.cc
+++ b/runtime/vm/compiler/frontend/bytecode_flow_graph_builder.cc
@@ -2013,10 +2013,10 @@
Array::ZoneHandle(Z, handlers.GetHandledTypes(try_index));
CatchBlockEntryInstr* entry = new (Z) CatchBlockEntryInstr(
- TokenPosition::kNoSource, handler_info.is_generated != 0,
- B->AllocateBlockId(), handler_info.outer_try_index, graph_entry,
- handler_types, try_index, handler_info.needs_stacktrace != 0,
- B->GetNextDeoptId(), nullptr, nullptr, exception_var_, stacktrace_var_);
+ handler_info.is_generated != 0, B->AllocateBlockId(),
+ handler_info.outer_try_index, graph_entry, handler_types, try_index,
+ handler_info.needs_stacktrace != 0, B->GetNextDeoptId(), nullptr,
+ nullptr, exception_var_, stacktrace_var_);
graph_entry->AddCatchEntry(entry);
code_ = Fragment(entry);
diff --git a/runtime/vm/compiler/frontend/bytecode_reader.cc b/runtime/vm/compiler/frontend/bytecode_reader.cc
index 870a42e..787c06a 100644
--- a/runtime/vm/compiler/frontend/bytecode_reader.cc
+++ b/runtime/vm/compiler/frontend/bytecode_reader.cc
@@ -613,6 +613,13 @@
const intptr_t num_type_params = reader_.ReadUInt();
ASSERT(num_type_params > 0);
+ intptr_t offset;
+ if (!parameterized_class.IsNull()) {
+ offset = parameterized_class.NumTypeArguments() - num_type_params;
+ } else {
+ offset = parameterized_function.NumParentTypeParameters();
+ }
+
// First setup the type parameters, so if any of the following code uses it
// (in a recursive way) we're fine.
//
@@ -628,6 +635,8 @@
parameter = TypeParameter::New(
parameterized_class, parameterized_function, i, name, bound,
/* is_generic_covariant_impl = */ false, TokenPosition::kNoSource);
+ parameter.set_index(offset + i);
+ parameter.SetIsFinalized();
type_parameters.SetTypeAt(i, parameter);
}
@@ -984,15 +993,14 @@
TokenPosition::kNoSource, try_index);
pc_descriptors_list->AddDescriptor(RawPcDescriptors::kOther, end_pc,
DeoptId::kNone,
- TokenPosition::kNoSource, -1);
+ TokenPosition::kNoSource, try_index);
// The exception handler keeps a zone handle of the types array, rather
// than a raw pointer. Do not share the handle across iterations to avoid
// clobbering the array.
exception_handlers_list->AddHandler(
- try_index, outer_try_index, handler_pc, TokenPosition::kNoSource,
- is_generated, Array::ZoneHandle(Z, handler_types.raw()),
- needs_stacktrace);
+ try_index, outer_try_index, handler_pc, is_generated,
+ Array::ZoneHandle(Z, handler_types.raw()), needs_stacktrace);
}
const PcDescriptors& descriptors = PcDescriptors::Handle(
Z, pc_descriptors_list->FinalizePcDescriptors(bytecode.PayloadStart()));
@@ -1622,7 +1630,9 @@
return AbstractType::void_type().raw();
case kSimpleType: {
const Class& cls = Class::CheckedHandle(Z, ReadObject());
- cls.EnsureDeclarationLoaded();
+ if (!cls.is_declaration_loaded()) {
+ LoadReferencedClass(cls);
+ }
return cls.DeclarationType();
}
case kTypeParameter: {
@@ -1646,14 +1656,13 @@
} else {
UNREACHABLE();
}
- AbstractType& type =
- AbstractType::Handle(Z, type_parameters.TypeAt(index_in_parent));
- // TODO(alexmarkov): skip type finalization
- return ClassFinalizer::FinalizeType(*active_class_->klass, type);
+ return type_parameters.TypeAt(index_in_parent);
}
case kGenericType: {
const Class& cls = Class::CheckedHandle(Z, ReadObject());
- cls.EnsureDeclarationLoaded();
+ if (!cls.is_declaration_loaded()) {
+ LoadReferencedClass(cls);
+ }
const TypeArguments& type_arguments =
TypeArguments::CheckedHandle(Z, ReadObject());
const Type& type = Type::Handle(
@@ -1664,7 +1673,9 @@
case kRecursiveGenericType: {
const intptr_t id = reader_.ReadUInt();
const Class& cls = Class::CheckedHandle(Z, ReadObject());
- cls.EnsureDeclarationLoaded();
+ if (!cls.is_declaration_loaded()) {
+ LoadReferencedClass(cls);
+ }
const auto saved_pending_recursive_types = pending_recursive_types_;
if (id == 0) {
pending_recursive_types_ = &GrowableObjectArray::Handle(
@@ -1808,16 +1819,17 @@
source = ReadString(/* is_canonical = */ false);
}
- if (source.IsNull() && line_starts.IsNull()) {
- // This script provides a uri only, but no source or line_starts array.
- // The source is set to the empty symbol, indicating that source and
- // line_starts array are lazily looked up if needed.
- source = Symbols::Empty().raw(); // Lookup is postponed.
- }
-
const Script& script = Script::Handle(
Z, Script::New(import_uri, uri, source, RawScript::kKernelTag));
script.set_line_starts(line_starts);
+
+ if (source.IsNull() && line_starts.IsNull()) {
+ // This script provides a uri only, but no source or line_starts array.
+ // This could be a reference to a Script in another kernel binary.
+ // Make an attempt to find source and line starts when needed.
+ script.SetLazyLookupSourceAndLineStarts(true);
+ }
+
return script.raw();
}
@@ -2301,6 +2313,27 @@
functions_ = nullptr;
}
+void BytecodeReaderHelper::LoadReferencedClass(const Class& cls) {
+ ASSERT(!cls.is_declaration_loaded());
+
+ if (!cls.is_declared_in_bytecode()) {
+ cls.EnsureDeclarationLoaded();
+ return;
+ }
+
+ const auto& script = Script::Handle(Z, cls.script());
+ if (H.GetKernelProgramInfo().raw() != script.kernel_program_info()) {
+ // Class comes from a different binary.
+ cls.EnsureDeclarationLoaded();
+ return;
+ }
+
+ // We can reuse current BytecodeReaderHelper.
+ ActiveClassScope active_class_scope(active_class_, &cls);
+ AlternativeReadingScope alt(&reader_, cls.bytecode_offset());
+ ReadClassDeclaration(cls);
+}
+
void BytecodeReaderHelper::ReadClassDeclaration(const Class& cls) {
// Class flags, must be in sync with ClassDeclaration constants in
// pkg/vm/lib/bytecode/declarations.dart.
@@ -2769,10 +2802,8 @@
Function::Handle(Z, function.parent_function()));
return;
case RawFunction::kDynamicInvocationForwarder:
- ParseForwarderFunction(
- parsed_function, function,
- Function::Handle(Z,
- function.GetTargetOfDynamicInvocationForwarder()));
+ ParseForwarderFunction(parsed_function, function,
+ Function::Handle(Z, function.ForwardingTarget()));
return;
case RawFunction::kImplicitGetter:
case RawFunction::kImplicitSetter:
diff --git a/runtime/vm/compiler/frontend/bytecode_reader.h b/runtime/vm/compiler/frontend/bytecode_reader.h
index ec915dd..39951e5 100644
--- a/runtime/vm/compiler/frontend/bytecode_reader.h
+++ b/runtime/vm/compiler/frontend/bytecode_reader.h
@@ -225,6 +225,10 @@
expression_evaluation_library_->raw() == library.raw();
}
+ // Similar to cls.EnsureClassDeclaration, but may be more efficient if
+ // class is from the current kernel binary.
+ void LoadReferencedClass(const Class& cls);
+
Reader reader_;
TranslationHelper& translation_helper_;
ActiveClass* const active_class_;
@@ -436,10 +440,11 @@
}
bool MoveNext() {
- if (entries_remaining_ == 0) {
+ if (entries_remaining_ <= 0) {
+ // Finished looking at the last entry, now we're done.
+ entries_remaining_ = -1;
return false;
}
- ASSERT(entries_remaining_ > 0);
--entries_remaining_;
cur_kind_and_flags_ = reader_.ReadByte();
cur_start_pc_ += reader_.ReadSLEB128();
@@ -464,7 +469,10 @@
return true;
}
- bool IsDone() const { return entries_remaining_ == 0; }
+ // Returns true after iterator moved past the last entry and
+ // MoveNext() returned false.
+ bool IsDone() const { return entries_remaining_ < 0; }
+
intptr_t Kind() const { return cur_kind_and_flags_ & kKindMask; }
bool IsScope() const { return Kind() == kScope; }
bool IsVariableDeclaration() const { return Kind() == kVariableDeclaration; }
diff --git a/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc b/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc
index 1cfab97..9fb9b27 100644
--- a/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc
+++ b/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc
@@ -232,7 +232,8 @@
ExternalTypedData::Handle(Z, class_field.KernelData());
ASSERT(!kernel_data.IsNull());
intptr_t field_offset = class_field.kernel_offset();
- AlternativeReadingScope alt(&reader_, &kernel_data, field_offset);
+ AlternativeReadingScopeWithNewData alt(&reader_, &kernel_data,
+ field_offset);
FieldHelper field_helper(this);
field_helper.ReadUntilExcluding(FieldHelper::kInitializer);
Tag initializer_tag = ReadTag(); // read first part of initializer.
@@ -3720,8 +3721,7 @@
const String& value =
H.DartString(ReadStringReference()); // read index into string table.
- const Integer& integer =
- Integer::ZoneHandle(Z, Integer::New(value, Heap::kOld));
+ const Integer& integer = Integer::ZoneHandle(Z, Integer::NewCanonical(value));
if (integer.IsNull()) {
H.ReportError(script_, TokenPosition::kNoSource,
"Integer literal %s is out of range", value.ToCString());
@@ -4768,6 +4768,10 @@
ASSERT(flags == kNativeYieldFlags); // Must have been desugared.
+ // Collect yield position
+ if (record_yield_positions_ != nullptr) {
+ record_yield_positions_->Add(Smi::Handle(Z, Smi::New(position.value())));
+ }
// Setup yield/continue point:
//
// ...
diff --git a/runtime/vm/compiler/frontend/kernel_binary_flowgraph.h b/runtime/vm/compiler/frontend/kernel_binary_flowgraph.h
index 0eab5b9b..2cdbb28 100644
--- a/runtime/vm/compiler/frontend/kernel_binary_flowgraph.h
+++ b/runtime/vm/compiler/frontend/kernel_binary_flowgraph.h
@@ -21,9 +21,11 @@
class StreamingFlowGraphBuilder : public KernelReaderHelper {
public:
- StreamingFlowGraphBuilder(FlowGraphBuilder* flow_graph_builder,
- const ExternalTypedData& data,
- intptr_t data_program_offset)
+ StreamingFlowGraphBuilder(
+ FlowGraphBuilder* flow_graph_builder,
+ const ExternalTypedData& data,
+ intptr_t data_program_offset,
+ GrowableObjectArray* record_yield_positions = nullptr)
: KernelReaderHelper(
flow_graph_builder->zone_,
&flow_graph_builder->translation_helper_,
@@ -44,7 +46,8 @@
inferred_type_metadata_helper_(this),
procedure_attributes_metadata_helper_(this),
call_site_attributes_metadata_helper_(this, &type_translator_),
- closure_owner_(Object::Handle(flow_graph_builder->zone_)) {}
+ closure_owner_(Object::Handle(flow_graph_builder->zone_)),
+ record_yield_positions_(record_yield_positions) {}
virtual ~StreamingFlowGraphBuilder() {}
@@ -367,6 +370,7 @@
ProcedureAttributesMetadataHelper procedure_attributes_metadata_helper_;
CallSiteAttributesMetadataHelper call_site_attributes_metadata_helper_;
Object& closure_owner_;
+ GrowableObjectArray* record_yield_positions_;
friend class KernelLoader;
diff --git a/runtime/vm/compiler/frontend/kernel_to_il.cc b/runtime/vm/compiler/frontend/kernel_to_il.cc
index fbca763..4748658 100644
--- a/runtime/vm/compiler/frontend/kernel_to_il.cc
+++ b/runtime/vm/compiler/frontend/kernel_to_il.cc
@@ -40,7 +40,8 @@
bool optimizing,
intptr_t osr_id,
intptr_t first_block_id,
- bool inlining_unchecked_entry)
+ bool inlining_unchecked_entry,
+ GrowableObjectArray* record_yield_positions)
: BaseFlowGraphBuilder(parsed_function,
first_block_id - 1,
osr_id,
@@ -68,6 +69,7 @@
catch_block_(NULL) {
const Script& script =
Script::Handle(Z, parsed_function->function().script());
+ record_yield_positions_ = record_yield_positions;
H.InitFromScript(script);
}
@@ -226,7 +228,6 @@
LocalVariable* raw_stacktrace_var = CurrentRawStackTrace();
CatchBlockEntryInstr* entry = new (Z) CatchBlockEntryInstr(
- TokenPosition::kNoSource, // Token position of catch block.
is_synthesized, // whether catch block was synthesized by FE compiler
AllocateBlockId(), CurrentTryIndex(), graph_entry_, handler_types,
handler_index, needs_stacktrace, GetNextDeoptId(), exception_var,
@@ -643,7 +644,7 @@
// TODO(alexmarkov): refactor this - StreamingFlowGraphBuilder should not be
// used for bytecode functions.
StreamingFlowGraphBuilder streaming_flow_graph_builder(
- this, kernel_data, kernel_data_program_offset);
+ this, kernel_data, kernel_data_program_offset, record_yield_positions_);
return streaming_flow_graph_builder.BuildGraph();
}
diff --git a/runtime/vm/compiler/frontend/kernel_to_il.h b/runtime/vm/compiler/frontend/kernel_to_il.h
index 0b9d2fe..3775000 100644
--- a/runtime/vm/compiler/frontend/kernel_to_il.h
+++ b/runtime/vm/compiler/frontend/kernel_to_il.h
@@ -56,7 +56,8 @@
bool optimizing,
intptr_t osr_id,
intptr_t first_block_id = 1,
- bool inlining_unchecked_entry = false);
+ bool inlining_unchecked_entry = false,
+ GrowableObjectArray* record_yield_position = nullptr);
virtual ~FlowGraphBuilder();
FlowGraph* BuildGraph();
@@ -377,6 +378,8 @@
ActiveClass active_class_;
+ GrowableObjectArray* record_yield_positions_;
+
friend class BreakableBlock;
friend class CatchBlock;
friend class ConstantEvaluator;
diff --git a/runtime/vm/compiler/frontend/kernel_translation_helper.cc b/runtime/vm/compiler/frontend/kernel_translation_helper.cc
index 4469fce..771d4ce 100644
--- a/runtime/vm/compiler/frontend/kernel_translation_helper.cc
+++ b/runtime/vm/compiler/frontend/kernel_translation_helper.cc
@@ -1623,8 +1623,8 @@
return false;
}
- AlternativeReadingScope alt(&helper_->reader_, &H.metadata_payloads(),
- md_offset);
+ AlternativeReadingScopeWithNewData alt(&helper_->reader_,
+ &H.metadata_payloads(), md_offset);
*target_name = helper_->ReadCanonicalNameReference();
*check_receiver_for_null = helper_->ReadBool();
@@ -1701,8 +1701,8 @@
InferredTypeMetadata::kFlagNullable);
}
- AlternativeReadingScope alt(&helper_->reader_, &H.metadata_payloads(),
- md_offset);
+ AlternativeReadingScopeWithNewData alt(&helper_->reader_,
+ &H.metadata_payloads(), md_offset);
const NameIndex kernel_name = helper_->ReadCanonicalNameReference();
const uint8_t flags = helper_->ReadByte();
@@ -1737,8 +1737,8 @@
return false;
}
- AlternativeReadingScope alt(&helper_->reader_, &H.metadata_payloads(),
- md_offset);
+ AlternativeReadingScopeWithNewData alt(&helper_->reader_,
+ &H.metadata_payloads(), md_offset);
const int kDynamicUsesBit = 1 << 0;
const int kNonThisUsesBit = 1 << 1;
@@ -1771,8 +1771,8 @@
return;
}
- AlternativeReadingScope alt(&helper_->reader_, &H.metadata_payloads(),
- md_offset);
+ AlternativeReadingScopeWithNewData alt(&helper_->reader_,
+ &H.metadata_payloads(), md_offset);
Obfuscator O(Thread::Current(), String::Handle());
intptr_t len = helper_->ReadUInt32();
@@ -1797,8 +1797,8 @@
return false;
}
- AlternativeReadingScope alt(&helper_->reader_, &H.metadata_payloads(),
- md_offset);
+ AlternativeReadingScopeWithNewData alt(&helper_->reader_,
+ &H.metadata_payloads(), md_offset);
metadata->receiver_type = &type_translator_.BuildType();
return true;
@@ -2475,8 +2475,7 @@
SkipStatement(); // read finalizer.
return;
case kYieldStatement: {
- TokenPosition position = ReadPosition(); // read position.
- RecordYieldPosition(position);
+ ReadPosition(); // read position.
ReadByte(); // read flags.
SkipExpression(); // read expression.
return;
diff --git a/runtime/vm/compiler/frontend/kernel_translation_helper.h b/runtime/vm/compiler/frontend/kernel_translation_helper.h
index 8f9371b..6187caa 100644
--- a/runtime/vm/compiler/frontend/kernel_translation_helper.h
+++ b/runtime/vm/compiler/frontend/kernel_translation_helper.h
@@ -1036,12 +1036,6 @@
USE(id);
}
- virtual void RecordYieldPosition(TokenPosition position) {
- // Do nothing by default.
- // This is overridden in KernelTokenPositionCollector.
- USE(position);
- }
-
virtual void RecordTokenPosition(TokenPosition position) {
// Do nothing by default.
// This is overridden in KernelTokenPositionCollector.
diff --git a/runtime/vm/compiler/frontend/scope_builder.cc b/runtime/vm/compiler/frontend/scope_builder.cc
index 8e4a4c6..2866061 100644
--- a/runtime/vm/compiler/frontend/scope_builder.cc
+++ b/runtime/vm/compiler/frontend/scope_builder.cc
@@ -188,8 +188,8 @@
ExternalTypedData::Handle(Z, class_field.KernelData());
ASSERT(!kernel_data.IsNull());
intptr_t field_offset = class_field.kernel_offset();
- AlternativeReadingScope alt(&helper_.reader_, &kernel_data,
- field_offset);
+ AlternativeReadingScopeWithNewData alt(
+ &helper_.reader_, &kernel_data, field_offset);
FieldHelper field_helper(&helper_);
field_helper.ReadUntilExcluding(FieldHelper::kInitializer);
Tag initializer_tag =
@@ -473,8 +473,8 @@
ExternalTypedData::Handle(Z, class_field.KernelData());
ASSERT(!kernel_data.IsNull());
intptr_t field_offset = class_field.kernel_offset();
- AlternativeReadingScope alt(&helper_.reader_, &kernel_data,
- field_offset);
+ AlternativeReadingScopeWithNewData alt(&helper_.reader_, &kernel_data,
+ field_offset);
FieldHelper field_helper(&helper_);
field_helper.ReadUntilExcluding(FieldHelper::kInitializer);
Tag initializer_tag = helper_.ReadTag();
@@ -1739,7 +1739,8 @@
ASSERT(!kernel_data.IsNull());
// Temporarily go to the variable declaration, read the name.
- AlternativeReadingScope alt(&helper_.reader_, &kernel_data, kernel_offset);
+ AlternativeReadingScopeWithNewData alt(&helper_.reader_, &kernel_data,
+ kernel_offset);
VariableDeclarationHelper helper(&helper_);
helper.ReadUntilIncluding(VariableDeclarationHelper::kNameIndex);
return helper.name_index_;
diff --git a/runtime/vm/compiler/jit/compiler.cc b/runtime/vm/compiler/jit/compiler.cc
index 5bf7d0a..dd25e7a 100644
--- a/runtime/vm/compiler/jit/compiler.cc
+++ b/runtime/vm/compiler/jit/compiler.cc
@@ -230,14 +230,14 @@
Exceptions::PropagateError(Error::Cast(result));
}
}
- if (function.HasBytecode()) {
+ if (function.HasBytecode() && (FLAG_compilation_counter_threshold != 0)) {
// If interpreter is enabled and there is bytecode, LazyCompile stub
// (which calls CompileFunction) should proceed to InterpretCall in order
// to enter interpreter. In such case, compilation is postponed and
// triggered by interpreter later via CompileInterpretedFunction.
return;
}
- // No bytecode, fall back to compilation.
+ // Fall back to compilation.
} else {
ASSERT(!function.HasCode());
}
@@ -646,26 +646,32 @@
}
{
TIMELINE_DURATION(thread(), CompilerVerbose, "FinalizeCompilation");
- if (thread()->IsMutatorThread()) {
+
+ auto install_code_fun = [&]() {
*result =
FinalizeCompilation(&assembler, &graph_compiler, flow_graph);
- } else {
- // This part of compilation must be at a safepoint.
- // Stop mutator thread before creating the instruction object and
- // installing code.
- // Mutator thread may not run code while we are creating the
- // instruction object, since the creation of instruction object
- // changes code page access permissions (makes them temporary not
- // executable).
- {
- CheckIfBackgroundCompilerIsBeingStopped(optimized());
- ForceGrowthSafepointOperationScope safepoint_scope(thread());
- CheckIfBackgroundCompilerIsBeingStopped(optimized());
- *result =
- FinalizeCompilation(&assembler, &graph_compiler, flow_graph);
- }
+ };
+
+ if (Compiler::IsBackgroundCompilation()) {
+ CheckIfBackgroundCompilerIsBeingStopped(optimized());
}
+ // We have to ensure no mutators are running, because:
+ //
+ // a) We allocate an instructions object, which might cause us to
+ // temporarily flip page protections (RX -> RW -> RX).
+ //
+ // b) We have to ensure the code generated does not violate
+ // assumptions (e.g. CHA, field guards), the validation has to
+ // happen while mutator is stopped.
+ //
+ // b) We update the [Function] object with a new [Code] which
+ // requires updating several pointers: We have to ensure all of
+ // those writes are observed atomically.
+ //
+ thread()->isolate_group()->RunWithStoppedMutators(
+ install_code_fun, install_code_fun, /*use_force_growth=*/true);
+
// We notify code observers after finalizing the code in order to be
// outside a [SafepointOperationScope].
Code::NotifyCodeObservers(function, *result, optimized());
@@ -1012,6 +1018,41 @@
}
}
+void Compiler::ComputeYieldPositions(const Function& function) {
+ Thread* thread = Thread::Current();
+ Zone* zone = thread->zone();
+ const Script& script = Script::Handle(zone, function.script());
+ Array& yield_position_map = Array::Handle(zone, script.yield_positions());
+ if (yield_position_map.IsNull()) {
+ yield_position_map = HashTables::New<UnorderedHashMap<SmiTraits>>(4);
+ }
+ UnorderedHashMap<SmiTraits> function_map(yield_position_map.raw());
+ Smi& key = Smi::Handle(zone, Smi::New(function.token_pos().value()));
+
+ if (function_map.ContainsKey(key)) {
+ ASSERT(function_map.Release().raw() == yield_position_map.raw());
+ return;
+ }
+
+ CompilerState state(thread);
+ LongJumpScope jump;
+ auto& array = GrowableObjectArray::Handle(zone, GrowableObjectArray::New());
+ if (setjmp(*jump.Set()) == 0) {
+ ParsedFunction* parsed_function =
+ new ParsedFunction(thread, Function::ZoneHandle(zone, function.raw()));
+ ZoneGrowableArray<const ICData*>* ic_data_array =
+ new ZoneGrowableArray<const ICData*>();
+ kernel::FlowGraphBuilder builder(parsed_function, ic_data_array, nullptr,
+ /* not inlining */ nullptr, false,
+ Compiler::kNoOSRDeoptId, 1, false, &array);
+ builder.BuildGraph();
+ }
+ function_map.UpdateOrInsert(key, array);
+ // Release and store back to script
+ yield_position_map = function_map.Release().raw();
+ script.set_yield_positions(yield_position_map);
+}
+
RawError* Compiler::CompileAllFunctions(const Class& cls) {
Thread* thread = Thread::Current();
Zone* zone = thread->zone();
@@ -1412,6 +1453,10 @@
UNREACHABLE();
}
+void Compiler::ComputeYieldPositions(const Function& function) {
+ UNREACHABLE();
+}
+
RawError* Compiler::CompileAllFunctions(const Class& cls) {
FATAL1("Attempt to compile class %s", cls.ToCString());
return Error::null();
diff --git a/runtime/vm/compiler/jit/compiler.h b/runtime/vm/compiler/jit/compiler.h
index 123e16a..94e22b7 100644
--- a/runtime/vm/compiler/jit/compiler.h
+++ b/runtime/vm/compiler/jit/compiler.h
@@ -108,6 +108,8 @@
// Generates local var descriptors and sets it in 'code'. Do not call if the
// local var descriptor already exists.
static void ComputeLocalVarDescriptors(const Code& code);
+ // Collect yield positions for function and store into its script object
+ static void ComputeYieldPositions(const Function& function);
// Eagerly compiles all functions in a class.
//
diff --git a/runtime/vm/compiler/relocation.cc b/runtime/vm/compiler/relocation.cc
index af363e6..feb31a3 100644
--- a/runtime/vm/compiler/relocation.cc
+++ b/runtime/vm/compiler/relocation.cc
@@ -23,7 +23,7 @@
// The trampolines will have a 1-word object header in front of them.
const intptr_t kOffsetInTrampoline = kWordSize;
-const intptr_t kTrampolineSize = OS::kMaxPreferredCodeAlignment;
+const intptr_t kTrampolineSize = 32;
CodeRelocator::CodeRelocator(Thread* thread,
GrowableArray<RawCode*>* code_objects,
@@ -33,7 +33,16 @@
commands_(commands),
kind_type_and_offset_(Smi::Handle(thread->zone())),
target_(Object::Handle(thread->zone())),
- destination_(Code::Handle(thread->zone())) {}
+ destination_(Code::Handle(thread->zone())) {
+ // Trampolines will be disguised as FreeListElement objects.
+ ASSERT(Utils::IsAligned(kTrampolineSize, kObjectAlignment));
+ // Trampolines will be inserted between Instructions objects and must
+ // preserve their alignment.
+ ASSERT(Utils::IsAligned(kTrampolineSize, OS::PreferredCodeAlignment()));
+ // Trampolines are big enough to hold a full-range call.
+ ASSERT((kOffsetInTrampoline +
+ PcRelativeTrampolineJumpPattern::kLengthInBytes) < kTrampolineSize);
+}
void CodeRelocator::Relocate(bool is_vm_isolate) {
Zone* zone = Thread::Current()->zone();
@@ -408,7 +417,12 @@
static void MarkAsFreeListElement(uint8_t* trampoline_bytes,
intptr_t trampoline_length) {
uint32_t tags = 0;
+#if defined(IS_SIMARM_X64)
+ // Account for difference in kObjectAlignment between host and target.
+ tags = RawObject::SizeTag::update(trampoline_length * 2, tags);
+#else
tags = RawObject::SizeTag::update(trampoline_length, tags);
+#endif
tags = RawObject::ClassIdTag::update(kFreeListElement, tags);
tags = RawObject::OldBit::update(true, tags);
tags = RawObject::OldAndNotMarkedBit::update(true, tags);
@@ -464,9 +478,6 @@
// buffer.
auto trampoline_bytes = new uint8_t[kTrampolineSize];
memset(trampoline_bytes, 0x00, kTrampolineSize);
- ASSERT((kOffsetInTrampoline +
- PcRelativeTrampolineJumpPattern::kLengthInBytes) <
- kTrampolineSize);
auto unresolved_trampoline = new UnresolvedTrampoline{
unresolved_call->callee,
unresolved_call->offset_into_target,
diff --git a/runtime/vm/compiler/runtime_api.cc b/runtime/vm/compiler/runtime_api.cc
index e7f6f80..88ad78e 100644
--- a/runtime/vm/compiler/runtime_api.cc
+++ b/runtime/vm/compiler/runtime_api.cc
@@ -508,7 +508,6 @@
intptr_t alignment = OS::PreferredCodeAlignment();
intptr_t aligned_size =
Utils::RoundUp(Instructions::UnalignedHeaderSize(), alignment);
- ASSERT(aligned_size == alignment);
return aligned_size;
}
diff --git a/runtime/vm/compiler/runtime_offsets_extracted.h b/runtime/vm/compiler/runtime_offsets_extracted.h
index add5eab..3e93b40 100644
--- a/runtime/vm/compiler/runtime_offsets_extracted.h
+++ b/runtime/vm/compiler/runtime_offsets_extracted.h
@@ -355,7 +355,7 @@
static constexpr dart::compiler::target::word Float32x4_InstanceSize = 24;
static constexpr dart::compiler::target::word Float64x2_InstanceSize = 24;
static constexpr dart::compiler::target::word Instructions_UnalignedHeaderSize =
- 16;
+ 12;
static constexpr dart::compiler::target::word Int32x4_InstanceSize = 24;
static constexpr dart::compiler::target::word Mint_InstanceSize = 16;
static constexpr dart::compiler::target::word NativeArguments_StructSize = 16;
@@ -714,7 +714,7 @@
static constexpr dart::compiler::target::word Float32x4_InstanceSize = 24;
static constexpr dart::compiler::target::word Float64x2_InstanceSize = 24;
static constexpr dart::compiler::target::word Instructions_UnalignedHeaderSize =
- 24;
+ 16;
static constexpr dart::compiler::target::word Int32x4_InstanceSize = 24;
static constexpr dart::compiler::target::word Mint_InstanceSize = 16;
static constexpr dart::compiler::target::word NativeArguments_StructSize = 32;
@@ -1065,7 +1065,7 @@
static constexpr dart::compiler::target::word Float32x4_InstanceSize = 24;
static constexpr dart::compiler::target::word Float64x2_InstanceSize = 24;
static constexpr dart::compiler::target::word Instructions_UnalignedHeaderSize =
- 16;
+ 12;
static constexpr dart::compiler::target::word Int32x4_InstanceSize = 24;
static constexpr dart::compiler::target::word Mint_InstanceSize = 16;
static constexpr dart::compiler::target::word NativeArguments_StructSize = 16;
@@ -1425,7 +1425,7 @@
static constexpr dart::compiler::target::word Float32x4_InstanceSize = 24;
static constexpr dart::compiler::target::word Float64x2_InstanceSize = 24;
static constexpr dart::compiler::target::word Instructions_UnalignedHeaderSize =
- 24;
+ 16;
static constexpr dart::compiler::target::word Int32x4_InstanceSize = 24;
static constexpr dart::compiler::target::word Mint_InstanceSize = 16;
static constexpr dart::compiler::target::word NativeArguments_StructSize = 32;
@@ -1712,7 +1712,7 @@
static constexpr dart::compiler::target::word Float32x4_InstanceSize = 24;
static constexpr dart::compiler::target::word Float64x2_InstanceSize = 24;
static constexpr dart::compiler::target::word Instructions_UnalignedHeaderSize =
- 24;
+ 16;
static constexpr dart::compiler::target::word Int32x4_InstanceSize = 24;
static constexpr dart::compiler::target::word Mint_InstanceSize = 16;
static constexpr dart::compiler::target::word NativeArguments_StructSize = 32;
@@ -1996,7 +1996,7 @@
static constexpr dart::compiler::target::word Float32x4_InstanceSize = 24;
static constexpr dart::compiler::target::word Float64x2_InstanceSize = 24;
static constexpr dart::compiler::target::word Instructions_UnalignedHeaderSize =
- 16;
+ 12;
static constexpr dart::compiler::target::word Int32x4_InstanceSize = 24;
static constexpr dart::compiler::target::word Mint_InstanceSize = 16;
static constexpr dart::compiler::target::word NativeArguments_StructSize = 16;
diff --git a/runtime/vm/compiler/stub_code_compiler_arm64.cc b/runtime/vm/compiler/stub_code_compiler_arm64.cc
index 16746a5..59674e3 100644
--- a/runtime/vm/compiler/stub_code_compiler_arm64.cc
+++ b/runtime/vm/compiler/stub_code_compiler_arm64.cc
@@ -222,6 +222,8 @@
__ PopRegisters(all_registers);
__ LeaveFrame();
+
+ __ mov(CSP, SP);
__ Ret();
}
@@ -249,6 +251,8 @@
__ PopRegisters(all_registers);
__ LeaveFrame();
+
+ __ mov(CSP, SP);
__ Ret();
}
@@ -395,7 +399,7 @@
// EnterSafepoint clobbers TMP, TMP2 and R8 -- all volatile and not holding
// return values.
- __ EnterSafepoint(R8);
+ __ EnterSafepoint(/*scratch=*/R8);
// Pop LR and THR from the real stack (CSP).
__ ldp(THR, LR, Address(CSP, 2 * target::kWordSize, Address::PairPostIndex));
@@ -872,7 +876,7 @@
__ AddImmediate(R1, -target::kWordSize);
__ AddImmediate(R3, target::kWordSize);
__ AddImmediateSetFlags(R2, R2, -target::ToRawSmi(1));
- __ str(R7, Address(R3, -target::kWordSize));
+ __ StoreIntoObject(R0, Address(R3, -target::kWordSize), R7);
__ b(&loop, GE);
__ Bind(&loop_exit);
}
diff --git a/runtime/vm/cpu_ia32.cc b/runtime/vm/cpu_ia32.cc
index 82ab263..a2ed128 100644
--- a/runtime/vm/cpu_ia32.cc
+++ b/runtime/vm/cpu_ia32.cc
@@ -27,21 +27,23 @@
return "ia32";
}
+const char* HostCPUFeatures::hardware_ = nullptr;
bool HostCPUFeatures::sse2_supported_ = false;
bool HostCPUFeatures::sse4_1_supported_ = false;
-const char* HostCPUFeatures::hardware_ = NULL;
+bool HostCPUFeatures::popcnt_supported_ = false;
+bool HostCPUFeatures::abm_supported_ = false;
#if defined(DEBUG)
bool HostCPUFeatures::initialized_ = false;
#endif
void HostCPUFeatures::Init() {
CpuInfo::Init();
-
hardware_ = CpuInfo::GetCpuModel();
sse2_supported_ = CpuInfo::FieldContains(kCpuInfoFeatures, "sse2");
sse4_1_supported_ = CpuInfo::FieldContains(kCpuInfoFeatures, "sse4_1") ||
CpuInfo::FieldContains(kCpuInfoFeatures, "sse4.1");
-
+ popcnt_supported_ = CpuInfo::FieldContains(kCpuInfoFeatures, "popcnt");
+ abm_supported_ = CpuInfo::FieldContains(kCpuInfoFeatures, "abm");
#if defined(DEBUG)
initialized_ = true;
#endif
diff --git a/runtime/vm/cpu_ia32.h b/runtime/vm/cpu_ia32.h
index a740fb5..f622c1f 100644
--- a/runtime/vm/cpu_ia32.h
+++ b/runtime/vm/cpu_ia32.h
@@ -32,13 +32,21 @@
DEBUG_ASSERT(initialized_);
return sse4_1_supported_ && FLAG_use_sse41;
}
+ static bool popcnt_supported() {
+ DEBUG_ASSERT(initialized_);
+ return popcnt_supported_;
+ }
+ static bool abm_supported() {
+ DEBUG_ASSERT(initialized_);
+ return abm_supported_;
+ }
private:
- static const uint64_t kSSE2BitMask = static_cast<uint64_t>(1) << 26;
- static const uint64_t kSSE4_1BitMask = static_cast<uint64_t>(1) << 51;
static const char* hardware_;
static bool sse2_supported_;
static bool sse4_1_supported_;
+ static bool popcnt_supported_;
+ static bool abm_supported_;
#if defined(DEBUG)
static bool initialized_;
#endif
@@ -51,6 +59,8 @@
static const char* hardware() { return HostCPUFeatures::hardware(); }
static bool sse2_supported() { return HostCPUFeatures::sse2_supported(); }
static bool sse4_1_supported() { return HostCPUFeatures::sse4_1_supported(); }
+ static bool popcnt_supported() { return HostCPUFeatures::popcnt_supported(); }
+ static bool abm_supported() { return HostCPUFeatures::abm_supported(); }
static bool double_truncate_round_supported() { return sse4_1_supported(); }
};
diff --git a/runtime/vm/cpu_x64.cc b/runtime/vm/cpu_x64.cc
index a4a17f1..c892d85 100644
--- a/runtime/vm/cpu_x64.cc
+++ b/runtime/vm/cpu_x64.cc
@@ -27,9 +27,12 @@
return "x64";
}
+const char* HostCPUFeatures::hardware_ = nullptr;
bool HostCPUFeatures::sse2_supported_ = true;
bool HostCPUFeatures::sse4_1_supported_ = false;
-const char* HostCPUFeatures::hardware_ = NULL;
+bool HostCPUFeatures::popcnt_supported_ = false;
+bool HostCPUFeatures::abm_supported_ = false;
+
#if defined(DEBUG)
bool HostCPUFeatures::initialized_ = false;
#endif
@@ -39,7 +42,8 @@
hardware_ = CpuInfo::GetCpuModel();
sse4_1_supported_ = CpuInfo::FieldContains(kCpuInfoFeatures, "sse4_1") ||
CpuInfo::FieldContains(kCpuInfoFeatures, "sse4.1");
-
+ popcnt_supported_ = CpuInfo::FieldContains(kCpuInfoFeatures, "popcnt");
+ abm_supported_ = CpuInfo::FieldContains(kCpuInfoFeatures, "abm");
#if defined(DEBUG)
initialized_ = true;
#endif
diff --git a/runtime/vm/cpu_x64.h b/runtime/vm/cpu_x64.h
index e87d2d5..6e6cf83 100644
--- a/runtime/vm/cpu_x64.h
+++ b/runtime/vm/cpu_x64.h
@@ -32,13 +32,21 @@
DEBUG_ASSERT(initialized_);
return sse4_1_supported_ && FLAG_use_sse41;
}
+ static bool popcnt_supported() {
+ DEBUG_ASSERT(initialized_);
+ return popcnt_supported_;
+ }
+ static bool abm_supported() {
+ DEBUG_ASSERT(initialized_);
+ return abm_supported_;
+ }
private:
- static const uint64_t kSSE2BitMask = static_cast<uint64_t>(1) << 26;
- static const uint64_t kSSE4_1BitMask = static_cast<uint64_t>(1) << 51;
static const char* hardware_;
static bool sse2_supported_;
static bool sse4_1_supported_;
+ static bool popcnt_supported_;
+ static bool abm_supported_;
#if defined(DEBUG)
static bool initialized_;
#endif
@@ -51,6 +59,8 @@
static const char* hardware() { return HostCPUFeatures::hardware(); }
static bool sse2_supported() { return HostCPUFeatures::sse2_supported(); }
static bool sse4_1_supported() { return HostCPUFeatures::sse4_1_supported(); }
+ static bool popcnt_supported() { return HostCPUFeatures::popcnt_supported(); }
+ static bool abm_supported() { return HostCPUFeatures::abm_supported(); }
static bool double_truncate_round_supported() { return false; }
};
diff --git a/runtime/vm/cpuid.cc b/runtime/vm/cpuid.cc
index ce80696..ce6b13f 100644
--- a/runtime/vm/cpuid.cc
+++ b/runtime/vm/cpuid.cc
@@ -19,8 +19,11 @@
bool CpuId::sse2_ = false;
bool CpuId::sse41_ = false;
-const char* CpuId::id_string_ = NULL;
-const char* CpuId::brand_string_ = NULL;
+bool CpuId::popcnt_ = false;
+bool CpuId::abm_ = false;
+
+const char* CpuId::id_string_ = nullptr;
+const char* CpuId::brand_string_ = nullptr;
#if defined(HOST_ARCH_IA32) || defined(HOST_ARCH_X64)
@@ -39,6 +42,7 @@
GetCpuId(0, info);
char* id_string = reinterpret_cast<char*>(malloc(3 * sizeof(int32_t)));
+
// Yes, these are supposed to be out of order.
*reinterpret_cast<uint32_t*>(id_string) = info[1];
*reinterpret_cast<uint32_t*>(id_string + 4) = info[3];
@@ -48,6 +52,10 @@
GetCpuId(1, info);
CpuId::sse41_ = (info[2] & (1 << 19)) != 0;
CpuId::sse2_ = (info[3] & (1 << 26)) != 0;
+ CpuId::popcnt_ = (info[2] & (1 << 23)) != 0;
+
+ GetCpuId(0x80000001, info);
+ CpuId::abm_ = (info[2] & (1 << 5)) != 0;
char* brand_string =
reinterpret_cast<char*>(malloc(3 * 4 * sizeof(uint32_t)));
@@ -89,15 +97,25 @@
case kCpuInfoHardware:
return brand_string();
case kCpuInfoFeatures: {
- if (sse2() && sse41()) {
- return strdup("sse2 sse4.1");
- } else if (sse2()) {
- return strdup("sse2");
- } else if (sse41()) {
- return strdup("sse4.1");
- } else {
- return strdup("");
+ char buffer[100];
+ char* p = buffer;
+ const char* q = p + 100;
+ *p = '\0';
+ if (sse2()) {
+ p += snprintf(p, q - p, "sse2 ");
}
+ if (sse41()) {
+ p += snprintf(p, q - p, "sse4.1 ");
+ }
+ if (popcnt()) {
+ p += snprintf(p, q - p, "popcnt ");
+ }
+ if (abm()) {
+ p += snprintf(p, q - p, "abm ");
+ }
+ // Remove last space before returning string.
+ if (p != buffer) *(p - 1) = '\0';
+ return strdup(buffer);
}
default: {
UNREACHABLE();
diff --git a/runtime/vm/cpuid.h b/runtime/vm/cpuid.h
index fb7ff70..99f4f34 100644
--- a/runtime/vm/cpuid.h
+++ b/runtime/vm/cpuid.h
@@ -23,7 +23,7 @@
#else
static void Init() {}
static void Cleanup() {}
- static const char* field(CpuInfoIndices idx) { return NULL; }
+ static const char* field(CpuInfoIndices idx) { return nullptr; }
#endif
private:
@@ -33,9 +33,13 @@
static bool sse2() { return sse2_; }
static bool sse41() { return sse41_; }
+ static bool popcnt() { return popcnt_; }
+ static bool abm() { return abm_; }
static bool sse2_;
static bool sse41_;
+ static bool popcnt_;
+ static bool abm_;
static const char* id_string_;
static const char* brand_string_;
diff --git a/runtime/vm/dart_api_impl_test.cc b/runtime/vm/dart_api_impl_test.cc
index 5d444dc..437ce00 100644
--- a/runtime/vm/dart_api_impl_test.cc
+++ b/runtime/vm/dart_api_impl_test.cc
@@ -7912,7 +7912,7 @@
TEST_CASE(DartAPI_InvokeImportedFunction) {
const char* kScriptChars =
"import 'dart:math';\n"
- "import 'dart:profiler';\n"
+ "import 'dart:developer';\n"
"main() {}";
Dart_Handle lib = TestCase::LoadTestScript(kScriptChars, NULL);
EXPECT_VALID(lib);
@@ -7924,11 +7924,6 @@
EXPECT_ERROR(result,
"NoSuchMethodError: No top-level method 'max' declared.");
- // The function 'getCurrentTag' is actually defined in the library
- // dart:developer. However, the library dart:profiler exports dart:developer
- // and exposes the function 'getCurrentTag'.
- // NOTE: dart:profiler is deprecated. So, its use in this test is only
- // an interim solution until we fix DartAPI_Invoke_CrossLibrary.
Dart_Handle getCurrentTag = Dart_NewStringFromCString("getCurrentTag");
result = Dart_Invoke(lib, getCurrentTag, 0, NULL);
EXPECT_ERROR(
diff --git a/runtime/vm/dart_entry.cc b/runtime/vm/dart_entry.cc
index 4bd384c..749f567 100644
--- a/runtime/vm/dart_entry.cc
+++ b/runtime/vm/dart_entry.cc
@@ -152,7 +152,7 @@
}
// If we have bytecode but no native code then invoke the interpreter.
- if (function.HasBytecode()) {
+ if (function.HasBytecode() && (FLAG_compilation_counter_threshold != 0)) {
ASSERT(thread->no_callback_scope_depth() == 0);
SuspendLongJumpScope suspend_long_jump_scope(thread);
TransitionToGenerated transition(thread);
@@ -160,7 +160,7 @@
arguments, thread);
}
- // No bytecode, fall back to compilation.
+ // Fall back to compilation.
}
const Object& result =
diff --git a/runtime/vm/debugger.cc b/runtime/vm/debugger.cc
index 6e3bcc2..7ba428b 100644
--- a/runtime/vm/debugger.cc
+++ b/runtime/vm/debugger.cc
@@ -1060,41 +1060,18 @@
ASSERT(!IsInterpreted());
ASSERT(script.kind() == RawScript::kKernelTag);
- const Array& await_to_token_map =
- Array::Handle(zone, script.yield_positions());
- if (await_to_token_map.IsNull()) {
- // No mapping.
- return;
- }
const intptr_t await_jump_var = GetAwaitJumpVariable();
if (await_jump_var < 0) {
return;
}
intptr_t await_to_token_map_index = await_jump_var - 1;
- // yield_positions returns all yield positions for the script (in sorted
- // order).
- // We thus need to offset the function start to get the actual index.
- if (!function_.token_pos().IsReal()) {
- return;
- }
- const intptr_t function_start = function_.token_pos().value();
- for (intptr_t i = 0;
- i < await_to_token_map.Length() &&
- Smi::Value(reinterpret_cast<RawSmi*>(await_to_token_map.At(i))) <
- function_start;
- i++) {
- await_to_token_map_index++;
- }
-
- if (await_to_token_map_index >= await_to_token_map.Length()) {
- return;
- }
-
+ const auto& array =
+ GrowableObjectArray::Handle(zone, script.GetYieldPositions(function_));
+ // await_jump_var is non zero means that array should not be empty
+ // index also fall into the correct range
+ ASSERT(array.Length() > 0 && await_to_token_map_index < array.Length());
const Object& token_pos =
- Object::Handle(await_to_token_map.At(await_to_token_map_index));
- if (token_pos.IsNull()) {
- return;
- }
+ Object::Handle(zone, array.At(await_to_token_map_index));
ASSERT(token_pos.IsSmi());
token_pos_ = TokenPosition(Smi::Cast(token_pos).Value());
token_pos_initialized_ = true;
@@ -1156,7 +1133,8 @@
} else if (obj.IsContext()) {
ctx_ = Context::Cast(obj).raw();
} else {
- ASSERT(obj.IsNull());
+ ASSERT(obj.IsNull() || obj.raw() == Symbols::OptimizedOut().raw());
+ ctx_ = Context::null();
}
return ctx_;
}
@@ -1431,7 +1409,12 @@
intptr_t ctx_slot,
intptr_t frame_ctx_level) {
const Context& ctx = GetSavedCurrentContext();
- ASSERT(!ctx.IsNull());
+
+ // It's possible that ctx was optimized out as no locals were captured by the
+ // context. See issue #38182.
+ if (ctx.IsNull()) {
+ return Symbols::OptimizedOut().raw();
+ }
intptr_t level_diff = frame_ctx_level - var_ctx_level;
if (level_diff == 0) {
@@ -1440,8 +1423,7 @@
}
ASSERT((ctx_slot >= 0) && (ctx_slot < ctx.num_variables()));
return ctx.At(ctx_slot);
- } else {
- ASSERT(level_diff > 0);
+ } else if (level_diff > 0) {
Context& var_ctx = Context::Handle(ctx.raw());
while (level_diff > 0 && !var_ctx.IsNull()) {
level_diff--;
@@ -1454,6 +1436,9 @@
ASSERT(!var_ctx.IsNull());
ASSERT((ctx_slot >= 0) && (ctx_slot < var_ctx.num_variables()));
return var_ctx.At(ctx_slot);
+ } else {
+ PrintContextMismatchError(ctx_slot, frame_ctx_level, var_ctx_level);
+ return Object::null();
}
}
@@ -1607,7 +1592,7 @@
}
const String& url = String::Handle(SourceUrl());
intptr_t line = LineNumber();
- const char* func_name = Debugger::QualifiedFunctionName(function());
+ const char* func_name = function().ToFullyQualifiedCString();
if (live_frame_) {
return Thread::Current()->zone()->PrintToString(
"[ Frame pc(0x%" Px " %s offset:0x%" Px ") fp(0x%" Px ") sp(0x%" Px
@@ -1802,6 +1787,7 @@
#endif
{
ASSERT(!bytecode.IsNull());
+ ASSERT(FLAG_enable_interpreter);
ASSERT(token_pos_.IsReal());
ASSERT(pc_ != 0);
}
@@ -3171,7 +3157,7 @@
ASSERT(!func.HasOptimizedCode());
ASSERT(func.HasCode() || func.HasBytecode());
#if !defined(DART_PRECOMPILED_RUNTIME)
- if (func.HasBytecode()) {
+ if (func.HasBytecode() && FLAG_enable_interpreter) {
Bytecode& bytecode = Bytecode::Handle(func.bytecode());
ASSERT(!bytecode.IsNull());
uword pc = 0;
@@ -3293,7 +3279,7 @@
(function.end_token_pos() == end_pos) &&
(function.script() == script.raw())) {
if (function.is_debuggable()) {
- if (function.HasBytecode()) {
+ if (FLAG_enable_interpreter && function.HasBytecode()) {
bytecode_function_list->Add(function);
}
if (function.HasCode()) {
@@ -3303,7 +3289,7 @@
if (function.HasImplicitClosureFunction()) {
function = function.ImplicitClosureFunction();
if (function.is_debuggable()) {
- if (function.HasBytecode()) {
+ if (FLAG_enable_interpreter && function.HasBytecode()) {
bytecode_function_list->Add(function);
}
if (function.HasCode()) {
@@ -3337,11 +3323,12 @@
ASSERT(!function.IsNull());
bool function_added = false;
if (function.is_debuggable() &&
- (function.HasCode() || function.HasBytecode()) &&
+ (function.HasCode() ||
+ (FLAG_enable_interpreter && function.HasBytecode())) &&
function.token_pos() == start_pos &&
function.end_token_pos() == end_pos &&
function.script() == script.raw()) {
- if (function.HasBytecode()) {
+ if (FLAG_enable_interpreter && function.HasBytecode()) {
bytecode_function_list->Add(function);
}
if (function.HasCode()) {
@@ -3352,7 +3339,7 @@
if (function_added && function.HasImplicitClosureFunction()) {
function = function.ImplicitClosureFunction();
if (function.is_debuggable()) {
- if (function.HasBytecode()) {
+ if (FLAG_enable_interpreter && function.HasBytecode()) {
bytecode_function_list->Add(function);
}
if (function.HasCode()) {
@@ -3498,6 +3485,7 @@
intptr_t requested_column,
TokenPosition exact_token_pos,
const GrowableObjectArray& functions) {
+ ASSERT(!in_bytecode || FLAG_enable_interpreter);
Function& function = Function::Handle();
function ^= functions.At(0);
TokenPosition breakpoint_pos =
@@ -4398,12 +4386,16 @@
ASSERT(!top_frame->IsInterpreted());
const Script& script = Script::Handle(zone, top_frame->SourceScript());
ASSERT(script.kind() == RawScript::kKernelTag);
- // Are we at a yield point (previous await)?
- const Array& yields = Array::Handle(script.yield_positions());
+ const auto& yield_positions = GrowableObjectArray::Handle(
+ zone, script.GetYieldPositions(top_frame->function()));
+ // No yield statements
+ if (yield_positions.IsNull() || (yield_positions.Length() == 0)) {
+ return false;
+ }
intptr_t looking_for = top_frame->TokenPos().value();
Smi& value = Smi::Handle(zone);
- for (int i = 0; i < yields.Length(); i++) {
- value ^= yields.At(i);
+ for (int i = 0; i < yield_positions.Length(); i++) {
+ value ^= yield_positions.At(i);
if (value.Value() == looking_for) {
return true;
}
@@ -4722,6 +4714,10 @@
// Return with minimal overhead if there are no breakpoints.
return;
}
+ if (bytecode_loaded && !FLAG_enable_interpreter) {
+ // We do not set breakpoints in bytecode if the interpreter is not used.
+ return;
+ }
if (!func.is_debuggable()) {
// Nothing to do if the function is not debuggable. If there is
// a pending breakpoint in an inner function (that is debuggable),
diff --git a/runtime/vm/debugger_dbc.cc b/runtime/vm/debugger_dbc.cc
index c36dddb..56234ce 100644
--- a/runtime/vm/debugger_dbc.cc
+++ b/runtime/vm/debugger_dbc.cc
@@ -29,9 +29,11 @@
void CodeBreakpoint::PatchCode() {
ASSERT(!is_enabled_);
- const Code& code = Code::Handle(code_);
- const Instructions& instrs = Instructions::Handle(code.instructions());
- {
+ auto thread = Thread::Current();
+ auto zone = thread->zone();
+ const Code& code = Code::Handle(zone, code_);
+ const Instructions& instrs = Instructions::Handle(zone, code.instructions());
+ thread->isolate_group()->RunWithStoppedMutators([&]() {
WritableInstructionsScope writable(instrs.PayloadStart(), instrs.Size());
saved_value_ = *CallInstructionFromReturnAddress(pc_);
switch (breakpoint_kind_) {
@@ -67,15 +69,17 @@
} else {
saved_value_fastsmi_ = SimulatorBytecode::kTrap;
}
- }
+ });
is_enabled_ = true;
}
void CodeBreakpoint::RestoreCode() {
ASSERT(is_enabled_);
- const Code& code = Code::Handle(code_);
- const Instructions& instrs = Instructions::Handle(code.instructions());
- {
+ auto thread = Thread::Current();
+ auto zone = thread->zone();
+ const Code& code = Code::Handle(zone, code_);
+ const Instructions& instrs = Instructions::Handle(zone, code.instructions());
+ thread->isolate_group()->RunWithStoppedMutators([&]() {
WritableInstructionsScope writable(instrs.PayloadStart(), instrs.Size());
switch (breakpoint_kind_) {
case RawPcDescriptors::kIcCall:
@@ -94,7 +98,7 @@
SimulatorBytecode::kNop);
*FastSmiInstructionFromReturnAddress(pc_) = saved_value_fastsmi_;
}
- }
+ });
is_enabled_ = false;
}
diff --git a/runtime/vm/debugger_ia32.cc b/runtime/vm/debugger_ia32.cc
index 10ee78f..8b1eb8a 100644
--- a/runtime/vm/debugger_ia32.cc
+++ b/runtime/vm/debugger_ia32.cc
@@ -25,10 +25,12 @@
void CodeBreakpoint::PatchCode() {
ASSERT(!is_enabled_);
- const Code& code = Code::Handle(code_);
- const Instructions& instrs = Instructions::Handle(code.instructions());
- Code& stub_target = Code::Handle();
- {
+ auto thread = Thread::Current();
+ auto zone = thread->zone();
+ const Code& code = Code::Handle(zone, code_);
+ const Instructions& instrs = Instructions::Handle(zone, code.instructions());
+ Code& stub_target = Code::Handle(zone);
+ thread->isolate_group()->RunWithStoppedMutators([&]() {
WritableInstructionsScope writable(instrs.PayloadStart(), instrs.Size());
switch (breakpoint_kind_) {
case RawPcDescriptors::kIcCall: {
@@ -49,15 +51,17 @@
}
saved_value_ = CodePatcher::GetStaticCallTargetAt(pc_, code);
CodePatcher::PatchStaticCallAt(pc_, code, stub_target);
- }
+ });
is_enabled_ = true;
}
void CodeBreakpoint::RestoreCode() {
ASSERT(is_enabled_);
- const Code& code = Code::Handle(code_);
- const Instructions& instrs = Instructions::Handle(code.instructions());
- {
+ auto thread = Thread::Current();
+ auto zone = thread->zone();
+ const Code& code = Code::Handle(zone, code_);
+ const Instructions& instrs = Instructions::Handle(zone, code.instructions());
+ thread->isolate_group()->RunWithStoppedMutators([&]() {
WritableInstructionsScope writable(instrs.PayloadStart(), instrs.Size());
switch (breakpoint_kind_) {
case RawPcDescriptors::kIcCall:
@@ -69,7 +73,7 @@
default:
UNREACHABLE();
}
- }
+ });
is_enabled_ = false;
}
diff --git a/runtime/vm/growable_array_test.cc b/runtime/vm/growable_array_test.cc
index 2b9b23b..7c0ee5d 100644
--- a/runtime/vm/growable_array_test.cc
+++ b/runtime/vm/growable_array_test.cc
@@ -107,4 +107,35 @@
EXPECT_EQ(1, test2->length());
}
+TEST_CASE(GrowableArrayMoveCtor) {
+ GrowableArray<int> a;
+ a.Add(4);
+ a.Add(5);
+ int* a_data = a.data();
+
+ GrowableArray<int> b(std::move(a));
+
+ EXPECT_EQ(0, a.length());
+ EXPECT_EQ((int*)nullptr, a.data());
+ EXPECT_EQ(2, b.length());
+ EXPECT_EQ(a_data, b.data());
+}
+
+TEST_CASE(GrowableArrayMoveAssign) {
+ GrowableArray<int> a, b;
+ a.Add(1);
+ a.Add(2);
+ a.Add(3);
+ b.Add(7);
+ int* a_data = a.data();
+ int* b_data = b.data();
+
+ a = std::move(b);
+
+ EXPECT_EQ(1, a.length());
+ EXPECT_EQ(b_data, a.data());
+ EXPECT_EQ(3, b.length());
+ EXPECT_EQ(a_data, b.data());
+}
+
} // namespace dart
diff --git a/runtime/vm/image_snapshot.cc b/runtime/vm/image_snapshot.cc
index c097744..bd6f62b 100644
--- a/runtime/vm/image_snapshot.cc
+++ b/runtime/vm/image_snapshot.cc
@@ -219,7 +219,7 @@
}
static constexpr intptr_t kSimarmX64InstructionsAlignment =
- 2 * compiler::target::ObjectAlignment::kObjectAlignment;
+ compiler::target::ObjectAlignment::kObjectAlignment;
static intptr_t InstructionsSizeInSnapshot(intptr_t len) {
const intptr_t header_size = Utils::RoundUp(3 * compiler::target::kWordSize,
kSimarmX64InstructionsAlignment);
@@ -738,7 +738,7 @@
uword next_reloc_offset = iterator.MoveNext() ? iterator.PcOffset() : -1;
for (uword cursor = entry; cursor < end;
- cursor += sizeof(compiler::target::uword*)) {
+ cursor += sizeof(compiler::target::uword)) {
compiler::target::uword data =
*reinterpret_cast<compiler::target::uword*>(cursor);
if ((cursor - entry) == next_reloc_offset) {
diff --git a/runtime/vm/interpreter.cc b/runtime/vm/interpreter.cc
index e4a735a..a46aa0f 100644
--- a/runtime/vm/interpreter.cc
+++ b/runtime/vm/interpreter.cc
@@ -535,9 +535,10 @@
// Calling into runtime may trigger garbage collection and relocate objects,
// so all RawObject* pointers become outdated and should not be used across
// runtime calls.
-// Note: functions below are marked DART_NOINLINE to recover performance on
-// ARM where inlining these functions into the interpreter loop seemed to cause
-// some code quality issues.
+// Note: functions below are marked DART_NOINLINE to recover performance where
+// inlining these functions into the interpreter loop seemed to cause some code
+// quality issues. Functions with the "returns_twice" attribute, such as setjmp,
+// prevent reusing spill slots and large frame sizes.
static DART_NOINLINE bool InvokeRuntime(Thread* thread,
Interpreter* interpreter,
RuntimeFunction drt,
@@ -725,50 +726,6 @@
}
}
-void Interpreter::InlineCacheMiss(int checked_args,
- Thread* thread,
- RawICData* icdata,
- RawObject** args,
- RawObject** top,
- const KBCInstr* pc,
- RawObject** FP,
- RawObject** SP) {
- RawObject** result = top;
- top[0] = 0; // Clean up result slot.
-
- // Save arguments descriptor as it may be clobbered by running Dart code
- // during the call to miss handler (class finalization).
- top[1] = argdesc_;
-
- RawObject** miss_handler_args = top + 2;
- for (intptr_t i = 0; i < checked_args; i++) {
- miss_handler_args[i] = args[i];
- }
- miss_handler_args[checked_args] = icdata;
- RuntimeFunction handler = NULL;
- switch (checked_args) {
- case 1:
- handler = DRT_InlineCacheMissHandlerOneArg;
- break;
- case 2:
- handler = DRT_InlineCacheMissHandlerTwoArgs;
- break;
- default:
- UNREACHABLE();
- break;
- }
-
- // Handler arguments: arguments to check and an ICData object.
- const intptr_t miss_handler_argc = checked_args + 1;
- RawObject** exit_frame = miss_handler_args + miss_handler_argc;
- Exit(thread, FP, exit_frame, pc);
- NativeArguments native_args(thread, miss_handler_argc, miss_handler_args,
- result);
- handler(native_args);
-
- argdesc_ = Array::RawCast(top[1]);
-}
-
DART_FORCE_INLINE bool Interpreter::InstanceCall(Thread* thread,
RawString* target_name,
RawObject** call_base,
@@ -1058,8 +1015,8 @@
SP[1] = 0; /* Unused result. */ \
SP[2] = function; \
Exit(thread, FP, SP + 3, pc); \
- NativeArguments native_args(thread, 1, SP + 2, SP + 1); \
- INVOKE_RUNTIME(DRT_CompileInterpretedFunction, native_args); \
+ INVOKE_RUNTIME(DRT_CompileInterpretedFunction, \
+ NativeArguments(thread, 1, SP + 2, SP + 1)); \
function = FrameFunction(FP); \
} \
}
@@ -1075,14 +1032,14 @@
if (thread->isolate()->debugger()->HasBytecodeBreakpointAt(pc)) { \
SP[1] = null_value; \
Exit(thread, FP, SP + 2, pc); \
- NativeArguments args(thread, 0, NULL, SP + 1); \
- INVOKE_RUNTIME(DRT_BreakpointRuntimeHandler, args) \
+ INVOKE_RUNTIME(DRT_BreakpointRuntimeHandler, \
+ NativeArguments(thread, 0, nullptr, SP + 1)) \
} \
/* The debugger expects to see the same pc again when single-stepping */ \
if (thread->isolate()->single_step()) { \
Exit(thread, FP, SP + 1, pc); \
- NativeArguments args(thread, 0, NULL, NULL); \
- INVOKE_RUNTIME(DRT_SingleStepHandler, args); \
+ INVOKE_RUNTIME(DRT_SingleStepHandler, \
+ NativeArguments(thread, 0, nullptr, nullptr)); \
} \
}
#endif // PRODUCT
@@ -1679,8 +1636,8 @@
if (reinterpret_cast<uword>(SP) >= overflow_stack_limit() ||
thread->HasScheduledInterrupts()) {
Exit(thread, FP, SP + 1, pc);
- NativeArguments args(thread, 0, NULL, NULL);
- INVOKE_RUNTIME(DRT_StackOverflow, args);
+ INVOKE_RUNTIME(DRT_StackOverflow,
+ NativeArguments(thread, 0, nullptr, nullptr));
}
}
RawFunction* function = FrameFunction(FP);
@@ -1691,8 +1648,8 @@
SP[1] = 0; // Unused result.
SP[2] = function;
Exit(thread, FP, SP + 3, pc);
- NativeArguments native_args(thread, 1, SP + 2, SP + 1);
- INVOKE_RUNTIME(DRT_CompileInterpretedFunction, native_args);
+ INVOKE_RUNTIME(DRT_CompileInterpretedFunction,
+ NativeArguments(thread, 1, SP + 2, SP + 1));
}
DISPATCH();
}
@@ -1734,8 +1691,8 @@
SP[3] = SP[0];
Exit(thread, FP, SP + 4, pc);
{
- NativeArguments args(thread, 3, SP + 1, SP - 1);
- INVOKE_RUNTIME(DRT_InstantiateType, args);
+ INVOKE_RUNTIME(DRT_InstantiateType,
+ NativeArguments(thread, 3, SP + 1, SP - 1));
}
SP -= 1;
DISPATCH();
@@ -1773,8 +1730,8 @@
SP[3] = function_type_args;
Exit(thread, FP, SP + 4, pc);
- NativeArguments args(thread, 3, SP + 1, SP - 1);
- INVOKE_RUNTIME(DRT_InstantiateTypeArguments, args);
+ INVOKE_RUNTIME(DRT_InstantiateTypeArguments,
+ NativeArguments(thread, 3, SP + 1, SP - 1));
}
InstantiateTypeArgumentsTOSDone:
@@ -1788,11 +1745,9 @@
SP[1] = 0; // Space for result.
Exit(thread, FP, SP + 2, pc);
if (rA == 0) { // Throw
- NativeArguments args(thread, 1, SP, SP + 1);
- INVOKE_RUNTIME(DRT_Throw, args);
+ INVOKE_RUNTIME(DRT_Throw, NativeArguments(thread, 1, SP, SP + 1));
} else { // ReThrow
- NativeArguments args(thread, 2, SP - 1, SP + 1);
- INVOKE_RUNTIME(DRT_ReThrow, args);
+ INVOKE_RUNTIME(DRT_ReThrow, NativeArguments(thread, 2, SP - 1, SP + 1));
}
}
DISPATCH();
@@ -2190,11 +2145,12 @@
RawObject** incoming_args = SP - num_arguments;
RawObject** return_slot = SP;
Exit(thread, FP, SP + 1, pc);
- NativeArguments args(thread, argc_tag, incoming_args, return_slot);
+ NativeArguments native_args(thread, argc_tag, incoming_args,
+ return_slot);
INVOKE_NATIVE(
payload->trampoline,
reinterpret_cast<Dart_NativeFunction>(payload->native_function),
- reinterpret_cast<Dart_NativeArguments>(&args));
+ reinterpret_cast<Dart_NativeArguments>(&native_args));
*(SP - num_arguments) = *return_slot;
SP -= num_arguments;
@@ -2305,8 +2261,9 @@
SP[2] = field;
SP[3] = value;
Exit(thread, FP, SP + 4, pc);
- NativeArguments args(thread, 2, /* argv */ SP + 2, /* retval */ SP + 1);
- if (!InvokeRuntime(thread, this, DRT_UpdateFieldCid, args)) {
+ if (!InvokeRuntime(thread, this, DRT_UpdateFieldCid,
+ NativeArguments(thread, 2, /* argv */ SP + 2,
+ /* retval */ SP + 1))) {
HANDLE_EXCEPTION;
}
@@ -2462,8 +2419,7 @@
{
SP[1] = SP[0]; // Context to clone.
Exit(thread, FP, SP + 2, pc);
- NativeArguments args(thread, 1, SP + 1, SP);
- INVOKE_RUNTIME(DRT_CloneContext, args);
+ INVOKE_RUNTIME(DRT_CloneContext, NativeArguments(thread, 1, SP + 1, SP));
}
DISPATCH();
}
@@ -2491,8 +2447,8 @@
SP[2] = cls; // Class object.
SP[3] = null_value; // Type arguments.
Exit(thread, FP, SP + 4, pc);
- NativeArguments args(thread, 2, SP + 2, SP + 1);
- INVOKE_RUNTIME(DRT_AllocateObject, args);
+ INVOKE_RUNTIME(DRT_AllocateObject,
+ NativeArguments(thread, 2, SP + 2, SP + 1));
SP++; // Result is in SP[1].
DISPATCH();
}
@@ -2523,8 +2479,8 @@
SP[1] = cls;
SP[2] = type_args;
Exit(thread, FP, SP + 3, pc);
- NativeArguments args(thread, 2, SP + 1, SP - 1);
- INVOKE_RUNTIME(DRT_AllocateObject, args);
+ INVOKE_RUNTIME(DRT_AllocateObject,
+ NativeArguments(thread, 2, SP + 1, SP - 1));
SP -= 1; // Result is in SP - 1.
DISPATCH();
}
@@ -2579,8 +2535,8 @@
RawObject** result_slot = SP;
Exit(thread, FP, SP + 1, pc);
- NativeArguments native_args(thread, 5, args, result_slot);
- INVOKE_RUNTIME(DRT_SubtypeCheck, native_args);
+ INVOKE_RUNTIME(DRT_SubtypeCheck,
+ NativeArguments(thread, 5, args, result_slot));
// Result slot not used anymore.
SP--;
@@ -2606,8 +2562,8 @@
{
SP[1] = SP[0]; // instance
Exit(thread, FP, SP + 2, pc);
- NativeArguments args(thread, 1, SP + 1, SP);
- INVOKE_RUNTIME(DRT_NonBoolTypeError, args);
+ INVOKE_RUNTIME(DRT_NonBoolTypeError,
+ NativeArguments(thread, 1, SP + 1, SP));
}
AssertBooleanOk:
@@ -3146,10 +3102,9 @@
SP[1] = null_value; // Result.
Exit(thread, FP, SP + 2, pc);
- NativeArguments native_args(thread, 0, /* argv */ SP + 1,
- /* retval */ SP + 1);
if (!InvokeRuntime(thread, this, DRT_AllocateSubtypeTestCache,
- native_args)) {
+ NativeArguments(thread, 0, /* argv */ SP + 1,
+ /* retval */ SP + 1))) {
HANDLE_EXCEPTION;
}
@@ -3185,9 +3140,9 @@
SP[2] = field;
SP[3] = value;
Exit(thread, FP, SP + 4, pc);
- NativeArguments native_args(thread, 2, /* argv */ SP + 2,
- /* retval */ SP + 1);
- if (!InvokeRuntime(thread, this, DRT_UpdateFieldCid, native_args)) {
+ if (!InvokeRuntime(thread, this, DRT_UpdateFieldCid,
+ NativeArguments(thread, 2, /* argv */ SP + 2,
+ /* retval */ SP + 1))) {
HANDLE_EXCEPTION;
}
@@ -3250,8 +3205,8 @@
SP[1] = 0; // Unused result of invoking the initializer.
SP[2] = field;
Exit(thread, FP, SP + 3, pc);
- NativeArguments native_args(thread, 1, SP + 2, SP + 1);
- INVOKE_RUNTIME(DRT_InitStaticField, native_args);
+ INVOKE_RUNTIME(DRT_InitStaticField,
+ NativeArguments(thread, 1, SP + 2, SP + 1));
// Reload objects after the call which may trigger GC.
function = FrameFunction(FP);
@@ -3351,8 +3306,8 @@
SP[3] = receiver; // Receiver.
SP[4] = function->ptr()->name_; // Field name.
Exit(thread, FP, SP + 5, pc);
- NativeArguments native_args(thread, 2, SP + 3, SP + 2);
- if (!InvokeRuntime(thread, this, DRT_GetFieldForDispatch, native_args)) {
+ if (!InvokeRuntime(thread, this, DRT_GetFieldForDispatch,
+ NativeArguments(thread, 2, SP + 3, SP + 2))) {
HANDLE_EXCEPTION;
}
argdesc_ = Array::RawCast(SP[1]);
@@ -3374,8 +3329,8 @@
SP[2] = receiver;
SP[3] = argdesc_;
Exit(thread, FP, SP + 4, pc);
- NativeArguments native_args(thread, 2, SP + 2, SP + 1);
- if (!InvokeRuntime(thread, this, DRT_ResolveCallFunction, native_args)) {
+ if (!InvokeRuntime(thread, this, DRT_ResolveCallFunction,
+ NativeArguments(thread, 2, SP + 2, SP + 1))) {
HANDLE_EXCEPTION;
}
argdesc_ = Array::RawCast(SP[3]);
@@ -3401,8 +3356,8 @@
SP[5] = Smi::New(argc); // length
SP[6] = null_value; // type
Exit(thread, FP, SP + 7, pc);
- NativeArguments native_args(thread, 2, SP + 5, SP + 4);
- if (!InvokeRuntime(thread, this, DRT_AllocateArray, native_args)) {
+ if (!InvokeRuntime(thread, this, DRT_AllocateArray,
+ NativeArguments(thread, 2, SP + 5, SP + 4))) {
HANDLE_EXCEPTION;
}
}
@@ -3422,8 +3377,8 @@
// array of arguments, and target name.
{
Exit(thread, FP, SP + 6, pc);
- NativeArguments native_args(thread, 4, SP + 2, SP + 1);
- if (!InvokeRuntime(thread, this, DRT_InvokeNoSuchMethod, native_args)) {
+ if (!InvokeRuntime(thread, this, DRT_InvokeNoSuchMethod,
+ NativeArguments(thread, 4, SP + 2, SP + 1))) {
HANDLE_EXCEPTION;
}
@@ -3484,8 +3439,8 @@
SP[8] = SP[5]; // instantiator_type_args
SP[9] = null_value; // function_type_args
Exit(thread, FP, SP + 10, pc);
- NativeArguments args(thread, 3, SP + 7, SP + 7);
- INVOKE_RUNTIME(DRT_InstantiateTypeArguments, args);
+ INVOKE_RUNTIME(DRT_InstantiateTypeArguments,
+ NativeArguments(thread, 3, SP + 7, SP + 7));
SP[6] = SP[7];
}
}
@@ -3518,8 +3473,8 @@
SP[9] = check->ptr()->name_;
SP[10] = 0;
Exit(thread, FP, SP + 11, pc);
- NativeArguments native_args(thread, 5, SP + 5, SP + 10);
- INVOKE_RUNTIME(DRT_SubtypeCheck, native_args);
+ INVOKE_RUNTIME(DRT_SubtypeCheck,
+ NativeArguments(thread, 5, SP + 5, SP + 10));
}
checks = Array::RawCast(SP[1]); // Reload after runtime call.
@@ -3602,9 +3557,9 @@
SP[2] = 0; // Code result.
SP[3] = function;
Exit(thread, FP, SP + 4, pc);
- NativeArguments native_args(thread, 1, /* argv */ SP + 3,
- /* retval */ SP + 2);
- if (!InvokeRuntime(thread, this, DRT_CompileFunction, native_args)) {
+ if (!InvokeRuntime(thread, this, DRT_CompileFunction,
+ NativeArguments(thread, 1, /* argv */ SP + 3,
+ /* retval */ SP + 2))) {
HANDLE_EXCEPTION;
}
function = Function::RawCast(SP[3]);
@@ -3637,8 +3592,8 @@
SP[6] = Smi::New(argc); // length
SP[7] = null_value; // type
Exit(thread, FP, SP + 8, pc);
- NativeArguments native_args(thread, 2, SP + 6, SP + 5);
- if (!InvokeRuntime(thread, this, DRT_AllocateArray, native_args)) {
+ if (!InvokeRuntime(thread, this, DRT_AllocateArray,
+ NativeArguments(thread, 2, SP + 6, SP + 5))) {
HANDLE_EXCEPTION;
}
@@ -3654,8 +3609,8 @@
// and array of arguments.
{
Exit(thread, FP, SP + 6, pc);
- NativeArguments native_args(thread, 4, SP + 2, SP + 1);
- INVOKE_RUNTIME(DRT_NoSuchMethodFromPrologue, native_args);
+ INVOKE_RUNTIME(DRT_NoSuchMethodFromPrologue,
+ NativeArguments(thread, 4, SP + 2, SP + 1));
++SP; // Result at SP[0]
}
@@ -3667,8 +3622,8 @@
// SP[0] contains selector.
SP[1] = 0; // Unused space for result.
Exit(thread, FP, SP + 2, pc);
- NativeArguments args(thread, 1, SP, SP + 1);
- INVOKE_RUNTIME(DRT_NullErrorWithSelector, args);
+ INVOKE_RUNTIME(DRT_NullErrorWithSelector,
+ NativeArguments(thread, 1, SP, SP + 1));
UNREACHABLE();
}
@@ -3676,8 +3631,8 @@
ThrowIntegerDivisionByZeroException:
SP[0] = 0; // Unused space for result.
Exit(thread, FP, SP + 1, pc);
- NativeArguments args(thread, 0, SP, SP);
- INVOKE_RUNTIME(DRT_IntegerDivisionByZeroException, args);
+ INVOKE_RUNTIME(DRT_IntegerDivisionByZeroException,
+ NativeArguments(thread, 0, SP, SP));
UNREACHABLE();
}
@@ -3686,8 +3641,7 @@
// SP[0] contains value.
SP[1] = 0; // Unused space for result.
Exit(thread, FP, SP + 2, pc);
- NativeArguments args(thread, 1, SP, SP + 1);
- INVOKE_RUNTIME(DRT_ArgumentError, args);
+ INVOKE_RUNTIME(DRT_ArgumentError, NativeArguments(thread, 1, SP, SP + 1));
UNREACHABLE();
}
diff --git a/runtime/vm/interpreter.h b/runtime/vm/interpreter.h
index 4889a5a..e7fa7d6 100644
--- a/runtime/vm/interpreter.h
+++ b/runtime/vm/interpreter.h
@@ -176,15 +176,6 @@
RawObject*** FP,
RawObject*** SP);
- void InlineCacheMiss(int checked_args,
- Thread* thread,
- RawICData* icdata,
- RawObject** call_base,
- RawObject** top,
- const KBCInstr* pc,
- RawObject** FP,
- RawObject** SP);
-
bool InstanceCall(Thread* thread,
RawString* target_name,
RawObject** call_base,
diff --git a/runtime/vm/isolate.cc b/runtime/vm/isolate.cc
index 261fde1..fc85292 100644
--- a/runtime/vm/isolate.cc
+++ b/runtime/vm/isolate.cc
@@ -132,17 +132,17 @@
IsolateGroup::IsolateGroup(std::unique_ptr<IsolateGroupSource> source,
void* embedder_data)
- : source_(std::move(source)),
- embedder_data_(embedder_data),
+ : embedder_data_(embedder_data),
+ isolates_rwlock_(new RwLock()),
+ isolates_(),
+ source_(std::move(source)),
thread_registry_(new ThreadRegistry()),
- safepoint_handler_(new SafepointHandler(this)),
- isolates_monitor_(new Monitor()),
- isolates_() {}
+ safepoint_handler_(new SafepointHandler(this)) {}
IsolateGroup::~IsolateGroup() {}
void IsolateGroup::RegisterIsolate(Isolate* isolate) {
- MonitorLocker ml(isolates_monitor_.get());
+ WriteRwLocker wl(ThreadState::Current(), isolates_rwlock_.get());
isolates_.Append(isolate);
isolate_count_++;
}
@@ -150,7 +150,7 @@
void IsolateGroup::UnregisterIsolate(Isolate* isolate) {
bool is_last_isolate = false;
{
- MonitorLocker ml(isolates_monitor_.get());
+ WriteRwLocker wl(ThreadState::Current(), isolates_rwlock_.get());
isolates_.Remove(isolate);
isolate_count_--;
is_last_isolate = isolate_count_ == 0;
@@ -2226,6 +2226,30 @@
ASSERT(!Thread::Current()->is_marking());
}
+void IsolateGroup::RunWithStoppedMutators(
+ std::function<void()> single_current_mutator,
+ std::function<void()> otherwise,
+ bool use_force_growth_in_otherwise) {
+ auto thread = Thread::Current();
+
+ ReadRwLocker wl(thread, isolates_rwlock_.get());
+ const bool only_one_isolate = isolates_.First() == isolates_.Last();
+ if (thread->IsMutatorThread() && only_one_isolate) {
+ single_current_mutator();
+ } else {
+ // We use the more strict safepoint operation scope here (which ensures that
+ // all other threads, including auxiliary threads are at a safepoint), even
+ // though we only need to ensure that the mutator threads are stopped.
+ if (use_force_growth_in_otherwise) {
+ ForceGrowthSafepointOperationScope safepoint_scope(thread);
+ otherwise();
+ } else {
+ SafepointOperationScope safepoint_scope(thread);
+ otherwise();
+ }
+ }
+}
+
RawClass* Isolate::GetClassForHeapWalkAt(intptr_t cid) {
RawClass* raw_class = nullptr;
#if !defined(PRODUCT) && !defined(DART_PRECOMPILED_RUNTIME)
diff --git a/runtime/vm/isolate.h b/runtime/vm/isolate.h
index faef0b3..701d58f 100644
--- a/runtime/vm/isolate.h
+++ b/runtime/vm/isolate.h
@@ -9,6 +9,7 @@
#error "Should not include runtime"
#endif
+#include <functional>
#include <memory>
#include <utility>
@@ -78,6 +79,7 @@
class RawInt32x4;
class RawUserTag;
class ReversePcLookupCache;
+class RwLock;
class SafepointHandler;
class SampleBuffer;
class SendPort;
@@ -262,16 +264,36 @@
library_tag_handler_ = handler;
}
+ // Ensures mutators are stopped during execution of the provided function.
+ //
+ // If the current thread is the only mutator in the isolate group,
+ // [single_current_mutator] will be called. Otherwise [otherwise] will be
+ // called inside a [SafepointOperationsScope] (or
+ // [ForceGrowthSafepointOperationScope] if [use_force_growth_in_otherwise]
+ // is set).
+ //
+ // During the duration of this function, no new isolates can be added to the
+ // isolate group.
+ void RunWithStoppedMutators(std::function<void()> single_current_mutator,
+ std::function<void()> otherwise,
+ bool use_force_growth_in_otherwise = false);
+
+ void RunWithStoppedMutators(std::function<void()> function) {
+ RunWithStoppedMutators(function, function);
+ }
+
private:
- std::unique_ptr<IsolateGroupSource> source_;
void* embedder_data_ = nullptr;
- std::unique_ptr<ThreadRegistry> thread_registry_;
- std::unique_ptr<SafepointHandler> safepoint_handler_;
- std::unique_ptr<Monitor> isolates_monitor_;
+
+ std::unique_ptr<RwLock> isolates_rwlock_;
IntrusiveDList<Isolate> isolates_;
intptr_t isolate_count_ = 0;
bool initial_spawn_successful_ = false;
Dart_LibraryTagHandler library_tag_handler_ = nullptr;
+
+ std::unique_ptr<IsolateGroupSource> source_;
+ std::unique_ptr<ThreadRegistry> thread_registry_;
+ std::unique_ptr<SafepointHandler> safepoint_handler_;
};
class Isolate : public BaseIsolate, public IntrusiveDListEntry<Isolate> {
diff --git a/runtime/vm/kernel.cc b/runtime/vm/kernel.cc
index 9e6af12..2b82f32 100644
--- a/runtime/vm/kernel.cc
+++ b/runtime/vm/kernel.cc
@@ -8,6 +8,7 @@
#include "vm/compiler/frontend/bytecode_reader.h"
#include "vm/compiler/frontend/constant_evaluator.h"
#include "vm/compiler/frontend/kernel_translation_helper.h"
+#include "vm/compiler/jit/compiler.h"
#include "vm/longjump.h"
#include "vm/object_store.h"
#include "vm/parser.h" // For Parser::kParameter* constants.
@@ -134,8 +135,7 @@
intptr_t data_program_offset,
intptr_t initial_script_index,
intptr_t record_for_script_id,
- GrowableArray<intptr_t>* record_token_positions_into,
- GrowableArray<intptr_t>* record_yield_positions_into)
+ GrowableArray<intptr_t>* record_token_positions_into)
: KernelReaderHelper(zone,
translation_helper,
script,
@@ -143,13 +143,11 @@
data_program_offset),
current_script_id_(initial_script_index),
record_for_script_id_(record_for_script_id),
- record_token_positions_into_(record_token_positions_into),
- record_yield_positions_into_(record_yield_positions_into) {}
+ record_token_positions_into_(record_token_positions_into) {}
void CollectTokenPositions(intptr_t kernel_offset);
void RecordTokenPosition(TokenPosition position) override;
- void RecordYieldPosition(TokenPosition position) override;
void set_current_script_id(intptr_t id) override { current_script_id_ = id; }
@@ -157,7 +155,6 @@
intptr_t current_script_id_;
intptr_t record_for_script_id_;
GrowableArray<intptr_t>* record_token_positions_into_;
- GrowableArray<intptr_t>* record_yield_positions_into_;
DISALLOW_COPY_AND_ASSIGN(KernelTokenPositionCollector);
};
@@ -195,13 +192,6 @@
}
}
-void KernelTokenPositionCollector::RecordYieldPosition(TokenPosition position) {
- if (record_for_script_id_ == current_script_id_ &&
- record_yield_positions_into_ != NULL && position.IsReal()) {
- record_yield_positions_into_->Add(position.value());
- }
-}
-
static int LowestFirst(const intptr_t* a, const intptr_t* b) {
return *a - *b;
}
@@ -246,8 +236,7 @@
intptr_t data_kernel_offset,
Zone* zone,
TranslationHelper* helper,
- GrowableArray<intptr_t>* token_positions,
- GrowableArray<intptr_t>* yield_positions) {
+ GrowableArray<intptr_t>* token_positions) {
if (kernel_data.IsNull()) {
return;
}
@@ -255,7 +244,7 @@
KernelTokenPositionCollector token_position_collector(
zone, helper, script, kernel_data, data_kernel_offset,
entry_script.kernel_script_index(), script.kernel_script_index(),
- token_positions, yield_positions);
+ token_positions);
token_position_collector.CollectTokenPositions(kernel_offset);
}
@@ -333,7 +322,6 @@
helper.InitFromScript(interesting_script);
GrowableArray<intptr_t> token_positions(10);
- GrowableArray<intptr_t> yield_positions(1);
Isolate* isolate = thread->isolate();
const GrowableObjectArray& libs =
@@ -396,7 +384,7 @@
data, interesting_script, entry_script,
temp_field.kernel_offset(),
temp_field.KernelDataProgramOffset(), zone, &helper,
- &token_positions, &yield_positions);
+ &token_positions);
}
}
temp_array = klass.functions();
@@ -415,7 +403,7 @@
data, interesting_script, entry_script,
temp_function.kernel_offset(),
temp_function.KernelDataProgramOffset(), zone, &helper,
- &token_positions, &yield_positions);
+ &token_positions);
}
}
} else {
@@ -432,10 +420,9 @@
if (entry_script.raw() != interesting_script.raw()) {
continue;
}
- CollectKernelDataTokenPositions(data, interesting_script,
- entry_script, class_offset,
- library_kernel_offset, zone, &helper,
- &token_positions, &yield_positions);
+ CollectKernelDataTokenPositions(
+ data, interesting_script, entry_script, class_offset,
+ library_kernel_offset, zone, &helper, &token_positions);
}
} else if (entry.IsFunction()) {
temp_function ^= entry.raw();
@@ -452,7 +439,7 @@
data, interesting_script, entry_script,
temp_function.kernel_offset(),
temp_function.KernelDataProgramOffset(), zone, &helper,
- &token_positions, &yield_positions);
+ &token_positions);
}
} else if (entry.IsField()) {
const Field& field = Field::Cast(entry);
@@ -476,8 +463,7 @@
data = field.KernelData();
CollectKernelDataTokenPositions(
data, interesting_script, entry_script, field.kernel_offset(),
- field.KernelDataProgramOffset(), zone, &helper, &token_positions,
- &yield_positions);
+ field.KernelDataProgramOffset(), zone, &helper, &token_positions);
}
}
}
@@ -487,10 +473,6 @@
Array& array_object = Array::Handle(zone);
array_object = AsSortedDuplicateFreeArray(&token_positions);
script.set_debug_positions(array_object);
- array_object = AsSortedDuplicateFreeArray(&yield_positions);
- // Note that yield positions in members declared in bytecode are not collected
- // here, but on demand in the debugger.
- script.set_yield_positions(array_object);
}
class MetadataEvaluator : public KernelReaderHelper {
@@ -589,7 +571,7 @@
type_translator_(this, active_class, /* finalize= */ true),
constant_evaluator_(this, &type_translator_, active_class, nullptr) {}
- RawObject* BuildParameterDescriptor(intptr_t kernel_offset);
+ RawObject* BuildParameterDescriptor(const Function& function);
private:
TypeTranslator type_translator_;
@@ -599,8 +581,8 @@
};
RawObject* ParameterDescriptorBuilder::BuildParameterDescriptor(
- intptr_t kernel_offset) {
- SetOffset(kernel_offset);
+ const Function& function) {
+ SetOffset(function.kernel_offset());
ReadUntilFunctionNode();
FunctionNodeHelper function_node_helper(this);
function_node_helper.ReadUntilExcluding(
@@ -628,17 +610,19 @@
helper.IsFinal() ? Bool::True() : Bool::False());
Tag tag = ReadTag(); // read (first part of) initializer.
- if (tag == kSomething) {
+ if ((tag == kSomething) && !function.is_abstract()) {
// this will (potentially) read the initializer, but reset the position.
Instance& constant = Instance::ZoneHandle(
zone_, constant_evaluator_.EvaluateExpression(ReaderOffset()));
- SkipExpression(); // read (actual) initializer.
param_descriptor.SetAt(entry_start + Parser::kParameterDefaultValueOffset,
constant);
} else {
param_descriptor.SetAt(entry_start + Parser::kParameterDefaultValueOffset,
Object::null_instance());
}
+ if (tag == kSomething) {
+ SkipExpression(); // read (actual) initializer.
+ }
if (FLAG_enable_mirrors && (helper.annotation_count_ > 0)) {
AlternativeReadingScope alt(&reader_, param_kernel_offset);
@@ -683,7 +667,7 @@
ExternalTypedData::Handle(zone, function.KernelData()),
function.KernelDataProgramOffset(), &active_class);
- return builder.BuildParameterDescriptor(function.kernel_offset());
+ return builder.BuildParameterDescriptor(function);
} else {
return Thread::Current()->StealStickyError();
}
@@ -818,6 +802,10 @@
ProcedureAttributesMetadata ProcedureAttributesOf(const Function& function,
Zone* zone) {
+ if (function.is_declared_in_bytecode()) {
+ // TODO(alexmarkov): add AOT metadata to bytecode.
+ return ProcedureAttributesMetadata();
+ }
const Script& script = Script::Handle(zone, function.script());
return ProcedureAttributesOf(
zone, script, ExternalTypedData::Handle(zone, function.KernelData()),
@@ -826,6 +814,10 @@
ProcedureAttributesMetadata ProcedureAttributesOf(const Field& field,
Zone* zone) {
+ if (field.is_declared_in_bytecode()) {
+ // TODO(alexmarkov): add AOT metadata to bytecode.
+ return ProcedureAttributesMetadata();
+ }
const Class& parent = Class::Handle(zone, field.Owner());
const Script& script = Script::Handle(zone, parent.script());
return ProcedureAttributesOf(
diff --git a/runtime/vm/kernel_binary.h b/runtime/vm/kernel_binary.h
index 009cab2..427163e 100644
--- a/runtime/vm/kernel_binary.h
+++ b/runtime/vm/kernel_binary.h
@@ -20,7 +20,7 @@
// Both version numbers are inclusive.
static const uint32_t kMinSupportedKernelFormatVersion = 18;
-static const uint32_t kMaxSupportedKernelFormatVersion = 31;
+static const uint32_t kMaxSupportedKernelFormatVersion = 32;
// Keep in sync with package:kernel/lib/binary/tag.dart
#define KERNEL_TAG_LIST(V) \
@@ -407,36 +407,43 @@
class AlternativeReadingScope {
public:
AlternativeReadingScope(Reader* reader, intptr_t new_position)
- : reader_(reader),
- saved_size_(reader_->size()),
- saved_raw_buffer_(reader_->raw_buffer()),
- saved_typed_data_(reader_->typed_data()),
- saved_offset_(reader_->offset()) {
+ : reader_(reader), saved_offset_(reader_->offset()) {
reader_->set_offset(new_position);
}
- AlternativeReadingScope(Reader* reader,
- const ExternalTypedData* new_typed_data,
- intptr_t new_position)
+ explicit AlternativeReadingScope(Reader* reader)
+ : reader_(reader), saved_offset_(reader_->offset()) {}
+
+ ~AlternativeReadingScope() { reader_->set_offset(saved_offset_); }
+
+ intptr_t saved_offset() { return saved_offset_; }
+
+ private:
+ Reader* const reader_;
+ const intptr_t saved_offset_;
+
+ DISALLOW_COPY_AND_ASSIGN(AlternativeReadingScope);
+};
+
+// Similar to AlternativeReadingScope, but also switches reading to another
+// typed data array.
+class AlternativeReadingScopeWithNewData {
+ public:
+ AlternativeReadingScopeWithNewData(Reader* reader,
+ const ExternalTypedData* new_typed_data,
+ intptr_t new_position)
: reader_(reader),
saved_size_(reader_->size()),
saved_raw_buffer_(reader_->raw_buffer()),
saved_typed_data_(reader_->typed_data()),
saved_offset_(reader_->offset()) {
- reader_->set_raw_buffer(NULL);
+ reader_->set_raw_buffer(nullptr);
reader_->set_typed_data(new_typed_data);
reader_->set_size(new_typed_data->Length());
reader_->set_offset(new_position);
}
- explicit AlternativeReadingScope(Reader* reader)
- : reader_(reader),
- saved_size_(reader_->size()),
- saved_raw_buffer_(reader_->raw_buffer()),
- saved_typed_data_(reader_->typed_data()),
- saved_offset_(reader_->offset()) {}
-
- ~AlternativeReadingScope() {
+ ~AlternativeReadingScopeWithNewData() {
reader_->set_raw_buffer(saved_raw_buffer_);
reader_->set_typed_data(saved_typed_data_);
reader_->set_size(saved_size_);
@@ -452,7 +459,7 @@
const ExternalTypedData* saved_typed_data_;
intptr_t saved_offset_;
- DISALLOW_COPY_AND_ASSIGN(AlternativeReadingScope);
+ DISALLOW_COPY_AND_ASSIGN(AlternativeReadingScopeWithNewData);
};
// A helper class that resets the readers min and max positions both upon
diff --git a/runtime/vm/kernel_loader.cc b/runtime/vm/kernel_loader.cc
index b591aef..e0631b8 100644
--- a/runtime/vm/kernel_loader.cc
+++ b/runtime/vm/kernel_loader.cc
@@ -1815,7 +1815,7 @@
}
const intptr_t offset_in_constant_table = helper_.ReadUInt();
- AlternativeReadingScope scope(
+ AlternativeReadingScopeWithNewData scope(
&helper_.reader_,
&ExternalTypedData::Handle(Z,
kernel_program_info_.constants_table()),
diff --git a/runtime/vm/lockers.cc b/runtime/vm/lockers.cc
index 79f6f25..ca5c671 100644
--- a/runtime/vm/lockers.cc
+++ b/runtime/vm/lockers.cc
@@ -101,4 +101,22 @@
}
}
+ReadRwLocker::ReadRwLocker(ThreadState* thread_state, RwLock* rw_lock)
+ : StackResource(thread_state), rw_lock_(rw_lock) {
+ rw_lock_->EnterRead();
+}
+
+ReadRwLocker::~ReadRwLocker() {
+ rw_lock_->LeaveRead();
+}
+
+WriteRwLocker::WriteRwLocker(ThreadState* thread_state, RwLock* rw_lock)
+ : StackResource(thread_state), rw_lock_(rw_lock) {
+ rw_lock_->EnterWrite();
+}
+
+WriteRwLocker::~WriteRwLocker() {
+ rw_lock_->LeaveWrite();
+}
+
} // namespace dart
diff --git a/runtime/vm/lockers.h b/runtime/vm/lockers.h
index de62b6c..3e81788 100644
--- a/runtime/vm/lockers.h
+++ b/runtime/vm/lockers.h
@@ -252,6 +252,91 @@
DISALLOW_COPY_AND_ASSIGN(SafepointMonitorLocker);
};
+class RwLock {
+ public:
+ RwLock() {}
+ ~RwLock() {}
+
+ private:
+ friend class ReadRwLocker;
+ friend class WriteRwLocker;
+
+ void EnterRead() {
+ MonitorLocker ml(&monitor_);
+ while (state_ == -1) {
+ ml.Wait();
+ }
+ ++state_;
+ }
+ void LeaveRead() {
+ MonitorLocker ml(&monitor_);
+ ASSERT(state_ > 0);
+ if (--state_ == 0) {
+ ml.NotifyAll();
+ }
+ }
+
+ void EnterWrite() {
+ MonitorLocker ml(&monitor_);
+ while (state_ != 0) {
+ ml.Wait();
+ }
+ state_ = -1;
+ }
+ void LeaveWrite() {
+ MonitorLocker ml(&monitor_);
+ ASSERT(state_ == -1);
+ state_ = 0;
+ ml.NotifyAll();
+ }
+
+ Monitor monitor_;
+ // [state_] > 0 : The lock is held by multiple readers.
+ // [state_] == 0 : The lock is free (no readers/writers).
+ // [state_] == -1: The lock is held by a single writer.
+ intptr_t state_ = 0;
+};
+
+/*
+ * Locks a given [RwLock] for reading purposes.
+ *
+ * It will block while the lock is held by a writer.
+ *
+ * If this locker is long'jmped over (e.g. on a background compiler thread) the
+ * lock will be freed.
+ *
+ * NOTE: If the locking operation blocks (due to a writer) it will not check
+ * for a pending safepoint operation.
+ */
+class ReadRwLocker : public StackResource {
+ public:
+ ReadRwLocker(ThreadState* thread_state, RwLock* rw_lock);
+ ~ReadRwLocker();
+
+ private:
+ RwLock* rw_lock_;
+};
+
+/*
+ * Locks a given [RwLock] for writing purposes.
+ *
+ * It will block while the lock is held by one or more readers.
+ *
+ * If this locker is long'jmped over (e.g. on a background compiler thread) the
+ * lock will be freed.
+ *
+ * NOTE: If the locking operation blocks (due to a writer) it will not check
+ * for a pending safepoint operation.
+ */
+class WriteRwLocker : public StackResource {
+ public:
+ WriteRwLocker(ThreadState* thread_state, RwLock* rw_lock);
+ ~WriteRwLocker();
+
+ private:
+ RwLock* rw_lock_;
+};
+
} // namespace dart
#endif // RUNTIME_VM_LOCKERS_H_
diff --git a/runtime/vm/object.cc b/runtime/vm/object.cc
index c541cd2..007878e 100644
--- a/runtime/vm/object.cc
+++ b/runtime/vm/object.cc
@@ -1931,6 +1931,15 @@
}
object_store->set_bootstrap_library(ObjectStore::kWasm, lib);
+#define REGISTER_WASM_TYPE(clazz) \
+ cls = Class::New<Instance>(k##clazz##Cid, isolate); \
+ cls.set_num_type_arguments(0); \
+ cls.set_is_prefinalized(); \
+ pending_classes.Add(cls); \
+ RegisterClass(cls, Symbols::clazz(), lib);
+ CLASS_LIST_WASM(REGISTER_WASM_TYPE);
+#undef REGISTER_WASM_TYPE
+
// Finish the initialization by compiling the bootstrap scripts containing
// the base interfaces and the implementation of the internal classes.
const Error& error = Error::Handle(
@@ -2025,6 +2034,11 @@
CLASS_LIST_FFI_TYPE_MARKER(REGISTER_FFI_CLASS);
#undef REGISTER_FFI_CLASS
+#define REGISTER_WASM_CLASS(clazz) \
+ cls = Class::New<Instance>(k##clazz##Cid, isolate);
+ CLASS_LIST_WASM(REGISTER_WASM_CLASS);
+#undef REGISTER_WASM_CLASS
+
cls = Class::New<Instance>(kFfiNativeFunctionCid, isolate);
cls = Class::NewPointerClass(kFfiPointerCid, isolate);
@@ -3173,16 +3187,6 @@
return result.raw();
}
-RawFunction* Function::GetTargetOfDynamicInvocationForwarder() const {
- ASSERT(IsDynamicInvocationForwarder());
- auto& func_name = String::Handle(name());
- func_name = DemangleDynamicInvocationForwarderName(func_name);
- const auto& owner = Class::Handle(Owner());
- RawFunction* target = owner.LookupDynamicFunction(func_name);
- ASSERT(target != Function::null());
- return target;
-}
-
#endif
bool AbstractType::InstantiateAndTestSubtype(
@@ -9372,13 +9376,12 @@
void Script::LookupSourceAndLineStarts(Zone* zone) const {
#if !defined(DART_PRECOMPILED_RUNTIME)
- if (Source() == String::null()) {
- // This is a script without source info.
+ if (!IsLazyLookupSourceAndLineStarts()) {
return;
}
const String& uri = String::Handle(zone, resolved_url());
ASSERT(uri.IsSymbol());
- if (uri.Length() > 0 && Source() == Symbols::Empty().raw()) {
+ if (uri.Length() > 0) {
// Entry included only to provide URI - actual source should already exist
// in the VM, so try to find it.
Library& lib = Library::Handle(zone);
@@ -9388,18 +9391,18 @@
for (intptr_t i = 0; i < libs.Length(); i++) {
lib ^= libs.At(i);
script = lib.LookupScript(uri, /* useResolvedUri = */ true);
- if (!script.IsNull() && script.kind() == RawScript::kKernelTag &&
- script.Source() != Symbols::Empty().raw()) {
- set_source(String::Handle(zone, script.Source()));
- set_line_starts(TypedData::Handle(zone, script.line_starts()));
- // Note that we may find a script without source info (null source).
- // We will not repeat the lookup in this case.
- return;
+ if (!script.IsNull() && script.kind() == RawScript::kKernelTag) {
+ const auto& source = String::Handle(zone, script.Source());
+ const auto& line_starts = TypedData::Handle(zone, script.line_starts());
+ if (!source.IsNull() || !line_starts.IsNull()) {
+ set_source(source);
+ set_line_starts(line_starts);
+ break;
+ }
}
}
- set_source(Object::null_string());
- // No script found. Set source to null to prevent further lookup.
}
+ SetLazyLookupSourceAndLineStarts(false);
#endif // !defined(DART_PRECOMPILED_RUNTIME)
}
@@ -9503,16 +9506,28 @@
}
RawArray* Script::yield_positions() const {
-#if !defined(DART_PRECOMPILED_RUNTIME)
- Array& yields = Array::Handle(raw_ptr()->yield_positions_);
- if (yields.IsNull() && kind() == RawScript::kKernelTag) {
- // This is created lazily. Now we need it.
- kernel::CollectTokenPositionsFor(*this);
- }
-#endif // !defined(DART_PRECOMPILED_RUNTIME)
return raw_ptr()->yield_positions_;
}
+RawGrowableObjectArray* Script::GetYieldPositions(
+ const Function& function) const {
+ if (!function.IsAsyncClosure() && !function.IsAsyncGenClosure())
+ return GrowableObjectArray::null();
+ ASSERT(!function.is_declared_in_bytecode());
+ Compiler::ComputeYieldPositions(function);
+ UnorderedHashMap<SmiTraits> function_map(raw_ptr()->yield_positions_);
+ const auto& key = Smi::Handle(Smi::New(function.token_pos().value()));
+ intptr_t entry = function_map.FindKey(key);
+ GrowableObjectArray& array = GrowableObjectArray::Handle();
+ if (entry < 0) {
+ array ^= GrowableObjectArray::null();
+ } else {
+ array ^= function_map.GetPayload(entry, 0);
+ }
+ function_map.Release();
+ return array.raw();
+}
+
RawTypedData* Script::line_starts() const {
return raw_ptr()->line_starts_;
}
@@ -9529,7 +9544,22 @@
}
void Script::set_kind(RawScript::Kind value) const {
- StoreNonPointer(&raw_ptr()->kind_, value);
+ set_kind_and_tags(
+ RawScript::KindBits::update(value, raw_ptr()->kind_and_tags_));
+}
+
+void Script::set_kind_and_tags(uint8_t value) const {
+ StoreNonPointer(&raw_ptr()->kind_and_tags_, value);
+}
+
+void Script::SetLazyLookupSourceAndLineStarts(bool value) const {
+ set_kind_and_tags(RawScript::LazyLookupSourceAndLineStartsBit::update(
+ value, raw_ptr()->kind_and_tags_));
+}
+
+bool Script::IsLazyLookupSourceAndLineStarts() const {
+ return RawScript::LazyLookupSourceAndLineStartsBit::decode(
+ raw_ptr()->kind_and_tags_);
}
void Script::set_load_timestamp(int64_t value) const {
@@ -9805,6 +9835,7 @@
String::Handle(zone, Symbols::New(thread, resolved_url)));
result.set_source(source);
result.SetLocationOffset(0, 0);
+ result.set_kind_and_tags(0);
result.set_kind(kind);
result.set_kernel_script_index(0);
result.set_load_timestamp(
@@ -11399,8 +11430,10 @@
const String& klass,
const Array& arguments,
const TypeArguments& type_arguments) {
+ Zone* zone = Thread::Current()->zone();
#if defined(DART_PRECOMPILED_RUNTIME)
const String& error_str = String::Handle(
+ zone,
String::New("Expression evaluation not available in precompiled mode."));
return ApiError::New(error_str);
#else
@@ -11409,36 +11442,51 @@
if (kernel_pgm == NULL) {
return ApiError::New(String::Handle(
- String::New("Kernel isolate returned ill-formed kernel.")));
+ zone, String::New("Kernel isolate returned ill-formed kernel.")));
}
kernel::KernelLoader loader(kernel_pgm.get(),
/*uri_to_source_table=*/nullptr);
- const Object& result = Object::Handle(
- loader.LoadExpressionEvaluationFunction(library_url, klass));
+ auto& result = Object::Handle(
+ zone, loader.LoadExpressionEvaluationFunction(library_url, klass));
kernel_pgm.reset();
if (result.IsError()) return result.raw();
- const Function& callee = Function::Cast(result);
+ const auto& callee = Function::CheckedHandle(zone, result.raw());
// type_arguments is null if all type arguments are dynamic.
if (type_definitions.Length() == 0 || type_arguments.IsNull()) {
- return DartEntry::InvokeFunction(callee, arguments);
+ result = DartEntry::InvokeFunction(callee, arguments);
+ } else {
+ intptr_t num_type_args = type_arguments.Length();
+ Array& real_arguments =
+ Array::Handle(zone, Array::New(arguments.Length() + 1));
+ real_arguments.SetAt(0, type_arguments);
+ Object& arg = Object::Handle(zone);
+ for (intptr_t i = 0; i < arguments.Length(); ++i) {
+ arg = arguments.At(i);
+ real_arguments.SetAt(i + 1, arg);
+ }
+
+ const Array& args_desc = Array::Handle(
+ zone, ArgumentsDescriptor::New(num_type_args, arguments.Length()));
+ result = DartEntry::InvokeFunction(callee, real_arguments, args_desc);
}
- intptr_t num_type_args = type_arguments.Length();
- Array& real_arguments = Array::Handle(Array::New(arguments.Length() + 1));
- real_arguments.SetAt(0, type_arguments);
- Object& arg = Object::Handle();
- for (intptr_t i = 0; i < arguments.Length(); ++i) {
- arg = arguments.At(i);
- real_arguments.SetAt(i + 1, arg);
+ if (callee.is_declared_in_bytecode()) {
+ // Expression evaluation binary expires immediately after evaluation is
+ // finished. However, hot reload may still find corresponding
+ // KernelProgramInfo object in the heap and it would try to patch it.
+ // To prevent accessing stale kernel binary in ResetObjectTable, bytecode
+ // component of the callee's KernelProgramInfo is reset here.
+ const auto& script = Script::Handle(zone, callee.script());
+ const auto& info =
+ KernelProgramInfo::Handle(zone, script.kernel_program_info());
+ info.set_bytecode_component(Object::null_array());
}
- const Array& args_desc = Array::Handle(
- ArgumentsDescriptor::New(num_type_args, arguments.Length()));
- return DartEntry::InvokeFunction(callee, real_arguments, args_desc);
+ return result.raw();
#endif
}
@@ -12447,6 +12495,21 @@
return "Instructions";
}
+CodeStatistics* Instructions::stats() const {
+#if defined(DART_PRECOMPILER)
+ return reinterpret_cast<CodeStatistics*>(
+ Thread::Current()->heap()->GetPeer(raw()));
+#else
+ return nullptr;
+#endif
+}
+
+void Instructions::set_stats(CodeStatistics* stats) const {
+#if defined(DART_PRECOMPILER)
+ Thread::Current()->heap()->SetPeer(raw(), stats);
+#endif
+}
+
// Encode integer |value| in SLEB128 format and store into |data|.
static void EncodeSLEB128(GrowableArray<uint8_t>* data, intptr_t value) {
bool is_last_part = false;
@@ -13019,7 +13082,6 @@
uword handler_pc_offset,
bool needs_stacktrace,
bool has_catch_all,
- TokenPosition token_pos,
bool is_generated) const {
ASSERT((try_index >= 0) && (try_index < num_entries()));
NoSafepointScope no_safepoint;
@@ -13408,7 +13470,7 @@
}
}
-bool ICData::RebindRuleFromCString(const char* str, RebindRule* out) {
+bool ICData::ParseRebindRule(const char* str, RebindRule* out) {
#define RULE_CASE(Name) \
if (strcmp(str, #Name) == 0) { \
*out = RebindRule::k##Name; \
@@ -14388,6 +14450,39 @@
Code::Comments::Comments(const Array& comments) : comments_(comments) {}
+const char* Code::EntryKindToCString(EntryKind kind) {
+ switch (kind) {
+ case EntryKind::kNormal:
+ return "Normal";
+ case EntryKind::kUnchecked:
+ return "Unchecked";
+ case EntryKind::kMonomorphic:
+ return "Monomorphic";
+ case EntryKind::kMonomorphicUnchecked:
+ return "MonomorphicUnchecked";
+ default:
+ UNREACHABLE();
+ return nullptr;
+ }
+}
+
+bool Code::ParseEntryKind(const char* str, EntryKind* out) {
+ if (strcmp(str, "Normal") == 0) {
+ *out = EntryKind::kNormal;
+ return true;
+ } else if (strcmp(str, "Unchecked") == 0) {
+ *out = EntryKind::kUnchecked;
+ return true;
+ } else if (strcmp(str, "Monomorphic") == 0) {
+ *out = EntryKind::kMonomorphic;
+ return true;
+ } else if (strcmp(str, "MonomorphicUnchecked") == 0) {
+ *out = EntryKind::kMonomorphicUnchecked;
+ return true;
+ }
+ return false;
+}
+
RawLocalVarDescriptors* Code::GetLocalVarDescriptors() const {
const LocalVarDescriptors& v = LocalVarDescriptors::Handle(var_descriptors());
if (v.IsNull()) {
@@ -18595,6 +18690,10 @@
// Out of range.
return Integer::null();
}
+ return NewCanonical(value);
+}
+
+RawInteger* Integer::NewCanonical(int64_t value) {
if (Smi::IsValid(value)) {
return Smi::New(static_cast<intptr_t>(value));
}
diff --git a/runtime/vm/object.h b/runtime/vm/object.h
index 37aba42..33a9dad 100644
--- a/runtime/vm/object.h
+++ b/runtime/vm/object.h
@@ -1810,7 +1810,7 @@
kNumRebindRules,
};
static const char* RebindRuleToCString(RebindRule r);
- static bool RebindRuleFromCString(const char* str, RebindRule* out);
+ static bool ParseRebindRule(const char* str, RebindRule* out);
RebindRule rebind_rule() const;
void set_rebind_rule(uint32_t rebind_rule) const;
@@ -2017,6 +2017,8 @@
}
private:
+ friend class FlowGraphSerializer; // For is_megamorphic()
+
static RawICData* New();
// Grows the array and also sets the argument to the index that should be used
@@ -2990,8 +2992,6 @@
RawFunction* GetDynamicInvocationForwarder(const String& mangled_name,
bool allow_add = true) const;
-
- RawFunction* GetTargetOfDynamicInvocationForwarder() const;
#endif
// Slow function, use in asserts to track changes in important library
@@ -3840,9 +3840,11 @@
void LookupSourceAndLineStarts(Zone* zone) const;
RawGrowableObjectArray* GenerateLineNumberArray() const;
+
RawScript::Kind kind() const {
- return static_cast<RawScript::Kind>(raw_ptr()->kind_);
+ return RawScript::KindBits::decode(raw_ptr()->kind_and_tags_);
}
+
const char* GetKindAsCString() const;
intptr_t line_offset() const { return raw_ptr()->line_offset_; }
intptr_t col_offset() const { return raw_ptr()->col_offset_; }
@@ -3877,6 +3879,8 @@
RawArray* yield_positions() const;
+ RawGrowableObjectArray* GetYieldPositions(const Function& function) const;
+
RawLibrary* FindLibrary() const;
RawString* GetLine(intptr_t line_number,
Heap::Space space = Heap::kNew) const;
@@ -3920,10 +3924,14 @@
intptr_t kernel_buffer_len) const;
#endif // !defined(DART_PRECOMPILED_RUNTIME)
+ void SetLazyLookupSourceAndLineStarts(bool value) const;
+ bool IsLazyLookupSourceAndLineStarts() const;
+
private:
void set_resolved_url(const String& value) const;
void set_source(const String& value) const;
void set_kind(RawScript::Kind value) const;
+ void set_kind_and_tags(uint8_t value) const;
void set_load_timestamp(int64_t value) const;
RawArray* debug_positions() const;
@@ -4783,19 +4791,16 @@
}
static intptr_t InstanceSize(intptr_t size) {
- intptr_t instructions_size =
- Utils::RoundUp(size, OS::PreferredCodeAlignment());
- intptr_t result = instructions_size + HeaderSize();
- ASSERT(result % OS::PreferredCodeAlignment() == 0);
- return result;
+ // OS::PreferredCodeAlignment() is smaller than kObjectAlignment for
+ // simarm_x64.
+ const intptr_t alignment =
+ Utils::Maximum(OS::PreferredCodeAlignment(), kObjectAlignment);
+ return Utils::RoundUp(HeaderSize() + size, alignment);
}
static intptr_t HeaderSize() {
intptr_t alignment = OS::PreferredCodeAlignment();
intptr_t aligned_size = Utils::RoundUp(sizeof(RawInstructions), alignment);
-#if !defined(IS_SIMARM_X64)
- ASSERT(aligned_size == alignment);
-#endif // !defined(IS_SIMARM_X64)
return aligned_size;
}
@@ -4814,19 +4819,8 @@
return memcmp(a->ptr(), b->ptr(), InstanceSize(Size(a))) == 0;
}
- CodeStatistics* stats() const {
-#if defined(DART_PRECOMPILER)
- return raw_ptr()->stats_;
-#else
- return nullptr;
-#endif
- }
-
- void set_stats(CodeStatistics* stats) const {
-#if defined(DART_PRECOMPILER)
- StoreNonPointer(&raw_ptr()->stats_, stats);
-#endif
- }
+ CodeStatistics* stats() const;
+ void set_stats(CodeStatistics* stats) const;
uword unchecked_entrypoint_pc_offset() const {
return raw_ptr()->unchecked_entrypoint_pc_offset_;
@@ -5168,7 +5162,6 @@
uword handler_pc_offset,
bool needs_stacktrace,
bool has_catch_all,
- TokenPosition token_pos,
bool is_generated) const;
RawArray* GetHandledTypes(intptr_t try_index) const;
@@ -5232,6 +5225,9 @@
using EntryKind = CodeEntryKind;
+ static const char* EntryKindToCString(EntryKind kind);
+ static bool ParseEntryKind(const char* str, EntryKind* out);
+
static intptr_t entry_point_offset(EntryKind kind = EntryKind::kNormal) {
switch (kind) {
case EntryKind::kNormal:
@@ -7292,6 +7288,7 @@
// Returns a canonical Integer object allocated in the old gen space.
// Returns null if integer is out of range.
static RawInteger* NewCanonical(const String& str);
+ static RawInteger* NewCanonical(int64_t value);
static RawInteger* New(int64_t value, Heap::Space space = Heap::kNew);
diff --git a/runtime/vm/object_store.h b/runtime/vm/object_store.h
index 8fab9f4..1fe1f7a 100644
--- a/runtime/vm/object_store.h
+++ b/runtime/vm/object_store.h
@@ -27,7 +27,6 @@
M(Isolate, isolate) \
M(Math, math) \
M(Mirrors, mirrors) \
- M(Profiler, profiler) \
M(TypedData, typed_data) \
M(VMService, _vmservice) \
M(Wasm, wasm)
diff --git a/runtime/vm/object_test.cc b/runtime/vm/object_test.cc
index ad0e5ae..8592a76 100644
--- a/runtime/vm/object_test.cc
+++ b/runtime/vm/object_test.cc
@@ -2644,14 +2644,10 @@
exception_handlers ^= ExceptionHandlers::New(kNumEntries);
const bool kNeedsStackTrace = true;
const bool kNoStackTrace = false;
- exception_handlers.SetHandlerInfo(0, -1, 20u, kNeedsStackTrace, false,
- TokenPosition::kNoSource, true);
- exception_handlers.SetHandlerInfo(1, 0, 30u, kNeedsStackTrace, false,
- TokenPosition::kNoSource, true);
- exception_handlers.SetHandlerInfo(2, -1, 40u, kNoStackTrace, true,
- TokenPosition::kNoSource, true);
- exception_handlers.SetHandlerInfo(3, 1, 150u, kNoStackTrace, true,
- TokenPosition::kNoSource, true);
+ exception_handlers.SetHandlerInfo(0, -1, 20u, kNeedsStackTrace, false, true);
+ exception_handlers.SetHandlerInfo(1, 0, 30u, kNeedsStackTrace, false, true);
+ exception_handlers.SetHandlerInfo(2, -1, 40u, kNoStackTrace, true, true);
+ exception_handlers.SetHandlerInfo(3, 1, 150u, kNoStackTrace, true, true);
extern void GenerateIncrement(compiler::Assembler * assembler);
compiler::ObjectPoolBuilder object_pool_builder;
diff --git a/runtime/vm/os.h b/runtime/vm/os.h
index af98eb1..f36bf2e 100644
--- a/runtime/vm/os.h
+++ b/runtime/vm/os.h
@@ -69,7 +69,7 @@
// This constant is guaranteed to be greater or equal to the
// preferred code alignment on all platforms.
- static const int kMaxPreferredCodeAlignment = 32;
+ static const int kMaxPreferredCodeAlignment = 16;
// Returns the preferred code alignment or zero if
// the platform doesn't care. Guaranteed to be a power of two.
diff --git a/runtime/vm/os_android.cc b/runtime/vm/os_android.cc
index 38168ad..9c105a9 100644
--- a/runtime/vm/os_android.cc
+++ b/runtime/vm/os_android.cc
@@ -204,9 +204,9 @@
intptr_t OS::PreferredCodeAlignment() {
#if defined(TARGET_ARCH_IA32) || defined(TARGET_ARCH_X64) || \
defined(TARGET_ARCH_ARM64) || defined(TARGET_ARCH_DBC)
- const int kMinimumAlignment = 32;
-#elif defined(TARGET_ARCH_ARM)
const int kMinimumAlignment = 16;
+#elif defined(TARGET_ARCH_ARM)
+ const int kMinimumAlignment = 8;
#else
#error Unsupported architecture.
#endif
diff --git a/runtime/vm/os_fuchsia.cc b/runtime/vm/os_fuchsia.cc
index 4eaae29..56dc743 100644
--- a/runtime/vm/os_fuchsia.cc
+++ b/runtime/vm/os_fuchsia.cc
@@ -153,9 +153,9 @@
intptr_t OS::PreferredCodeAlignment() {
#if defined(TARGET_ARCH_IA32) || defined(TARGET_ARCH_X64) || \
defined(TARGET_ARCH_ARM64) || defined(TARGET_ARCH_DBC)
- const int kMinimumAlignment = 32;
-#elif defined(TARGET_ARCH_ARM)
const int kMinimumAlignment = 16;
+#elif defined(TARGET_ARCH_ARM)
+ const int kMinimumAlignment = 8;
#else
#error Unsupported architecture.
#endif
diff --git a/runtime/vm/os_linux.cc b/runtime/vm/os_linux.cc
index 9baba7e..65541b0 100644
--- a/runtime/vm/os_linux.cc
+++ b/runtime/vm/os_linux.cc
@@ -516,9 +516,9 @@
intptr_t OS::PreferredCodeAlignment() {
#if defined(TARGET_ARCH_IA32) || defined(TARGET_ARCH_X64) || \
defined(TARGET_ARCH_ARM64) || defined(TARGET_ARCH_DBC)
- const int kMinimumAlignment = 32;
-#elif defined(TARGET_ARCH_ARM)
const int kMinimumAlignment = 16;
+#elif defined(TARGET_ARCH_ARM)
+ const int kMinimumAlignment = 8;
#else
#error Unsupported architecture.
#endif
diff --git a/runtime/vm/os_macos.cc b/runtime/vm/os_macos.cc
index 4788b6c..5518b4a 100644
--- a/runtime/vm/os_macos.cc
+++ b/runtime/vm/os_macos.cc
@@ -154,9 +154,9 @@
intptr_t OS::PreferredCodeAlignment() {
#if defined(TARGET_ARCH_IA32) || defined(TARGET_ARCH_X64) || \
defined(TARGET_ARCH_ARM64) || defined(TARGET_ARCH_DBC)
- const int kMinimumAlignment = 32;
-#elif defined(TARGET_ARCH_ARM)
const int kMinimumAlignment = 16;
+#elif defined(TARGET_ARCH_ARM)
+ const int kMinimumAlignment = 8;
#else
#error Unsupported architecture.
#endif
diff --git a/runtime/vm/os_win.cc b/runtime/vm/os_win.cc
index c0f8e39..fa7a880 100644
--- a/runtime/vm/os_win.cc
+++ b/runtime/vm/os_win.cc
@@ -191,12 +191,12 @@
}
intptr_t OS::PreferredCodeAlignment() {
- ASSERT(32 <= OS::kMaxPreferredCodeAlignment);
+ ASSERT(16 <= OS::kMaxPreferredCodeAlignment);
#if defined(TARGET_ARCH_IA32) || defined(TARGET_ARCH_X64) || \
defined(TARGET_ARCH_ARM64) || defined(TARGET_ARCH_DBC)
- return 32;
-#elif defined(TARGET_ARCH_ARM)
return 16;
+#elif defined(TARGET_ARCH_ARM)
+ return 8;
#else
#error Unsupported architecture.
#endif
diff --git a/runtime/vm/profiler.cc b/runtime/vm/profiler.cc
index fee9e8e..a8f25d3 100644
--- a/runtime/vm/profiler.cc
+++ b/runtime/vm/profiler.cc
@@ -57,6 +57,15 @@
false,
"Collect native stack traces when tracing Dart allocations.");
+DEFINE_FLAG(
+ int,
+ sample_buffer_duration,
+ 0,
+ "Defines the size of the profiler sample buffer to contain at least "
+ "N seconds of samples at a given sample rate. If not provided, the "
+ "default is ~4 seconds. Large values will greatly increase memory "
+ "consumption.");
+
#ifndef PRODUCT
bool Profiler::initialized_ = false;
@@ -72,12 +81,13 @@
return;
}
ASSERT(!initialized_);
- sample_buffer_ = new SampleBuffer();
+ SetSamplePeriod(FLAG_profile_period);
+ intptr_t capacity = CalculateSampleBufferCapacity();
+ sample_buffer_ = new SampleBuffer(capacity);
Profiler::InitAllocationSampleBuffer();
// Zero counters.
memset(&counters_, 0, sizeof(counters_));
ThreadInterrupter::Init();
- SetSamplePeriod(FLAG_profile_period);
ThreadInterrupter::Startup();
initialized_ = true;
}
@@ -116,6 +126,25 @@
}
}
+static intptr_t SamplesPerSecond() {
+ const intptr_t kMicrosPerSec = 1000000;
+ return kMicrosPerSec / FLAG_profile_period;
+}
+
+intptr_t Profiler::CalculateSampleBufferCapacity() {
+ if (FLAG_sample_buffer_duration <= 0) {
+ return SampleBuffer::kDefaultBufferCapacity;
+ }
+ // Deeper stacks require more than a single Sample object to be represented
+ // correctly. These samples are chained, so we need to determine the worst
+ // case sample chain length for a single stack.
+ const intptr_t max_sample_chain_length =
+ FLAG_max_profile_depth / kMaxSamplesPerTick;
+ const intptr_t buffer_size = FLAG_sample_buffer_duration *
+ SamplesPerSecond() * max_sample_chain_length;
+ return buffer_size;
+}
+
void Profiler::SetSamplePeriod(intptr_t period) {
const int kMinimumProfilePeriod = 50;
if (period < kMinimumProfilePeriod) {
@@ -163,6 +192,18 @@
OS::PrintErr("Profiler sample is %" Pd " bytes\n", Sample::instance_size());
OS::PrintErr("Profiler memory usage = %" Pd " bytes\n", size);
}
+ if (FLAG_sample_buffer_duration != 0) {
+ OS::PrintErr(
+ "** WARNING ** Custom sample buffer size provided via "
+ "--sample-buffer-duration\n");
+ OS::PrintErr(
+ "The sample buffer can hold at least %ds worth of "
+ "samples with stacks depths of up to %d, collected at "
+ "a sample rate of %" Pd "Hz.\n",
+ FLAG_sample_buffer_duration, FLAG_max_profile_depth,
+ SamplesPerSecond());
+ OS::PrintErr("The resulting sample buffer size is %" Pd " bytes.\n", size);
+ }
}
AllocationSampleBuffer::AllocationSampleBuffer(intptr_t capacity)
diff --git a/runtime/vm/profiler.h b/runtime/vm/profiler.h
index 9c879ae..c972c40 100644
--- a/runtime/vm/profiler.h
+++ b/runtime/vm/profiler.h
@@ -95,6 +95,13 @@
private:
static void DumpStackTrace(uword sp, uword fp, uword pc, bool for_crash);
+ // Calculates the sample buffer capacity. Returns
+ // SampleBuffer::kDefaultBufferCapacity if --sample-buffer-duration is not
+ // provided. Otherwise, the capacity is based on the sample rate, maximum
+ // sample stack depth, and the number of seconds of samples the sample buffer
+ // should be able to accomodate.
+ static intptr_t CalculateSampleBufferCapacity();
+
// Does not walk the thread's stack.
static void SampleThreadSingleFrame(Thread* thread, uintptr_t pc);
static bool initialized_;
diff --git a/runtime/vm/profiler_test.cc b/runtime/vm/profiler_test.cc
index 65e7a5f..e39faf0 100644
--- a/runtime/vm/profiler_test.cc
+++ b/runtime/vm/profiler_test.cc
@@ -1413,7 +1413,7 @@
DisableNativeProfileScope dnps;
DisableBackgroundCompilationScope dbcs;
SetFlagScope<int> sfs(&FLAG_optimization_counter_threshold, 30000);
- SetFlagScope<bool> sfs2(&FLAG_enable_interpreter, false);
+ SetFlagScope<int> sfs2(&FLAG_compilation_counter_threshold, 0);
const char* kScript =
"class A {\n"
@@ -1532,7 +1532,7 @@
DisableNativeProfileScope dnps;
DisableBackgroundCompilationScope dbcs;
SetFlagScope<int> sfs(&FLAG_optimization_counter_threshold, 30000);
- SetFlagScope<bool> sfs2(&FLAG_enable_interpreter, false);
+ SetFlagScope<int> sfs2(&FLAG_compilation_counter_threshold, 0);
const char* kScript =
"class A {\n"
@@ -1850,8 +1850,8 @@
DisableNativeProfileScope dnps;
DisableBackgroundCompilationScope dbcs;
// Optimize quickly.
- SetFlagScope<int> sfs2(&FLAG_optimization_counter_threshold, 5);
- SetFlagScope<bool> sfs3(&FLAG_enable_interpreter, false);
+ SetFlagScope<int> sfs(&FLAG_optimization_counter_threshold, 5);
+ SetFlagScope<int> sfs2(&FLAG_compilation_counter_threshold, 0);
const char* kScript =
"class A {\n"
" var a;\n"
@@ -2020,8 +2020,8 @@
DisableNativeProfileScope dnps;
DisableBackgroundCompilationScope dbcs;
// Optimize quickly.
- SetFlagScope<int> sfs2(&FLAG_optimization_counter_threshold, 5);
- SetFlagScope<bool> sfs3(&FLAG_enable_interpreter, false);
+ SetFlagScope<int> sfs(&FLAG_optimization_counter_threshold, 5);
+ SetFlagScope<int> sfs2(&FLAG_compilation_counter_threshold, 0);
const char* kScript =
"class A {\n"
@@ -2225,8 +2225,8 @@
DisableNativeProfileScope dnps;
DisableBackgroundCompilationScope dbcs;
// Optimize quickly.
- SetFlagScope<int> sfs2(&FLAG_optimization_counter_threshold, 5);
- SetFlagScope<bool> sfs3(&FLAG_enable_interpreter, false);
+ SetFlagScope<int> sfs(&FLAG_optimization_counter_threshold, 5);
+ SetFlagScope<int> sfs2(&FLAG_compilation_counter_threshold, 0);
const char* kScript =
"class A {\n"
@@ -2300,11 +2300,9 @@
ProfileStackWalker walker(&profile, true);
EXPECT_STREQ("DRT_AllocateObject", walker.VMTagName());
- if (!FLAG_enable_interpreter) {
- EXPECT_STREQ("[Stub] Allocate A", walker.CurrentName());
- EXPECT_EQ(1, walker.CurrentExclusiveTicks());
- EXPECT(walker.Down());
- }
+ EXPECT_STREQ("[Stub] Allocate A", walker.CurrentName());
+ EXPECT_EQ(1, walker.CurrentExclusiveTicks());
+ EXPECT(walker.Down());
EXPECT_STREQ("B.boo", walker.CurrentName());
EXPECT_EQ(1, walker.CurrentInclusiveTicks());
EXPECT_STREQ("A", walker.CurrentToken());
diff --git a/runtime/vm/raw_object.cc b/runtime/vm/raw_object.cc
index 212d274..209363f 100644
--- a/runtime/vm/raw_object.cc
+++ b/runtime/vm/raw_object.cc
@@ -226,8 +226,8 @@
ASSERT(use_saved_class_table || class_table->SizeAt(class_id) > 0);
if (!class_table->IsValidIndex(class_id) ||
(!class_table->HasValidClassAt(class_id) && !use_saved_class_table)) {
- FATAL2("Invalid class id: %" Pd " from tags %x\n", class_id,
- ptr()->tags_);
+ FATAL3("Invalid cid: %" Pd ", obj: %p, tags: %x. Corrupt heap?",
+ class_id, this, ptr()->tags_);
}
#endif // DEBUG
instance_size = isolate->GetClassSizeForHeapWalkAt(class_id);
@@ -320,6 +320,13 @@
break;
}
#undef RAW_VISITPOINTERS
+#define RAW_VISITPOINTERS(clazz) case k##clazz##Cid:
+ CLASS_LIST_WASM(RAW_VISITPOINTERS) {
+ // These wasm types do not have any fields or type arguments.
+ size = HeapSize();
+ break;
+ }
+#undef RAW_VISITPOINTERS
case kFreeListElement: {
uword addr = RawObject::ToAddr(this);
FreeListElement* element = reinterpret_cast<FreeListElement*>(addr);
@@ -336,8 +343,8 @@
size = HeapSize();
break;
default:
- OS::PrintErr("Class Id: %" Pd "\n", class_id);
- UNREACHABLE();
+ FATAL3("Invalid cid: %" Pd ", obj: %p, tags: %x. Corrupt heap?", class_id,
+ this, ptr()->tags_);
break;
}
@@ -660,7 +667,7 @@
}
}
-bool RawPcDescriptors::KindFromCString(const char* cstr, Kind* out) {
+bool RawPcDescriptors::ParseKind(const char* cstr, Kind* out) {
ASSERT(cstr != nullptr && out != nullptr);
#define ENUM_CASE(name, init) \
if (strcmp(#name, cstr) == 0) { \
diff --git a/runtime/vm/raw_object.h b/runtime/vm/raw_object.h
index 0c88bdc..1820fa8 100644
--- a/runtime/vm/raw_object.h
+++ b/runtime/vm/raw_object.h
@@ -899,7 +899,7 @@
}
}
- static bool KindFromCString(const char* str, Kind* out) {
+ static bool ParseKind(const char* str, Kind* out) {
#define KIND_CASE(Name) \
if (strcmp(str, #Name) == 0) { \
*out = Kind::k##Name; \
@@ -1162,6 +1162,12 @@
kEvaluateTag,
kKernelTag,
};
+ enum {
+ kKindPos = 0,
+ kKindSize = 3,
+ kLazyLookupSourceAndLineStartsPos = kKindPos + kKindSize,
+ kLazyLookupSourceAndLineStartsSize = 1,
+ };
private:
RAW_HEAP_OBJECT_IMPLEMENTATION(Script);
@@ -1194,7 +1200,15 @@
int32_t line_offset_;
int32_t col_offset_;
- int8_t kind_; // Of type Kind.
+
+ using KindBits = BitField<uint8_t, Kind, kKindPos, kKindSize>;
+ using LazyLookupSourceAndLineStartsBit =
+ BitField<uint8_t,
+ bool,
+ kLazyLookupSourceAndLineStartsPos,
+ kLazyLookupSourceAndLineStartsSize>;
+ uint8_t kind_and_tags_;
+
intptr_t kernel_script_index_;
int64_t load_timestamp_;
};
@@ -1464,15 +1478,6 @@
uint32_t size_and_flags_;
uint32_t unchecked_entrypoint_pc_offset_;
- // There is a gap between size_and_flags_ and the entry point
- // because we align entry point by 4 words on all platforms.
- // This allows us to have a free field here without affecting
- // the aligned size of the Instructions object header.
- // This also means that entry point offset is the same
- // whether this field is included or excluded.
- // TODO(37103): This field should be removed.
- CodeStatistics* stats_;
-
// Variable length data follows here.
uint8_t* data() { OPEN_ARRAY_START(uint8_t, uint8_t); }
@@ -1527,7 +1532,7 @@
};
static const char* KindToCString(Kind k);
- static bool KindFromCString(const char* cstr, Kind* out);
+ static bool ParseKind(const char* cstr, Kind* out);
class MergedKindTry {
public:
diff --git a/runtime/vm/regexp_assembler_ir.cc b/runtime/vm/regexp_assembler_ir.cc
index f7f18ac..65d81e2 100644
--- a/runtime/vm/regexp_assembler_ir.cc
+++ b/runtime/vm/regexp_assembler_ir.cc
@@ -363,7 +363,7 @@
ConstantInstr* IRRegExpMacroAssembler::Int64Constant(int64_t value) const {
return new (Z)
- ConstantInstr(Integer::ZoneHandle(Z, Integer::New(value, Heap::kOld)));
+ ConstantInstr(Integer::ZoneHandle(Z, Integer::NewCanonical(value)));
}
ConstantInstr* IRRegExpMacroAssembler::Uint64Constant(uint64_t value) const {
diff --git a/runtime/vm/service.cc b/runtime/vm/service.cc
index 98539e3..68cc4a7 100644
--- a/runtime/vm/service.cc
+++ b/runtime/vm/service.cc
@@ -3902,6 +3902,18 @@
return GetAllocationProfileImpl(thread, js, true);
}
+static const MethodParameter* collect_all_garbage_params[] = {
+ RUNNABLE_ISOLATE_PARAMETER,
+ NULL,
+};
+
+static bool CollectAllGarbage(Thread* thread, JSONStream* js) {
+ Isolate* isolate = thread->isolate();
+ isolate->heap()->CollectAllGarbage(Heap::kDebugging);
+ PrintSuccess(js);
+ return true;
+}
+
static const MethodParameter* get_heap_map_params[] = {
RUNNABLE_ISOLATE_PARAMETER, NULL,
};
@@ -4154,6 +4166,7 @@
// load the source before sending the response.
if (obj.IsScript()) {
const Script& script = Script::Cast(obj);
+ script.LookupSourceAndLineStarts(thread->zone());
if (!script.HasSource() && script.IsPartOfDartColonLibrary() &&
Service::HasDartLibraryKernelForSources()) {
const uint8_t* kernel_buffer = Service::dart_library_kernel();
@@ -4747,6 +4760,8 @@
set_vm_name_params },
{ "setVMTimelineFlags", SetVMTimelineFlags,
set_vm_timeline_flags_params },
+ { "_collectAllGarbage", CollectAllGarbage,
+ collect_all_garbage_params },
{ "_getDefaultClassesAliases", GetDefaultClassesAliases,
get_default_classes_aliases_params },
};
diff --git a/runtime/vm/simulator_dbc.cc b/runtime/vm/simulator_dbc.cc
index 619c72e..a0993b7 100644
--- a/runtime/vm/simulator_dbc.cc
+++ b/runtime/vm/simulator_dbc.cc
@@ -927,9 +927,10 @@
argdesc_ = args_desc;
}
-// Note: functions below are marked DART_NOINLINE to recover performance on
-// ARM where inlining these functions into the interpreter loop seemed to cause
-// some code quality issues.
+// Note: functions below are marked DART_NOINLINE to recover performance where
+// inlining these functions into the interpreter loop seemed to cause some code
+// quality issues. Functions with the "returns_twice" attribute, such as setjmp,
+// prevent reusing spill slots and large frame sizes.
DART_NOINLINE static bool InvokeRuntime(Thread* thread,
Simulator* sim,
RuntimeFunction drt,
diff --git a/runtime/vm/source_report.cc b/runtime/vm/source_report.cc
index 59bc7a3..5e161d9 100644
--- a/runtime/vm/source_report.cc
+++ b/runtime/vm/source_report.cc
@@ -585,6 +585,13 @@
functions = cls.functions();
for (int i = 0; i < functions.Length(); i++) {
func ^= functions.At(i);
+ // Skip getter functions of static const field.
+ if (func.kind() == RawFunction::kImplicitStaticGetter) {
+ field ^= func.accessor_field();
+ if (field.is_const() && field.is_static()) {
+ continue;
+ }
+ }
VisitFunction(jsarr, func);
}
diff --git a/runtime/vm/stub_code.cc b/runtime/vm/stub_code.cc
index d22df2b..097510e 100644
--- a/runtime/vm/stub_code.cc
+++ b/runtime/vm/stub_code.cc
@@ -178,40 +178,43 @@
const char* name = cls.ToCString();
compiler::StubCodeCompiler::GenerateAllocationStubForClass(&assembler, cls);
- if (thread->IsMutatorThread()) {
- stub = Code::FinalizeCodeAndNotify(name, nullptr, &assembler,
- pool_attachment,
- /*optimized1*/ false);
+ auto mutator_fun = [&]() {
+ stub = Code::FinalizeCode(nullptr, &assembler, pool_attachment,
+ /*optimized=*/false,
+ /*stats=*/nullptr);
// Check if background compilation thread has not already added the stub.
if (cls.allocation_stub() == Code::null()) {
stub.set_owner(cls);
cls.set_allocation_stub(stub);
}
- } else {
- // This part of stub code generation must be at a safepoint.
- // Stop mutator thread before creating the instruction object and
- // installing code.
- // Mutator thread may not run code while we are creating the
- // instruction object, since the creation of instruction object
- // changes code page access permissions (makes them temporary not
- // executable).
- {
- ForceGrowthSafepointOperationScope safepoint_scope(thread);
- stub = cls.allocation_stub();
- // Check if stub was already generated.
- if (!stub.IsNull()) {
- return stub.raw();
- }
- stub = Code::FinalizeCode(nullptr, &assembler, pool_attachment,
- /*optimized=*/false, /*stats=*/nullptr);
- stub.set_owner(cls);
- cls.set_allocation_stub(stub);
+ };
+ auto bg_compiler_fun = [&]() {
+ ForceGrowthSafepointOperationScope safepoint_scope(thread);
+ stub = cls.allocation_stub();
+ // Check if stub was already generated.
+ if (!stub.IsNull()) {
+ return;
}
+ stub = Code::FinalizeCode(nullptr, &assembler, pool_attachment,
+ /*optimized=*/false, /*stats=*/nullptr);
+ stub.set_owner(cls);
+ cls.set_allocation_stub(stub);
+ };
- // We notify code observers after finalizing the code in order to be
- // outside a [SafepointOperationScope].
- Code::NotifyCodeObservers(name, stub, /*optimized=*/false);
- }
+ // We have to ensure no mutators are running, because:
+ //
+ // a) We allocate an instructions object, which might cause us to
+ // temporarily flip page protections from (RX -> RW -> RX).
+ //
+ // b) To ensure only one thread succeeds installing an allocation for the
+ // given class.
+ //
+ thread->isolate_group()->RunWithStoppedMutators(
+ mutator_fun, bg_compiler_fun, /*use_force_growth=*/true);
+
+ // We notify code observers after finalizing the code in order to be
+ // outside a [SafepointOperationScope].
+ Code::NotifyCodeObservers(name, stub, /*optimized=*/false);
#ifndef PRODUCT
if (FLAG_support_disassembler && FLAG_disassemble_stubs) {
LogBlock lb;
diff --git a/runtime/vm/symbols.h b/runtime/vm/symbols.h
index 31bb9e7..c0f5f16 100644
--- a/runtime/vm/symbols.h
+++ b/runtime/vm/symbols.h
@@ -89,8 +89,8 @@
V(DartSchemePrivate, "dart:_") \
V(DartTypedData, "dart:typed_data") \
V(DartVMProduct, "dart.vm.product") \
- V(DartVMServiceIO, "dart:vmservice_io") \
V(DartVMService, "dart:_vmservice") \
+ V(DartVMServiceIO, "dart:vmservice_io") \
V(DebugClassName, "#DebugClass") \
V(DebugProcedureName, ":Eval") \
V(Default, "Default") \
@@ -158,6 +158,7 @@
V(FutureValue, "Future.value") \
V(Get, "get") \
V(GetCall, "get:call") \
+ V(GetLength, "get:length") \
V(GetRuntimeType, "get:runtimeType") \
V(GetterPrefix, "get:") \
V(GreaterEqualOperator, ">=") \
@@ -191,7 +192,6 @@
V(LanguageError, "LanguageError") \
V(LeftShiftOperator, "<<") \
V(Length, "length") \
- V(GetLength, "get:length") \
V(LessEqualOperator, "<=") \
V(LibraryClass, "Library") \
V(LibraryPrefix, "LibraryPrefix") \
@@ -262,8 +262,8 @@
V(ThrowNew, "_throwNew") \
V(ThrowNewInvocation, "_throwNewInvocation") \
V(TopLevel, "::") \
- V(TruncDivOperator, "~/") \
V(TransferableTypedData, "TransferableTypedData") \
+ V(TruncDivOperator, "~/") \
V(TryFinallyReturnValue, ":try_finally_return_value") \
V(TwoByteString, "_TwoByteString") \
V(TwoSpaces, " ") \
@@ -285,6 +285,11 @@
V(UnwindError, "UnwindError") \
V(Value, "value") \
V(Values, "values") \
+ V(WasmInt32, "Int32") \
+ V(WasmInt64, "Int64") \
+ V(WasmFloat, "Float") \
+ V(WasmDouble, "Double") \
+ V(WasmVoid, "Void") \
V(YieldKw, "yield") \
V(_AsyncAwaitCompleter, "_AsyncAwaitCompleter") \
V(_AsyncAwaitCompleterConstructor, "_AsyncAwaitCompleter.") \
@@ -298,8 +303,10 @@
V(_ByteBufferDot_New, "_ByteBuffer._New") \
V(_ByteDataView, "_ByteDataView") \
V(_CapabilityImpl, "_CapabilityImpl") \
+ V(_ClassMirror, "_ClassMirror") \
V(_Closure, "_Closure") \
V(_ClosureCall, "_Closure.call") \
+ V(_CombinatorMirror, "_CombinatorMirror") \
V(_CompileTimeError, "_CompileTimeError") \
V(_CompleteOnAsyncReturn, "_completeOnAsyncReturn") \
V(_DeletedEnumPrefix, "Deleted enum value from ") \
@@ -333,6 +340,7 @@
V(_Float64x2ArrayFactory, "Float64x2List.") \
V(_Float64x2ArrayView, "_Float64x2ArrayView") \
V(_Float64x2List, "_Float64x2List") \
+ V(_FunctionTypeMirror, "_FunctionTypeMirror") \
V(_GrowableList, "_GrowableList") \
V(_GrowableListFactory, "_GrowableList.") \
V(_GrowableListWithData, "_GrowableList._withData") \
@@ -354,30 +362,23 @@
V(_Int8ArrayView, "_Int8ArrayView") \
V(_Int8List, "_Int8List") \
V(_IntegerImplementation, "_IntegerImplementation") \
+ V(_IsolateMirror, "_IsolateMirror") \
+ V(_LibraryDependencyMirror, "_LibraryDependencyMirror") \
+ V(_LibraryMirror, "_LibraryMirror") \
V(_LibraryPrefix, "_LibraryPrefix") \
V(_LinkedHashMap, "_InternalLinkedHashMap") \
V(_LinkedHashSet, "_CompactLinkedHashSet") \
V(_List, "_List") \
V(_ListFactory, "_List.") \
- V(_LocalClassMirror, "_LocalClassMirror") \
- V(_LocalCombinatorMirror, "_LocalCombinatorMirror") \
- V(_LocalFunctionTypeMirror, "_LocalFunctionTypeMirror") \
- V(_LocalIsolateMirror, "_LocalIsolateMirror") \
- V(_LocalLibraryDependencyMirror, "_LocalLibraryDependencyMirror") \
- V(_LocalLibraryMirror, "_LocalLibraryMirror") \
- V(_LocalMethodMirror, "_LocalMethodMirror") \
- V(_LocalMirrorSystem, "_LocalMirrorSystem") \
- V(_LocalParameterMirror, "_LocalParameterMirror") \
- V(_LocalTypeVariableMirror, "_LocalTypeVariableMirror") \
- V(_LocalTypedefMirror, "_LocalTypedefMirror") \
- V(_LocalVariableMirror, "_LocalVariableMirror") \
+ V(_MethodMirror, "_MethodMirror") \
V(_Mint, "_Mint") \
V(_MirrorReference, "_MirrorReference") \
+ V(_MirrorSystem, "_MirrorSystem") \
+ V(_ParameterMirror, "_ParameterMirror") \
V(_Random, "_Random") \
V(_RawReceivePortImpl, "_RawReceivePortImpl") \
V(_RegExp, "_RegExp") \
V(_SendPortImpl, "_SendPortImpl") \
- V(_TransferableTypedDataImpl, "_TransferableTypedDataImpl") \
V(_Smi, "_Smi") \
V(_SourceLocation, "_SourceLocation") \
V(_SpecialTypeMirror, "_SpecialTypeMirror") \
@@ -387,9 +388,12 @@
V(_SyncIterable, "_SyncIterable") \
V(_SyncIterableConstructor, "_SyncIterable.") \
V(_SyncIterator, "_SyncIterator") \
+ V(_TransferableTypedDataImpl, "_TransferableTypedDataImpl") \
V(_Type, "_Type") \
V(_TypeParameter, "_TypeParameter") \
V(_TypeRef, "_TypeRef") \
+ V(_TypeVariableMirror, "_TypeVariableMirror") \
+ V(_TypedefMirror, "_TypedefMirror") \
V(_Uint16ArrayFactory, "Uint16List.") \
V(_Uint16ArrayView, "_Uint16ArrayView") \
V(_Uint16List, "_Uint16List") \
@@ -406,6 +410,7 @@
V(_Uint8ClampedList, "_Uint8ClampedList") \
V(_Uint8List, "_Uint8List") \
V(_UserTag, "_UserTag") \
+ V(_VariableMirror, "_VariableMirror") \
V(_WeakProperty, "_WeakProperty") \
V(_classRangeCheck, "_classRangeCheck") \
V(_current, "_current") \
diff --git a/runtime/vm/timeline.h b/runtime/vm/timeline.h
index 6582016..1bce4cc 100644
--- a/runtime/vm/timeline.h
+++ b/runtime/vm/timeline.h
@@ -53,7 +53,7 @@
V(Embedder, "dart:embedder") \
V(GC, "dart:gc") \
V(Isolate, "dart:isolate") \
- V(Profiler, "dart:profiler") \
+ V(Developer, "dart:developer") \
V(VM, "dart:vm")
// A stream of timeline events. A stream has a name and can be enabled or
diff --git a/runtime/vm/type_testing_stubs.cc b/runtime/vm/type_testing_stubs.cc
index 9d41d66..ac2c84a 100644
--- a/runtime/vm/type_testing_stubs.cc
+++ b/runtime/vm/type_testing_stubs.cc
@@ -176,7 +176,8 @@
#if !defined(DART_PRECOMPILED_RUNTIME)
RawCode* TypeTestingStubGenerator::BuildCodeForType(const Type& type) {
- HierarchyInfo* hi = Thread::Current()->hierarchy_info();
+ auto thread = Thread::Current();
+ HierarchyInfo* hi = thread->hierarchy_info();
ASSERT(hi != NULL);
if (!hi->CanUseSubtypeRangeCheckFor(type) &&
@@ -195,8 +196,23 @@
const auto pool_attachment = FLAG_use_bare_instructions
? Code::PoolAttachment::kNotAttachPool
: Code::PoolAttachment::kAttachPool;
- const Code& code = Code::Handle(Code::FinalizeCodeAndNotify(
- name, nullptr, &assembler, pool_attachment, false /* optimized */));
+
+ Code& code = Code::Handle(thread->zone());
+ auto install_code_fun = [&]() {
+ code = Code::FinalizeCode(nullptr, &assembler, pool_attachment,
+ /*optimized=*/false, /*stats=*/nullptr);
+ };
+
+ // We have to ensure no mutators are running, because:
+ //
+ // a) We allocate an instructions object, which might cause us to
+ // temporarily flip page protections from (RX -> RW -> RX).
+ //
+ thread->isolate_group()->RunWithStoppedMutators(
+ install_code_fun, install_code_fun, /*use_force_growth=*/true);
+
+ Code::NotifyCodeObservers(name, code, /*optimized=*/false);
+
code.set_owner(type);
#ifndef PRODUCT
if (FLAG_support_disassembler && FLAG_disassemble_stubs) {
diff --git a/sdk/BUILD.gn b/sdk/BUILD.gn
index 228fc3c..9a4a1c5 100644
--- a/sdk/BUILD.gn
+++ b/sdk/BUILD.gn
@@ -134,20 +134,16 @@
],
]
if (create_kernel_service_snapshot) {
- _platform_sdk_snapshots += [
- [
- "kernel-service",
- "../utils/kernel-service:kernel-service_snapshot",
- ],
- ]
+ _platform_sdk_snapshots += [ [
+ "kernel-service",
+ "../utils/kernel-service:kernel-service_snapshot",
+ ] ]
}
if (dart_target_arch != "arm") {
- _platform_sdk_snapshots += [
- [
- "analysis_server",
- "../utils/analysis_server",
- ],
- ]
+ _platform_sdk_snapshots += [ [
+ "analysis_server",
+ "../utils/analysis_server",
+ ] ]
}
_full_sdk_snapshots = [
@@ -185,20 +181,16 @@
],
]
if (create_kernel_service_snapshot) {
- _full_sdk_snapshots += [
- [
- "kernel-service",
- "../utils/kernel-service:kernel-service_snapshot",
- ],
- ]
+ _full_sdk_snapshots += [ [
+ "kernel-service",
+ "../utils/kernel-service:kernel-service_snapshot",
+ ] ]
}
if (dart_target_arch != "arm") {
- _full_sdk_snapshots += [
- [
- "analysis_server",
- "../utils/analysis_server",
- ],
- ]
+ _full_sdk_snapshots += [ [
+ "analysis_server",
+ "../utils/analysis_server",
+ ] ]
}
# Libraries that go under lib/
@@ -222,7 +214,6 @@
"js_util",
"math",
"mirrors",
- "profiler",
"svg",
"typed_data",
"wasm",
@@ -249,7 +240,6 @@
# "isolate",
# "math",
# "mirrors",
-# "profiler",
# "typed_data",
# ]
_platform_sdk_libraries = _full_sdk_libraries
@@ -260,74 +250,82 @@
# This rule copies dartdoc templates to
# bin/resources/dartdoc/templates
-copy_tree_specs += [ {
- target = "copy_dartdoc_templates"
- visibility = [ ":copy_dartdoc_files" ]
- source = "../third_party/pkg/dartdoc/lib/templates"
- dest = "$root_out_dir/dart-sdk/bin/resources/dartdoc/templates"
- ignore_patterns = "{}"
- } ]
+copy_tree_specs += [
+ {
+ target = "copy_dartdoc_templates"
+ visibility = [ ":copy_dartdoc_files" ]
+ source = "../third_party/pkg/dartdoc/lib/templates"
+ dest = "$root_out_dir/dart-sdk/bin/resources/dartdoc/templates"
+ ignore_patterns = "{}"
+ },
+]
# This rule copies dartdoc resources to
# bin/resources/dartdoc/resources
-copy_tree_specs += [ {
- target = "copy_dartdoc_resources"
- visibility = [ ":copy_dartdoc_files" ]
- source = "../third_party/pkg/dartdoc/lib/resources"
- dest = "$root_out_dir/dart-sdk/bin/resources/dartdoc/resources"
- ignore_patterns = "{}"
- } ]
+copy_tree_specs += [
+ {
+ target = "copy_dartdoc_resources"
+ visibility = [ ":copy_dartdoc_files" ]
+ source = "../third_party/pkg/dartdoc/lib/resources"
+ dest = "$root_out_dir/dart-sdk/bin/resources/dartdoc/resources"
+ ignore_patterns = "{}"
+ },
+]
# This loop generates rules to copy libraries to lib/
foreach(library, _full_sdk_libraries) {
- copy_tree_specs += [ {
- target = "copy_${library}_library"
- visibility = [
- ":copy_platform_sdk_libraries",
- ":copy_full_sdk_libraries",
- ]
- source = "lib/$library"
- dest = "$root_out_dir/dart-sdk/lib/$library"
- ignore_patterns = "*.svn,doc,*.py,*.gypi,*.sh,.gitignore"
- } ]
+ copy_tree_specs += [
+ {
+ target = "copy_${library}_library"
+ visibility = [
+ ":copy_platform_sdk_libraries",
+ ":copy_full_sdk_libraries",
+ ]
+ source = "lib/$library"
+ dest = "$root_out_dir/dart-sdk/lib/$library"
+ ignore_patterns = "*.svn,doc,*.py,*.gypi,*.sh,.gitignore"
+ },
+ ]
}
if (is_win) {
- copy_tree_specs += [ {
- target = "copy_7zip"
- visibility = [ ":create_common_sdk" ]
- deps = [
- ":copy_libraries",
- ]
- source = "../third_party/7zip"
- dest = "$root_out_dir/dart-sdk/lib/_internal/pub/asset/7zip"
- ignore_patterns = ".svn"
- } ]
+ copy_tree_specs += [
+ {
+ target = "copy_7zip"
+ visibility = [ ":create_common_sdk" ]
+ deps = [
+ ":copy_libraries",
+ ]
+ source = "../third_party/7zip"
+ dest = "$root_out_dir/dart-sdk/lib/_internal/pub/asset/7zip"
+ ignore_patterns = ".svn"
+ },
+ ]
}
if (target_cpu == "x64") {
copy_tree_specs += [
- {
- target = "copy_language_model"
- visibility = [ ":create_common_sdk" ]
- deps = [
- ":copy_libraries",
- ]
- source = "../pkg/analysis_server/language_model"
- dest = "$root_out_dir/dart-sdk/model"
- ignore_patterns = "{}"
- },
- {
- target = "copy_libtensorflowlite_c"
- visibility = [ ":create_common_sdk" ]
- deps = [
- ":copy_libraries",
- ]
- source = "../third_party/pkg/tflite_native/lib/src/blobs"
- dest = "$root_out_dir/dart-sdk/bin/snapshots"
- ignore_patterns = "{}"
- }
- ]
+ {
+ target = "copy_language_model"
+ visibility = [ ":create_common_sdk" ]
+ deps = [
+ ":copy_libraries",
+ ]
+ source = "../pkg/analysis_server/language_model"
+ dest = "$root_out_dir/dart-sdk/model"
+ ignore_patterns = "{}"
+ },
+ {
+ target = "copy_libtensorflowlite_c"
+ visibility = [ ":create_common_sdk" ]
+ deps = [
+ ":copy_libraries",
+ ]
+ source = "../third_party/pkg/tflite_native/lib/src/blobs"
+ dest = "$root_out_dir/dart-sdk/bin/snapshots"
+ ignore_patterns = "{}"
+ },
+ ]
}
# This generates targets for everything in copy_tree_specs. The targets have the
@@ -399,7 +397,8 @@
deps = [
"../runtime/bin:dartaotruntime",
]
- dartaotruntime_out = get_label_info("../runtime/bin:dartaotruntime", "root_out_dir")
+ dartaotruntime_out =
+ get_label_info("../runtime/bin:dartaotruntime", "root_out_dir")
if (is_win) {
sources = [
"$dartaotruntime_out/dartaotruntime.exe",
@@ -421,7 +420,8 @@
deps = [
"../runtime/bin:gen_snapshot",
]
- gen_snapshot_out = get_label_info("../runtime/bin:gen_snapshot", "root_out_dir")
+ gen_snapshot_out =
+ get_label_info("../runtime/bin:gen_snapshot", "root_out_dir")
if (is_win) {
sources = [
"$gen_snapshot_out/gen_snapshot.exe",
@@ -663,8 +663,8 @@
visibility = [ ":copy_dev_compiler_sdk" ]
deps = [
":copy_libraries",
- "../utils/dartdevc:dartdevc_sdk",
"../utils/dartdevc:dartdevc_kernel_sdk_outline",
+ "../utils/dartdevc:dartdevc_sdk",
]
gen_dir = get_label_info("../utils/dartdevc:dartdevc_sdk", "target_gen_dir")
sources = [
@@ -736,8 +736,8 @@
deps = [
"../utils/dartdevc:dartdevc_kernel_sdk",
]
- gen_dir = get_label_info("../utils/dartdevc:dartdevc_kernel_sdk",
- "target_gen_dir")
+ gen_dir =
+ get_label_info("../utils/dartdevc:dartdevc_kernel_sdk", "target_gen_dir")
sources = [
"$gen_dir/kernel/amd/dart_sdk.js",
"$gen_dir/kernel/amd/dart_sdk.js.map",
@@ -754,8 +754,8 @@
deps = [
"../utils/dartdevc:dartdevc_kernel_sdk",
]
- gen_dir = get_label_info("../utils/dartdevc:dartdevc_kernel_sdk",
- "target_gen_dir")
+ gen_dir =
+ get_label_info("../utils/dartdevc:dartdevc_kernel_sdk", "target_gen_dir")
sources = [
"$gen_dir/kernel/common/dart_sdk.js",
"$gen_dir/kernel/common/dart_sdk.js.map",
@@ -772,8 +772,8 @@
deps = [
"../utils/dartdevc:dartdevc_kernel_sdk",
]
- gen_dir = get_label_info("../utils/dartdevc:dartdevc_kernel_sdk",
- "target_gen_dir")
+ gen_dir =
+ get_label_info("../utils/dartdevc:dartdevc_kernel_sdk", "target_gen_dir")
sources = [
"$gen_dir/kernel/es6/dart_sdk.js",
"$gen_dir/kernel/es6/dart_sdk.js.map",
@@ -1006,8 +1006,8 @@
":copy_dartdoc_files",
":copy_headers",
":copy_libraries_dart",
- ":copy_license",
":copy_libraries_specification",
+ ":copy_license",
":copy_readme",
":copy_vm_dill_files",
":write_dartdoc_options",
diff --git a/sdk/lib/_http/websocket_impl.dart b/sdk/lib/_http/websocket_impl.dart
index 8750ccc..ebbce45 100644
--- a/sdk/lib/_http/websocket_impl.dart
+++ b/sdk/lib/_http/websocket_impl.dart
@@ -601,11 +601,11 @@
data.addAll(const [0x00, 0x00, 0xff, 0xff]);
decoder.process(data, 0, data.length);
- var result = <int>[];
+ final result = new BytesBuilder();
List<int> out;
while ((out = decoder.processed()) != null) {
- result.addAll(out);
+ result.add(out);
}
if ((serverSide && clientNoContextTakeover) ||
@@ -613,7 +613,7 @@
decoder = null;
}
- return new Uint8List.fromList(result);
+ return result.takeBytes();
}
List<int> processOutgoingMessage(List<int> msg) {
diff --git a/sdk/lib/_internal/js_dev_runtime/lib/js/dart2js/js_dart2js.dart b/sdk/lib/_internal/js_dev_runtime/lib/js/dart2js/js_dart2js.dart
index 91d6847..83421ab 100644
--- a/sdk/lib/_internal/js_dev_runtime/lib/js/dart2js/js_dart2js.dart
+++ b/sdk/lib/_internal/js_dev_runtime/lib/js/dart2js/js_dart2js.dart
@@ -2,89 +2,88 @@
// 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.
-/**
- * Support for interoperating with JavaScript.
- *
- * This library provides access to JavaScript objects from Dart, allowing
- * Dart code to get and set properties, and call methods of JavaScript objects
- * and invoke JavaScript functions. The library takes care of converting
- * between Dart and JavaScript objects where possible, or providing proxies if
- * conversion isn't possible.
- *
- * This library does not yet make Dart objects usable from JavaScript, their
- * methods and proeprties are not accessible, though it does allow Dart
- * functions to be passed into and called from JavaScript.
- *
- * [JsObject] is the core type and represents a proxy of a JavaScript object.
- * JsObject gives access to the underlying JavaScript objects properties and
- * methods. `JsObject`s can be acquired by calls to JavaScript, or they can be
- * created from proxies to JavaScript constructors.
- *
- * The top-level getter [context] provides a [JsObject] that represents the
- * global object in JavaScript, usually `window`.
- *
- * The following example shows an alert dialog via a JavaScript call to the
- * global function `alert()`:
- *
- * import 'dart:js';
- *
- * main() => context.callMethod('alert', ['Hello from Dart!']);
- *
- * This example shows how to create a [JsObject] from a JavaScript constructor
- * and access its properties:
- *
- * import 'dart:js';
- *
- * main() {
- * var object = new JsObject(context['Object']);
- * object['greeting'] = 'Hello';
- * object['greet'] = (name) => "${object['greeting']} $name";
- * var message = object.callMethod('greet', ['JavaScript']);
- * context['console'].callMethod('log', [message]);
- * }
- *
- * ## Proxying and automatic conversion
- *
- * When setting properties on a JsObject or passing arguments to a Javascript
- * method or function, Dart objects are automatically converted or proxied to
- * JavaScript objects. When accessing JavaScript properties, or when a Dart
- * closure is invoked from JavaScript, the JavaScript objects are also
- * converted to Dart.
- *
- * Functions and closures are proxied in such a way that they are callable. A
- * Dart closure assigned to a JavaScript property is proxied by a function in
- * JavaScript. A JavaScript function accessed from Dart is proxied by a
- * [JsFunction], which has a [apply] method to invoke it.
- *
- * The following types are transferred directly and not proxied:
- *
- * * "Basic" types: `null`, `bool`, `num`, `String`, `DateTime`
- * * `Blob`
- * * `Event`
- * * `HtmlCollection`
- * * `ImageData`
- * * `KeyRange`
- * * `Node`
- * * `NodeList`
- * * `TypedData`, including its subclasses like `Int32List`, but _not_
- * `ByteBuffer`
- * * `Window`
- *
- * ## Converting collections with JsObject.jsify()
- *
- * To create a JavaScript collection from a Dart collection use the
- * [JsObject.jsify] constructor, which converts Dart [Map]s and [Iterable]s
- * into JavaScript Objects and Arrays.
- *
- * The following expression creates a new JavaScript object with the properties
- * `a` and `b` defined:
- *
- * var jsMap = new JsObject.jsify({'a': 1, 'b': 2});
- *
- * This expression creates a JavaScript array:
- *
- * var jsArray = new JsObject.jsify([1, 2, 3]);
- */
+// DDC version of sdk/lib/js/dart2js/js_dart2js.dart
+
+/// Low-level support for interoperating with JavaScript.
+///
+/// You should usually use `package:js` instead of this library. For more
+/// information, see the [JS interop page](https://dart.dev/web/js-interop).
+///
+/// This library provides access to JavaScript objects from Dart, allowing
+/// Dart code to get and set properties, and call methods of JavaScript objects
+/// and invoke JavaScript functions. The library takes care of converting
+/// between Dart and JavaScript objects where possible, or providing proxies if
+/// conversion isn't possible.
+///
+/// This library does not make Dart objects usable from JavaScript, their
+/// methods and properties are not accessible, though it does allow Dart
+/// functions to be passed into and called from JavaScript.
+///
+/// [JsObject] is the core type and represents a proxy of a JavaScript object.
+/// JsObject gives access to the underlying JavaScript objects properties and
+/// methods. `JsObject`s can be acquired by calls to JavaScript, or they can be
+/// created from proxies to JavaScript constructors.
+///
+/// The top-level getter [context] provides a [JsObject] that represents the
+/// global object in JavaScript, usually `window`.
+///
+/// The following example shows an alert dialog via a JavaScript call to the
+/// global function `alert()`:
+///
+/// import 'dart:js';
+///
+/// main() => context.callMethod('alert', ['Hello from Dart!']);
+///
+/// This example shows how to create a [JsObject] from a JavaScript constructor
+/// and access its properties:
+///
+/// import 'dart:js';
+///
+/// main() {
+/// var object = JsObject(context['Object']);
+/// object['greeting'] = 'Hello';
+/// object['greet'] = (name) => "${object['greeting']} $name";
+/// var message = object.callMethod('greet', ['JavaScript']);
+/// context['console'].callMethod('log', [message]);
+/// }
+///
+/// ## Proxying and automatic conversion
+///
+/// When setting properties on a JsObject or passing arguments to a Javascript
+/// method or function, Dart objects are automatically converted or proxied to
+/// JavaScript objects. When accessing JavaScript properties, or when a Dart
+/// closure is invoked from JavaScript, the JavaScript objects are also
+/// converted to Dart.
+///
+/// Functions and closures are proxied in such a way that they are callable. A
+/// Dart closure assigned to a JavaScript property is proxied by a function in
+/// JavaScript. A JavaScript function accessed from Dart is proxied by a
+/// [JsFunction], which has a [apply] method to invoke it.
+///
+/// The following types are transferred directly and not proxied:
+///
+/// * Basic types: `null`, `bool`, `num`, `String`, `DateTime`
+/// * `TypedData`, including its subclasses like `Int32List`, but _not_
+/// `ByteBuffer`
+/// * When compiling for the web, also: `Blob`, `Event`, `ImageData`,
+/// `KeyRange`, `Node`, and `Window`.
+///
+/// ## Converting collections with JsObject.jsify()
+///
+/// To create a JavaScript collection from a Dart collection use the
+/// [JsObject.jsify] constructor, which converts Dart [Map]s and [Iterable]s
+/// into JavaScript Objects and Arrays.
+///
+/// The following expression creates a new JavaScript object with the properties
+/// `a` and `b` defined:
+///
+/// var jsMap = JsObject.jsify({'a': 1, 'b': 2});
+///
+/// This expression creates a JavaScript array:
+///
+/// var jsArray = JsObject.jsify([1, 2, 3]);
+///
+/// {@category Web}
library dart.js;
import 'dart:collection' show HashMap, ListMixin;
@@ -93,14 +92,13 @@
import 'dart:_foreign_helper' show JS;
import 'dart:_runtime' as dart;
+/// The JavaScript global object, usually `window`.
final JsObject context = _wrapToDart(dart.global_);
-/**
- * Proxies a JavaScript object to Dart.
- *
- * The properties of the JavaScript object are accessible via the `[]` and
- * `[]=` operators. Methods are callable via [callMethod].
- */
+/// A proxy on a JavaScript object.
+///
+/// The properties of the JavaScript object are accessible via the `[]` and
+/// `[]=` operators. Methods are callable via [callMethod].
class JsObject {
// The wrapped JS object.
final dynamic _jsObject;
@@ -110,10 +108,8 @@
assert(_jsObject != null);
}
- /**
- * Constructs a new JavaScript object from [constructor] and returns a proxy
- * to it.
- */
+ /// Constructs a JavaScript object from its native [constructor] and returns
+ /// a proxy to it.
factory JsObject(JsFunction constructor, [List arguments]) {
var ctor = constructor._jsObject;
if (arguments == null) {
@@ -123,17 +119,15 @@
return _wrapToDart(JS('', 'new #(...#)', ctor, unwrapped));
}
- /**
- * Constructs a [JsObject] that proxies a native Dart object; _for expert use
- * only_.
- *
- * Use this constructor only if you wish to get access to JavaScript
- * properties attached to a browser host object, such as a Node or Blob, that
- * is normally automatically converted into a native Dart object.
- *
- * An exception will be thrown if [object] either is `null` or has the type
- * `bool`, `num`, or `String`.
- */
+ /// Constructs a [JsObject] that proxies a native Dart object; _for expert use
+ /// only_.
+ ///
+ /// Use this constructor only if you wish to get access to JavaScript
+ /// properties attached to a browser host object, such as a Node or Blob, that
+ /// is normally automatically converted into a native Dart object.
+ ///
+ /// An exception will be thrown if [object] either is `null` or has the type
+ /// `bool`, `num`, or `String`.
factory JsObject.fromBrowserObject(object) {
if (object is num || object is String || object is bool || object == null) {
throw ArgumentError("object cannot be a num, string, bool, or null");
@@ -141,15 +135,13 @@
return _wrapToDart(_convertToJS(object));
}
- /**
- * Recursively converts a JSON-like collection of Dart objects to a
- * collection of JavaScript objects and returns a [JsObject] proxy to it.
- *
- * [object] must be a [Map] or [Iterable], the contents of which are also
- * converted. Maps and Iterables are copied to a new JavaScript object.
- * Primitives and other transferable values are directly converted to their
- * JavaScript type, and all other objects are proxied.
- */
+ /// Recursively converts a JSON-like collection of Dart objects to a
+ /// collection of JavaScript objects and returns a [JsObject] proxy to it.
+ ///
+ /// [object] must be a [Map] or [Iterable], the contents of which are also
+ /// converted. Maps and Iterables are copied to a new JavaScript object.
+ /// Primitives and other transferable values are directly converted to their
+ /// JavaScript type, and all other objects are proxied.
factory JsObject.jsify(object) {
if ((object is! Map) && (object is! Iterable)) {
throw ArgumentError("object must be a Map or Iterable");
@@ -184,12 +176,10 @@
return _convert(data);
}
- /**
- * Returns the value associated with [property] from the proxied JavaScript
- * object.
- *
- * The type of [property] must be either [String] or [num].
- */
+ /// Returns the value associated with [property] from the proxied JavaScript
+ /// object.
+ ///
+ /// The type of [property] must be either [String] or [num].
dynamic operator [](Object property) {
if (property is! String && property is! num) {
throw ArgumentError("property is not a String or num");
@@ -197,12 +187,10 @@
return _convertToDart(JS('', '#[#]', _jsObject, property));
}
- /**
- * Sets the value associated with [property] on the proxied JavaScript
- * object.
- *
- * The type of [property] must be either [String] or [num].
- */
+ // Sets the value associated with [property] on the proxied JavaScript
+ // object.
+ //
+ // The type of [property] must be either [String] or [num].
void operator []=(Object property, value) {
if (property is! String && property is! num) {
throw ArgumentError("property is not a String or num");
@@ -215,12 +203,10 @@
bool operator ==(other) =>
other is JsObject && JS<bool>('!', '# === #', _jsObject, other._jsObject);
- /**
- * Returns `true` if the JavaScript object contains the specified property
- * either directly or though its prototype chain.
- *
- * This is the equivalent of the `in` operator in JavaScript.
- */
+ /// Returns `true` if the JavaScript object contains the specified property
+ /// either directly or though its prototype chain.
+ ///
+ /// This is the equivalent of the `in` operator in JavaScript.
bool hasProperty(property) {
if (property is! String && property is! num) {
throw ArgumentError("property is not a String or num");
@@ -228,11 +214,9 @@
return JS<bool>('!', '# in #', property, _jsObject);
}
- /**
- * Removes [property] from the JavaScript object.
- *
- * This is the equivalent of the `delete` operator in JavaScript.
- */
+ /// Removes [property] from the JavaScript object.
+ ///
+ /// This is the equivalent of the `delete` operator in JavaScript.
void deleteProperty(property) {
if (property is! String && property is! num) {
throw ArgumentError("property is not a String or num");
@@ -240,18 +224,14 @@
JS<bool>('!', 'delete #[#]', _jsObject, property);
}
- /**
- * Returns `true` if the JavaScript object has [type] in its prototype chain.
- *
- * This is the equivalent of the `instanceof` operator in JavaScript.
- */
+ /// Returns `true` if the JavaScript object has [type] in its prototype chain.
+ ///
+ /// This is the equivalent of the `instanceof` operator in JavaScript.
bool instanceof(JsFunction type) {
return JS<bool>('!', '# instanceof #', _jsObject, _convertToJS(type));
}
- /**
- * Returns the result of the JavaScript objects `toString` method.
- */
+ /// Returns the result of the JavaScript objects `toString` method.
String toString() {
try {
return JS<String>('!', 'String(#)', _jsObject);
@@ -260,12 +240,10 @@
}
}
- /**
- * Calls [method] on the JavaScript object with the arguments [args] and
- * returns the result.
- *
- * The type of [method] must be either [String] or [num].
- */
+ /// Calls [method] on the JavaScript object with the arguments [args] and
+ /// returns the result.
+ ///
+ /// The type of [method] must be either [String] or [num].
dynamic callMethod(method, [List args]) {
if (method is! String && method is! num) {
throw ArgumentError("method is not a String or num");
@@ -279,14 +257,10 @@
}
}
-/**
- * Proxies a JavaScript Function object.
- */
+/// A proxy on a JavaScript Function object.
class JsFunction extends JsObject {
- /**
- * Returns a [JsFunction] that captures its 'this' binding and calls [f]
- * with the value of this passed as the first argument.
- */
+ /// Returns a [JsFunction] that captures its 'this' binding and calls [f]
+ /// with the value of JavaScript `this` passed as the first argument.
factory JsFunction.withThis(Function f) {
return JsFunction._fromJs(JS(
'',
@@ -305,10 +279,8 @@
JsFunction._fromJs(jsObject) : super._fromJs(jsObject);
- /**
- * Invokes the JavaScript function with arguments [args]. If [thisArg] is
- * supplied it is the value of `this` for the invocation.
- */
+ /// Invokes the JavaScript function with arguments [args]. If [thisArg] is
+ /// supplied it is the value of `this` for the invocation.
dynamic apply(List args, {thisArg}) => _convertToDart(JS(
'',
'#.apply(#, #)',
@@ -318,17 +290,13 @@
}
// TODO(jmesserly): this is totally unnecessary in dev_compiler.
-/** A [List] that proxies a JavaScript array. */
+/// A [List] that proxies a JavaScript array.
class JsArray<E> extends JsObject with ListMixin<E> {
- /**
- * Creates a new JavaScript array.
- */
+ /// Creates an empty JavaScript array.
JsArray() : super._fromJs([]);
- /**
- * Creates a new JavaScript array and initializes it to the contents of
- * [other].
- */
+ /// Creates a new JavaScript array and initializes it to the contents of
+ /// [other].
JsArray.from(Iterable<E> other)
: super._fromJs([]..addAll(other.map(_convertToJS)));
@@ -544,16 +512,16 @@
Expando<Function> _interopExpando = Expando<Function>();
/// Returns a wrapper around function [f] that can be called from JavaScript
-/// using the package:js Dart-JavaScript interop.
+/// using `package:js` JavaScript interop.
///
-/// For performance reasons in Dart2Js, by default Dart functions cannot be
-/// passed directly to JavaScript unless this method is called to create
-/// a Function compatible with both Dart and JavaScript.
-/// Calling this method repeatedly on a function will return the same function.
-/// The [Function] returned by this method can be used from both Dart and
-/// JavaScript. We may remove the need to call this method completely in the
-/// future if Dart2Js is refactored so that its function calling conventions
-/// are more compatible with JavaScript.
+/// The calling conventions in Dart2Js differ from JavaScript and so, by
+/// default, it is not possible to call a Dart function directly. Wrapping with
+/// `allowInterop` creates a function that can be called from JavaScript or
+/// Dart. The semantics of the wrapped function are still more strict than
+/// JavaScript, and the function will throw if called with too many or too few
+/// arguments.
+///
+/// Calling this method repeatedly on a function will return the same result.
F allowInterop<F extends Function>(F f) {
var ret = _interopExpando[f];
if (ret == null) {
@@ -571,12 +539,13 @@
Expando<Function> _interopCaptureThisExpando = Expando<Function>();
-/// Returns a [Function] that when called from JavaScript captures its 'this'
-/// binding and calls [f] with the value of this passed as the first argument.
-/// When called from Dart, [null] will be passed as the first argument.
+/// Returns a wrapper around function [f] that can be called from JavaScript
+/// using `package:js` JavaScript interop, passing JavaScript `this` as the first
+/// argument.
///
-/// See the documentation for [allowInterop]. This method should only be used
-/// with package:js Dart-JavaScript interop.
+/// See [allowInterop].
+///
+/// When called from Dart, [null] will be passed as the first argument.
Function allowInteropCaptureThis(Function f) {
var ret = _interopCaptureThisExpando[f];
if (ret == null) {
diff --git a/sdk/lib/_internal/js_runtime/lib/js_helper.dart b/sdk/lib/_internal/js_runtime/lib/js_helper.dart
index 8c167115..a1187f6 100644
--- a/sdk/lib/_internal/js_runtime/lib/js_helper.dart
+++ b/sdk/lib/_internal/js_runtime/lib/js_helper.dart
@@ -366,7 +366,7 @@
list.add(createRuntimeType(_arguments[start + index]));
}
}
- return list;
+ return JSArray.markUnmodifiableList(list);
}
List get positionalArguments {
diff --git a/sdk/lib/_internal/js_runtime/lib/rti.dart b/sdk/lib/_internal/js_runtime/lib/rti.dart
index f7ca527..780f6c0 100644
--- a/sdk/lib/_internal/js_runtime/lib/rti.dart
+++ b/sdk/lib/_internal/js_runtime/lib/rti.dart
@@ -2147,11 +2147,16 @@
}
}
+ // TODO(fishythefish): Disallow JavaScriptFunction as a subtype of function
+ // types using features inaccessible from JavaScript.
+
if (isGenericFunctionKind(t)) {
+ if (isJsFunctionType(s)) return true;
return _isGenericFunctionSubtype(universe, s, sEnv, t, tEnv);
}
if (isFunctionKind(t)) {
+ if (isJsFunctionType(s)) return true;
return _isFunctionSubtype(universe, s, sEnv, t, tEnv);
}
@@ -2398,6 +2403,11 @@
Rti._getKind(t) == Rti.kindInterface &&
Rti._getInterfaceName(t) == JS_GET_NAME(JsGetName.FUNCTION_CLASS_TYPE_NAME);
+bool isJsFunctionType(Rti t) =>
+ Rti._getKind(t) == Rti.kindInterface &&
+ Rti._getInterfaceName(t) ==
+ JS_GET_NAME(JsGetName.JS_FUNCTION_CLASS_TYPE_NAME);
+
/// Unchecked cast to Rti.
Rti _castToRti(s) => JS('Rti', '#', s);
diff --git a/sdk/lib/_internal/js_runtime/lib/shared/embedded_names.dart b/sdk/lib/_internal/js_runtime/lib/shared/embedded_names.dart
index 50cf7e8..6800e37 100644
--- a/sdk/lib/_internal/js_runtime/lib/shared/embedded_names.dart
+++ b/sdk/lib/_internal/js_runtime/lib/shared/embedded_names.dart
@@ -326,6 +326,9 @@
/// String representation of the type of the function class.
FUNCTION_CLASS_TYPE_NAME,
+ /// String representation of the type of the JavaScriptFunction class.
+ JS_FUNCTION_CLASS_TYPE_NAME,
+
/// String recipe for the [bool] type.
BOOL_RECIPE,
diff --git a/runtime/bin/builtin.dart b/sdk/lib/_internal/vm/bin/builtin.dart
similarity index 100%
rename from runtime/bin/builtin.dart
rename to sdk/lib/_internal/vm/bin/builtin.dart
diff --git a/runtime/bin/cli_patch.dart b/sdk/lib/_internal/vm/bin/cli_patch.dart
similarity index 100%
rename from runtime/bin/cli_patch.dart
rename to sdk/lib/_internal/vm/bin/cli_patch.dart
diff --git a/runtime/bin/common_patch.dart b/sdk/lib/_internal/vm/bin/common_patch.dart
similarity index 100%
rename from runtime/bin/common_patch.dart
rename to sdk/lib/_internal/vm/bin/common_patch.dart
diff --git a/runtime/bin/directory_patch.dart b/sdk/lib/_internal/vm/bin/directory_patch.dart
similarity index 100%
rename from runtime/bin/directory_patch.dart
rename to sdk/lib/_internal/vm/bin/directory_patch.dart
diff --git a/runtime/bin/eventhandler_patch.dart b/sdk/lib/_internal/vm/bin/eventhandler_patch.dart
similarity index 100%
rename from runtime/bin/eventhandler_patch.dart
rename to sdk/lib/_internal/vm/bin/eventhandler_patch.dart
diff --git a/runtime/bin/file_patch.dart b/sdk/lib/_internal/vm/bin/file_patch.dart
similarity index 100%
rename from runtime/bin/file_patch.dart
rename to sdk/lib/_internal/vm/bin/file_patch.dart
diff --git a/runtime/bin/file_system_entity_patch.dart b/sdk/lib/_internal/vm/bin/file_system_entity_patch.dart
similarity index 100%
rename from runtime/bin/file_system_entity_patch.dart
rename to sdk/lib/_internal/vm/bin/file_system_entity_patch.dart
diff --git a/runtime/bin/filter_patch.dart b/sdk/lib/_internal/vm/bin/filter_patch.dart
similarity index 100%
rename from runtime/bin/filter_patch.dart
rename to sdk/lib/_internal/vm/bin/filter_patch.dart
diff --git a/runtime/bin/io_service_patch.dart b/sdk/lib/_internal/vm/bin/io_service_patch.dart
similarity index 100%
rename from runtime/bin/io_service_patch.dart
rename to sdk/lib/_internal/vm/bin/io_service_patch.dart
diff --git a/runtime/bin/namespace_patch.dart b/sdk/lib/_internal/vm/bin/namespace_patch.dart
similarity index 100%
rename from runtime/bin/namespace_patch.dart
rename to sdk/lib/_internal/vm/bin/namespace_patch.dart
diff --git a/runtime/bin/platform_patch.dart b/sdk/lib/_internal/vm/bin/platform_patch.dart
similarity index 100%
rename from runtime/bin/platform_patch.dart
rename to sdk/lib/_internal/vm/bin/platform_patch.dart
diff --git a/runtime/bin/process_patch.dart b/sdk/lib/_internal/vm/bin/process_patch.dart
similarity index 100%
rename from runtime/bin/process_patch.dart
rename to sdk/lib/_internal/vm/bin/process_patch.dart
diff --git a/runtime/bin/secure_socket_patch.dart b/sdk/lib/_internal/vm/bin/secure_socket_patch.dart
similarity index 100%
rename from runtime/bin/secure_socket_patch.dart
rename to sdk/lib/_internal/vm/bin/secure_socket_patch.dart
diff --git a/runtime/bin/socket_patch.dart b/sdk/lib/_internal/vm/bin/socket_patch.dart
similarity index 100%
rename from runtime/bin/socket_patch.dart
rename to sdk/lib/_internal/vm/bin/socket_patch.dart
diff --git a/runtime/bin/stdio_patch.dart b/sdk/lib/_internal/vm/bin/stdio_patch.dart
similarity index 100%
rename from runtime/bin/stdio_patch.dart
rename to sdk/lib/_internal/vm/bin/stdio_patch.dart
diff --git a/runtime/bin/sync_socket_patch.dart b/sdk/lib/_internal/vm/bin/sync_socket_patch.dart
similarity index 100%
rename from runtime/bin/sync_socket_patch.dart
rename to sdk/lib/_internal/vm/bin/sync_socket_patch.dart
diff --git a/runtime/lib/array.dart b/sdk/lib/_internal/vm/lib/array.dart
similarity index 100%
rename from runtime/lib/array.dart
rename to sdk/lib/_internal/vm/lib/array.dart
diff --git a/runtime/lib/array_patch.dart b/sdk/lib/_internal/vm/lib/array_patch.dart
similarity index 100%
rename from runtime/lib/array_patch.dart
rename to sdk/lib/_internal/vm/lib/array_patch.dart
diff --git a/runtime/lib/async_patch.dart b/sdk/lib/_internal/vm/lib/async_patch.dart
similarity index 100%
rename from runtime/lib/async_patch.dart
rename to sdk/lib/_internal/vm/lib/async_patch.dart
diff --git a/runtime/lib/bigint_patch.dart b/sdk/lib/_internal/vm/lib/bigint_patch.dart
similarity index 100%
rename from runtime/lib/bigint_patch.dart
rename to sdk/lib/_internal/vm/lib/bigint_patch.dart
diff --git a/runtime/lib/bool_patch.dart b/sdk/lib/_internal/vm/lib/bool_patch.dart
similarity index 100%
rename from runtime/lib/bool_patch.dart
rename to sdk/lib/_internal/vm/lib/bool_patch.dart
diff --git a/runtime/lib/class_id.dart b/sdk/lib/_internal/vm/lib/class_id.dart
similarity index 100%
rename from runtime/lib/class_id.dart
rename to sdk/lib/_internal/vm/lib/class_id.dart
diff --git a/runtime/lib/class_id_fasta.dart b/sdk/lib/_internal/vm/lib/class_id_fasta.dart
similarity index 100%
rename from runtime/lib/class_id_fasta.dart
rename to sdk/lib/_internal/vm/lib/class_id_fasta.dart
diff --git a/runtime/lib/collection_patch.dart b/sdk/lib/_internal/vm/lib/collection_patch.dart
similarity index 100%
rename from runtime/lib/collection_patch.dart
rename to sdk/lib/_internal/vm/lib/collection_patch.dart
diff --git a/runtime/lib/compact_hash.dart b/sdk/lib/_internal/vm/lib/compact_hash.dart
similarity index 100%
rename from runtime/lib/compact_hash.dart
rename to sdk/lib/_internal/vm/lib/compact_hash.dart
diff --git a/runtime/lib/convert_patch.dart b/sdk/lib/_internal/vm/lib/convert_patch.dart
similarity index 100%
rename from runtime/lib/convert_patch.dart
rename to sdk/lib/_internal/vm/lib/convert_patch.dart
diff --git a/runtime/lib/core_patch.dart b/sdk/lib/_internal/vm/lib/core_patch.dart
similarity index 100%
rename from runtime/lib/core_patch.dart
rename to sdk/lib/_internal/vm/lib/core_patch.dart
diff --git a/runtime/lib/date_patch.dart b/sdk/lib/_internal/vm/lib/date_patch.dart
similarity index 100%
rename from runtime/lib/date_patch.dart
rename to sdk/lib/_internal/vm/lib/date_patch.dart
diff --git a/runtime/lib/deferred_load_patch.dart b/sdk/lib/_internal/vm/lib/deferred_load_patch.dart
similarity index 100%
rename from runtime/lib/deferred_load_patch.dart
rename to sdk/lib/_internal/vm/lib/deferred_load_patch.dart
diff --git a/runtime/lib/developer.dart b/sdk/lib/_internal/vm/lib/developer.dart
similarity index 100%
rename from runtime/lib/developer.dart
rename to sdk/lib/_internal/vm/lib/developer.dart
diff --git a/runtime/lib/double.dart b/sdk/lib/_internal/vm/lib/double.dart
similarity index 100%
rename from runtime/lib/double.dart
rename to sdk/lib/_internal/vm/lib/double.dart
diff --git a/runtime/lib/double_patch.dart b/sdk/lib/_internal/vm/lib/double_patch.dart
similarity index 100%
rename from runtime/lib/double_patch.dart
rename to sdk/lib/_internal/vm/lib/double_patch.dart
diff --git a/runtime/lib/empty_source.dart b/sdk/lib/_internal/vm/lib/empty_source.dart
similarity index 100%
rename from runtime/lib/empty_source.dart
rename to sdk/lib/_internal/vm/lib/empty_source.dart
diff --git a/runtime/lib/errors_patch.dart b/sdk/lib/_internal/vm/lib/errors_patch.dart
similarity index 100%
rename from runtime/lib/errors_patch.dart
rename to sdk/lib/_internal/vm/lib/errors_patch.dart
diff --git a/runtime/lib/expando_patch.dart b/sdk/lib/_internal/vm/lib/expando_patch.dart
similarity index 100%
rename from runtime/lib/expando_patch.dart
rename to sdk/lib/_internal/vm/lib/expando_patch.dart
diff --git a/runtime/lib/ffi_dynamic_library_patch.dart b/sdk/lib/_internal/vm/lib/ffi_dynamic_library_patch.dart
similarity index 100%
rename from runtime/lib/ffi_dynamic_library_patch.dart
rename to sdk/lib/_internal/vm/lib/ffi_dynamic_library_patch.dart
diff --git a/runtime/lib/ffi_native_type_patch.dart b/sdk/lib/_internal/vm/lib/ffi_native_type_patch.dart
similarity index 100%
rename from runtime/lib/ffi_native_type_patch.dart
rename to sdk/lib/_internal/vm/lib/ffi_native_type_patch.dart
diff --git a/runtime/lib/ffi_patch.dart b/sdk/lib/_internal/vm/lib/ffi_patch.dart
similarity index 100%
rename from runtime/lib/ffi_patch.dart
rename to sdk/lib/_internal/vm/lib/ffi_patch.dart
diff --git a/runtime/lib/function.dart b/sdk/lib/_internal/vm/lib/function.dart
similarity index 100%
rename from runtime/lib/function.dart
rename to sdk/lib/_internal/vm/lib/function.dart
diff --git a/runtime/lib/function_patch.dart b/sdk/lib/_internal/vm/lib/function_patch.dart
similarity index 100%
rename from runtime/lib/function_patch.dart
rename to sdk/lib/_internal/vm/lib/function_patch.dart
diff --git a/runtime/lib/growable_array.dart b/sdk/lib/_internal/vm/lib/growable_array.dart
similarity index 100%
rename from runtime/lib/growable_array.dart
rename to sdk/lib/_internal/vm/lib/growable_array.dart
diff --git a/runtime/lib/identical_patch.dart b/sdk/lib/_internal/vm/lib/identical_patch.dart
similarity index 100%
rename from runtime/lib/identical_patch.dart
rename to sdk/lib/_internal/vm/lib/identical_patch.dart
diff --git a/runtime/lib/immutable_map.dart b/sdk/lib/_internal/vm/lib/immutable_map.dart
similarity index 100%
rename from runtime/lib/immutable_map.dart
rename to sdk/lib/_internal/vm/lib/immutable_map.dart
diff --git a/runtime/lib/integers.dart b/sdk/lib/_internal/vm/lib/integers.dart
similarity index 100%
rename from runtime/lib/integers.dart
rename to sdk/lib/_internal/vm/lib/integers.dart
diff --git a/runtime/lib/integers_patch.dart b/sdk/lib/_internal/vm/lib/integers_patch.dart
similarity index 100%
rename from runtime/lib/integers_patch.dart
rename to sdk/lib/_internal/vm/lib/integers_patch.dart
diff --git a/runtime/lib/internal_patch.dart b/sdk/lib/_internal/vm/lib/internal_patch.dart
similarity index 100%
rename from runtime/lib/internal_patch.dart
rename to sdk/lib/_internal/vm/lib/internal_patch.dart
diff --git a/runtime/lib/invocation_mirror_patch.dart b/sdk/lib/_internal/vm/lib/invocation_mirror_patch.dart
similarity index 100%
rename from runtime/lib/invocation_mirror_patch.dart
rename to sdk/lib/_internal/vm/lib/invocation_mirror_patch.dart
diff --git a/runtime/lib/isolate_patch.dart b/sdk/lib/_internal/vm/lib/isolate_patch.dart
similarity index 100%
rename from runtime/lib/isolate_patch.dart
rename to sdk/lib/_internal/vm/lib/isolate_patch.dart
diff --git a/runtime/lib/lib_prefix.dart b/sdk/lib/_internal/vm/lib/lib_prefix.dart
similarity index 100%
rename from runtime/lib/lib_prefix.dart
rename to sdk/lib/_internal/vm/lib/lib_prefix.dart
diff --git a/runtime/lib/map_patch.dart b/sdk/lib/_internal/vm/lib/map_patch.dart
similarity index 100%
rename from runtime/lib/map_patch.dart
rename to sdk/lib/_internal/vm/lib/map_patch.dart
diff --git a/runtime/lib/math_patch.dart b/sdk/lib/_internal/vm/lib/math_patch.dart
similarity index 100%
rename from runtime/lib/math_patch.dart
rename to sdk/lib/_internal/vm/lib/math_patch.dart
diff --git a/runtime/lib/mirror_reference.dart b/sdk/lib/_internal/vm/lib/mirror_reference.dart
similarity index 100%
rename from runtime/lib/mirror_reference.dart
rename to sdk/lib/_internal/vm/lib/mirror_reference.dart
diff --git a/runtime/lib/mirrors_impl.dart b/sdk/lib/_internal/vm/lib/mirrors_impl.dart
similarity index 90%
copy from runtime/lib/mirrors_impl.dart
copy to sdk/lib/_internal/vm/lib/mirrors_impl.dart
index d6d07fd..013246c 100644
--- a/runtime/lib/mirrors_impl.dart
+++ b/sdk/lib/_internal/vm/lib/mirrors_impl.dart
@@ -67,7 +67,7 @@
bool _subtypeTest(Type a, Type b) native 'TypeMirror_subtypeTest';
-class _LocalMirrorSystem extends MirrorSystem {
+class _MirrorSystem extends MirrorSystem {
final TypeMirror dynamicType = new _SpecialTypeMirror._('dynamic');
final TypeMirror voidType = new _SpecialTypeMirror._('void');
@@ -114,13 +114,11 @@
}
}
-abstract class _LocalMirror implements Mirror {}
-
-class _LocalIsolateMirror extends _LocalMirror implements IsolateMirror {
+class _IsolateMirror extends Mirror implements IsolateMirror {
final String debugName;
final LibraryMirror rootLibrary;
- _LocalIsolateMirror._(this.debugName, this.rootLibrary);
+ _IsolateMirror._(this.debugName, this.rootLibrary);
bool get isCurrent => true;
@@ -201,14 +199,14 @@
List<InstanceMirror> get metadata => const <InstanceMirror>[];
}
-abstract class _LocalObjectMirror extends _LocalMirror implements ObjectMirror {
+abstract class _ObjectMirror extends Mirror implements ObjectMirror {
_invoke(reflectee, functionName, arguments, argumentNames);
_invokeGetter(reflectee, getterName);
_invokeSetter(reflectee, setterName, value);
final _reflectee; // May be a MirrorReference or an ordinary object.
- _LocalObjectMirror._(this._reflectee);
+ _ObjectMirror._(this._reflectee);
InstanceMirror invoke(Symbol memberName, List positionalArguments,
[Map<Symbol, dynamic> namedArguments]) {
@@ -260,9 +258,8 @@
}
}
-class _LocalInstanceMirror extends _LocalObjectMirror
- implements InstanceMirror {
- _LocalInstanceMirror._(reflectee) : super._(reflectee);
+class _InstanceMirror extends _ObjectMirror implements InstanceMirror {
+ _InstanceMirror._(reflectee) : super._(reflectee);
ClassMirror _type;
ClassMirror get type {
@@ -282,8 +279,7 @@
String toString() => 'InstanceMirror on ${Error.safeToString(_reflectee)}';
bool operator ==(other) {
- return other is _LocalInstanceMirror &&
- identical(_reflectee, other._reflectee);
+ return other is _InstanceMirror && identical(_reflectee, other._reflectee);
}
int get hashCode {
@@ -334,9 +330,8 @@
static _computeType(reflectee) native 'InstanceMirror_computeType';
}
-class _LocalClosureMirror extends _LocalInstanceMirror
- implements ClosureMirror {
- _LocalClosureMirror._(reflectee) : super._(reflectee);
+class _ClosureMirror extends _InstanceMirror implements ClosureMirror {
+ _ClosureMirror._(reflectee) : super._(reflectee);
MethodMirror _function;
MethodMirror get function {
@@ -356,12 +351,11 @@
static _computeFunction(reflectee) native 'ClosureMirror_function';
}
-abstract class _LocalTypeMirror {
+abstract class _TypeMirror {
Type get _reflectedType;
}
-class _LocalClassMirror extends _LocalObjectMirror
- implements ClassMirror, _LocalTypeMirror {
+class _ClassMirror extends _ObjectMirror implements ClassMirror, _TypeMirror {
final Type _reflectedType;
Symbol _simpleName;
DeclarationMirror _owner;
@@ -377,7 +371,7 @@
final bool isEnum;
Type _instantiator;
- _LocalClassMirror._(
+ _ClassMirror._(
reflectee,
reflectedType,
String simpleName,
@@ -419,7 +413,7 @@
DeclarationMirror get owner {
if (_owner == null) {
- var uri = _LocalClassMirror._libraryUri(_reflectee);
+ var uri = _ClassMirror._libraryUri(_reflectee);
_owner = currentMirrorSystem().libraries[Uri.parse(uri)];
}
return _owner;
@@ -433,8 +427,8 @@
return _location(_reflectee);
}
- _LocalClassMirror _trueSuperclassField;
- _LocalClassMirror get _trueSuperclass {
+ _ClassMirror _trueSuperclassField;
+ _ClassMirror get _trueSuperclass {
if (_trueSuperclassField == null) {
Type supertype = isOriginalDeclaration
? _supertype(_reflectedType)
@@ -487,8 +481,7 @@
var _mixin;
ClassMirror get mixin {
if (_mixin == null) {
- Type mixinType =
- _nativeMixinInstantiated(_reflectedType, _instantiator);
+ Type mixinType = _nativeMixinInstantiated(_reflectedType, _instantiator);
if (mixinType == null) {
// The reflectee is not a mixin application.
_mixin = this;
@@ -599,7 +592,7 @@
ClassMirror owner = originalDeclaration;
var mirror;
for (var i = 0; i < params.length; i += 2) {
- mirror = new _LocalTypeVariableMirror._(params[i + 1], params[i], owner);
+ mirror = new _TypeVariableMirror._(params[i + 1], params[i], owner);
_typeVariables.add(mirror);
}
_typeVariables =
@@ -676,14 +669,13 @@
bool isSubtypeOf(TypeMirror other) {
if (other == currentMirrorSystem().dynamicType) return true;
if (other == currentMirrorSystem().voidType) return false;
- return _subtypeTest(
- _reflectedType, (other as _LocalTypeMirror)._reflectedType);
+ return _subtypeTest(_reflectedType, (other as _TypeMirror)._reflectedType);
}
bool isAssignableTo(TypeMirror other) {
if (other == currentMirrorSystem().dynamicType) return true;
if (other == currentMirrorSystem().voidType) return false;
- final otherReflectedType = (other as _LocalTypeMirror)._reflectedType;
+ final otherReflectedType = (other as _TypeMirror)._reflectedType;
return _subtypeTest(_reflectedType, otherReflectedType) ||
_subtypeTest(otherReflectedType, _reflectedType);
}
@@ -741,12 +733,11 @@
native "ClassMirror_type_arguments";
}
-class _LocalFunctionTypeMirror extends _LocalClassMirror
- implements FunctionTypeMirror {
+class _FunctionTypeMirror extends _ClassMirror implements FunctionTypeMirror {
final _functionReflectee;
- _LocalFunctionTypeMirror._(reflectee, this._functionReflectee, reflectedType)
- : super._(reflectee, reflectedType, null, null, false, false, false, false,
- false);
+ _FunctionTypeMirror._(reflectee, this._functionReflectee, reflectedType)
+ : super._(reflectee, reflectedType, null, null, false, false, false,
+ false, false);
bool get _isAnonymousMixinApplication => false;
@@ -805,12 +796,11 @@
native "FunctionTypeMirror_parameters";
}
-abstract class _LocalDeclarationMirror extends _LocalMirror
- implements DeclarationMirror {
+abstract class _DeclarationMirror extends Mirror implements DeclarationMirror {
final _reflectee;
Symbol _simpleName;
- _LocalDeclarationMirror._(this._reflectee, this._simpleName);
+ _DeclarationMirror._(this._reflectee, this._simpleName);
Symbol get simpleName => _simpleName;
@@ -843,9 +833,9 @@
int get hashCode => simpleName.hashCode;
}
-class _LocalTypeVariableMirror extends _LocalDeclarationMirror
- implements TypeVariableMirror, _LocalTypeMirror {
- _LocalTypeVariableMirror._(reflectee, String simpleName, this._owner)
+class _TypeVariableMirror extends _DeclarationMirror
+ implements TypeVariableMirror, _TypeMirror {
+ _TypeVariableMirror._(reflectee, String simpleName, this._owner)
: super._(reflectee, _s(simpleName));
DeclarationMirror _owner;
@@ -894,14 +884,13 @@
bool isSubtypeOf(TypeMirror other) {
if (other == currentMirrorSystem().dynamicType) return true;
if (other == currentMirrorSystem().voidType) return false;
- return _subtypeTest(
- _reflectedType, (other as _LocalTypeMirror)._reflectedType);
+ return _subtypeTest(_reflectedType, (other as _TypeMirror)._reflectedType);
}
bool isAssignableTo(TypeMirror other) {
if (other == currentMirrorSystem().dynamicType) return true;
if (other == currentMirrorSystem().voidType) return false;
- final otherReflectedType = (other as _LocalTypeMirror)._reflectedType;
+ final otherReflectedType = (other as _TypeMirror)._reflectedType;
return _subtypeTest(_reflectedType, otherReflectedType) ||
_subtypeTest(otherReflectedType, _reflectedType);
}
@@ -913,13 +902,13 @@
native "TypeVariableMirror_upper_bound";
}
-class _LocalTypedefMirror extends _LocalDeclarationMirror
- implements TypedefMirror, _LocalTypeMirror {
+class _TypedefMirror extends _DeclarationMirror
+ implements TypedefMirror, _TypeMirror {
final Type _reflectedType;
final bool _isGeneric;
final bool _isGenericDeclaration;
- _LocalTypedefMirror(reflectee, this._reflectedType, String simpleName,
+ _TypedefMirror(reflectee, this._reflectedType, String simpleName,
this._isGeneric, this._isGenericDeclaration, this._owner)
: super._(reflectee, _s(simpleName));
@@ -928,13 +917,13 @@
DeclarationMirror _owner;
DeclarationMirror get owner {
if (_owner == null) {
- var uri = _LocalClassMirror._libraryUri(_reflectee);
+ var uri = _ClassMirror._libraryUri(_reflectee);
_owner = currentMirrorSystem().libraries[Uri.parse(uri)];
}
return _owner;
}
- _LocalFunctionTypeMirror _referent;
+ _FunctionTypeMirror _referent;
FunctionTypeMirror get referent {
if (_referent == null) {
_referent = _nativeReferent(_reflectedType);
@@ -966,11 +955,11 @@
List<TypeVariableMirror> get typeVariables {
if (_typeVariables == null) {
_typeVariables = new List<TypeVariableMirror>();
- List params = _LocalClassMirror._ClassMirror_type_variables(_reflectee);
+ List params = _ClassMirror._ClassMirror_type_variables(_reflectee);
TypedefMirror owner = originalDeclaration;
var mirror;
for (var i = 0; i < params.length; i += 2) {
- mirror = new _LocalTypeVariableMirror._(params[i + 1], params[i], owner);
+ mirror = new _TypeVariableMirror._(params[i + 1], params[i], owner);
_typeVariables.add(mirror);
}
}
@@ -983,9 +972,9 @@
if (_isGenericDeclaration) {
_typeArguments = const <TypeMirror>[];
} else {
- _typeArguments = new UnmodifiableListView<TypeMirror>(_LocalClassMirror
- ._computeTypeArguments(_reflectedType)
- .cast<TypeMirror>());
+ _typeArguments = new UnmodifiableListView<TypeMirror>(
+ _ClassMirror._computeTypeArguments(_reflectedType)
+ .cast<TypeMirror>());
}
}
return _typeArguments;
@@ -996,14 +985,13 @@
bool isSubtypeOf(TypeMirror other) {
if (other == currentMirrorSystem().dynamicType) return true;
if (other == currentMirrorSystem().voidType) return false;
- return _subtypeTest(
- _reflectedType, (other as _LocalTypeMirror)._reflectedType);
+ return _subtypeTest(_reflectedType, (other as _TypeMirror)._reflectedType);
}
bool isAssignableTo(TypeMirror other) {
if (other == currentMirrorSystem().dynamicType) return true;
if (other == currentMirrorSystem().voidType) return false;
- final otherReflectedType = (other as _LocalTypeMirror)._reflectedType;
+ final otherReflectedType = (other as _TypeMirror)._reflectedType;
return _subtypeTest(_reflectedType, otherReflectedType) ||
_subtypeTest(otherReflectedType, _reflectedType);
}
@@ -1020,11 +1008,11 @@
return MirrorSystem.getSymbol('${unwrapped}=', library);
}
-class _LocalLibraryMirror extends _LocalObjectMirror implements LibraryMirror {
+class _LibraryMirror extends _ObjectMirror implements LibraryMirror {
final Symbol simpleName;
final Uri uri;
- _LocalLibraryMirror._(reflectee, String simpleName, String url)
+ _LibraryMirror._(reflectee, String simpleName, String url)
: this.simpleName = _s(simpleName),
this.uri = Uri.parse(url),
super._(reflectee);
@@ -1097,7 +1085,7 @@
List<dynamic> _computeMembers(reflectee) native "LibraryMirror_members";
}
-class _LocalLibraryDependencyMirror extends _LocalMirror
+class _LibraryDependencyMirror extends Mirror
implements LibraryDependencyMirror {
final LibraryMirror sourceLibrary;
var _targetMirrorOrPrefix;
@@ -1107,7 +1095,7 @@
final bool isDeferred;
final List<InstanceMirror> metadata;
- _LocalLibraryDependencyMirror._(
+ _LibraryDependencyMirror._(
this.sourceLibrary,
this._targetMirrorOrPrefix,
List<dynamic> mutableCombinators,
@@ -1124,7 +1112,7 @@
bool get isExport => !isImport;
LibraryMirror get targetLibrary {
- if (_targetMirrorOrPrefix is _LocalLibraryMirror) {
+ if (_targetMirrorOrPrefix is _LibraryMirror) {
return _targetMirrorOrPrefix;
}
var mirrorOrNull = _tryUpgradePrefix(_targetMirrorOrPrefix);
@@ -1135,7 +1123,7 @@
}
Future<LibraryMirror> loadLibrary() {
- if (_targetMirrorOrPrefix is _LocalLibraryMirror) {
+ if (_targetMirrorOrPrefix is _LibraryMirror) {
return new Future.value(_targetMirrorOrPrefix);
}
var savedPrefix = _targetMirrorOrPrefix;
@@ -1150,25 +1138,24 @@
SourceLocation get location => null;
}
-class _LocalCombinatorMirror extends _LocalMirror implements CombinatorMirror {
+class _CombinatorMirror extends Mirror implements CombinatorMirror {
final List<Symbol> identifiers;
final bool isShow;
- _LocalCombinatorMirror._(identifierString, this.isShow)
+ _CombinatorMirror._(identifierString, this.isShow)
: this.identifiers =
new UnmodifiableListView<Symbol>(<Symbol>[_s(identifierString)]);
bool get isHide => !isShow;
}
-class _LocalMethodMirror extends _LocalDeclarationMirror
- implements MethodMirror {
+class _MethodMirror extends _DeclarationMirror implements MethodMirror {
final Type _instantiator;
final bool isStatic;
final int _kindFlags;
- _LocalMethodMirror._(reflectee, String simpleName, this._owner,
- this._instantiator, this.isStatic, this._kindFlags)
+ _MethodMirror._(reflectee, String simpleName, this._owner, this._instantiator,
+ this.isStatic, this._kindFlags)
: super._(reflectee, _s(simpleName));
static const kAbstract = 0;
@@ -1289,14 +1276,13 @@
static String _MethodMirror_source(reflectee) native "MethodMirror_source";
}
-class _LocalVariableMirror extends _LocalDeclarationMirror
- implements VariableMirror {
+class _VariableMirror extends _DeclarationMirror implements VariableMirror {
final DeclarationMirror owner;
final bool isStatic;
final bool isFinal;
final bool isConst;
- _LocalVariableMirror._(reflectee, String simpleName, this.owner, this._type,
+ _VariableMirror._(reflectee, String simpleName, this.owner, this._type,
this.isStatic, this.isFinal, this.isConst)
: super._(reflectee, _s(simpleName));
@@ -1304,11 +1290,11 @@
Type get _instantiator {
final o = owner; // Note: need local variable for promotion to happen.
- if (o is _LocalClassMirror) {
+ if (o is _ClassMirror) {
return o._instantiator;
- } else if (o is _LocalMethodMirror) {
+ } else if (o is _MethodMirror) {
return o._instantiator;
- } else if (o is _LocalLibraryMirror) {
+ } else if (o is _LibraryMirror) {
return o._instantiator;
} else {
throw new UnsupportedError("unexpected owner ${owner}");
@@ -1330,14 +1316,13 @@
native "VariableMirror_type";
}
-class _LocalParameterMirror extends _LocalVariableMirror
- implements ParameterMirror {
+class _ParameterMirror extends _VariableMirror implements ParameterMirror {
final int _position;
final bool isOptional;
final bool isNamed;
final List _unmirroredMetadata;
- _LocalParameterMirror._(
+ _ParameterMirror._(
reflectee,
String simpleName,
DeclarationMirror owner,
@@ -1396,7 +1381,7 @@
native "ParameterMirror_type";
}
-class _SpecialTypeMirror extends _LocalMirror
+class _SpecialTypeMirror extends Mirror
implements TypeMirror, DeclarationMirror {
final Symbol simpleName;
@@ -1445,7 +1430,7 @@
}
class _Mirrors {
- static MirrorSystem _currentMirrorSystem = new _LocalMirrorSystem();
+ static MirrorSystem _currentMirrorSystem = new _MirrorSystem();
static MirrorSystem currentMirrorSystem() {
return _currentMirrorSystem;
}
@@ -1453,8 +1438,8 @@
// Creates a new local mirror for some Object.
static InstanceMirror reflect(Object reflectee) {
return reflectee is Function
- ? new _LocalClosureMirror._(reflectee)
- : new _LocalInstanceMirror._(reflectee);
+ ? new _ClosureMirror._(reflectee)
+ : new _InstanceMirror._(reflectee);
}
static ClassMirror _makeLocalClassMirror(Type key)
@@ -1464,8 +1449,7 @@
static Type _instantiateGenericType(Type key, typeArguments)
native "Mirrors_instantiateGenericType";
- static Expando<_LocalClassMirror> _declarationCache =
- new Expando("ClassMirror");
+ static Expando<_ClassMirror> _declarationCache = new Expando("ClassMirror");
static Expando<TypeMirror> _instantiationCache = new Expando("TypeMirror");
static ClassMirror reflectClass(Type key) {
@@ -1488,7 +1472,7 @@
if (typeMirror == null) {
typeMirror = _makeLocalTypeMirror(key);
_instantiationCache[key] = typeMirror;
- if (typeMirror is _LocalClassMirror && !typeMirror._isGeneric) {
+ if (typeMirror is _ClassMirror && !typeMirror._isGeneric) {
_declarationCache[key] = typeMirror;
}
}
diff --git a/runtime/lib/mirrors_patch.dart b/sdk/lib/_internal/vm/lib/mirrors_patch.dart
similarity index 94%
copy from runtime/lib/mirrors_patch.dart
copy to sdk/lib/_internal/vm/lib/mirrors_patch.dart
index 623fd65..9850e91 100644
--- a/runtime/lib/mirrors_patch.dart
+++ b/sdk/lib/_internal/vm/lib/mirrors_patch.dart
@@ -78,12 +78,12 @@
@patch
static Symbol getSymbol(String name, [LibraryMirror library]) {
- if ((library != null && library is! _LocalLibraryMirror) ||
+ if ((library != null && library is! _LibraryMirror) ||
((name.length > 0) && (name[0] == '_') && (library == null))) {
throw new ArgumentError(library);
}
if (library != null) {
- name = _mangleName(name, (library as _LocalLibraryMirror)._reflectee);
+ name = _mangleName(name, (library as _LibraryMirror)._reflectee);
}
return new internal.Symbol.unvalidated(name);
}
diff --git a/runtime/lib/null_patch.dart b/sdk/lib/_internal/vm/lib/null_patch.dart
similarity index 100%
rename from runtime/lib/null_patch.dart
rename to sdk/lib/_internal/vm/lib/null_patch.dart
diff --git a/runtime/lib/object_patch.dart b/sdk/lib/_internal/vm/lib/object_patch.dart
similarity index 100%
rename from runtime/lib/object_patch.dart
rename to sdk/lib/_internal/vm/lib/object_patch.dart
diff --git a/runtime/lib/print_patch.dart b/sdk/lib/_internal/vm/lib/print_patch.dart
similarity index 100%
rename from runtime/lib/print_patch.dart
rename to sdk/lib/_internal/vm/lib/print_patch.dart
diff --git a/runtime/lib/profiler.dart b/sdk/lib/_internal/vm/lib/profiler.dart
similarity index 100%
rename from runtime/lib/profiler.dart
rename to sdk/lib/_internal/vm/lib/profiler.dart
diff --git a/runtime/lib/regexp_patch.dart b/sdk/lib/_internal/vm/lib/regexp_patch.dart
similarity index 100%
rename from runtime/lib/regexp_patch.dart
rename to sdk/lib/_internal/vm/lib/regexp_patch.dart
diff --git a/runtime/lib/schedule_microtask_patch.dart b/sdk/lib/_internal/vm/lib/schedule_microtask_patch.dart
similarity index 100%
rename from runtime/lib/schedule_microtask_patch.dart
rename to sdk/lib/_internal/vm/lib/schedule_microtask_patch.dart
diff --git a/runtime/lib/stacktrace.dart b/sdk/lib/_internal/vm/lib/stacktrace.dart
similarity index 100%
rename from runtime/lib/stacktrace.dart
rename to sdk/lib/_internal/vm/lib/stacktrace.dart
diff --git a/runtime/lib/stopwatch_patch.dart b/sdk/lib/_internal/vm/lib/stopwatch_patch.dart
similarity index 100%
rename from runtime/lib/stopwatch_patch.dart
rename to sdk/lib/_internal/vm/lib/stopwatch_patch.dart
diff --git a/runtime/lib/string_buffer_patch.dart b/sdk/lib/_internal/vm/lib/string_buffer_patch.dart
similarity index 100%
rename from runtime/lib/string_buffer_patch.dart
rename to sdk/lib/_internal/vm/lib/string_buffer_patch.dart
diff --git a/runtime/lib/string_patch.dart b/sdk/lib/_internal/vm/lib/string_patch.dart
similarity index 98%
copy from runtime/lib/string_patch.dart
copy to sdk/lib/_internal/vm/lib/string_patch.dart
index c08bd49..837599b 100644
--- a/runtime/lib/string_patch.dart
+++ b/sdk/lib/_internal/vm/lib/string_patch.dart
@@ -948,7 +948,9 @@
@pragma("vm:entry-point")
class _OneByteString extends _StringBase {
- factory _OneByteString._uninstantiable() { throw "Unreachable"; }
+ factory _OneByteString._uninstantiable() {
+ throw "Unreachable";
+ }
@pragma("vm:exact-result-type", "dart:core#_Smi")
int get hashCode native "String_getHashCode";
@@ -1254,7 +1256,9 @@
@pragma("vm:entry-point")
class _TwoByteString extends _StringBase {
- factory _TwoByteString._uninstantiable() { throw "Unreachable"; }
+ factory _TwoByteString._uninstantiable() {
+ throw "Unreachable";
+ }
static String _allocateFromTwoByteList(List<int> list, int start, int end)
native "TwoByteString_allocateFromTwoByteList";
@@ -1274,7 +1278,9 @@
@pragma("vm:entry-point")
class _ExternalOneByteString extends _StringBase {
- factory _ExternalOneByteString._uninstantiable() { throw "Unreachable"; }
+ factory _ExternalOneByteString._uninstantiable() {
+ throw "Unreachable";
+ }
bool _isWhitespace(int codeUnit) {
return _StringBase._isOneByteWhitespace(codeUnit);
@@ -1290,7 +1296,9 @@
@pragma("vm:entry-point")
class _ExternalTwoByteString extends _StringBase {
- factory _ExternalTwoByteString._uninstantiable() { throw "Unreachable"; }
+ factory _ExternalTwoByteString._uninstantiable() {
+ throw "Unreachable";
+ }
bool _isWhitespace(int codeUnit) {
return _StringBase._isTwoByteWhitespace(codeUnit);
diff --git a/runtime/lib/symbol_patch.dart b/sdk/lib/_internal/vm/lib/symbol_patch.dart
similarity index 100%
rename from runtime/lib/symbol_patch.dart
rename to sdk/lib/_internal/vm/lib/symbol_patch.dart
diff --git a/runtime/lib/timeline.dart b/sdk/lib/_internal/vm/lib/timeline.dart
similarity index 100%
rename from runtime/lib/timeline.dart
rename to sdk/lib/_internal/vm/lib/timeline.dart
diff --git a/runtime/lib/timer_impl.dart b/sdk/lib/_internal/vm/lib/timer_impl.dart
similarity index 100%
rename from runtime/lib/timer_impl.dart
rename to sdk/lib/_internal/vm/lib/timer_impl.dart
diff --git a/runtime/lib/timer_patch.dart b/sdk/lib/_internal/vm/lib/timer_patch.dart
similarity index 100%
rename from runtime/lib/timer_patch.dart
rename to sdk/lib/_internal/vm/lib/timer_patch.dart
diff --git a/runtime/lib/type_patch.dart b/sdk/lib/_internal/vm/lib/type_patch.dart
similarity index 100%
rename from runtime/lib/type_patch.dart
rename to sdk/lib/_internal/vm/lib/type_patch.dart
diff --git a/runtime/lib/typed_data_patch.dart b/sdk/lib/_internal/vm/lib/typed_data_patch.dart
similarity index 100%
rename from runtime/lib/typed_data_patch.dart
rename to sdk/lib/_internal/vm/lib/typed_data_patch.dart
diff --git a/runtime/lib/uri_patch.dart b/sdk/lib/_internal/vm/lib/uri_patch.dart
similarity index 100%
rename from runtime/lib/uri_patch.dart
rename to sdk/lib/_internal/vm/lib/uri_patch.dart
diff --git a/sdk/lib/_internal/vm/lib/wasm_patch.dart b/sdk/lib/_internal/vm/lib/wasm_patch.dart
new file mode 100644
index 0000000..f0c2794
--- /dev/null
+++ b/sdk/lib/_internal/vm/lib/wasm_patch.dart
@@ -0,0 +1,149 @@
+// Copyright (c) 2019, 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.
+
+import 'dart:_internal' show patch;
+import "dart:nativewrappers" show NativeFieldWrapperClass1;
+import 'dart:typed_data';
+
+@patch
+@pragma("vm:entry-point")
+class Int32 {}
+
+@patch
+@pragma("vm:entry-point")
+class Int64 {}
+
+@patch
+@pragma("vm:entry-point")
+class Float {}
+
+@patch
+@pragma("vm:entry-point")
+class Double {}
+
+@patch
+@pragma("vm:entry-point")
+class Void {}
+
+@patch
+class WasmModule {
+ @patch
+ factory WasmModule(Uint8List data) {
+ return _NativeWasmModule(data);
+ }
+}
+
+@patch
+class WasmMemory {
+ @patch
+ factory WasmMemory(int initialPages, [int maxPages]) {
+ return _NativeWasmMemory(initialPages, maxPages);
+ }
+}
+
+@patch
+class WasmImports {
+ @patch
+ factory WasmImports(String moduleName) {
+ return _NativeWasmImports(moduleName);
+ }
+}
+
+class _NativeWasmModule extends NativeFieldWrapperClass1 implements WasmModule {
+ _NativeWasmModule(Uint8List data) {
+ _init(data);
+ }
+
+ WasmInstance instantiate(covariant _NativeWasmImports imports) {
+ return _NativeWasmInstance(this, imports);
+ }
+
+ void _init(Uint8List data) native 'Wasm_initModule';
+}
+
+class _NativeWasmImports extends NativeFieldWrapperClass1
+ implements WasmImports {
+ List<WasmMemory> _memories;
+
+ _NativeWasmImports(String moduleName) : _memories = [] {
+ _init(moduleName);
+ }
+
+ void addMemory(String name, WasmMemory memory) {
+ _memories.add(memory);
+ _addMemory(name, memory);
+ }
+
+ void addGlobal<T>(String name, num value, bool mutable) {
+ _addGlobal(name, value, T, mutable);
+ }
+
+ void _init(String moduleName) native 'Wasm_initImports';
+ void _addMemory(String name, WasmMemory memory) native 'Wasm_addMemoryImport';
+ void _addGlobal(String name, num value, Type type, bool mutable)
+ native 'Wasm_addGlobalImport';
+}
+
+class _NativeWasmMemory extends NativeFieldWrapperClass1 implements WasmMemory {
+ int _pages;
+ Uint8List _buffer;
+
+ _NativeWasmMemory(int initialPages, int maxPages) : _pages = initialPages {
+ _buffer = _init(initialPages, maxPages);
+ }
+
+ int get lengthInPages => _pages;
+ int get lengthInBytes => _buffer.lengthInBytes;
+ int operator [](int index) => _buffer[index];
+ void operator []=(int index, int value) {
+ _buffer[index] = value;
+ }
+
+ int grow(int deltaPages) {
+ int oldPages = _pages;
+ _buffer = _grow(deltaPages);
+ _pages += deltaPages;
+ return oldPages;
+ }
+
+ Uint8List _init(int initialPages, int maxPages) native 'Wasm_initMemory';
+ Uint8List _grow(int deltaPages) native 'Wasm_growMemory';
+}
+
+class _NativeWasmInstance extends NativeFieldWrapperClass1
+ implements WasmInstance {
+ _NativeWasmModule _module;
+ _NativeWasmImports _imports;
+
+ _NativeWasmInstance(_NativeWasmModule module, _NativeWasmImports imports)
+ : _module = module,
+ _imports = imports {
+ _init(module, imports);
+ }
+
+ WasmFunction<T> lookupFunction<T extends Function>(String name) {
+ return _NativeWasmFunction<T>(this, name);
+ }
+
+ void _init(_NativeWasmModule module, _NativeWasmImports imports)
+ native 'Wasm_initInstance';
+}
+
+class _NativeWasmFunction<T extends Function> extends NativeFieldWrapperClass1
+ implements WasmFunction<T> {
+ _NativeWasmInstance _inst;
+
+ _NativeWasmFunction(_NativeWasmInstance inst, String name) : _inst = inst {
+ _init(inst, name, T);
+ }
+
+ num call(List<num> args) {
+ var arg_copy = List<num>.from(args, growable: false);
+ return _call(arg_copy);
+ }
+
+ void _init(_NativeWasmInstance inst, String name, Type fnType)
+ native 'Wasm_initFunction';
+ num _call(List<num> args) native 'Wasm_callFunction';
+}
diff --git a/runtime/lib/weak_property.dart b/sdk/lib/_internal/vm/lib/weak_property.dart
similarity index 100%
rename from runtime/lib/weak_property.dart
rename to sdk/lib/_internal/vm/lib/weak_property.dart
diff --git a/sdk/lib/html/html_common/conversions.dart b/sdk/lib/html/html_common/conversions.dart
index 4c31efb..5fa8385 100644
--- a/sdk/lib/html/html_common/conversions.dart
+++ b/sdk/lib/html/html_common/conversions.dart
@@ -76,6 +76,9 @@
cleanupSlots() {} // Will be needed if we mark objects with a property.
bool cloneNotRequired(object);
+ JSObject newJsObject();
+ void forEachObjectKey(object, action(key, value));
+ void putIntoObject(object, key, value);
newJsMap();
List newJsList(length);
void putIntoMap(map, key, value);
@@ -134,6 +137,19 @@
return copy;
}
+ if (e is JSObject) {
+ var slot = findSlot(e);
+ var copy = readSlot(slot);
+ if (copy != null) return copy;
+ copy = newJsObject();
+ writeSlot(slot, copy);
+ // TODO: Consider inlining this so we don't allocate a closure.
+ forEachObjectKey(e, (key, value) {
+ putIntoObject(copy, key, walk(value));
+ });
+ return copy;
+ }
+
throw new UnimplementedError('structured clone of other type');
}
diff --git a/sdk/lib/html/html_common/conversions_dart2js.dart b/sdk/lib/html/html_common/conversions_dart2js.dart
index 36153cf..d077775 100644
--- a/sdk/lib/html/html_common/conversions_dart2js.dart
+++ b/sdk/lib/html/html_common/conversions_dart2js.dart
@@ -53,6 +53,18 @@
.convertNativeToDart_AcceptStructuredClone(object, mustCopy: mustCopy);
class _StructuredCloneDart2Js extends _StructuredClone {
+ JSObject newJsObject() => JS('JSObject', '{}');
+
+ void forEachObjectKey(object, action(key, value)) {
+ for (final key
+ in JS('returns:JSExtendableArray;new:true', 'Object.keys(#)', object)) {
+ action(key, JS('var', '#[#]', object, key));
+ }
+ }
+
+ void putIntoObject(object, key, value) =>
+ JS('void', '#[#] = #', object, key, value);
+
newJsMap() => JS('var', '{}');
putIntoMap(map, key, value) => JS('void', '#[#] = #', map, key, value);
newJsList(length) => JS('JSExtendableArray', 'new Array(#)', length);
diff --git a/sdk/lib/html/html_common/html_common_dart2js.dart b/sdk/lib/html/html_common/html_common_dart2js.dart
index f162ad8..de8d89e 100644
--- a/sdk/lib/html/html_common/html_common_dart2js.dart
+++ b/sdk/lib/html/html_common/html_common_dart2js.dart
@@ -13,7 +13,7 @@
import 'dart:_native_typed_data';
import 'dart:_js_helper' show Creates, Returns, convertDartClosureToJS;
import 'dart:_foreign_helper' show JS;
-import 'dart:_interceptors' show Interceptor, JSExtendableArray;
+import 'dart:_interceptors' show Interceptor, JSExtendableArray, JSObject;
import 'dart:_metadata';
export 'dart:_metadata';
diff --git a/sdk/lib/js/dart2js/js_dart2js.dart b/sdk/lib/js/dart2js/js_dart2js.dart
index 535227b..23656d7 100644
--- a/sdk/lib/js/dart2js/js_dart2js.dart
+++ b/sdk/lib/js/dart2js/js_dart2js.dart
@@ -2,85 +2,86 @@
// 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.
-/**
- * Support for interoperating with JavaScript.
- *
- * This library provides access to JavaScript objects from Dart, allowing
- * Dart code to get and set properties, and call methods of JavaScript objects
- * and invoke JavaScript functions. The library takes care of converting
- * between Dart and JavaScript objects where possible, or providing proxies if
- * conversion isn't possible.
- *
- * This library does not yet make Dart objects usable from JavaScript, their
- * methods and proeprties are not accessible, though it does allow Dart
- * functions to be passed into and called from JavaScript.
- *
- * [JsObject] is the core type and represents a proxy of a JavaScript object.
- * JsObject gives access to the underlying JavaScript objects properties and
- * methods. `JsObject`s can be acquired by calls to JavaScript, or they can be
- * created from proxies to JavaScript constructors.
- *
- * The top-level getter [context] provides a [JsObject] that represents the
- * global object in JavaScript, usually `window`.
- *
- * The following example shows an alert dialog via a JavaScript call to the
- * global function `alert()`:
- *
- * import 'dart:js';
- *
- * main() => context.callMethod('alert', ['Hello from Dart!']);
- *
- * This example shows how to create a [JsObject] from a JavaScript constructor
- * and access its properties:
- *
- * import 'dart:js';
- *
- * main() {
- * var object = new JsObject(context['Object']);
- * object['greeting'] = 'Hello';
- * object['greet'] = (name) => "${object['greeting']} $name";
- * var message = object.callMethod('greet', ['JavaScript']);
- * context['console'].callMethod('log', [message]);
- * }
- *
- * ## Proxying and automatic conversion
- *
- * When setting properties on a JsObject or passing arguments to a Javascript
- * method or function, Dart objects are automatically converted or proxied to
- * JavaScript objects. When accessing JavaScript properties, or when a Dart
- * closure is invoked from JavaScript, the JavaScript objects are also
- * converted to Dart.
- *
- * Functions and closures are proxied in such a way that they are callable. A
- * Dart closure assigned to a JavaScript property is proxied by a function in
- * JavaScript. A JavaScript function accessed from Dart is proxied by a
- * [JsFunction], which has a [apply] method to invoke it.
- *
- * The following types are transferred directly and not proxied:
- *
- * * Basic types: `null`, `bool`, `num`, `String`, `DateTime`
- * * `TypedData`, including its subclasses like `Int32List`, but _not_
- * `ByteBuffer`
- * * When compiling for the web, also: `Blob`, `Event`, `ImageData`,
- * `KeyRange`, `Node`, and `Window`.
- *
- * ## Converting collections with JsObject.jsify()
- *
- * To create a JavaScript collection from a Dart collection use the
- * [JsObject.jsify] constructor, which converts Dart [Map]s and [Iterable]s
- * into JavaScript Objects and Arrays.
- *
- * The following expression creates a new JavaScript object with the properties
- * `a` and `b` defined:
- *
- * var jsMap = new JsObject.jsify({'a': 1, 'b': 2});
- *
- * This expression creates a JavaScript array:
- *
- * var jsArray = new JsObject.jsify([1, 2, 3]);
- *
- * {@category Web}
- */
+/// Low-level support for interoperating with JavaScript.
+///
+/// You should usually use `package:js` instead of this library. For more
+/// information, see the [JS interop page](https://dart.dev/web/js-interop).
+///
+/// This library provides access to JavaScript objects from Dart, allowing
+/// Dart code to get and set properties, and call methods of JavaScript objects
+/// and invoke JavaScript functions. The library takes care of converting
+/// between Dart and JavaScript objects where possible, or providing proxies if
+/// conversion isn't possible.
+///
+/// This library does not make Dart objects usable from JavaScript, their
+/// methods and properties are not accessible, though it does allow Dart
+/// functions to be passed into and called from JavaScript.
+///
+/// [JsObject] is the core type and represents a proxy of a JavaScript object.
+/// JsObject gives access to the underlying JavaScript objects properties and
+/// methods. `JsObject`s can be acquired by calls to JavaScript, or they can be
+/// created from proxies to JavaScript constructors.
+///
+/// The top-level getter [context] provides a [JsObject] that represents the
+/// global object in JavaScript, usually `window`.
+///
+/// The following example shows an alert dialog via a JavaScript call to the
+/// global function `alert()`:
+///
+/// import 'dart:js';
+///
+/// main() => context.callMethod('alert', ['Hello from Dart!']);
+///
+/// This example shows how to create a [JsObject] from a JavaScript constructor
+/// and access its properties:
+///
+/// import 'dart:js';
+///
+/// main() {
+/// var object = JsObject(context['Object']);
+/// object['greeting'] = 'Hello';
+/// object['greet'] = (name) => "${object['greeting']} $name";
+/// var message = object.callMethod('greet', ['JavaScript']);
+/// context['console'].callMethod('log', [message]);
+/// }
+///
+/// ## Proxying and automatic conversion
+///
+/// When setting properties on a JsObject or passing arguments to a Javascript
+/// method or function, Dart objects are automatically converted or proxied to
+/// JavaScript objects. When accessing JavaScript properties, or when a Dart
+/// closure is invoked from JavaScript, the JavaScript objects are also
+/// converted to Dart.
+///
+/// Functions and closures are proxied in such a way that they are callable. A
+/// Dart closure assigned to a JavaScript property is proxied by a function in
+/// JavaScript. A JavaScript function accessed from Dart is proxied by a
+/// [JsFunction], which has a [apply] method to invoke it.
+///
+/// The following types are transferred directly and not proxied:
+///
+/// * Basic types: `null`, `bool`, `num`, `String`, `DateTime`
+/// * `TypedData`, including its subclasses like `Int32List`, but _not_
+/// `ByteBuffer`
+/// * When compiling for the web, also: `Blob`, `Event`, `ImageData`,
+/// `KeyRange`, `Node`, and `Window`.
+///
+/// ## Converting collections with JsObject.jsify()
+///
+/// To create a JavaScript collection from a Dart collection use the
+/// [JsObject.jsify] constructor, which converts Dart [Map]s and [Iterable]s
+/// into JavaScript Objects and Arrays.
+///
+/// The following expression creates a new JavaScript object with the properties
+/// `a` and `b` defined:
+///
+/// var jsMap = JsObject.jsify({'a': 1, 'b': 2});
+///
+/// This expression creates a JavaScript array:
+///
+/// var jsArray = JsObject.jsify([1, 2, 3]);
+///
+/// {@category Web}
library dart.js;
import 'dart:collection' show HashMap, ListMixin;
@@ -99,6 +100,7 @@
export 'dart:_interceptors' show JavaScriptObject;
+/// The JavaScript global object, usually `window`.
final JsObject context = _wrapToDart(JS('', 'self'));
_convertDartFunction(Function f, {bool captureThis: false}) {
@@ -121,56 +123,51 @@
if (captureThis) {
arguments = [self]..addAll(arguments);
}
- var dartArgs = new List.from(arguments.map(_convertToDart));
+ var dartArgs = List.from(arguments.map(_convertToDart));
return _convertToJS(Function.apply(callback, dartArgs));
}
-/**
- * Proxies a JavaScript object to Dart.
- *
- * The properties of the JavaScript object are accessible via the `[]` and
- * `[]=` operators. Methods are callable via [callMethod].
- */
+/// A proxy on a JavaScript object.
+///
+/// The properties of the JavaScript object are accessible via the `[]` and
+/// `[]=` operators. Methods are callable via [callMethod].
class JsObject {
// The wrapped JS object.
final dynamic _jsObject;
- // This shoud only be called from _wrapToDart
+ // This should only be called from _wrapToDart
JsObject._fromJs(this._jsObject) {
assert(_jsObject != null);
}
- /**
- * Constructs a new JavaScript object from [constructor] and returns a proxy
- * to it.
- */
+ /// Constructs a JavaScript object from its native [constructor] and returns
+ /// a proxy to it.
factory JsObject(JsFunction constructor, [List arguments]) {
- var constr = _convertToJS(constructor);
+ var ctor = _convertToJS(constructor);
if (arguments == null) {
- return _wrapToDart(JS('', 'new #()', constr));
+ return _wrapToDart(JS('', 'new #()', ctor));
}
if (JS('bool', '# instanceof Array', arguments)) {
int argumentCount = JS('int', '#.length', arguments);
switch (argumentCount) {
case 0:
- return _wrapToDart(JS('', 'new #()', constr));
+ return _wrapToDart(JS('', 'new #()', ctor));
case 1:
var arg0 = _convertToJS(JS('', '#[0]', arguments));
- return _wrapToDart(JS('', 'new #(#)', constr, arg0));
+ return _wrapToDart(JS('', 'new #(#)', ctor, arg0));
case 2:
var arg0 = _convertToJS(JS('', '#[0]', arguments));
var arg1 = _convertToJS(JS('', '#[1]', arguments));
- return _wrapToDart(JS('', 'new #(#, #)', constr, arg0, arg1));
+ return _wrapToDart(JS('', 'new #(#, #)', ctor, arg0, arg1));
case 3:
var arg0 = _convertToJS(JS('', '#[0]', arguments));
var arg1 = _convertToJS(JS('', '#[1]', arguments));
var arg2 = _convertToJS(JS('', '#[2]', arguments));
- return _wrapToDart(
- JS('', 'new #(#, #, #)', constr, arg0, arg1, arg2));
+ return _wrapToDart(JS('', 'new #(#, #, #)', ctor, arg0, arg1, arg2));
case 4:
var arg0 = _convertToJS(JS('', '#[0]', arguments));
@@ -178,7 +175,7 @@
var arg2 = _convertToJS(JS('', '#[2]', arguments));
var arg3 = _convertToJS(JS('', '#[3]', arguments));
return _wrapToDart(
- JS('', 'new #(#, #, #, #)', constr, arg0, arg1, arg2, arg3));
+ JS('', 'new #(#, #, #, #)', ctor, arg0, arg1, arg2, arg3));
}
}
@@ -190,7 +187,7 @@
// After that, use the JavaScript 'new' operator which overrides any binding
// of 'this' with the new instance.
var args = <dynamic>[null]..addAll(arguments.map(_convertToJS));
- var factoryFunction = JS('', '#.bind.apply(#, #)', constr, constr, args);
+ var factoryFunction = JS('', '#.bind.apply(#, #)', ctor, ctor, args);
// Without this line, calling factoryFunction as a constructor throws
JS('String', 'String(#)', factoryFunction);
// This could return an UnknownJavaScriptObject, or a native
@@ -201,48 +198,44 @@
// TODO(sra): Investigate:
//
- // var jsObj = JS('', 'Object.create(#.prototype)', constr);
- // JS('', '#.apply(#, #)', constr, jsObj,
+ // var jsObj = JS('', 'Object.create(#.prototype)', ctor);
+ // JS('', '#.apply(#, #)', ctor, jsObj,
// []..addAll(arguments.map(_convertToJS)));
// return _wrapToDart(jsObj);
}
- /**
- * Constructs a [JsObject] that proxies a native Dart object; _for expert use
- * only_.
- *
- * Use this constructor only if you wish to get access to JavaScript
- * properties attached to a browser host object, such as a Node or Blob, that
- * is normally automatically converted into a native Dart object.
- *
- * An exception will be thrown if [object] either is `null` or has the type
- * `bool`, `num`, or `String`.
- */
+ /// Constructs a [JsObject] that proxies a native Dart object; _for expert use
+ /// only_.
+ ///
+ /// Use this constructor only if you wish to get access to JavaScript
+ /// properties attached to a browser host object, such as a Node or Blob, that
+ /// is normally automatically converted into a native Dart object.
+ ///
+ /// An exception will be thrown if [object] either is `null` or has the type
+ /// `bool`, `num`, or `String`.
factory JsObject.fromBrowserObject(object) {
if (object is num || object is String || object is bool || object == null) {
- throw new 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));
}
- /**
- * Recursively converts a JSON-like collection of Dart objects to a
- * collection of JavaScript objects and returns a [JsObject] proxy to it.
- *
- * [object] must be a [Map] or [Iterable], the contents of which are also
- * converted. Maps and Iterables are copied to a new JavaScript object.
- * Primitives and other transferrable values are directly converted to their
- * JavaScript type, and all other objects are proxied.
- */
+ /// Recursively converts a JSON-like collection of Dart objects to a
+ /// collection of JavaScript objects and returns a [JsObject] proxy to it.
+ ///
+ /// [object] must be a [Map] or [Iterable], the contents of which are also
+ /// converted. Maps and Iterables are copied to a new JavaScript object.
+ /// Primitives and other transferable values are directly converted to their
+ /// JavaScript type, and all other objects are proxied.
factory JsObject.jsify(object) {
if ((object is! Map) && (object is! Iterable)) {
- throw new ArgumentError("object must be a Map or Iterable");
+ throw ArgumentError("object must be a Map or Iterable");
}
return _wrapToDart(_convertDataTree(object));
}
static _convertDataTree(data) {
- var _convertedObjects = new HashMap.identity();
+ var _convertedObjects = HashMap.identity();
_convert(o) {
if (_convertedObjects.containsKey(o)) {
@@ -252,7 +245,7 @@
final convertedMap = JS('=Object', '{}');
_convertedObjects[o] = convertedMap;
for (var key in o.keys) {
- JS('=Object', '#[#]=#', convertedMap, key, _convert(o[key]));
+ JS('=Object', '#[#] = #', convertedMap, key, _convert(o[key]));
}
return convertedMap;
} else if (o is Iterable) {
@@ -268,30 +261,26 @@
return _convert(data);
}
- /**
- * Returns the value associated with [property] from the proxied JavaScript
- * object.
- *
- * The type of [property] must be either [String] or [num].
- */
+ /// Returns the value associated with [property] from the proxied JavaScript
+ /// object.
+ ///
+ /// The type of [property] must be either [String] or [num].
dynamic operator [](property) {
if (property is! String && property is! num) {
- throw new ArgumentError("property is not a String or num");
+ throw ArgumentError("property is not a String or num");
}
return _convertToDart(JS('', '#[#]', _jsObject, property));
}
- /**
- * Sets the value associated with [property] on the proxied JavaScript
- * object.
- *
- * The type of [property] must be either [String] or [num].
- */
- operator []=(property, value) {
+ // Sets the value associated with [property] on the proxied JavaScript
+ // object.
+ //
+ // The type of [property] must be either [String] or [num].
+ void operator []=(property, value) {
if (property is! String && property is! num) {
- throw new ArgumentError("property is not a String or num");
+ throw ArgumentError("property is not a String or num");
}
- JS('', '#[#]=#', _jsObject, property, _convertToJS(value));
+ JS('', '#[#] = #', _jsObject, property, _convertToJS(value));
}
int get hashCode => 0;
@@ -299,43 +288,35 @@
bool operator ==(other) =>
other is JsObject && JS('bool', '# === #', _jsObject, other._jsObject);
- /**
- * Returns `true` if the JavaScript object contains the specified property
- * either directly or though its prototype chain.
- *
- * This is the equivalent of the `in` operator in JavaScript.
- */
+ /// Returns `true` if the JavaScript object contains the specified property
+ /// either directly or though its prototype chain.
+ ///
+ /// This is the equivalent of the `in` operator in JavaScript.
bool hasProperty(property) {
if (property is! String && property is! num) {
- throw new ArgumentError("property is not a String or num");
+ throw ArgumentError("property is not a String or num");
}
return JS('bool', '# in #', property, _jsObject);
}
- /**
- * Removes [property] from the JavaScript object.
- *
- * This is the equivalent of the `delete` operator in JavaScript.
- */
+ /// Removes [property] from the JavaScript object.
+ ///
+ /// This is the equivalent of the `delete` operator in JavaScript.
void deleteProperty(property) {
if (property is! String && property is! num) {
- throw new ArgumentError("property is not a String or num");
+ throw ArgumentError("property is not a String or num");
}
JS('bool', 'delete #[#]', _jsObject, property);
}
- /**
- * Returns `true` if the JavaScript object has [type] in its prototype chain.
- *
- * This is the equivalent of the `instanceof` operator in JavaScript.
- */
+ /// Returns `true` if the JavaScript object has [type] in its prototype chain.
+ ///
+ /// This is the equivalent of the `instanceof` operator in JavaScript.
bool instanceof(JsFunction type) {
return JS('bool', '# instanceof #', _jsObject, _convertToJS(type));
}
- /**
- * Returns the result of the JavaScript objects `toString` method.
- */
+ /// Returns the result of the JavaScript objects `toString` method.
String toString() {
try {
return JS('String', 'String(#)', _jsObject);
@@ -344,66 +325,47 @@
}
}
- /**
- * Calls [method] on the JavaScript object with the arguments [args] and
- * returns the result.
- *
- * The type of [method] must be either [String] or [num].
- */
+ /// Calls [method] on the JavaScript object with the arguments [args] and
+ /// returns the result.
+ ///
+ /// The type of [method] must be either [String] or [num].
dynamic callMethod(method, [List args]) {
if (method is! String && method is! num) {
- throw new ArgumentError("method is not a String or num");
+ throw ArgumentError("method is not a String or num");
}
- return _convertToDart(JS(
- '',
- '#[#].apply(#, #)',
- _jsObject,
- method,
- _jsObject,
- args == null ? null : new List.from(args.map(_convertToJS))));
+ return _convertToDart(JS('', '#[#].apply(#, #)', _jsObject, method,
+ _jsObject, args == null ? null : List.from(args.map(_convertToJS))));
}
}
-/**
- * Proxies a JavaScript Function object.
- */
+/// A proxy on a JavaScript Function object.
class JsFunction extends JsObject {
- /**
- * Returns a [JsFunction] that captures its 'this' binding and calls [f]
- * with the value of this passed as the first argument.
- */
+ /// Returns a [JsFunction] that captures its 'this' binding and calls [f]
+ /// with the value of JavaScript `this` passed as the first argument.
factory JsFunction.withThis(Function f) {
var jsFunc = _convertDartFunction(f, captureThis: true);
- return new JsFunction._fromJs(jsFunc);
+ return JsFunction._fromJs(jsFunc);
}
JsFunction._fromJs(jsObject) : super._fromJs(jsObject);
- /**
- * Invokes the JavaScript function with arguments [args]. If [thisArg] is
- * supplied it is the value of `this` for the invocation.
- */
+ /// Invokes the JavaScript function with arguments [args]. If [thisArg] is
+ /// supplied it is the value of `this` for the invocation.
dynamic apply(List args, {thisArg}) => _convertToDart(JS(
'',
'#.apply(#, #)',
_jsObject,
_convertToJS(thisArg),
- args == null ? null : new List.from(args.map(_convertToJS))));
+ args == null ? null : List.from(args.map(_convertToJS))));
}
-/**
- * A [List] that proxies a JavaScript array.
- */
+/// A [List] that proxies a JavaScript array.
class JsArray<E> extends JsObject with ListMixin<E> {
- /**
- * Creates a new JavaScript array.
- */
+ /// Creates an empty JavaScript array.
JsArray() : super._fromJs([]);
- /**
- * Creates a new JavaScript array and initializes it to the contents of
- * [other].
- */
+ /// Creates a new JavaScript array and initializes it to the contents of
+ /// [other].
JsArray.from(Iterable<E> other)
: super._fromJs([]..addAll(other.map(_convertToJS)));
@@ -411,22 +373,22 @@
_checkIndex(int index) {
if (index is int && (index < 0 || index >= length)) {
- throw new RangeError.range(index, 0, length);
+ throw RangeError.range(index, 0, length);
}
}
_checkInsertIndex(int index) {
if (index is int && (index < 0 || index >= length + 1)) {
- throw new RangeError.range(index, 0, length);
+ throw RangeError.range(index, 0, length);
}
}
static _checkRange(int start, int end, int length) {
if (start < 0 || start > length) {
- throw new RangeError.range(start, 0, length);
+ throw RangeError.range(start, 0, length);
}
if (end < start || end > length) {
- throw new RangeError.range(end, start, length);
+ throw RangeError.range(end, start, length);
}
}
@@ -457,7 +419,7 @@
if (JS('bool', 'typeof # === "number" && (# >>> 0) === #', len, len, len)) {
return JS('int', '#', len);
}
- throw new StateError('Bad JsArray length');
+ throw StateError('Bad JsArray length');
}
void set length(int length) {
@@ -473,7 +435,7 @@
void addAll(Iterable<E> iterable) {
var list = (JS('bool', '# instanceof Array', iterable))
? iterable
- : new List.from(iterable);
+ : List.from(iterable);
callMethod('push', list);
}
@@ -488,7 +450,7 @@
}
E removeLast() {
- if (length == 0) throw new RangeError(-1);
+ if (length == 0) throw RangeError(-1);
return callMethod('pop');
}
@@ -501,7 +463,7 @@
_checkRange(start, end, this.length);
int length = end - start;
if (length == 0) return;
- if (skipCount < 0) throw new ArgumentError(skipCount);
+ if (skipCount < 0) throw ArgumentError(skipCount);
var args = <dynamic>[start, length]
..addAll(iterable.skip(skipCount).take(length));
callMethod('splice', args);
@@ -612,7 +574,7 @@
return JS('TypedData', '#', o);
} else if (JS('bool', '# instanceof Date', o)) {
var ms = JS('num', '#.getTime()', o);
- return new DateTime.fromMillisecondsSinceEpoch(ms);
+ return DateTime.fromMillisecondsSinceEpoch(ms);
} else if (JS('bool', '#.constructor === #', o, _dartProxyCtor)) {
return JS('', '#.o', o);
} else {
@@ -623,14 +585,14 @@
Object _wrapToDart(o) {
if (JS('bool', 'typeof # == "function"', o)) {
return _getDartProxy(
- o, DART_CLOSURE_PROPERTY_NAME, (o) => new JsFunction._fromJs(o));
+ o, DART_CLOSURE_PROPERTY_NAME, (o) => JsFunction._fromJs(o));
}
if (JS('bool', '# instanceof Array', o)) {
return _getDartProxy(
- o, _DART_OBJECT_PROPERTY_NAME, (o) => new JsArray._fromJs(o));
+ o, _DART_OBJECT_PROPERTY_NAME, (o) => JsArray._fromJs(o));
}
return _getDartProxy(
- o, _DART_OBJECT_PROPERTY_NAME, (o) => new JsObject._fromJs(o));
+ o, _DART_OBJECT_PROPERTY_NAME, (o) => JsObject._fromJs(o));
}
Object _getDartProxy(o, String propertyName, createProxy(o)) {
@@ -649,9 +611,6 @@
return dartProxy;
}
-// ---------------------------------------------------------------------------
-// Start of methods for new style Dart-JS interop.
-
_convertDartFunctionFast(Function f) {
var existing = JS('', '#.#', f, _JS_FUNCTION_PROPERTY_NAME);
if (existing != null) return existing;
@@ -698,6 +657,17 @@
return Function.apply(callback, [self]..addAll(arguments));
}
+/// Returns a wrapper around function [f] that can be called from JavaScript
+/// using `package:js` JavaScript interop.
+///
+/// The calling conventions in Dart2Js differ from JavaScript and so, by
+/// default, it is not possible to call a Dart function directly. Wrapping with
+/// `allowInterop` creates a function that can be called from JavaScript or
+/// Dart. The semantics of the wrapped function are still more strict than
+/// JavaScript, and the function will throw if called with too many or too few
+/// arguments.
+///
+/// Calling this method repeatedly on a function will return the same result.
F allowInterop<F extends Function>(F f) {
if (JS('bool', 'typeof(#) == "function"', f)) {
// Already supports interop, just use the existing function.
@@ -707,10 +677,17 @@
}
}
+/// Returns a wrapper around function [f] that can be called from JavaScript
+/// using `package:js` JavaScript interop, passing JavaScript `this` as the first
+/// argument.
+///
+/// See [allowInterop].
+///
+/// When called from Dart, [null] will be passed as the first argument.
Function allowInteropCaptureThis(Function f) {
if (JS('bool', 'typeof(#) == "function"', f)) {
// Behavior when the function is already a JS function is unspecified.
- throw new ArgumentError(
+ throw ArgumentError(
"Function is already a JS function so cannot capture this.");
return f;
} else {
diff --git a/sdk/lib/libraries.json b/sdk/lib/libraries.json
index 663991f..a6c8390 100644
--- a/sdk/lib/libraries.json
+++ b/sdk/lib/libraries.json
@@ -4,150 +4,150 @@
"vm": {
"libraries": {
"_builtin": {
- "uri": "../../runtime/bin/builtin.dart"
+ "uri": "_internal/vm/bin/builtin.dart"
},
"cli": {
"patches": [
- "../../runtime/bin/cli_patch.dart"
+ "_internal/vm/bin/cli_patch.dart"
],
"uri": "cli/cli.dart"
},
"core": {
"patches": [
- "../../runtime/lib/core_patch.dart",
- "../../runtime/lib/array.dart",
- "../../runtime/lib/array_patch.dart",
- "../../runtime/lib/bigint_patch.dart",
- "../../runtime/lib/bool_patch.dart",
- "../../runtime/lib/date_patch.dart",
- "../../runtime/lib/double.dart",
- "../../runtime/lib/double_patch.dart",
- "../../runtime/lib/errors_patch.dart",
- "../../runtime/lib/expando_patch.dart",
- "../../runtime/lib/function.dart",
- "../../runtime/lib/function_patch.dart",
- "../../runtime/lib/growable_array.dart",
- "../../runtime/lib/identical_patch.dart",
- "../../runtime/lib/immutable_map.dart",
- "../../runtime/lib/integers.dart",
- "../../runtime/lib/integers_patch.dart",
- "../../runtime/lib/invocation_mirror_patch.dart",
- "../../runtime/lib/lib_prefix.dart",
- "../../runtime/lib/map_patch.dart",
- "../../runtime/lib/null_patch.dart",
- "../../runtime/lib/object_patch.dart",
- "../../runtime/lib/regexp_patch.dart",
- "../../runtime/lib/stacktrace.dart",
- "../../runtime/lib/stopwatch_patch.dart",
- "../../runtime/lib/string_buffer_patch.dart",
- "../../runtime/lib/string_patch.dart",
- "../../runtime/lib/type_patch.dart",
- "../../runtime/lib/uri_patch.dart",
- "../../runtime/lib/weak_property.dart"
+ "_internal/vm/lib/core_patch.dart",
+ "_internal/vm/lib/array.dart",
+ "_internal/vm/lib/array_patch.dart",
+ "_internal/vm/lib/bigint_patch.dart",
+ "_internal/vm/lib/bool_patch.dart",
+ "_internal/vm/lib/date_patch.dart",
+ "_internal/vm/lib/double.dart",
+ "_internal/vm/lib/double_patch.dart",
+ "_internal/vm/lib/errors_patch.dart",
+ "_internal/vm/lib/expando_patch.dart",
+ "_internal/vm/lib/function.dart",
+ "_internal/vm/lib/function_patch.dart",
+ "_internal/vm/lib/growable_array.dart",
+ "_internal/vm/lib/identical_patch.dart",
+ "_internal/vm/lib/immutable_map.dart",
+ "_internal/vm/lib/integers.dart",
+ "_internal/vm/lib/integers_patch.dart",
+ "_internal/vm/lib/invocation_mirror_patch.dart",
+ "_internal/vm/lib/lib_prefix.dart",
+ "_internal/vm/lib/map_patch.dart",
+ "_internal/vm/lib/null_patch.dart",
+ "_internal/vm/lib/object_patch.dart",
+ "_internal/vm/lib/regexp_patch.dart",
+ "_internal/vm/lib/stacktrace.dart",
+ "_internal/vm/lib/stopwatch_patch.dart",
+ "_internal/vm/lib/string_buffer_patch.dart",
+ "_internal/vm/lib/string_patch.dart",
+ "_internal/vm/lib/type_patch.dart",
+ "_internal/vm/lib/uri_patch.dart",
+ "_internal/vm/lib/weak_property.dart"
],
"uri": "core/core.dart"
},
"async": {
"patches": [
- "../../runtime/lib/async_patch.dart",
- "../../runtime/lib/deferred_load_patch.dart",
- "../../runtime/lib/schedule_microtask_patch.dart",
- "../../runtime/lib/timer_patch.dart"
+ "_internal/vm/lib/async_patch.dart",
+ "_internal/vm/lib/deferred_load_patch.dart",
+ "_internal/vm/lib/schedule_microtask_patch.dart",
+ "_internal/vm/lib/timer_patch.dart"
],
"uri": "async/async.dart"
},
"collection": {
"patches": [
- "../../runtime/lib/collection_patch.dart",
- "../../runtime/lib/compact_hash.dart"
+ "_internal/vm/lib/collection_patch.dart",
+ "_internal/vm/lib/compact_hash.dart"
],
"uri": "collection/collection.dart"
},
"ffi": {
"patches": [
- "../../runtime/lib/ffi_patch.dart",
- "../../runtime/lib/ffi_dynamic_library_patch.dart",
- "../../runtime/lib/ffi_native_type_patch.dart"
+ "_internal/vm/lib/ffi_patch.dart",
+ "_internal/vm/lib/ffi_dynamic_library_patch.dart",
+ "_internal/vm/lib/ffi_native_type_patch.dart"
],
"uri": "ffi/ffi.dart"
},
- "wasm": {
- "patches": [
- "../../runtime/lib/wasm_patch.dart"
- ],
- "uri": "wasm/wasm.dart"
- },
"typed_data": {
- "patches": "../../runtime/lib/typed_data_patch.dart",
+ "patches": "_internal/vm/lib/typed_data_patch.dart",
"uri": "typed_data/typed_data.dart"
},
"nativewrappers": {
"uri": "html/dartium/nativewrappers.dart"
},
+ "mirrors": {
+ "patches": [
+ "_internal/vm/lib/mirrors_patch.dart",
+ "_internal/vm/lib/mirrors_impl.dart",
+ "_internal/vm/lib/mirror_reference.dart"
+ ],
+ "uri": "mirrors/mirrors.dart"
+ },
"developer": {
"patches": [
- "../../runtime/lib/developer.dart",
- "../../runtime/lib/profiler.dart",
- "../../runtime/lib/timeline.dart"
+ "_internal/vm/lib/developer.dart",
+ "_internal/vm/lib/profiler.dart",
+ "_internal/vm/lib/timeline.dart"
],
"uri": "developer/developer.dart"
},
"isolate": {
"patches": [
- "../../runtime/lib/isolate_patch.dart",
- "../../runtime/lib/timer_impl.dart"
+ "_internal/vm/lib/isolate_patch.dart",
+ "_internal/vm/lib/timer_impl.dart"
],
"uri": "isolate/isolate.dart"
},
- "mirrors": {
- "patches": [
- "../../runtime/lib/mirrors_patch.dart",
- "../../runtime/lib/mirrors_impl.dart",
- "../../runtime/lib/mirror_reference.dart"
- ],
- "uri": "mirrors/mirrors.dart"
- },
"_vmservice": {
"uri": "vmservice/vmservice.dart"
},
+ "wasm": {
+ "patches": [
+ "_internal/vm/lib/wasm_patch.dart"
+ ],
+ "uri": "wasm/wasm.dart"
+ },
"io": {
"patches": [
- "../../runtime/bin/common_patch.dart",
- "../../runtime/bin/directory_patch.dart",
- "../../runtime/bin/eventhandler_patch.dart",
- "../../runtime/bin/file_patch.dart",
- "../../runtime/bin/file_system_entity_patch.dart",
- "../../runtime/bin/filter_patch.dart",
- "../../runtime/bin/io_service_patch.dart",
- "../../runtime/bin/namespace_patch.dart",
- "../../runtime/bin/platform_patch.dart",
- "../../runtime/bin/process_patch.dart",
- "../../runtime/bin/socket_patch.dart",
- "../../runtime/bin/stdio_patch.dart",
- "../../runtime/bin/secure_socket_patch.dart",
- "../../runtime/bin/sync_socket_patch.dart"
+ "_internal/vm/bin/common_patch.dart",
+ "_internal/vm/bin/directory_patch.dart",
+ "_internal/vm/bin/eventhandler_patch.dart",
+ "_internal/vm/bin/file_patch.dart",
+ "_internal/vm/bin/file_system_entity_patch.dart",
+ "_internal/vm/bin/filter_patch.dart",
+ "_internal/vm/bin/io_service_patch.dart",
+ "_internal/vm/bin/namespace_patch.dart",
+ "_internal/vm/bin/platform_patch.dart",
+ "_internal/vm/bin/process_patch.dart",
+ "_internal/vm/bin/socket_patch.dart",
+ "_internal/vm/bin/stdio_patch.dart",
+ "_internal/vm/bin/secure_socket_patch.dart",
+ "_internal/vm/bin/sync_socket_patch.dart"
],
"uri": "io/io.dart"
},
"_internal": {
"patches": [
- "../../runtime/lib/internal_patch.dart",
- "../../runtime/lib/class_id_fasta.dart",
- "../../runtime/lib/print_patch.dart",
- "../../runtime/lib/symbol_patch.dart",
+ "_internal/vm/lib/internal_patch.dart",
+ "_internal/vm/lib/class_id_fasta.dart",
+ "_internal/vm/lib/print_patch.dart",
+ "_internal/vm/lib/symbol_patch.dart",
"internal/patch.dart"
],
"uri": "internal/internal.dart"
},
"convert": {
- "patches": "../../runtime/lib/convert_patch.dart",
+ "patches": "_internal/vm/lib/convert_patch.dart",
"uri": "convert/convert.dart"
},
"profiler": {
"uri": "profiler/profiler.dart"
},
"math": {
- "patches": "../../runtime/lib/math_patch.dart",
+ "patches": "_internal/vm/lib/math_patch.dart",
"uri": "math/math.dart"
},
"_http": {
@@ -487,4 +487,4 @@
}
}
}
-}
+}
\ No newline at end of file
diff --git a/sdk/lib/libraries.yaml b/sdk/lib/libraries.yaml
index f33a42b..a4358e5 100644
--- a/sdk/lib/libraries.yaml
+++ b/sdk/lib/libraries.yaml
@@ -17,87 +17,87 @@
vm:
libraries:
_builtin:
- uri: "../../runtime/bin/builtin.dart"
+ uri: "_internal/vm/bin/builtin.dart"
_internal:
uri: "internal/internal.dart"
patches:
- - "../../runtime/lib/internal_patch.dart"
- - "../../runtime/lib/class_id_fasta.dart"
- - "../../runtime/lib/print_patch.dart"
- - "../../runtime/lib/symbol_patch.dart"
+ - "_internal/vm/lib/internal_patch.dart"
+ - "_internal/vm/lib/class_id_fasta.dart"
+ - "_internal/vm/lib/print_patch.dart"
+ - "_internal/vm/lib/symbol_patch.dart"
- "internal/patch.dart"
async:
uri: "async/async.dart"
patches:
- - "../../runtime/lib/async_patch.dart"
- - "../../runtime/lib/deferred_load_patch.dart"
- - "../../runtime/lib/schedule_microtask_patch.dart"
- - "../../runtime/lib/timer_patch.dart"
+ - "_internal/vm/lib/async_patch.dart"
+ - "_internal/vm/lib/deferred_load_patch.dart"
+ - "_internal/vm/lib/schedule_microtask_patch.dart"
+ - "_internal/vm/lib/timer_patch.dart"
collection:
uri: "collection/collection.dart"
patches:
- - "../../runtime/lib/collection_patch.dart"
- - "../../runtime/lib/compact_hash.dart"
+ - "_internal/vm/lib/collection_patch.dart"
+ - "_internal/vm/lib/compact_hash.dart"
convert:
uri: "convert/convert.dart"
- patches: "../../runtime/lib/convert_patch.dart"
+ patches: "_internal/vm/lib/convert_patch.dart"
core:
uri: "core/core.dart"
patches:
- - "../../runtime/lib/core_patch.dart"
- - "../../runtime/lib/array.dart"
- - "../../runtime/lib/array_patch.dart"
- - "../../runtime/lib/bigint_patch.dart"
- - "../../runtime/lib/bool_patch.dart"
- - "../../runtime/lib/date_patch.dart"
- - "../../runtime/lib/double.dart"
- - "../../runtime/lib/double_patch.dart"
- - "../../runtime/lib/errors_patch.dart"
- - "../../runtime/lib/expando_patch.dart"
- - "../../runtime/lib/function.dart"
- - "../../runtime/lib/function_patch.dart"
- - "../../runtime/lib/growable_array.dart"
- - "../../runtime/lib/identical_patch.dart"
- - "../../runtime/lib/immutable_map.dart"
- - "../../runtime/lib/integers.dart"
- - "../../runtime/lib/integers_patch.dart"
- - "../../runtime/lib/invocation_mirror_patch.dart"
- - "../../runtime/lib/lib_prefix.dart"
- - "../../runtime/lib/map_patch.dart"
- - "../../runtime/lib/null_patch.dart"
- - "../../runtime/lib/object_patch.dart"
- - "../../runtime/lib/regexp_patch.dart"
- - "../../runtime/lib/stacktrace.dart"
- - "../../runtime/lib/stopwatch_patch.dart"
- - "../../runtime/lib/string_buffer_patch.dart"
- - "../../runtime/lib/string_patch.dart"
- - "../../runtime/lib/type_patch.dart"
- - "../../runtime/lib/uri_patch.dart"
- - "../../runtime/lib/weak_property.dart"
+ - "_internal/vm/lib/core_patch.dart"
+ - "_internal/vm/lib/array.dart"
+ - "_internal/vm/lib/array_patch.dart"
+ - "_internal/vm/lib/bigint_patch.dart"
+ - "_internal/vm/lib/bool_patch.dart"
+ - "_internal/vm/lib/date_patch.dart"
+ - "_internal/vm/lib/double.dart"
+ - "_internal/vm/lib/double_patch.dart"
+ - "_internal/vm/lib/errors_patch.dart"
+ - "_internal/vm/lib/expando_patch.dart"
+ - "_internal/vm/lib/function.dart"
+ - "_internal/vm/lib/function_patch.dart"
+ - "_internal/vm/lib/growable_array.dart"
+ - "_internal/vm/lib/identical_patch.dart"
+ - "_internal/vm/lib/immutable_map.dart"
+ - "_internal/vm/lib/integers.dart"
+ - "_internal/vm/lib/integers_patch.dart"
+ - "_internal/vm/lib/invocation_mirror_patch.dart"
+ - "_internal/vm/lib/lib_prefix.dart"
+ - "_internal/vm/lib/map_patch.dart"
+ - "_internal/vm/lib/null_patch.dart"
+ - "_internal/vm/lib/object_patch.dart"
+ - "_internal/vm/lib/regexp_patch.dart"
+ - "_internal/vm/lib/stacktrace.dart"
+ - "_internal/vm/lib/stopwatch_patch.dart"
+ - "_internal/vm/lib/string_buffer_patch.dart"
+ - "_internal/vm/lib/string_patch.dart"
+ - "_internal/vm/lib/type_patch.dart"
+ - "_internal/vm/lib/uri_patch.dart"
+ - "_internal/vm/lib/weak_property.dart"
developer:
uri: "developer/developer.dart"
patches:
- - "../../runtime/lib/developer.dart"
- - "../../runtime/lib/profiler.dart"
- - "../../runtime/lib/timeline.dart"
+ - "_internal/vm/lib/developer.dart"
+ - "_internal/vm/lib/profiler.dart"
+ - "_internal/vm/lib/timeline.dart"
ffi:
uri: "ffi/ffi.dart"
patches:
- - "../../runtime/lib/ffi_patch.dart"
- - "../../runtime/lib/ffi_dynamic_library_patch.dart"
- - "../../runtime/lib/ffi_native_type_patch.dart"
+ - "_internal/vm/lib/ffi_patch.dart"
+ - "_internal/vm/lib/ffi_dynamic_library_patch.dart"
+ - "_internal/vm/lib/ffi_native_type_patch.dart"
wasm:
uri: "wasm/wasm.dart"
patches:
- - "../../runtime/lib/wasm_patch.dart"
+ - "_internal/vm/lib/wasm_patch.dart"
_http:
uri: "_http/http.dart"
@@ -105,37 +105,37 @@
io:
uri: "io/io.dart"
patches:
- - "../../runtime/bin/common_patch.dart"
- - "../../runtime/bin/directory_patch.dart"
- - "../../runtime/bin/eventhandler_patch.dart"
- - "../../runtime/bin/file_patch.dart"
- - "../../runtime/bin/file_system_entity_patch.dart"
- - "../../runtime/bin/filter_patch.dart"
- - "../../runtime/bin/io_service_patch.dart"
- - "../../runtime/bin/namespace_patch.dart"
- - "../../runtime/bin/platform_patch.dart"
- - "../../runtime/bin/process_patch.dart"
- - "../../runtime/bin/socket_patch.dart"
- - "../../runtime/bin/stdio_patch.dart"
- - "../../runtime/bin/secure_socket_patch.dart"
- - "../../runtime/bin/sync_socket_patch.dart"
+ - "_internal/vm/bin/common_patch.dart"
+ - "_internal/vm/bin/directory_patch.dart"
+ - "_internal/vm/bin/eventhandler_patch.dart"
+ - "_internal/vm/bin/file_patch.dart"
+ - "_internal/vm/bin/file_system_entity_patch.dart"
+ - "_internal/vm/bin/filter_patch.dart"
+ - "_internal/vm/bin/io_service_patch.dart"
+ - "_internal/vm/bin/namespace_patch.dart"
+ - "_internal/vm/bin/platform_patch.dart"
+ - "_internal/vm/bin/process_patch.dart"
+ - "_internal/vm/bin/socket_patch.dart"
+ - "_internal/vm/bin/stdio_patch.dart"
+ - "_internal/vm/bin/secure_socket_patch.dart"
+ - "_internal/vm/bin/sync_socket_patch.dart"
isolate:
uri: "isolate/isolate.dart"
patches:
- - "../../runtime/lib/isolate_patch.dart"
- - "../../runtime/lib/timer_impl.dart"
+ - "_internal/vm/lib/isolate_patch.dart"
+ - "_internal/vm/lib/timer_impl.dart"
math:
uri: "math/math.dart"
- patches: "../../runtime/lib/math_patch.dart"
+ patches: "_internal/vm/lib/math_patch.dart"
mirrors:
uri: "mirrors/mirrors.dart"
patches:
- - "../../runtime/lib/mirrors_patch.dart"
- - "../../runtime/lib/mirrors_impl.dart"
- - "../../runtime/lib/mirror_reference.dart"
+ - "_internal/vm/lib/mirrors_patch.dart"
+ - "_internal/vm/lib/mirrors_impl.dart"
+ - "_internal/vm/lib/mirror_reference.dart"
nativewrappers:
uri: "html/dartium/nativewrappers.dart"
@@ -146,11 +146,11 @@
cli:
uri: "cli/cli.dart"
patches:
- - "../../runtime/bin/cli_patch.dart"
+ - "_internal/vm/bin/cli_patch.dart"
typed_data:
uri: "typed_data/typed_data.dart"
- patches: "../../runtime/lib/typed_data_patch.dart"
+ patches: "_internal/vm/lib/typed_data_patch.dart"
_vmservice:
uri: "vmservice/vmservice.dart"
diff --git a/sdk/lib/profiler/profiler.dart b/sdk/lib/profiler/profiler.dart
deleted file mode 100644
index 1b96dfe..0000000
--- a/sdk/lib/profiler/profiler.dart
+++ /dev/null
@@ -1,10 +0,0 @@
-// Copyright (c) 2014, 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.
-
-/// Please see 'dart:developer'.
-@Deprecated("Dart SDK 1.12")
-library dart.profiler;
-
-export 'dart:developer'
- show getCurrentTag, Counter, Gauge, Metric, Metrics, UserTag;
diff --git a/sdk/lib/profiler/profiler_sources.gni b/sdk/lib/profiler/profiler_sources.gni
deleted file mode 100644
index adbf447..0000000
--- a/sdk/lib/profiler/profiler_sources.gni
+++ /dev/null
@@ -1,8 +0,0 @@
-# Copyright (c) 2017, 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.
-
-profiler_sdk_sources = [
- "profiler.dart",
- # The above file needs to be first if additional parts are added to the lib.
-]
diff --git a/sdk/lib/wasm/wasm.dart b/sdk/lib/wasm/wasm.dart
index edf0887..a9a09cc 100644
--- a/sdk/lib/wasm/wasm.dart
+++ b/sdk/lib/wasm/wasm.dart
@@ -6,8 +6,76 @@
/// {@nodoc}
library dart.wasm;
-int callWasm(String name, int arg) {
- return _callWasm(name, arg);
+import 'dart:typed_data';
+
+// Represents the WASM 32-bit int type.
+class Int32 {}
+
+// Represents the WASM 64-bit int type.
+class Int64 {}
+
+// Represents the WASM 32-bit float type.
+class Float {}
+
+// Represents the WASM 64-bit float type.
+class Double {}
+
+// Represents the return type of a void function in WASM.
+class Void {}
+
+// WasmModule is a compiled module that can be instantiated.
+abstract class WasmModule {
+ // Compile a module.
+ external factory WasmModule(Uint8List data);
+
+ // Instantiate the module with the given imports.
+ WasmInstance instantiate(WasmImports imports);
}
-external int _callWasm(String name, int arg);
+// WasmImports holds all the imports for a WasmInstance.
+abstract class WasmImports {
+ // Create an imports object.
+ external factory WasmImports(String moduleName);
+
+ // Add a global variable to the imports.
+ void addGlobal<T>(String name, num value, bool mutable);
+
+ // Add a memory to the imports.
+ void addMemory(String name, WasmMemory memory);
+}
+
+// WasmMemory is a sandbox for a WasmInstance to run in.
+abstract class WasmMemory {
+ // Create a new memory with the given number of initial pages, and optional
+ // maximum number of pages.
+ external factory WasmMemory(int initialPages, [int maxPages]);
+
+ // The WASM spec defines the page size as 64KiB.
+ static const int kPageSizeInBytes = 64 * 1024;
+
+ // Returns the length of the memory in pages.
+ int get lengthInPages;
+
+ // Returns the length of the memory in bytes.
+ int get lengthInBytes;
+
+ // Returns the byte at the given index.
+ int operator [](int index);
+
+ // Sets the byte at the iven index to value.
+ void operator []=(int index, int value);
+
+ // Grow the memory by deltaPages. Returns the number of pages before resizing.
+ int grow(int deltaPages);
+}
+
+// WasmInstance is an instantiated WasmModule.
+abstract class WasmInstance {
+ // Find an exported function with the given signature.
+ WasmFunction<T> lookupFunction<T extends Function>(String name);
+}
+
+// WasmFunction is a callable function in a WasmInstance.
+abstract class WasmFunction<T extends Function> {
+ num call(List<num> args);
+}
diff --git a/sdk_nnbd/BUILD.gn b/sdk_nnbd/BUILD.gn
index 228fc3c..9a4a1c5 100644
--- a/sdk_nnbd/BUILD.gn
+++ b/sdk_nnbd/BUILD.gn
@@ -134,20 +134,16 @@
],
]
if (create_kernel_service_snapshot) {
- _platform_sdk_snapshots += [
- [
- "kernel-service",
- "../utils/kernel-service:kernel-service_snapshot",
- ],
- ]
+ _platform_sdk_snapshots += [ [
+ "kernel-service",
+ "../utils/kernel-service:kernel-service_snapshot",
+ ] ]
}
if (dart_target_arch != "arm") {
- _platform_sdk_snapshots += [
- [
- "analysis_server",
- "../utils/analysis_server",
- ],
- ]
+ _platform_sdk_snapshots += [ [
+ "analysis_server",
+ "../utils/analysis_server",
+ ] ]
}
_full_sdk_snapshots = [
@@ -185,20 +181,16 @@
],
]
if (create_kernel_service_snapshot) {
- _full_sdk_snapshots += [
- [
- "kernel-service",
- "../utils/kernel-service:kernel-service_snapshot",
- ],
- ]
+ _full_sdk_snapshots += [ [
+ "kernel-service",
+ "../utils/kernel-service:kernel-service_snapshot",
+ ] ]
}
if (dart_target_arch != "arm") {
- _full_sdk_snapshots += [
- [
- "analysis_server",
- "../utils/analysis_server",
- ],
- ]
+ _full_sdk_snapshots += [ [
+ "analysis_server",
+ "../utils/analysis_server",
+ ] ]
}
# Libraries that go under lib/
@@ -222,7 +214,6 @@
"js_util",
"math",
"mirrors",
- "profiler",
"svg",
"typed_data",
"wasm",
@@ -249,7 +240,6 @@
# "isolate",
# "math",
# "mirrors",
-# "profiler",
# "typed_data",
# ]
_platform_sdk_libraries = _full_sdk_libraries
@@ -260,74 +250,82 @@
# This rule copies dartdoc templates to
# bin/resources/dartdoc/templates
-copy_tree_specs += [ {
- target = "copy_dartdoc_templates"
- visibility = [ ":copy_dartdoc_files" ]
- source = "../third_party/pkg/dartdoc/lib/templates"
- dest = "$root_out_dir/dart-sdk/bin/resources/dartdoc/templates"
- ignore_patterns = "{}"
- } ]
+copy_tree_specs += [
+ {
+ target = "copy_dartdoc_templates"
+ visibility = [ ":copy_dartdoc_files" ]
+ source = "../third_party/pkg/dartdoc/lib/templates"
+ dest = "$root_out_dir/dart-sdk/bin/resources/dartdoc/templates"
+ ignore_patterns = "{}"
+ },
+]
# This rule copies dartdoc resources to
# bin/resources/dartdoc/resources
-copy_tree_specs += [ {
- target = "copy_dartdoc_resources"
- visibility = [ ":copy_dartdoc_files" ]
- source = "../third_party/pkg/dartdoc/lib/resources"
- dest = "$root_out_dir/dart-sdk/bin/resources/dartdoc/resources"
- ignore_patterns = "{}"
- } ]
+copy_tree_specs += [
+ {
+ target = "copy_dartdoc_resources"
+ visibility = [ ":copy_dartdoc_files" ]
+ source = "../third_party/pkg/dartdoc/lib/resources"
+ dest = "$root_out_dir/dart-sdk/bin/resources/dartdoc/resources"
+ ignore_patterns = "{}"
+ },
+]
# This loop generates rules to copy libraries to lib/
foreach(library, _full_sdk_libraries) {
- copy_tree_specs += [ {
- target = "copy_${library}_library"
- visibility = [
- ":copy_platform_sdk_libraries",
- ":copy_full_sdk_libraries",
- ]
- source = "lib/$library"
- dest = "$root_out_dir/dart-sdk/lib/$library"
- ignore_patterns = "*.svn,doc,*.py,*.gypi,*.sh,.gitignore"
- } ]
+ copy_tree_specs += [
+ {
+ target = "copy_${library}_library"
+ visibility = [
+ ":copy_platform_sdk_libraries",
+ ":copy_full_sdk_libraries",
+ ]
+ source = "lib/$library"
+ dest = "$root_out_dir/dart-sdk/lib/$library"
+ ignore_patterns = "*.svn,doc,*.py,*.gypi,*.sh,.gitignore"
+ },
+ ]
}
if (is_win) {
- copy_tree_specs += [ {
- target = "copy_7zip"
- visibility = [ ":create_common_sdk" ]
- deps = [
- ":copy_libraries",
- ]
- source = "../third_party/7zip"
- dest = "$root_out_dir/dart-sdk/lib/_internal/pub/asset/7zip"
- ignore_patterns = ".svn"
- } ]
+ copy_tree_specs += [
+ {
+ target = "copy_7zip"
+ visibility = [ ":create_common_sdk" ]
+ deps = [
+ ":copy_libraries",
+ ]
+ source = "../third_party/7zip"
+ dest = "$root_out_dir/dart-sdk/lib/_internal/pub/asset/7zip"
+ ignore_patterns = ".svn"
+ },
+ ]
}
if (target_cpu == "x64") {
copy_tree_specs += [
- {
- target = "copy_language_model"
- visibility = [ ":create_common_sdk" ]
- deps = [
- ":copy_libraries",
- ]
- source = "../pkg/analysis_server/language_model"
- dest = "$root_out_dir/dart-sdk/model"
- ignore_patterns = "{}"
- },
- {
- target = "copy_libtensorflowlite_c"
- visibility = [ ":create_common_sdk" ]
- deps = [
- ":copy_libraries",
- ]
- source = "../third_party/pkg/tflite_native/lib/src/blobs"
- dest = "$root_out_dir/dart-sdk/bin/snapshots"
- ignore_patterns = "{}"
- }
- ]
+ {
+ target = "copy_language_model"
+ visibility = [ ":create_common_sdk" ]
+ deps = [
+ ":copy_libraries",
+ ]
+ source = "../pkg/analysis_server/language_model"
+ dest = "$root_out_dir/dart-sdk/model"
+ ignore_patterns = "{}"
+ },
+ {
+ target = "copy_libtensorflowlite_c"
+ visibility = [ ":create_common_sdk" ]
+ deps = [
+ ":copy_libraries",
+ ]
+ source = "../third_party/pkg/tflite_native/lib/src/blobs"
+ dest = "$root_out_dir/dart-sdk/bin/snapshots"
+ ignore_patterns = "{}"
+ },
+ ]
}
# This generates targets for everything in copy_tree_specs. The targets have the
@@ -399,7 +397,8 @@
deps = [
"../runtime/bin:dartaotruntime",
]
- dartaotruntime_out = get_label_info("../runtime/bin:dartaotruntime", "root_out_dir")
+ dartaotruntime_out =
+ get_label_info("../runtime/bin:dartaotruntime", "root_out_dir")
if (is_win) {
sources = [
"$dartaotruntime_out/dartaotruntime.exe",
@@ -421,7 +420,8 @@
deps = [
"../runtime/bin:gen_snapshot",
]
- gen_snapshot_out = get_label_info("../runtime/bin:gen_snapshot", "root_out_dir")
+ gen_snapshot_out =
+ get_label_info("../runtime/bin:gen_snapshot", "root_out_dir")
if (is_win) {
sources = [
"$gen_snapshot_out/gen_snapshot.exe",
@@ -663,8 +663,8 @@
visibility = [ ":copy_dev_compiler_sdk" ]
deps = [
":copy_libraries",
- "../utils/dartdevc:dartdevc_sdk",
"../utils/dartdevc:dartdevc_kernel_sdk_outline",
+ "../utils/dartdevc:dartdevc_sdk",
]
gen_dir = get_label_info("../utils/dartdevc:dartdevc_sdk", "target_gen_dir")
sources = [
@@ -736,8 +736,8 @@
deps = [
"../utils/dartdevc:dartdevc_kernel_sdk",
]
- gen_dir = get_label_info("../utils/dartdevc:dartdevc_kernel_sdk",
- "target_gen_dir")
+ gen_dir =
+ get_label_info("../utils/dartdevc:dartdevc_kernel_sdk", "target_gen_dir")
sources = [
"$gen_dir/kernel/amd/dart_sdk.js",
"$gen_dir/kernel/amd/dart_sdk.js.map",
@@ -754,8 +754,8 @@
deps = [
"../utils/dartdevc:dartdevc_kernel_sdk",
]
- gen_dir = get_label_info("../utils/dartdevc:dartdevc_kernel_sdk",
- "target_gen_dir")
+ gen_dir =
+ get_label_info("../utils/dartdevc:dartdevc_kernel_sdk", "target_gen_dir")
sources = [
"$gen_dir/kernel/common/dart_sdk.js",
"$gen_dir/kernel/common/dart_sdk.js.map",
@@ -772,8 +772,8 @@
deps = [
"../utils/dartdevc:dartdevc_kernel_sdk",
]
- gen_dir = get_label_info("../utils/dartdevc:dartdevc_kernel_sdk",
- "target_gen_dir")
+ gen_dir =
+ get_label_info("../utils/dartdevc:dartdevc_kernel_sdk", "target_gen_dir")
sources = [
"$gen_dir/kernel/es6/dart_sdk.js",
"$gen_dir/kernel/es6/dart_sdk.js.map",
@@ -1006,8 +1006,8 @@
":copy_dartdoc_files",
":copy_headers",
":copy_libraries_dart",
- ":copy_license",
":copy_libraries_specification",
+ ":copy_license",
":copy_readme",
":copy_vm_dill_files",
":write_dartdoc_options",
diff --git a/sdk_nnbd/lib/_chrome/dart2js/chrome_dart2js.dart b/sdk_nnbd/lib/_chrome/dart2js/chrome_dart2js.dart
index 023afe4..c9a9735 100644
--- a/sdk_nnbd/lib/_chrome/dart2js/chrome_dart2js.dart
+++ b/sdk_nnbd/lib/_chrome/dart2js/chrome_dart2js.dart
@@ -5,6 +5,8 @@
///
/// For more information on these APIs, see the
/// [chrome.* API documentation](http://developer.chrome.com/apps/api_index.html).
+// @dart = 2.5
+
library _chrome;
import 'dart:_foreign_helper' show JS;
diff --git a/sdk_nnbd/lib/_http/crypto.dart b/sdk_nnbd/lib/_http/crypto.dart
index 28b65ee..0efbe45 100644
--- a/sdk_nnbd/lib/_http/crypto.dart
+++ b/sdk_nnbd/lib/_http/crypto.dart
@@ -2,6 +2,8 @@
// 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.5
+
part of dart._http;
class _CryptoUtils {
diff --git a/sdk_nnbd/lib/_http/http.dart b/sdk_nnbd/lib/_http/http.dart
index 2fc751f..2689758 100644
--- a/sdk_nnbd/lib/_http/http.dart
+++ b/sdk_nnbd/lib/_http/http.dart
@@ -2,6 +2,8 @@
// 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.5
+
library dart._http;
import 'dart:async';
diff --git a/sdk_nnbd/lib/_http/http_date.dart b/sdk_nnbd/lib/_http/http_date.dart
index d9301b4..80b0397 100644
--- a/sdk_nnbd/lib/_http/http_date.dart
+++ b/sdk_nnbd/lib/_http/http_date.dart
@@ -2,6 +2,8 @@
// 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.5
+
part of dart._http;
/**
diff --git a/sdk_nnbd/lib/_http/http_headers.dart b/sdk_nnbd/lib/_http/http_headers.dart
index 7601485..58fe2af 100644
--- a/sdk_nnbd/lib/_http/http_headers.dart
+++ b/sdk_nnbd/lib/_http/http_headers.dart
@@ -2,6 +2,8 @@
// 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.5
+
part of dart._http;
class _HttpHeaders implements HttpHeaders {
diff --git a/sdk_nnbd/lib/_http/http_impl.dart b/sdk_nnbd/lib/_http/http_impl.dart
index cdf2412..9741981 100644
--- a/sdk_nnbd/lib/_http/http_impl.dart
+++ b/sdk_nnbd/lib/_http/http_impl.dart
@@ -2,6 +2,8 @@
// 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.5
+
part of dart._http;
int _nextServiceId = 1;
diff --git a/sdk_nnbd/lib/_http/http_parser.dart b/sdk_nnbd/lib/_http/http_parser.dart
index bd85b2b..f3c619d 100644
--- a/sdk_nnbd/lib/_http/http_parser.dart
+++ b/sdk_nnbd/lib/_http/http_parser.dart
@@ -2,6 +2,8 @@
// 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.5
+
part of dart._http;
// Global constants.
diff --git a/sdk_nnbd/lib/_http/http_session.dart b/sdk_nnbd/lib/_http/http_session.dart
index 3907609..0cffefe 100644
--- a/sdk_nnbd/lib/_http/http_session.dart
+++ b/sdk_nnbd/lib/_http/http_session.dart
@@ -2,6 +2,8 @@
// 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.5
+
part of dart._http;
const String _DART_SESSION_ID = "DARTSESSID";
diff --git a/sdk_nnbd/lib/_http/overrides.dart b/sdk_nnbd/lib/_http/overrides.dart
index 7f9e689..962a009 100644
--- a/sdk_nnbd/lib/_http/overrides.dart
+++ b/sdk_nnbd/lib/_http/overrides.dart
@@ -2,6 +2,8 @@
// 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.5
+
part of dart._http;
final _httpOverridesToken = new Object();
diff --git a/sdk_nnbd/lib/_http/websocket.dart b/sdk_nnbd/lib/_http/websocket.dart
index 5a949af..8faa0e1 100644
--- a/sdk_nnbd/lib/_http/websocket.dart
+++ b/sdk_nnbd/lib/_http/websocket.dart
@@ -2,6 +2,8 @@
// 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.5
+
part of dart._http;
/**
diff --git a/sdk_nnbd/lib/_http/websocket_impl.dart b/sdk_nnbd/lib/_http/websocket_impl.dart
index 8750ccc..c3e8bc4 100644
--- a/sdk_nnbd/lib/_http/websocket_impl.dart
+++ b/sdk_nnbd/lib/_http/websocket_impl.dart
@@ -2,6 +2,8 @@
// 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.5
+
part of dart._http;
const String _webSocketGUID = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11";
@@ -601,11 +603,11 @@
data.addAll(const [0x00, 0x00, 0xff, 0xff]);
decoder.process(data, 0, data.length);
- var result = <int>[];
+ final result = new BytesBuilder();
List<int> out;
while ((out = decoder.processed()) != null) {
- result.addAll(out);
+ result.add(out);
}
if ((serverSide && clientNoContextTakeover) ||
@@ -613,7 +615,7 @@
decoder = null;
}
- return new Uint8List.fromList(result);
+ return result.takeBytes();
}
List<int> processOutgoingMessage(List<int> msg) {
diff --git a/sdk_nnbd/lib/_internal/js_dev_runtime/lib/js/dart2js/js_dart2js.dart b/sdk_nnbd/lib/_internal/js_dev_runtime/lib/js/dart2js/js_dart2js.dart
index 91d6847..42d4c42 100644
--- a/sdk_nnbd/lib/_internal/js_dev_runtime/lib/js/dart2js/js_dart2js.dart
+++ b/sdk_nnbd/lib/_internal/js_dev_runtime/lib/js/dart2js/js_dart2js.dart
@@ -2,89 +2,90 @@
// 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.
-/**
- * Support for interoperating with JavaScript.
- *
- * This library provides access to JavaScript objects from Dart, allowing
- * Dart code to get and set properties, and call methods of JavaScript objects
- * and invoke JavaScript functions. The library takes care of converting
- * between Dart and JavaScript objects where possible, or providing proxies if
- * conversion isn't possible.
- *
- * This library does not yet make Dart objects usable from JavaScript, their
- * methods and proeprties are not accessible, though it does allow Dart
- * functions to be passed into and called from JavaScript.
- *
- * [JsObject] is the core type and represents a proxy of a JavaScript object.
- * JsObject gives access to the underlying JavaScript objects properties and
- * methods. `JsObject`s can be acquired by calls to JavaScript, or they can be
- * created from proxies to JavaScript constructors.
- *
- * The top-level getter [context] provides a [JsObject] that represents the
- * global object in JavaScript, usually `window`.
- *
- * The following example shows an alert dialog via a JavaScript call to the
- * global function `alert()`:
- *
- * import 'dart:js';
- *
- * main() => context.callMethod('alert', ['Hello from Dart!']);
- *
- * This example shows how to create a [JsObject] from a JavaScript constructor
- * and access its properties:
- *
- * import 'dart:js';
- *
- * main() {
- * var object = new JsObject(context['Object']);
- * object['greeting'] = 'Hello';
- * object['greet'] = (name) => "${object['greeting']} $name";
- * var message = object.callMethod('greet', ['JavaScript']);
- * context['console'].callMethod('log', [message]);
- * }
- *
- * ## Proxying and automatic conversion
- *
- * When setting properties on a JsObject or passing arguments to a Javascript
- * method or function, Dart objects are automatically converted or proxied to
- * JavaScript objects. When accessing JavaScript properties, or when a Dart
- * closure is invoked from JavaScript, the JavaScript objects are also
- * converted to Dart.
- *
- * Functions and closures are proxied in such a way that they are callable. A
- * Dart closure assigned to a JavaScript property is proxied by a function in
- * JavaScript. A JavaScript function accessed from Dart is proxied by a
- * [JsFunction], which has a [apply] method to invoke it.
- *
- * The following types are transferred directly and not proxied:
- *
- * * "Basic" types: `null`, `bool`, `num`, `String`, `DateTime`
- * * `Blob`
- * * `Event`
- * * `HtmlCollection`
- * * `ImageData`
- * * `KeyRange`
- * * `Node`
- * * `NodeList`
- * * `TypedData`, including its subclasses like `Int32List`, but _not_
- * `ByteBuffer`
- * * `Window`
- *
- * ## Converting collections with JsObject.jsify()
- *
- * To create a JavaScript collection from a Dart collection use the
- * [JsObject.jsify] constructor, which converts Dart [Map]s and [Iterable]s
- * into JavaScript Objects and Arrays.
- *
- * The following expression creates a new JavaScript object with the properties
- * `a` and `b` defined:
- *
- * var jsMap = new JsObject.jsify({'a': 1, 'b': 2});
- *
- * This expression creates a JavaScript array:
- *
- * var jsArray = new JsObject.jsify([1, 2, 3]);
- */
+// @dart = 2.5
+
+// DDC version of sdk/lib/js/dart2js/js_dart2js.dart
+
+/// Low-level support for interoperating with JavaScript.
+///
+/// You should usually use `package:js` instead of this library. For more
+/// information, see the [JS interop page](https://dart.dev/web/js-interop).
+///
+/// This library provides access to JavaScript objects from Dart, allowing
+/// Dart code to get and set properties, and call methods of JavaScript objects
+/// and invoke JavaScript functions. The library takes care of converting
+/// between Dart and JavaScript objects where possible, or providing proxies if
+/// conversion isn't possible.
+///
+/// This library does not make Dart objects usable from JavaScript, their
+/// methods and properties are not accessible, though it does allow Dart
+/// functions to be passed into and called from JavaScript.
+///
+/// [JsObject] is the core type and represents a proxy of a JavaScript object.
+/// JsObject gives access to the underlying JavaScript objects properties and
+/// methods. `JsObject`s can be acquired by calls to JavaScript, or they can be
+/// created from proxies to JavaScript constructors.
+///
+/// The top-level getter [context] provides a [JsObject] that represents the
+/// global object in JavaScript, usually `window`.
+///
+/// The following example shows an alert dialog via a JavaScript call to the
+/// global function `alert()`:
+///
+/// import 'dart:js';
+///
+/// main() => context.callMethod('alert', ['Hello from Dart!']);
+///
+/// This example shows how to create a [JsObject] from a JavaScript constructor
+/// and access its properties:
+///
+/// import 'dart:js';
+///
+/// main() {
+/// var object = JsObject(context['Object']);
+/// object['greeting'] = 'Hello';
+/// object['greet'] = (name) => "${object['greeting']} $name";
+/// var message = object.callMethod('greet', ['JavaScript']);
+/// context['console'].callMethod('log', [message]);
+/// }
+///
+/// ## Proxying and automatic conversion
+///
+/// When setting properties on a JsObject or passing arguments to a Javascript
+/// method or function, Dart objects are automatically converted or proxied to
+/// JavaScript objects. When accessing JavaScript properties, or when a Dart
+/// closure is invoked from JavaScript, the JavaScript objects are also
+/// converted to Dart.
+///
+/// Functions and closures are proxied in such a way that they are callable. A
+/// Dart closure assigned to a JavaScript property is proxied by a function in
+/// JavaScript. A JavaScript function accessed from Dart is proxied by a
+/// [JsFunction], which has a [apply] method to invoke it.
+///
+/// The following types are transferred directly and not proxied:
+///
+/// * Basic types: `null`, `bool`, `num`, `String`, `DateTime`
+/// * `TypedData`, including its subclasses like `Int32List`, but _not_
+/// `ByteBuffer`
+/// * When compiling for the web, also: `Blob`, `Event`, `ImageData`,
+/// `KeyRange`, `Node`, and `Window`.
+///
+/// ## Converting collections with JsObject.jsify()
+///
+/// To create a JavaScript collection from a Dart collection use the
+/// [JsObject.jsify] constructor, which converts Dart [Map]s and [Iterable]s
+/// into JavaScript Objects and Arrays.
+///
+/// The following expression creates a new JavaScript object with the properties
+/// `a` and `b` defined:
+///
+/// var jsMap = JsObject.jsify({'a': 1, 'b': 2});
+///
+/// This expression creates a JavaScript array:
+///
+/// var jsArray = JsObject.jsify([1, 2, 3]);
+///
+/// {@category Web}
library dart.js;
import 'dart:collection' show HashMap, ListMixin;
@@ -93,14 +94,13 @@
import 'dart:_foreign_helper' show JS;
import 'dart:_runtime' as dart;
+/// The JavaScript global object, usually `window`.
final JsObject context = _wrapToDart(dart.global_);
-/**
- * Proxies a JavaScript object to Dart.
- *
- * The properties of the JavaScript object are accessible via the `[]` and
- * `[]=` operators. Methods are callable via [callMethod].
- */
+/// A proxy on a JavaScript object.
+///
+/// The properties of the JavaScript object are accessible via the `[]` and
+/// `[]=` operators. Methods are callable via [callMethod].
class JsObject {
// The wrapped JS object.
final dynamic _jsObject;
@@ -110,10 +110,8 @@
assert(_jsObject != null);
}
- /**
- * Constructs a new JavaScript object from [constructor] and returns a proxy
- * to it.
- */
+ /// Constructs a JavaScript object from its native [constructor] and returns
+ /// a proxy to it.
factory JsObject(JsFunction constructor, [List arguments]) {
var ctor = constructor._jsObject;
if (arguments == null) {
@@ -123,17 +121,15 @@
return _wrapToDart(JS('', 'new #(...#)', ctor, unwrapped));
}
- /**
- * Constructs a [JsObject] that proxies a native Dart object; _for expert use
- * only_.
- *
- * Use this constructor only if you wish to get access to JavaScript
- * properties attached to a browser host object, such as a Node or Blob, that
- * is normally automatically converted into a native Dart object.
- *
- * An exception will be thrown if [object] either is `null` or has the type
- * `bool`, `num`, or `String`.
- */
+ /// Constructs a [JsObject] that proxies a native Dart object; _for expert use
+ /// only_.
+ ///
+ /// Use this constructor only if you wish to get access to JavaScript
+ /// properties attached to a browser host object, such as a Node or Blob, that
+ /// is normally automatically converted into a native Dart object.
+ ///
+ /// An exception will be thrown if [object] either is `null` or has the type
+ /// `bool`, `num`, or `String`.
factory JsObject.fromBrowserObject(object) {
if (object is num || object is String || object is bool || object == null) {
throw ArgumentError("object cannot be a num, string, bool, or null");
@@ -141,15 +137,13 @@
return _wrapToDart(_convertToJS(object));
}
- /**
- * Recursively converts a JSON-like collection of Dart objects to a
- * collection of JavaScript objects and returns a [JsObject] proxy to it.
- *
- * [object] must be a [Map] or [Iterable], the contents of which are also
- * converted. Maps and Iterables are copied to a new JavaScript object.
- * Primitives and other transferable values are directly converted to their
- * JavaScript type, and all other objects are proxied.
- */
+ /// Recursively converts a JSON-like collection of Dart objects to a
+ /// collection of JavaScript objects and returns a [JsObject] proxy to it.
+ ///
+ /// [object] must be a [Map] or [Iterable], the contents of which are also
+ /// converted. Maps and Iterables are copied to a new JavaScript object.
+ /// Primitives and other transferable values are directly converted to their
+ /// JavaScript type, and all other objects are proxied.
factory JsObject.jsify(object) {
if ((object is! Map) && (object is! Iterable)) {
throw ArgumentError("object must be a Map or Iterable");
@@ -184,12 +178,10 @@
return _convert(data);
}
- /**
- * Returns the value associated with [property] from the proxied JavaScript
- * object.
- *
- * The type of [property] must be either [String] or [num].
- */
+ /// Returns the value associated with [property] from the proxied JavaScript
+ /// object.
+ ///
+ /// The type of [property] must be either [String] or [num].
dynamic operator [](Object property) {
if (property is! String && property is! num) {
throw ArgumentError("property is not a String or num");
@@ -197,12 +189,10 @@
return _convertToDart(JS('', '#[#]', _jsObject, property));
}
- /**
- * Sets the value associated with [property] on the proxied JavaScript
- * object.
- *
- * The type of [property] must be either [String] or [num].
- */
+ // Sets the value associated with [property] on the proxied JavaScript
+ // object.
+ //
+ // The type of [property] must be either [String] or [num].
void operator []=(Object property, value) {
if (property is! String && property is! num) {
throw ArgumentError("property is not a String or num");
@@ -215,12 +205,10 @@
bool operator ==(other) =>
other is JsObject && JS<bool>('!', '# === #', _jsObject, other._jsObject);
- /**
- * Returns `true` if the JavaScript object contains the specified property
- * either directly or though its prototype chain.
- *
- * This is the equivalent of the `in` operator in JavaScript.
- */
+ /// Returns `true` if the JavaScript object contains the specified property
+ /// either directly or though its prototype chain.
+ ///
+ /// This is the equivalent of the `in` operator in JavaScript.
bool hasProperty(property) {
if (property is! String && property is! num) {
throw ArgumentError("property is not a String or num");
@@ -228,11 +216,9 @@
return JS<bool>('!', '# in #', property, _jsObject);
}
- /**
- * Removes [property] from the JavaScript object.
- *
- * This is the equivalent of the `delete` operator in JavaScript.
- */
+ /// Removes [property] from the JavaScript object.
+ ///
+ /// This is the equivalent of the `delete` operator in JavaScript.
void deleteProperty(property) {
if (property is! String && property is! num) {
throw ArgumentError("property is not a String or num");
@@ -240,18 +226,14 @@
JS<bool>('!', 'delete #[#]', _jsObject, property);
}
- /**
- * Returns `true` if the JavaScript object has [type] in its prototype chain.
- *
- * This is the equivalent of the `instanceof` operator in JavaScript.
- */
+ /// Returns `true` if the JavaScript object has [type] in its prototype chain.
+ ///
+ /// This is the equivalent of the `instanceof` operator in JavaScript.
bool instanceof(JsFunction type) {
return JS<bool>('!', '# instanceof #', _jsObject, _convertToJS(type));
}
- /**
- * Returns the result of the JavaScript objects `toString` method.
- */
+ /// Returns the result of the JavaScript objects `toString` method.
String toString() {
try {
return JS<String>('!', 'String(#)', _jsObject);
@@ -260,12 +242,10 @@
}
}
- /**
- * Calls [method] on the JavaScript object with the arguments [args] and
- * returns the result.
- *
- * The type of [method] must be either [String] or [num].
- */
+ /// Calls [method] on the JavaScript object with the arguments [args] and
+ /// returns the result.
+ ///
+ /// The type of [method] must be either [String] or [num].
dynamic callMethod(method, [List args]) {
if (method is! String && method is! num) {
throw ArgumentError("method is not a String or num");
@@ -279,14 +259,10 @@
}
}
-/**
- * Proxies a JavaScript Function object.
- */
+/// A proxy on a JavaScript Function object.
class JsFunction extends JsObject {
- /**
- * Returns a [JsFunction] that captures its 'this' binding and calls [f]
- * with the value of this passed as the first argument.
- */
+ /// Returns a [JsFunction] that captures its 'this' binding and calls [f]
+ /// with the value of JavaScript `this` passed as the first argument.
factory JsFunction.withThis(Function f) {
return JsFunction._fromJs(JS(
'',
@@ -305,10 +281,8 @@
JsFunction._fromJs(jsObject) : super._fromJs(jsObject);
- /**
- * Invokes the JavaScript function with arguments [args]. If [thisArg] is
- * supplied it is the value of `this` for the invocation.
- */
+ /// Invokes the JavaScript function with arguments [args]. If [thisArg] is
+ /// supplied it is the value of `this` for the invocation.
dynamic apply(List args, {thisArg}) => _convertToDart(JS(
'',
'#.apply(#, #)',
@@ -318,17 +292,13 @@
}
// TODO(jmesserly): this is totally unnecessary in dev_compiler.
-/** A [List] that proxies a JavaScript array. */
+/// A [List] that proxies a JavaScript array.
class JsArray<E> extends JsObject with ListMixin<E> {
- /**
- * Creates a new JavaScript array.
- */
+ /// Creates an empty JavaScript array.
JsArray() : super._fromJs([]);
- /**
- * Creates a new JavaScript array and initializes it to the contents of
- * [other].
- */
+ /// Creates a new JavaScript array and initializes it to the contents of
+ /// [other].
JsArray.from(Iterable<E> other)
: super._fromJs([]..addAll(other.map(_convertToJS)));
@@ -544,16 +514,16 @@
Expando<Function> _interopExpando = Expando<Function>();
/// Returns a wrapper around function [f] that can be called from JavaScript
-/// using the package:js Dart-JavaScript interop.
+/// using `package:js` JavaScript interop.
///
-/// For performance reasons in Dart2Js, by default Dart functions cannot be
-/// passed directly to JavaScript unless this method is called to create
-/// a Function compatible with both Dart and JavaScript.
-/// Calling this method repeatedly on a function will return the same function.
-/// The [Function] returned by this method can be used from both Dart and
-/// JavaScript. We may remove the need to call this method completely in the
-/// future if Dart2Js is refactored so that its function calling conventions
-/// are more compatible with JavaScript.
+/// The calling conventions in Dart2Js differ from JavaScript and so, by
+/// default, it is not possible to call a Dart function directly. Wrapping with
+/// `allowInterop` creates a function that can be called from JavaScript or
+/// Dart. The semantics of the wrapped function are still more strict than
+/// JavaScript, and the function will throw if called with too many or too few
+/// arguments.
+///
+/// Calling this method repeatedly on a function will return the same result.
F allowInterop<F extends Function>(F f) {
var ret = _interopExpando[f];
if (ret == null) {
@@ -571,12 +541,13 @@
Expando<Function> _interopCaptureThisExpando = Expando<Function>();
-/// Returns a [Function] that when called from JavaScript captures its 'this'
-/// binding and calls [f] with the value of this passed as the first argument.
-/// When called from Dart, [null] will be passed as the first argument.
+/// Returns a wrapper around function [f] that can be called from JavaScript
+/// using `package:js` JavaScript interop, passing JavaScript `this` as the first
+/// argument.
///
-/// See the documentation for [allowInterop]. This method should only be used
-/// with package:js Dart-JavaScript interop.
+/// See [allowInterop].
+///
+/// When called from Dart, [null] will be passed as the first argument.
Function allowInteropCaptureThis(Function f) {
var ret = _interopCaptureThisExpando[f];
if (ret == null) {
diff --git a/sdk_nnbd/lib/_internal/js_dev_runtime/lib/js_util/dart2js/js_util_dart2js.dart b/sdk_nnbd/lib/_internal/js_dev_runtime/lib/js_util/dart2js/js_util_dart2js.dart
index 4b9fdb0..66f8c29 100644
--- a/sdk_nnbd/lib/_internal/js_dev_runtime/lib/js_util/dart2js/js_util_dart2js.dart
+++ b/sdk_nnbd/lib/_internal/js_dev_runtime/lib/js_util/dart2js/js_util_dart2js.dart
@@ -2,6 +2,8 @@
// 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.5
+
/// Utility methods to efficiently manipulate typed JSInterop objects in cases
/// where the name to call is not known at runtime. You should only use these
/// methods when the same effect cannot be achieved with @JS annotations.
diff --git a/sdk_nnbd/lib/_internal/js_dev_runtime/libraries.dart b/sdk_nnbd/lib/_internal/js_dev_runtime/libraries.dart
index d5cffa2..ce023f1 100644
--- a/sdk_nnbd/lib/_internal/js_dev_runtime/libraries.dart
+++ b/sdk_nnbd/lib/_internal/js_dev_runtime/libraries.dart
@@ -2,6 +2,8 @@
// 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.5
+
library libraries;
/**
diff --git a/sdk_nnbd/lib/_internal/js_dev_runtime/patch/async_patch.dart b/sdk_nnbd/lib/_internal/js_dev_runtime/patch/async_patch.dart
index 894aef4..88d2407 100644
--- a/sdk_nnbd/lib/_internal/js_dev_runtime/patch/async_patch.dart
+++ b/sdk_nnbd/lib/_internal/js_dev_runtime/patch/async_patch.dart
@@ -2,6 +2,8 @@
// 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.5
+
// Patch file for the dart:async library.
import 'dart:_js_helper' show notNull, patch, ReifyFunctionTypes;
diff --git a/sdk_nnbd/lib/_internal/js_dev_runtime/patch/cli_patch.dart b/sdk_nnbd/lib/_internal/js_dev_runtime/patch/cli_patch.dart
index b1c3841..266941b 100644
--- a/sdk_nnbd/lib/_internal/js_dev_runtime/patch/cli_patch.dart
+++ b/sdk_nnbd/lib/_internal/js_dev_runtime/patch/cli_patch.dart
@@ -2,6 +2,8 @@
// 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.5
+
import 'dart:_js_helper' show patch;
@patch
diff --git a/sdk_nnbd/lib/_internal/js_dev_runtime/patch/collection_patch.dart b/sdk_nnbd/lib/_internal/js_dev_runtime/patch/collection_patch.dart
index daa3bf8..d37655d 100644
--- a/sdk_nnbd/lib/_internal/js_dev_runtime/patch/collection_patch.dart
+++ b/sdk_nnbd/lib/_internal/js_dev_runtime/patch/collection_patch.dart
@@ -2,6 +2,8 @@
// 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.5
+
// Patch file for dart:collection classes.
import 'dart:_foreign_helper' show JS, JSExportName;
import 'dart:_runtime' as dart;
diff --git a/sdk_nnbd/lib/_internal/js_dev_runtime/patch/convert_patch.dart b/sdk_nnbd/lib/_internal/js_dev_runtime/patch/convert_patch.dart
index 486473b..637febd 100644
--- a/sdk_nnbd/lib/_internal/js_dev_runtime/patch/convert_patch.dart
+++ b/sdk_nnbd/lib/_internal/js_dev_runtime/patch/convert_patch.dart
@@ -2,6 +2,8 @@
// 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.5
+
// Patch file for dart:convert library.
import 'dart:_js_helper' show argumentErrorValue, patch;
diff --git a/sdk_nnbd/lib/_internal/js_dev_runtime/patch/core_patch.dart b/sdk_nnbd/lib/_internal/js_dev_runtime/patch/core_patch.dart
index 746ac61..7a8ac4b 100644
--- a/sdk_nnbd/lib/_internal/js_dev_runtime/patch/core_patch.dart
+++ b/sdk_nnbd/lib/_internal/js_dev_runtime/patch/core_patch.dart
@@ -2,6 +2,8 @@
// 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.5
+
// Patch file for dart:core classes.
import "dart:_internal" as _symbol_dev;
import 'dart:_interceptors';
diff --git a/sdk_nnbd/lib/_internal/js_dev_runtime/patch/developer_patch.dart b/sdk_nnbd/lib/_internal/js_dev_runtime/patch/developer_patch.dart
index 7f5e4fe..4f2befc 100644
--- a/sdk_nnbd/lib/_internal/js_dev_runtime/patch/developer_patch.dart
+++ b/sdk_nnbd/lib/_internal/js_dev_runtime/patch/developer_patch.dart
@@ -2,6 +2,8 @@
// 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.5
+
// Patch file for dart:developer library.
import 'dart:_js_helper' show patch, ForceInline, ReifyFunctionTypes;
diff --git a/sdk_nnbd/lib/_internal/js_dev_runtime/patch/internal_patch.dart b/sdk_nnbd/lib/_internal/js_dev_runtime/patch/internal_patch.dart
index 5e850bb..e642b5c 100644
--- a/sdk_nnbd/lib/_internal/js_dev_runtime/patch/internal_patch.dart
+++ b/sdk_nnbd/lib/_internal/js_dev_runtime/patch/internal_patch.dart
@@ -2,6 +2,8 @@
// 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.5
+
import 'dart:core' hide Symbol;
import 'dart:core' as core show Symbol;
import 'dart:_js_primitives' show printString;
diff --git a/sdk_nnbd/lib/_internal/js_dev_runtime/patch/io_patch.dart b/sdk_nnbd/lib/_internal/js_dev_runtime/patch/io_patch.dart
index 61d031a..595f4c2 100644
--- a/sdk_nnbd/lib/_internal/js_dev_runtime/patch/io_patch.dart
+++ b/sdk_nnbd/lib/_internal/js_dev_runtime/patch/io_patch.dart
@@ -2,6 +2,8 @@
// 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.5
+
import 'dart:_js_helper' show patch;
import 'dart:async';
import 'dart:convert';
diff --git a/sdk_nnbd/lib/_internal/js_dev_runtime/patch/isolate_patch.dart b/sdk_nnbd/lib/_internal/js_dev_runtime/patch/isolate_patch.dart
index f6aa73bb..cbe69f0 100644
--- a/sdk_nnbd/lib/_internal/js_dev_runtime/patch/isolate_patch.dart
+++ b/sdk_nnbd/lib/_internal/js_dev_runtime/patch/isolate_patch.dart
@@ -2,6 +2,8 @@
// 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.5
+
// Patch file for the dart:isolate library.
import 'dart:_js_helper' show patch, NoReifyGeneric;
diff --git a/sdk_nnbd/lib/_internal/js_dev_runtime/patch/math_patch.dart b/sdk_nnbd/lib/_internal/js_dev_runtime/patch/math_patch.dart
index 2ba4220..eb5c568 100644
--- a/sdk_nnbd/lib/_internal/js_dev_runtime/patch/math_patch.dart
+++ b/sdk_nnbd/lib/_internal/js_dev_runtime/patch/math_patch.dart
@@ -2,6 +2,8 @@
// 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.5
+
// Patch file for dart:math library.
import 'dart:_foreign_helper' show JS;
import 'dart:_js_helper' show patch, nullCheck, notNull;
diff --git a/sdk_nnbd/lib/_internal/js_dev_runtime/patch/mirrors_patch.dart b/sdk_nnbd/lib/_internal/js_dev_runtime/patch/mirrors_patch.dart
index e3b015b..9aca3ee 100644
--- a/sdk_nnbd/lib/_internal/js_dev_runtime/patch/mirrors_patch.dart
+++ b/sdk_nnbd/lib/_internal/js_dev_runtime/patch/mirrors_patch.dart
@@ -2,6 +2,8 @@
// 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.5
+
// Patch library for dart:mirrors.
import 'dart:_js_helper' show patch;
diff --git a/sdk_nnbd/lib/_internal/js_dev_runtime/patch/typed_data_patch.dart b/sdk_nnbd/lib/_internal/js_dev_runtime/patch/typed_data_patch.dart
index f1e2dc1..a06bd14 100644
--- a/sdk_nnbd/lib/_internal/js_dev_runtime/patch/typed_data_patch.dart
+++ b/sdk_nnbd/lib/_internal/js_dev_runtime/patch/typed_data_patch.dart
@@ -2,6 +2,8 @@
// 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.5
+
import 'dart:collection';
import 'dart:_js_helper' show patch;
import 'dart:_native_typed_data';
diff --git a/sdk_nnbd/lib/_internal/js_dev_runtime/private/annotations.dart b/sdk_nnbd/lib/_internal/js_dev_runtime/private/annotations.dart
index bc437da..1673fd1 100644
--- a/sdk_nnbd/lib/_internal/js_dev_runtime/private/annotations.dart
+++ b/sdk_nnbd/lib/_internal/js_dev_runtime/private/annotations.dart
@@ -2,6 +2,8 @@
// 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.5
+
part of dart._js_helper;
/// Tells the optimizing compiler to always inline the annotated method.
diff --git a/sdk_nnbd/lib/_internal/js_dev_runtime/private/custom_hash_map.dart b/sdk_nnbd/lib/_internal/js_dev_runtime/private/custom_hash_map.dart
index c7c920d..07fc5c6 100644
--- a/sdk_nnbd/lib/_internal/js_dev_runtime/private/custom_hash_map.dart
+++ b/sdk_nnbd/lib/_internal/js_dev_runtime/private/custom_hash_map.dart
@@ -2,6 +2,8 @@
// 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.5
+
part of dart._js_helper;
class CustomKeyHashMap<K, V> extends CustomHashMap<K, V> {
diff --git a/sdk_nnbd/lib/_internal/js_dev_runtime/private/ddc_runtime/classes.dart b/sdk_nnbd/lib/_internal/js_dev_runtime/private/ddc_runtime/classes.dart
index 8fe2fa6..fb2b5b0 100644
--- a/sdk_nnbd/lib/_internal/js_dev_runtime/private/ddc_runtime/classes.dart
+++ b/sdk_nnbd/lib/_internal/js_dev_runtime/private/ddc_runtime/classes.dart
@@ -2,6 +2,8 @@
// 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.5
+
/// This library defines the operations that define and manipulate Dart
/// classes. Included in this are:
/// - Generics
diff --git a/sdk_nnbd/lib/_internal/js_dev_runtime/private/ddc_runtime/errors.dart b/sdk_nnbd/lib/_internal/js_dev_runtime/private/ddc_runtime/errors.dart
index f875336..b4ee6a6 100644
--- a/sdk_nnbd/lib/_internal/js_dev_runtime/private/ddc_runtime/errors.dart
+++ b/sdk_nnbd/lib/_internal/js_dev_runtime/private/ddc_runtime/errors.dart
@@ -2,6 +2,8 @@
// 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.5
+
part of dart._runtime;
// We need to set these properties while the sdk is only partially initialized
diff --git a/sdk_nnbd/lib/_internal/js_dev_runtime/private/ddc_runtime/operations.dart b/sdk_nnbd/lib/_internal/js_dev_runtime/private/ddc_runtime/operations.dart
index e388cd6..224ba1c 100644
--- a/sdk_nnbd/lib/_internal/js_dev_runtime/private/ddc_runtime/operations.dart
+++ b/sdk_nnbd/lib/_internal/js_dev_runtime/private/ddc_runtime/operations.dart
@@ -2,6 +2,8 @@
// 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.5
+
/// This library defines runtime operations on objects used by the code
/// generator.
part of dart._runtime;
diff --git a/sdk_nnbd/lib/_internal/js_dev_runtime/private/ddc_runtime/rtti.dart b/sdk_nnbd/lib/_internal/js_dev_runtime/private/ddc_runtime/rtti.dart
index 11ea1ae..6ac07ee 100644
--- a/sdk_nnbd/lib/_internal/js_dev_runtime/private/ddc_runtime/rtti.dart
+++ b/sdk_nnbd/lib/_internal/js_dev_runtime/private/ddc_runtime/rtti.dart
@@ -2,6 +2,8 @@
// 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.5
+
/// This library defines the association between runtime objects and
/// runtime types.
part of dart._runtime;
diff --git a/sdk_nnbd/lib/_internal/js_dev_runtime/private/ddc_runtime/runtime.dart b/sdk_nnbd/lib/_internal/js_dev_runtime/private/ddc_runtime/runtime.dart
index 99e1ab9..198ba6e 100644
--- a/sdk_nnbd/lib/_internal/js_dev_runtime/private/ddc_runtime/runtime.dart
+++ b/sdk_nnbd/lib/_internal/js_dev_runtime/private/ddc_runtime/runtime.dart
@@ -2,6 +2,8 @@
// 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.5
+
@ReifyFunctionTypes(false)
library dart._runtime;
diff --git a/sdk_nnbd/lib/_internal/js_dev_runtime/private/ddc_runtime/types.dart b/sdk_nnbd/lib/_internal/js_dev_runtime/private/ddc_runtime/types.dart
index 3175eeb..5dbff7f 100644
--- a/sdk_nnbd/lib/_internal/js_dev_runtime/private/ddc_runtime/types.dart
+++ b/sdk_nnbd/lib/_internal/js_dev_runtime/private/ddc_runtime/types.dart
@@ -2,6 +2,8 @@
// 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.5
+
/// This library defines the representation of runtime types.
part of dart._runtime;
diff --git a/sdk_nnbd/lib/_internal/js_dev_runtime/private/ddc_runtime/utils.dart b/sdk_nnbd/lib/_internal/js_dev_runtime/private/ddc_runtime/utils.dart
index 2c06179..6313fdd 100644
--- a/sdk_nnbd/lib/_internal/js_dev_runtime/private/ddc_runtime/utils.dart
+++ b/sdk_nnbd/lib/_internal/js_dev_runtime/private/ddc_runtime/utils.dart
@@ -2,6 +2,8 @@
// 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.5
+
part of dart._runtime;
/// This library defines a set of general javascript utilities for us
diff --git a/sdk_nnbd/lib/_internal/js_dev_runtime/private/debugger.dart b/sdk_nnbd/lib/_internal/js_dev_runtime/private/debugger.dart
index 4618317..8715cbd 100644
--- a/sdk_nnbd/lib/_internal/js_dev_runtime/private/debugger.dart
+++ b/sdk_nnbd/lib/_internal/js_dev_runtime/private/debugger.dart
@@ -2,6 +2,8 @@
// 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.5
+
library dart._debugger;
import 'dart:_foreign_helper' show JS;
diff --git a/sdk_nnbd/lib/_internal/js_dev_runtime/private/foreign_helper.dart b/sdk_nnbd/lib/_internal/js_dev_runtime/private/foreign_helper.dart
index 588d789..c9296cc 100644
--- a/sdk_nnbd/lib/_internal/js_dev_runtime/private/foreign_helper.dart
+++ b/sdk_nnbd/lib/_internal/js_dev_runtime/private/foreign_helper.dart
@@ -2,6 +2,8 @@
// 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.5
+
library dart._foreign_helper;
/**
diff --git a/sdk_nnbd/lib/_internal/js_dev_runtime/private/identity_hash_map.dart b/sdk_nnbd/lib/_internal/js_dev_runtime/private/identity_hash_map.dart
index 04107cc..3918bea 100644
--- a/sdk_nnbd/lib/_internal/js_dev_runtime/private/identity_hash_map.dart
+++ b/sdk_nnbd/lib/_internal/js_dev_runtime/private/identity_hash_map.dart
@@ -2,6 +2,8 @@
// 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.5
+
part of dart._js_helper;
class IdentityMap<K, V> extends InternalMap<K, V> {
diff --git a/sdk_nnbd/lib/_internal/js_dev_runtime/private/interceptors.dart b/sdk_nnbd/lib/_internal/js_dev_runtime/private/interceptors.dart
index 6ddd96b..1de2473 100644
--- a/sdk_nnbd/lib/_internal/js_dev_runtime/private/interceptors.dart
+++ b/sdk_nnbd/lib/_internal/js_dev_runtime/private/interceptors.dart
@@ -2,6 +2,8 @@
// 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.5
+
library dart._interceptors;
import 'dart:collection';
diff --git a/sdk_nnbd/lib/_internal/js_dev_runtime/private/isolate_helper.dart b/sdk_nnbd/lib/_internal/js_dev_runtime/private/isolate_helper.dart
index 490c4b9..ad4ec46 100644
--- a/sdk_nnbd/lib/_internal/js_dev_runtime/private/isolate_helper.dart
+++ b/sdk_nnbd/lib/_internal/js_dev_runtime/private/isolate_helper.dart
@@ -2,6 +2,8 @@
// 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.5
+
library dart._isolate_helper;
import 'dart:_runtime' as dart;
diff --git a/sdk_nnbd/lib/_internal/js_dev_runtime/private/js_array.dart b/sdk_nnbd/lib/_internal/js_dev_runtime/private/js_array.dart
index f064b24..1818f08 100644
--- a/sdk_nnbd/lib/_internal/js_dev_runtime/private/js_array.dart
+++ b/sdk_nnbd/lib/_internal/js_dev_runtime/private/js_array.dart
@@ -2,6 +2,8 @@
// 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.5
+
part of dart._interceptors;
/**
diff --git a/sdk_nnbd/lib/_internal/js_dev_runtime/private/js_helper.dart b/sdk_nnbd/lib/_internal/js_dev_runtime/private/js_helper.dart
index 5d6b037..e86378d 100644
--- a/sdk_nnbd/lib/_internal/js_dev_runtime/private/js_helper.dart
+++ b/sdk_nnbd/lib/_internal/js_dev_runtime/private/js_helper.dart
@@ -2,6 +2,8 @@
// 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.5
+
library dart._js_helper;
import 'dart:collection';
diff --git a/sdk_nnbd/lib/_internal/js_dev_runtime/private/js_mirrors.dart b/sdk_nnbd/lib/_internal/js_dev_runtime/private/js_mirrors.dart
index a93f5fb..42db17d 100644
--- a/sdk_nnbd/lib/_internal/js_dev_runtime/private/js_mirrors.dart
+++ b/sdk_nnbd/lib/_internal/js_dev_runtime/private/js_mirrors.dart
@@ -2,6 +2,8 @@
// 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.5
+
library dart._js_mirrors;
import 'dart:mirrors';
diff --git a/sdk_nnbd/lib/_internal/js_dev_runtime/private/js_number.dart b/sdk_nnbd/lib/_internal/js_dev_runtime/private/js_number.dart
index 5f8c7e0..36350b6 100644
--- a/sdk_nnbd/lib/_internal/js_dev_runtime/private/js_number.dart
+++ b/sdk_nnbd/lib/_internal/js_dev_runtime/private/js_number.dart
@@ -2,6 +2,8 @@
// 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.5
+
part of dart._interceptors;
/**
diff --git a/sdk_nnbd/lib/_internal/js_dev_runtime/private/js_primitives.dart b/sdk_nnbd/lib/_internal/js_dev_runtime/private/js_primitives.dart
index 1347b62..addcd83 100644
--- a/sdk_nnbd/lib/_internal/js_dev_runtime/private/js_primitives.dart
+++ b/sdk_nnbd/lib/_internal/js_dev_runtime/private/js_primitives.dart
@@ -2,6 +2,8 @@
// 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.5
+
/// dart2js "primitives", that is, features that cannot be implemented without
/// access to JavaScript features.
library dart2js._js_primitives;
diff --git a/sdk_nnbd/lib/_internal/js_dev_runtime/private/js_rti.dart b/sdk_nnbd/lib/_internal/js_dev_runtime/private/js_rti.dart
index 015c83e..37a9644 100644
--- a/sdk_nnbd/lib/_internal/js_dev_runtime/private/js_rti.dart
+++ b/sdk_nnbd/lib/_internal/js_dev_runtime/private/js_rti.dart
@@ -2,6 +2,8 @@
// 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.5
+
part of dart._js_helper;
// TODO(leafp): Maybe get rid of this? Currently used by the interceptors
diff --git a/sdk_nnbd/lib/_internal/js_dev_runtime/private/js_string.dart b/sdk_nnbd/lib/_internal/js_dev_runtime/private/js_string.dart
index 4271d34..90e39ae 100644
--- a/sdk_nnbd/lib/_internal/js_dev_runtime/private/js_string.dart
+++ b/sdk_nnbd/lib/_internal/js_dev_runtime/private/js_string.dart
@@ -2,6 +2,8 @@
// 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.5
+
part of dart._interceptors;
/**
diff --git a/sdk_nnbd/lib/_internal/js_dev_runtime/private/linked_hash_map.dart b/sdk_nnbd/lib/_internal/js_dev_runtime/private/linked_hash_map.dart
index 1c03db8..04f8a5c 100644
--- a/sdk_nnbd/lib/_internal/js_dev_runtime/private/linked_hash_map.dart
+++ b/sdk_nnbd/lib/_internal/js_dev_runtime/private/linked_hash_map.dart
@@ -2,6 +2,8 @@
// 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.5
+
// Efficient JavaScript based implementation of a linked hash map used as a
// backing map for constant maps and the [LinkedHashMap] patch
diff --git a/sdk_nnbd/lib/_internal/js_dev_runtime/private/mirror_helper.dart b/sdk_nnbd/lib/_internal/js_dev_runtime/private/mirror_helper.dart
index f78926a..96d2da9 100644
--- a/sdk_nnbd/lib/_internal/js_dev_runtime/private/mirror_helper.dart
+++ b/sdk_nnbd/lib/_internal/js_dev_runtime/private/mirror_helper.dart
@@ -1,6 +1,8 @@
// 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
// BSD-style license that can be found in the LICENSE file.
+// @dart = 2.5
+
/**
* Helps dealing with reflection in the case that the source code has been
* changed as a result of compiling with dart2dart.
diff --git a/sdk_nnbd/lib/_internal/js_dev_runtime/private/native_helper.dart b/sdk_nnbd/lib/_internal/js_dev_runtime/private/native_helper.dart
index cc214e8..c36cd41 100644
--- a/sdk_nnbd/lib/_internal/js_dev_runtime/private/native_helper.dart
+++ b/sdk_nnbd/lib/_internal/js_dev_runtime/private/native_helper.dart
@@ -2,6 +2,8 @@
// 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.5
+
part of dart._js_helper;
// Obsolete in dart dev compiler. Added only so that the same version of
diff --git a/sdk_nnbd/lib/_internal/js_dev_runtime/private/native_typed_data.dart b/sdk_nnbd/lib/_internal/js_dev_runtime/private/native_typed_data.dart
index 2a7a621..13fc0b5 100644
--- a/sdk_nnbd/lib/_internal/js_dev_runtime/private/native_typed_data.dart
+++ b/sdk_nnbd/lib/_internal/js_dev_runtime/private/native_typed_data.dart
@@ -2,6 +2,8 @@
// 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.5
+
/**
* Specialized integers and floating point numbers,
* with SIMD support and efficient lists.
diff --git a/sdk_nnbd/lib/_internal/js_dev_runtime/private/profile.dart b/sdk_nnbd/lib/_internal/js_dev_runtime/private/profile.dart
index d46f7f7..8f3410b 100644
--- a/sdk_nnbd/lib/_internal/js_dev_runtime/private/profile.dart
+++ b/sdk_nnbd/lib/_internal/js_dev_runtime/private/profile.dart
@@ -2,6 +2,8 @@
// 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.5
+
/// This file supports profiling dynamic calls.
part of dart._debugger;
diff --git a/sdk_nnbd/lib/_internal/js_dev_runtime/private/regexp_helper.dart b/sdk_nnbd/lib/_internal/js_dev_runtime/private/regexp_helper.dart
index fadcda0..fb0ee04 100644
--- a/sdk_nnbd/lib/_internal/js_dev_runtime/private/regexp_helper.dart
+++ b/sdk_nnbd/lib/_internal/js_dev_runtime/private/regexp_helper.dart
@@ -2,6 +2,8 @@
// 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.5
+
part of dart._js_helper;
// Helper method used by internal libraries.
diff --git a/sdk_nnbd/lib/_internal/js_dev_runtime/private/string_helper.dart b/sdk_nnbd/lib/_internal/js_dev_runtime/private/string_helper.dart
index c1b5c18..81bc0c7 100644
--- a/sdk_nnbd/lib/_internal/js_dev_runtime/private/string_helper.dart
+++ b/sdk_nnbd/lib/_internal/js_dev_runtime/private/string_helper.dart
@@ -2,6 +2,8 @@
// 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.5
+
part of dart._js_helper;
@notNull
diff --git a/sdk_nnbd/lib/_internal/js_runtime/lib/annotations.dart b/sdk_nnbd/lib/_internal/js_runtime/lib/annotations.dart
index f53c5f3..17e1de8 100644
--- a/sdk_nnbd/lib/_internal/js_runtime/lib/annotations.dart
+++ b/sdk_nnbd/lib/_internal/js_runtime/lib/annotations.dart
@@ -2,6 +2,8 @@
// 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.5
+
part of _js_helper;
/// Marks a class as native and defines its JavaScript name(s).
diff --git a/sdk_nnbd/lib/_internal/js_runtime/lib/async_patch.dart b/sdk_nnbd/lib/_internal/js_runtime/lib/async_patch.dart
index 68bcbeb..39c2e50 100644
--- a/sdk_nnbd/lib/_internal/js_runtime/lib/async_patch.dart
+++ b/sdk_nnbd/lib/_internal/js_runtime/lib/async_patch.dart
@@ -2,6 +2,8 @@
// 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.5
+
// Patch file for the dart:async library.
import 'dart:_js_helper'
diff --git a/sdk_nnbd/lib/_internal/js_runtime/lib/cli_patch.dart b/sdk_nnbd/lib/_internal/js_runtime/lib/cli_patch.dart
index 6921e60..e66d4e6 100644
--- a/sdk_nnbd/lib/_internal/js_runtime/lib/cli_patch.dart
+++ b/sdk_nnbd/lib/_internal/js_runtime/lib/cli_patch.dart
@@ -2,6 +2,8 @@
// 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.5
+
import 'dart:_js_helper' show patch;
@patch
diff --git a/sdk_nnbd/lib/_internal/js_runtime/lib/collection_patch.dart b/sdk_nnbd/lib/_internal/js_runtime/lib/collection_patch.dart
index 300d490..a0cb1b3 100644
--- a/sdk_nnbd/lib/_internal/js_runtime/lib/collection_patch.dart
+++ b/sdk_nnbd/lib/_internal/js_runtime/lib/collection_patch.dart
@@ -2,6 +2,8 @@
// 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.5
+
// Patch file for dart:collection classes.
import 'dart:_foreign_helper' show JS;
import 'dart:_js_helper'
diff --git a/sdk_nnbd/lib/_internal/js_runtime/lib/constant_map.dart b/sdk_nnbd/lib/_internal/js_runtime/lib/constant_map.dart
index f7c7936..829d620 100644
--- a/sdk_nnbd/lib/_internal/js_runtime/lib/constant_map.dart
+++ b/sdk_nnbd/lib/_internal/js_runtime/lib/constant_map.dart
@@ -2,6 +2,8 @@
// 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.5
+
part of _js_helper;
class ConstantMapView<K, V> extends UnmodifiableMapView<K, V>
diff --git a/sdk_nnbd/lib/_internal/js_runtime/lib/convert_patch.dart b/sdk_nnbd/lib/_internal/js_runtime/lib/convert_patch.dart
index fa6a0b0..bc996be 100644
--- a/sdk_nnbd/lib/_internal/js_runtime/lib/convert_patch.dart
+++ b/sdk_nnbd/lib/_internal/js_runtime/lib/convert_patch.dart
@@ -2,6 +2,8 @@
// 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.5
+
// Patch file for dart:convert library.
import 'dart:_js_helper' show argumentErrorValue, patch;
diff --git a/sdk_nnbd/lib/_internal/js_runtime/lib/core_patch.dart b/sdk_nnbd/lib/_internal/js_runtime/lib/core_patch.dart
index c655fc2..3fb8ccd 100644
--- a/sdk_nnbd/lib/_internal/js_runtime/lib/core_patch.dart
+++ b/sdk_nnbd/lib/_internal/js_runtime/lib/core_patch.dart
@@ -2,6 +2,8 @@
// 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.5
+
// Patch file for dart:core classes.
import "dart:_internal" hide Symbol, LinkedList, LinkedListEntry;
import "dart:_internal" as _symbol_dev;
diff --git a/sdk_nnbd/lib/_internal/js_runtime/lib/developer_patch.dart b/sdk_nnbd/lib/_internal/js_runtime/lib/developer_patch.dart
index 0ff0f66..719d7d4 100644
--- a/sdk_nnbd/lib/_internal/js_runtime/lib/developer_patch.dart
+++ b/sdk_nnbd/lib/_internal/js_runtime/lib/developer_patch.dart
@@ -2,6 +2,8 @@
// 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.5
+
// Patch file for dart:developer library.
import 'dart:_js_helper' show patch, ForceInline;
diff --git a/sdk_nnbd/lib/_internal/js_runtime/lib/foreign_helper.dart b/sdk_nnbd/lib/_internal/js_runtime/lib/foreign_helper.dart
index 0cecf96..6e4b037 100644
--- a/sdk_nnbd/lib/_internal/js_runtime/lib/foreign_helper.dart
+++ b/sdk_nnbd/lib/_internal/js_runtime/lib/foreign_helper.dart
@@ -2,6 +2,8 @@
// 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.5
+
library _foreign_helper;
import 'dart:_js_embedded_names' show JsGetName, JsBuiltin;
diff --git a/sdk_nnbd/lib/_internal/js_runtime/lib/instantiation.dart b/sdk_nnbd/lib/_internal/js_runtime/lib/instantiation.dart
index bb003e6..bdc2150 100644
--- a/sdk_nnbd/lib/_internal/js_runtime/lib/instantiation.dart
+++ b/sdk_nnbd/lib/_internal/js_runtime/lib/instantiation.dart
@@ -2,6 +2,8 @@
// 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.5
+
part of _js_helper;
/// Support class for generic function type instantiation (binding of types).
diff --git a/sdk_nnbd/lib/_internal/js_runtime/lib/interceptors.dart b/sdk_nnbd/lib/_internal/js_runtime/lib/interceptors.dart
index b676c1b..02235c4 100644
--- a/sdk_nnbd/lib/_internal/js_runtime/lib/interceptors.dart
+++ b/sdk_nnbd/lib/_internal/js_runtime/lib/interceptors.dart
@@ -2,6 +2,8 @@
// 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.5
+
library _interceptors;
import 'dart:_js_embedded_names'
diff --git a/sdk_nnbd/lib/_internal/js_runtime/lib/internal_patch.dart b/sdk_nnbd/lib/_internal/js_runtime/lib/internal_patch.dart
index 77884e2..af49181 100644
--- a/sdk_nnbd/lib/_internal/js_runtime/lib/internal_patch.dart
+++ b/sdk_nnbd/lib/_internal/js_runtime/lib/internal_patch.dart
@@ -2,6 +2,8 @@
// 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.5
+
import 'dart:core' hide Symbol;
import 'dart:core' as core;
import 'dart:_js_primitives' show printString;
diff --git a/sdk_nnbd/lib/_internal/js_runtime/lib/io_patch.dart b/sdk_nnbd/lib/_internal/js_runtime/lib/io_patch.dart
index 4f3894d..8460b21 100644
--- a/sdk_nnbd/lib/_internal/js_runtime/lib/io_patch.dart
+++ b/sdk_nnbd/lib/_internal/js_runtime/lib/io_patch.dart
@@ -2,6 +2,8 @@
// 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.5
+
import 'dart:_js_helper' show patch;
import 'dart:_internal' hide Symbol;
import 'dart:async';
diff --git a/sdk_nnbd/lib/_internal/js_runtime/lib/isolate_patch.dart b/sdk_nnbd/lib/_internal/js_runtime/lib/isolate_patch.dart
index d781e7a..9251920 100644
--- a/sdk_nnbd/lib/_internal/js_runtime/lib/isolate_patch.dart
+++ b/sdk_nnbd/lib/_internal/js_runtime/lib/isolate_patch.dart
@@ -2,6 +2,8 @@
// 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.5
+
// Patch file for the dart:isolate library.
import "dart:async";
diff --git a/sdk_nnbd/lib/_internal/js_runtime/lib/js_array.dart b/sdk_nnbd/lib/_internal/js_runtime/lib/js_array.dart
index ff820d4..716e85f 100644
--- a/sdk_nnbd/lib/_internal/js_runtime/lib/js_array.dart
+++ b/sdk_nnbd/lib/_internal/js_runtime/lib/js_array.dart
@@ -2,6 +2,8 @@
// 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.5
+
part of _interceptors;
class _Growable {
diff --git a/sdk_nnbd/lib/_internal/js_runtime/lib/js_helper.dart b/sdk_nnbd/lib/_internal/js_runtime/lib/js_helper.dart
index 8c167115..b8640d7 100644
--- a/sdk_nnbd/lib/_internal/js_runtime/lib/js_helper.dart
+++ b/sdk_nnbd/lib/_internal/js_runtime/lib/js_helper.dart
@@ -2,6 +2,8 @@
// 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.5
+
library _js_helper;
import 'dart:_js_embedded_names'
@@ -366,7 +368,7 @@
list.add(createRuntimeType(_arguments[start + index]));
}
}
- return list;
+ return JSArray.markUnmodifiableList(list);
}
List get positionalArguments {
diff --git a/sdk_nnbd/lib/_internal/js_runtime/lib/js_names.dart b/sdk_nnbd/lib/_internal/js_runtime/lib/js_names.dart
index cb4aa0e..3498028 100644
--- a/sdk_nnbd/lib/_internal/js_runtime/lib/js_names.dart
+++ b/sdk_nnbd/lib/_internal/js_runtime/lib/js_names.dart
@@ -2,6 +2,8 @@
// 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.5
+
library dart._js_names;
import 'dart:_js_embedded_names'
diff --git a/sdk_nnbd/lib/_internal/js_runtime/lib/js_number.dart b/sdk_nnbd/lib/_internal/js_runtime/lib/js_number.dart
index 918c1ba..30d8c1d 100644
--- a/sdk_nnbd/lib/_internal/js_runtime/lib/js_number.dart
+++ b/sdk_nnbd/lib/_internal/js_runtime/lib/js_number.dart
@@ -2,6 +2,8 @@
// 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.5
+
part of _interceptors;
/// The super interceptor class for [JSInt] and [JSDouble]. The compiler
diff --git a/sdk_nnbd/lib/_internal/js_runtime/lib/js_primitives.dart b/sdk_nnbd/lib/_internal/js_runtime/lib/js_primitives.dart
index 97577a0..5f55985 100644
--- a/sdk_nnbd/lib/_internal/js_runtime/lib/js_primitives.dart
+++ b/sdk_nnbd/lib/_internal/js_runtime/lib/js_primitives.dart
@@ -2,6 +2,8 @@
// 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.5
+
/// dart2js "primitives", that is, features that cannot be implemented without
/// access to JavaScript features.
library dart2js._js_primitives;
diff --git a/sdk_nnbd/lib/_internal/js_runtime/lib/js_rti.dart b/sdk_nnbd/lib/_internal/js_runtime/lib/js_rti.dart
index fd82931..9487c0d 100644
--- a/sdk_nnbd/lib/_internal/js_runtime/lib/js_rti.dart
+++ b/sdk_nnbd/lib/_internal/js_runtime/lib/js_rti.dart
@@ -2,6 +2,8 @@
// 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.5
+
/// This part contains helpers for supporting runtime type information.
///
/// The helper use a mixture of Dart and JavaScript objects. To indicate which
diff --git a/sdk_nnbd/lib/_internal/js_runtime/lib/js_string.dart b/sdk_nnbd/lib/_internal/js_runtime/lib/js_string.dart
index 39370d7..4a1d1ef 100644
--- a/sdk_nnbd/lib/_internal/js_runtime/lib/js_string.dart
+++ b/sdk_nnbd/lib/_internal/js_runtime/lib/js_string.dart
@@ -2,6 +2,8 @@
// 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.5
+
part of _interceptors;
/// The interceptor class for [String]. The compiler recognizes this
diff --git a/sdk_nnbd/lib/_internal/js_runtime/lib/linked_hash_map.dart b/sdk_nnbd/lib/_internal/js_runtime/lib/linked_hash_map.dart
index 42ad0c4..307b108 100644
--- a/sdk_nnbd/lib/_internal/js_runtime/lib/linked_hash_map.dart
+++ b/sdk_nnbd/lib/_internal/js_runtime/lib/linked_hash_map.dart
@@ -2,6 +2,8 @@
// 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.5
+
// Efficient JavaScript based implementation of a linked hash map used as a
// backing map for constant maps and the [LinkedHashMap] patch
diff --git a/sdk_nnbd/lib/_internal/js_runtime/lib/math_patch.dart b/sdk_nnbd/lib/_internal/js_runtime/lib/math_patch.dart
index 677953e..369045e 100644
--- a/sdk_nnbd/lib/_internal/js_runtime/lib/math_patch.dart
+++ b/sdk_nnbd/lib/_internal/js_runtime/lib/math_patch.dart
@@ -2,6 +2,8 @@
// 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.5
+
// Patch file for dart:math library.
import 'dart:_foreign_helper' show JS;
import 'dart:_js_helper' show patch, checkNum;
diff --git a/sdk_nnbd/lib/_internal/js_runtime/lib/mirrors_patch_cfe.dart b/sdk_nnbd/lib/_internal/js_runtime/lib/mirrors_patch_cfe.dart
index 6f8018a..005b14f 100644
--- a/sdk_nnbd/lib/_internal/js_runtime/lib/mirrors_patch_cfe.dart
+++ b/sdk_nnbd/lib/_internal/js_runtime/lib/mirrors_patch_cfe.dart
@@ -2,6 +2,8 @@
// 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.5
+
// Patch library for dart:mirrors.
import 'dart:_js_helper' show patch;
diff --git a/sdk_nnbd/lib/_internal/js_runtime/lib/native_helper.dart b/sdk_nnbd/lib/_internal/js_runtime/lib/native_helper.dart
index ccfa26f..058352a 100644
--- a/sdk_nnbd/lib/_internal/js_runtime/lib/native_helper.dart
+++ b/sdk_nnbd/lib/_internal/js_runtime/lib/native_helper.dart
@@ -2,6 +2,8 @@
// 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.5
+
part of _js_helper;
// TODO(ngeoffray): stop using this method once our optimizers can
diff --git a/sdk_nnbd/lib/_internal/js_runtime/lib/native_typed_data.dart b/sdk_nnbd/lib/_internal/js_runtime/lib/native_typed_data.dart
index 0a91641..63c4cba 100644
--- a/sdk_nnbd/lib/_internal/js_runtime/lib/native_typed_data.dart
+++ b/sdk_nnbd/lib/_internal/js_runtime/lib/native_typed_data.dart
@@ -2,6 +2,8 @@
// 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.5
+
/// Specialized integers and floating point numbers,
/// with SIMD support and efficient lists.
library dart.typed_data.implementation;
diff --git a/sdk_nnbd/lib/_internal/js_runtime/lib/regexp_helper.dart b/sdk_nnbd/lib/_internal/js_runtime/lib/regexp_helper.dart
index 3dacc06..4b65967 100644
--- a/sdk_nnbd/lib/_internal/js_runtime/lib/regexp_helper.dart
+++ b/sdk_nnbd/lib/_internal/js_runtime/lib/regexp_helper.dart
@@ -2,6 +2,8 @@
// 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.5
+
part of _js_helper;
// Helper method used by internal libraries.
diff --git a/sdk_nnbd/lib/_internal/js_runtime/lib/rti.dart b/sdk_nnbd/lib/_internal/js_runtime/lib/rti.dart
index f7ca527..5ad56dc 100644
--- a/sdk_nnbd/lib/_internal/js_runtime/lib/rti.dart
+++ b/sdk_nnbd/lib/_internal/js_runtime/lib/rti.dart
@@ -2,6 +2,8 @@
// 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.5
+
/// This library contains support for runtime type information.
library rti;
@@ -2147,11 +2149,16 @@
}
}
+ // TODO(fishythefish): Disallow JavaScriptFunction as a subtype of function
+ // types using features inaccessible from JavaScript.
+
if (isGenericFunctionKind(t)) {
+ if (isJsFunctionType(s)) return true;
return _isGenericFunctionSubtype(universe, s, sEnv, t, tEnv);
}
if (isFunctionKind(t)) {
+ if (isJsFunctionType(s)) return true;
return _isFunctionSubtype(universe, s, sEnv, t, tEnv);
}
@@ -2398,6 +2405,11 @@
Rti._getKind(t) == Rti.kindInterface &&
Rti._getInterfaceName(t) == JS_GET_NAME(JsGetName.FUNCTION_CLASS_TYPE_NAME);
+bool isJsFunctionType(Rti t) =>
+ Rti._getKind(t) == Rti.kindInterface &&
+ Rti._getInterfaceName(t) ==
+ JS_GET_NAME(JsGetName.JS_FUNCTION_CLASS_TYPE_NAME);
+
/// Unchecked cast to Rti.
Rti _castToRti(s) => JS('Rti', '#', s);
diff --git a/sdk_nnbd/lib/_internal/js_runtime/lib/shared/async_await_error_codes.dart b/sdk_nnbd/lib/_internal/js_runtime/lib/shared/async_await_error_codes.dart
index f87406b..0e9d7b2 100644
--- a/sdk_nnbd/lib/_internal/js_runtime/lib/shared/async_await_error_codes.dart
+++ b/sdk_nnbd/lib/_internal/js_runtime/lib/shared/async_await_error_codes.dart
@@ -2,6 +2,8 @@
// 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.5
+
/// Contains error codes that transformed async/async* functions use to
/// communicate with js_helper functions.
diff --git a/sdk_nnbd/lib/_internal/js_runtime/lib/shared/embedded_names.dart b/sdk_nnbd/lib/_internal/js_runtime/lib/shared/embedded_names.dart
index 50cf7e8..389c6db 100644
--- a/sdk_nnbd/lib/_internal/js_runtime/lib/shared/embedded_names.dart
+++ b/sdk_nnbd/lib/_internal/js_runtime/lib/shared/embedded_names.dart
@@ -2,6 +2,8 @@
// 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.5
+
/// Contains the names of globals that are embedded into the output by the
/// compiler.
///
@@ -326,6 +328,9 @@
/// String representation of the type of the function class.
FUNCTION_CLASS_TYPE_NAME,
+ /// String representation of the type of the JavaScriptFunction class.
+ JS_FUNCTION_CLASS_TYPE_NAME,
+
/// String recipe for the [bool] type.
BOOL_RECIPE,
diff --git a/sdk_nnbd/lib/_internal/js_runtime/lib/shared/recipe_syntax.dart b/sdk_nnbd/lib/_internal/js_runtime/lib/shared/recipe_syntax.dart
index 7666379..cab107f 100644
--- a/sdk_nnbd/lib/_internal/js_runtime/lib/shared/recipe_syntax.dart
+++ b/sdk_nnbd/lib/_internal/js_runtime/lib/shared/recipe_syntax.dart
@@ -2,6 +2,8 @@
// 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.5
+
/// Constants and predicates used for encoding and decoding type recipes.
///
/// This library is shared between the compiler and the runtime system.
diff --git a/sdk_nnbd/lib/_internal/js_runtime/lib/string_helper.dart b/sdk_nnbd/lib/_internal/js_runtime/lib/string_helper.dart
index ea5374e..5290dc9 100644
--- a/sdk_nnbd/lib/_internal/js_runtime/lib/string_helper.dart
+++ b/sdk_nnbd/lib/_internal/js_runtime/lib/string_helper.dart
@@ -2,6 +2,8 @@
// 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.5
+
part of _js_helper;
stringIndexOfStringUnchecked(receiver, other, startIndex) {
diff --git a/sdk_nnbd/lib/_internal/js_runtime/lib/typed_data_patch.dart b/sdk_nnbd/lib/_internal/js_runtime/lib/typed_data_patch.dart
index 615c9da..20fe6f6 100644
--- a/sdk_nnbd/lib/_internal/js_runtime/lib/typed_data_patch.dart
+++ b/sdk_nnbd/lib/_internal/js_runtime/lib/typed_data_patch.dart
@@ -2,6 +2,8 @@
// 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.5
+
import 'dart:_js_helper' show patch;
import 'dart:_native_typed_data';
diff --git a/sdk_nnbd/lib/_internal/sdk_library_metadata/lib/libraries.dart b/sdk_nnbd/lib/_internal/sdk_library_metadata/lib/libraries.dart
index ba141fa..9d41ab3 100644
--- a/sdk_nnbd/lib/_internal/sdk_library_metadata/lib/libraries.dart
+++ b/sdk_nnbd/lib/_internal/sdk_library_metadata/lib/libraries.dart
@@ -2,6 +2,8 @@
// 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.5
+
library libraries;
/**
diff --git a/sdk_nnbd/lib/_internal/vm/bin/builtin.dart b/sdk_nnbd/lib/_internal/vm/bin/builtin.dart
new file mode 100644
index 0000000..69ebae3
--- /dev/null
+++ b/sdk_nnbd/lib/_internal/vm/bin/builtin.dart
@@ -0,0 +1,349 @@
+// 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.5
+
+library builtin;
+
+// NOTE: Do not import 'dart:io' in builtin.
+import 'dart:async';
+import 'dart:collection' hide LinkedList, LinkedListEntry;
+import 'dart:_internal' hide Symbol;
+import 'dart:isolate';
+import 'dart:typed_data';
+
+// Embedder sets this to true if the --trace-loading flag was passed on the
+// command line.
+bool _traceLoading = false;
+
+// Before handling an embedder entrypoint we finalize the setup of the
+// dart:_builtin library.
+bool _setupCompleted = false;
+
+// 'print' implementation.
+// The standalone embedder registers the closurized _print function with the
+// dart:core library.
+void _printString(String s) native "Builtin_PrintString";
+
+void _print(arg) {
+ _printString(arg.toString());
+}
+
+@pragma("vm:entry-point")
+_getPrintClosure() => _print;
+
+// Asynchronous loading of resources.
+// The embedder forwards loading requests to the service isolate.
+
+// A port for communicating with the service isolate for I/O.
+@pragma("vm:entry-point")
+SendPort _loadPort;
+
+// The isolateId used to communicate with the service isolate for I/O.
+@pragma("vm:entry-point")
+int _isolateId;
+
+// Requests made to the service isolate over the load port.
+
+// Extra requests. Keep these in sync between loader.dart and builtin.dart.
+const _Dart_kInitLoader = 4; // Initialize the loader.
+const _Dart_kResourceLoad = 5; // Resource class support.
+const _Dart_kGetPackageRootUri = 6; // Uri of the packages/ directory.
+const _Dart_kGetPackageConfigUri = 7; // Uri of the .packages file.
+const _Dart_kResolvePackageUri = 8; // Resolve a package: uri.
+
+// Make a request to the loader. Future will complete with result which is
+// either a Uri or a List<int>.
+Future<T> _makeLoaderRequest<T>(int tag, String uri) {
+ assert(_isolateId != null);
+ if (_loadPort == null) {
+ throw new UnsupportedError("Service isolate is not available.");
+ }
+ Completer completer = new Completer<T>();
+ RawReceivePort port = new RawReceivePort();
+ port.handler = (msg) {
+ // Close the port.
+ port.close();
+ completer.complete(msg);
+ };
+ _loadPort.send([_traceLoading, _isolateId, tag, port.sendPort, uri]);
+ return completer.future;
+}
+
+// The current working directory when the embedder was launched.
+Uri _workingDirectory;
+// The URI that the root script was loaded from. Remembered so that
+// package imports can be resolved relative to it. The root script is the basis
+// for the root library in the VM.
+Uri _rootScript;
+// The package root set on the command line.
+Uri _packageRoot;
+
+// Special handling for Windows paths so that they are compatible with URI
+// handling.
+// Embedder sets this to true if we are running on Windows.
+@pragma("vm:entry-point")
+bool _isWindows = false;
+
+// Logging from builtin.dart is prefixed with a '*'.
+String _logId = (Isolate.current.hashCode % 0x100000).toRadixString(16);
+_log(msg) {
+ _print("* $_logId $msg");
+}
+
+_sanitizeWindowsPath(path) {
+ // For Windows we need to massage the paths a bit according to
+ // http://blogs.msdn.com/b/ie/archive/2006/12/06/file-uris-in-windows.aspx
+ //
+ // Convert
+ // C:\one\two\three
+ // to
+ // /C:/one/two/three
+
+ if (_isWindows == false) {
+ // Do nothing when not running Windows.
+ return path;
+ }
+
+ var fixedPath = "${path.replaceAll('\\', '/')}";
+
+ if ((path.length > 2) && (path[1] == ':')) {
+ // Path begins with a drive letter.
+ return '/$fixedPath';
+ }
+
+ return fixedPath;
+}
+
+_trimWindowsPath(path) {
+ // Convert /X:/ to X:/.
+ if (_isWindows == false) {
+ // Do nothing when not running Windows.
+ return path;
+ }
+ if (!path.startsWith('/') || (path.length < 3)) {
+ return path;
+ }
+ // Match '/?:'.
+ if ((path[0] == '/') && (path[2] == ':')) {
+ // Remove leading '/'.
+ return path.substring(1);
+ }
+ return path;
+}
+
+// Ensure we have a trailing slash character.
+_enforceTrailingSlash(uri) {
+ if (!uri.endsWith('/')) {
+ return '$uri/';
+ }
+ return uri;
+}
+
+// Embedder Entrypoint:
+// The embedder calls this method with the current working directory.
+@pragma("vm:entry-point")
+void _setWorkingDirectory(String cwd) {
+ if (!_setupCompleted) {
+ _setupHooks();
+ }
+ if (_traceLoading) {
+ _log('Setting working directory: $cwd');
+ }
+ _workingDirectory = new Uri.directory(cwd);
+ if (_traceLoading) {
+ _log('Working directory URI: $_workingDirectory');
+ }
+}
+
+// Embedder Entrypoint:
+// The embedder calls this method with a custom package root.
+@pragma("vm:entry-point")
+String _setPackageRoot(String packageRoot) {
+ if (!_setupCompleted) {
+ _setupHooks();
+ }
+ if (_traceLoading) {
+ _log('Setting package root: $packageRoot');
+ }
+ if (packageRoot.startsWith('file:') ||
+ packageRoot.startsWith('http:') ||
+ packageRoot.startsWith('https:')) {
+ packageRoot = _enforceTrailingSlash(packageRoot);
+ _packageRoot = _workingDirectory.resolve(packageRoot);
+ } else {
+ packageRoot = _sanitizeWindowsPath(packageRoot);
+ packageRoot = _trimWindowsPath(packageRoot);
+ _packageRoot = _workingDirectory.resolveUri(new Uri.directory(packageRoot));
+ }
+ // Now that we have determined the packageRoot value being used, set it
+ // up for use in Platform.packageRoot. This is only set when the embedder
+ // sets up the package root. Automatically discovered package root will
+ // not update the VMLibraryHooks value.
+ var packageRootStr = _packageRoot.toString();
+ VMLibraryHooks.packageRootString = packageRootStr;
+ if (_traceLoading) {
+ _log('Package root URI: $_packageRoot');
+ }
+ return packageRootStr;
+}
+
+// Embedder Entrypoint:
+@pragma("vm:entry-point")
+String _setPackagesMap(String packagesParam) {
+ if (!_setupCompleted) {
+ _setupHooks();
+ }
+ // First convert the packages parameter from the command line to a URI which
+ // can be handled by the loader code.
+ // TODO(iposva): Consider refactoring the common code below which is almost
+ // shared with resolution of the root script.
+ if (_traceLoading) {
+ _log("Resolving packages map: $packagesParam");
+ }
+ if (_workingDirectory == null) {
+ throw 'No current working directory set.';
+ }
+ var packagesName = _sanitizeWindowsPath(packagesParam);
+ var packagesUri = Uri.parse(packagesName);
+ if (packagesUri.scheme == '') {
+ // Script does not have a scheme, assume that it is a path,
+ // resolve it against the working directory.
+ packagesUri = _workingDirectory.resolveUri(packagesUri);
+ }
+ var packagesUriStr = packagesUri.toString();
+ VMLibraryHooks.packageConfigString = packagesUriStr;
+ if (_traceLoading) {
+ _log('Resolved packages map to: $packagesUri');
+ }
+ return packagesUriStr;
+}
+
+// Resolves the script uri in the current working directory iff the given uri
+// did not specify a scheme (e.g. a path to a script file on the command line).
+@pragma("vm:entry-point")
+String _resolveScriptUri(String scriptName) {
+ if (_traceLoading) {
+ _log("Resolving script: $scriptName");
+ }
+ if (_workingDirectory == null) {
+ throw 'No current working directory set.';
+ }
+ scriptName = _sanitizeWindowsPath(scriptName);
+
+ var scriptUri = Uri.parse(scriptName);
+ if (scriptUri.scheme == '') {
+ // Script does not have a scheme, assume that it is a path,
+ // resolve it against the working directory.
+ scriptUri = _workingDirectory.resolveUri(scriptUri);
+ }
+
+ // Remember the root script URI so that we can resolve packages based on
+ // this location.
+ _rootScript = scriptUri;
+
+ if (_traceLoading) {
+ _log('Resolved entry point to: $_rootScript');
+ }
+ return scriptUri.toString();
+}
+
+// Only used by vm/cc unit tests.
+Uri _resolvePackageUri(Uri uri) {
+ assert(_packageRoot != null);
+ return _packageRoot.resolve(uri.path);
+}
+
+// Returns either a file path or a URI starting with http[s]:, as a String.
+String _filePathFromUri(String userUri) {
+ var uri = Uri.parse(userUri);
+ if (_traceLoading) {
+ _log('Getting file path from: $uri');
+ }
+
+ var path;
+ switch (uri.scheme) {
+ case '':
+ case 'file':
+ return uri.toFilePath();
+ case 'package':
+ return _filePathFromUri(_resolvePackageUri(uri).toString());
+ case 'data':
+ case 'http':
+ case 'https':
+ return uri.toString();
+ default:
+ // Only handling file, http, and package URIs
+ // in standalone binary.
+ if (_traceLoading) {
+ _log('Unknown scheme (${uri.scheme}) in $uri.');
+ }
+ throw 'Not a known scheme: $uri';
+ }
+}
+
+// Register callbacks and hooks with the rest of the core libraries.
+@pragma("vm:entry-point")
+_setupHooks() {
+ _setupCompleted = true;
+ VMLibraryHooks.resourceReadAsBytes = _resourceReadAsBytes;
+
+ VMLibraryHooks.packageRootUriFuture = _getPackageRootFuture;
+ VMLibraryHooks.packageConfigUriFuture = _getPackageConfigFuture;
+ VMLibraryHooks.resolvePackageUriFuture = _resolvePackageUriFuture;
+}
+
+// Handling of Resource class by dispatching to the load port.
+Future<List<int>> _resourceReadAsBytes(Uri uri) async {
+ List response =
+ await _makeLoaderRequest<List<int>>(_Dart_kResourceLoad, uri.toString());
+ if (response[4] is String) {
+ // Throw the error.
+ throw response[4];
+ } else {
+ return response[4];
+ }
+}
+
+// TODO(mfairhurst): remove this
+Future<Uri> _getPackageRootFuture() {
+ if (_traceLoading) {
+ _log("Request for package root from user code.");
+ }
+ // Return null, as the `packages/` directory is not supported in dart 2.
+ return new Future.value(null);
+}
+
+Future<Uri> _getPackageConfigFuture() {
+ if (_traceLoading) {
+ _log("Request for package config from user code.");
+ }
+ assert(_loadPort != null);
+ return _makeLoaderRequest<Uri>(_Dart_kGetPackageConfigUri, null);
+}
+
+Future<Uri> _resolvePackageUriFuture(Uri packageUri) async {
+ if (_traceLoading) {
+ _log("Request for package Uri resolution from user code: $packageUri");
+ }
+ if (packageUri.scheme != "package") {
+ if (_traceLoading) {
+ _log("Non-package Uri, returning unmodified: $packageUri");
+ }
+ // Return the incoming parameter if not passed a package: URI.
+ return packageUri;
+ }
+ var result = await _makeLoaderRequest<Uri>(
+ _Dart_kResolvePackageUri, packageUri.toString());
+ if (result is! Uri) {
+ if (_traceLoading) {
+ _log("Exception when resolving package URI: $packageUri");
+ }
+ result = null;
+ }
+ if (_traceLoading) {
+ _log("Resolved '$packageUri' to '$result'");
+ }
+ return result;
+}
diff --git a/sdk_nnbd/lib/_internal/vm/bin/cli_patch.dart b/sdk_nnbd/lib/_internal/vm/bin/cli_patch.dart
new file mode 100644
index 0000000..6e373a5
--- /dev/null
+++ b/sdk_nnbd/lib/_internal/vm/bin/cli_patch.dart
@@ -0,0 +1,10 @@
+// Copyright (c) 2017, 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.5
+
+import "dart:_internal" show patch;
+
+@patch
+void _waitForEvent(int timeoutMillis) native "CLI_WaitForEvent";
diff --git a/sdk_nnbd/lib/_internal/vm/bin/common_patch.dart b/sdk_nnbd/lib/_internal/vm/bin/common_patch.dart
new file mode 100644
index 0000000..f974bae
--- /dev/null
+++ b/sdk_nnbd/lib/_internal/vm/bin/common_patch.dart
@@ -0,0 +1,64 @@
+// 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.5
+
+/// Note: the VM concatenates all patch files into a single patch file. This
+/// file is the first patch in "dart:io" which contains all the imports used by
+/// patches of that library. We plan to change this when we have a shared front
+/// end and simply use parts.
+
+import "dart:_internal" show VMLibraryHooks, patch;
+
+import "dart:async"
+ show
+ Completer,
+ Future,
+ Stream,
+ StreamConsumer,
+ StreamController,
+ StreamSubscription,
+ Timer,
+ Zone,
+ scheduleMicrotask;
+
+import "dart:collection" show HashMap;
+
+import "dart:convert" show Encoding, utf8;
+
+import "dart:developer" show registerExtension;
+
+import "dart:isolate" show RawReceivePort, ReceivePort, SendPort;
+
+import "dart:math" show min;
+
+import "dart:nativewrappers" show NativeFieldWrapperClass1;
+
+import "dart:typed_data" show Uint8List;
+
+/// These are the additional parts of this patch library:
+// part "directory_patch.dart";
+// part "eventhandler_patch.dart";
+// part "file_patch.dart";
+// part "file_system_entity_patch.dart";
+// part "filter_patch.dart";
+// part "io_service_patch.dart";
+// part "platform_patch.dart";
+// part "process_patch.dart";
+// part "socket_patch.dart";
+// part "stdio_patch.dart";
+// part "secure_socket_patch.dart";
+// part "sync_socket_patch.dart";
+
+@patch
+class _IOCrypto {
+ @patch
+ static Uint8List getRandomBytes(int count) native "Crypto_GetRandomBytes";
+}
+
+@pragma("vm:entry-point", "call")
+_setupHooks() {
+ VMLibraryHooks.eventHandlerSendData = _EventHandler._sendData;
+ VMLibraryHooks.timerMillisecondClock = _EventHandler._timerMillisecondClock;
+}
diff --git a/sdk_nnbd/lib/_internal/vm/bin/directory_patch.dart b/sdk_nnbd/lib/_internal/vm/bin/directory_patch.dart
new file mode 100644
index 0000000..951bd09
--- /dev/null
+++ b/sdk_nnbd/lib/_internal/vm/bin/directory_patch.dart
@@ -0,0 +1,73 @@
+// 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.5
+
+// part of "common_patch.dart";
+
+@patch
+class _Directory {
+ @patch
+ static _current(_Namespace namespace) native "Directory_Current";
+ @patch
+ static _setCurrent(_Namespace namespace, Uint8List rawPath)
+ native "Directory_SetCurrent";
+ @patch
+ static _createTemp(_Namespace namespace, Uint8List rawPath)
+ native "Directory_CreateTemp";
+ @patch
+ static String _systemTemp(_Namespace namespace) native "Directory_SystemTemp";
+ @patch
+ static _exists(_Namespace namespace, Uint8List rawPath)
+ native "Directory_Exists";
+ @patch
+ static _create(_Namespace namespace, Uint8List rawPath)
+ native "Directory_Create";
+ @patch
+ static _deleteNative(_Namespace namespace, Uint8List rawPath, bool recursive)
+ native "Directory_Delete";
+ @patch
+ static _rename(_Namespace namespace, Uint8List rawPath, String newPath)
+ native "Directory_Rename";
+ @patch
+ static void _fillWithDirectoryListing(
+ _Namespace namespace,
+ List<FileSystemEntity> list,
+ Uint8List rawPath,
+ bool recursive,
+ bool followLinks) native "Directory_FillWithDirectoryListing";
+}
+
+@patch
+class _AsyncDirectoryListerOps {
+ @patch
+ factory _AsyncDirectoryListerOps(int pointer) =>
+ new _AsyncDirectoryListerOpsImpl(pointer);
+}
+
+class _AsyncDirectoryListerOpsImpl extends NativeFieldWrapperClass1
+ implements _AsyncDirectoryListerOps {
+ _AsyncDirectoryListerOpsImpl._();
+
+ factory _AsyncDirectoryListerOpsImpl(int pointer) =>
+ new _AsyncDirectoryListerOpsImpl._().._setPointer(pointer);
+
+ void _setPointer(int pointer)
+ native "Directory_SetAsyncDirectoryListerPointer";
+ int getPointer() native "Directory_GetAsyncDirectoryListerPointer";
+}
+
+// Corelib 'Uri.base' implementation.
+// Uri.base is susceptible to changes in the current working directory.
+Uri _uriBaseClosure() {
+ var result = _Directory._current(_Namespace._namespace);
+ if (result is OSError) {
+ throw new FileSystemException(
+ "Getting current working directory failed", "", result);
+ }
+ return new Uri.directory(result);
+}
+
+@pragma("vm:entry-point", "call")
+_getUriBaseClosure() => _uriBaseClosure;
diff --git a/sdk_nnbd/lib/_internal/vm/bin/eventhandler_patch.dart b/sdk_nnbd/lib/_internal/vm/bin/eventhandler_patch.dart
new file mode 100644
index 0000000..abc5e21
--- /dev/null
+++ b/sdk_nnbd/lib/_internal/vm/bin/eventhandler_patch.dart
@@ -0,0 +1,17 @@
+// 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.5
+
+// part of "common_patch.dart";
+
+@patch
+class _EventHandler {
+ @patch
+ static void _sendData(Object sender, SendPort sendPort, int data)
+ native "EventHandler_SendData";
+
+ static int _timerMillisecondClock()
+ native "EventHandler_TimerMillisecondClock";
+}
diff --git a/sdk_nnbd/lib/_internal/vm/bin/file_patch.dart b/sdk_nnbd/lib/_internal/vm/bin/file_patch.dart
new file mode 100644
index 0000000..3ebdc82
--- /dev/null
+++ b/sdk_nnbd/lib/_internal/vm/bin/file_patch.dart
@@ -0,0 +1,423 @@
+// 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.5
+
+// part of "common_patch.dart";
+
+@patch
+class _File {
+ @patch
+ static _exists(_Namespace namespace, Uint8List rawPath) native "File_Exists";
+ @patch
+ static _create(_Namespace namespace, Uint8List rawPath) native "File_Create";
+ @patch
+ static _createLink(_Namespace namespace, Uint8List rawPath, String target)
+ native "File_CreateLink";
+ @patch
+ static _linkTarget(_Namespace namespace, Uint8List rawPath)
+ native "File_LinkTarget";
+ @patch
+ static _deleteNative(_Namespace namespace, Uint8List rawPath)
+ native "File_Delete";
+ @patch
+ static _deleteLinkNative(_Namespace namespace, Uint8List rawPath)
+ native "File_DeleteLink";
+ @patch
+ static _rename(_Namespace namespace, Uint8List oldPath, String newPath)
+ native "File_Rename";
+ @patch
+ static _renameLink(_Namespace namespace, Uint8List oldPath, String newPath)
+ native "File_RenameLink";
+ @patch
+ static _copy(_Namespace namespace, Uint8List oldPath, String newPath)
+ native "File_Copy";
+ @patch
+ static _lengthFromPath(_Namespace namespace, Uint8List rawPath)
+ native "File_LengthFromPath";
+ @patch
+ static _lastModified(_Namespace namespace, Uint8List rawPath)
+ native "File_LastModified";
+ @patch
+ static _setLastModified(_Namespace namespace, Uint8List rawPath, int millis)
+ native "File_SetLastModified";
+ @patch
+ static _lastAccessed(_Namespace namespace, Uint8List rawPath)
+ native "File_LastAccessed";
+ @patch
+ static _setLastAccessed(_Namespace namespace, Uint8List rawPath, int millis)
+ native "File_SetLastAccessed";
+ @patch
+ static _open(_Namespace namespace, Uint8List rawPath, int mode)
+ native "File_Open";
+ @patch
+ static int _openStdio(int fd) native "File_OpenStdio";
+}
+
+@patch
+class _RandomAccessFileOps {
+ @patch
+ factory _RandomAccessFileOps(int pointer) =>
+ new _RandomAccessFileOpsImpl(pointer);
+}
+
+@pragma("vm:entry-point")
+class _RandomAccessFileOpsImpl extends NativeFieldWrapperClass1
+ implements _RandomAccessFileOps {
+ _RandomAccessFileOpsImpl._();
+
+ factory _RandomAccessFileOpsImpl(int pointer) =>
+ new _RandomAccessFileOpsImpl._().._setPointer(pointer);
+
+ void _setPointer(int pointer) native "File_SetPointer";
+
+ int getPointer() native "File_GetPointer";
+ int close() native "File_Close";
+ readByte() native "File_ReadByte";
+ read(int bytes) native "File_Read";
+ readInto(List<int> buffer, int start, int end) native "File_ReadInto";
+ writeByte(int value) native "File_WriteByte";
+ writeFrom(List<int> buffer, int start, int end) native "File_WriteFrom";
+ position() native "File_Position";
+ setPosition(int position) native "File_SetPosition";
+ truncate(int length) native "File_Truncate";
+ length() native "File_Length";
+ flush() native "File_Flush";
+ lock(int lock, int start, int end) native "File_Lock";
+}
+
+class _WatcherPath {
+ final int pathId;
+ final String path;
+ final int events;
+ int count = 0;
+ _WatcherPath(this.pathId, this.path, this.events);
+}
+
+@patch
+class _FileSystemWatcher {
+ void _pathWatchedEnd();
+
+ static int _id;
+ static final Map<int, _WatcherPath> _idMap = {};
+
+ final String _path;
+ final int _events;
+ final bool _recursive;
+
+ _WatcherPath _watcherPath;
+
+ StreamController<FileSystemEvent> _broadcastController;
+
+ @patch
+ static Stream<FileSystemEvent> _watch(
+ String path, int events, bool recursive) {
+ if (Platform.isLinux) {
+ return new _InotifyFileSystemWatcher(path, events, recursive)._stream;
+ }
+ if (Platform.isWindows) {
+ return new _Win32FileSystemWatcher(path, events, recursive)._stream;
+ }
+ if (Platform.isMacOS) {
+ return new _FSEventStreamFileSystemWatcher(path, events, recursive)
+ ._stream;
+ }
+ throw new FileSystemException(
+ "File system watching is not supported on this platform");
+ }
+
+ _FileSystemWatcher._(this._path, this._events, this._recursive) {
+ if (!isSupported) {
+ throw new FileSystemException(
+ "File system watching is not supported on this platform", _path);
+ }
+ _broadcastController = new StreamController<FileSystemEvent>.broadcast(
+ onListen: _listen, onCancel: _cancel);
+ }
+
+ Stream<FileSystemEvent> get _stream => _broadcastController.stream;
+
+ void _listen() {
+ if (_id == null) {
+ try {
+ _id = _initWatcher();
+ _newWatcher();
+ } catch (e) {
+ _broadcastController.addError(new FileSystemException(
+ "Failed to initialize file system entity watcher", null, e));
+ _broadcastController.close();
+ return;
+ }
+ }
+ var pathId;
+ try {
+ pathId =
+ _watchPath(_id, _Namespace._namespace, _path, _events, _recursive);
+ } catch (e) {
+ _broadcastController
+ .addError(new FileSystemException("Failed to watch path", _path, e));
+ _broadcastController.close();
+ return;
+ }
+ if (!_idMap.containsKey(pathId)) {
+ _idMap[pathId] = new _WatcherPath(pathId, _path, _events);
+ }
+ _watcherPath = _idMap[pathId];
+ _watcherPath.count++;
+ _pathWatched().pipe(_broadcastController);
+ }
+
+ void _cancel() {
+ if (_watcherPath != null) {
+ assert(_watcherPath.count > 0);
+ _watcherPath.count--;
+ if (_watcherPath.count == 0) {
+ _unwatchPath(_id, _watcherPath.pathId);
+ _pathWatchedEnd();
+ _idMap.remove(_watcherPath.pathId);
+ }
+ _watcherPath = null;
+ }
+ if (_idMap.isEmpty && _id != null) {
+ _closeWatcher(_id);
+ _doneWatcher();
+ _id = null;
+ }
+ }
+
+ // Called when (and after) a new watcher instance is created and available.
+ void _newWatcher() {}
+ // Called when a watcher is no longer needed.
+ void _doneWatcher() {}
+ // Called when a new path is being watched.
+ Stream _pathWatched() {}
+ // Called when a path is no longer being watched.
+ void _donePathWatched() {}
+
+ static _WatcherPath _pathFromPathId(int pathId) {
+ return _idMap[pathId];
+ }
+
+ static Stream _listenOnSocket(int socketId, int id, int pathId) {
+ var native = new _NativeSocket.watch(socketId);
+ var socket = new _RawSocket(native);
+ return socket.expand((event) {
+ var stops = [];
+ var events = [];
+ var pair = {};
+ if (event == RawSocketEvent.read) {
+ String getPath(event) {
+ var path = _pathFromPathId(event[4]).path;
+ if (event[2] != null && event[2].isNotEmpty) {
+ path += Platform.pathSeparator;
+ path += event[2];
+ }
+ return path;
+ }
+
+ bool getIsDir(event) {
+ if (Platform.isWindows) {
+ // Windows does not get 'isDir' as part of the event.
+ return FileSystemEntity.isDirectorySync(getPath(event));
+ }
+ return (event[0] & FileSystemEvent._isDir) != 0;
+ }
+
+ void add(id, event) {
+ if ((event.type & _pathFromPathId(id).events) == 0) return;
+ events.add([id, event]);
+ }
+
+ void rewriteMove(event, isDir) {
+ if (event[3]) {
+ add(event[4], new FileSystemCreateEvent._(getPath(event), isDir));
+ } else {
+ add(event[4], new FileSystemDeleteEvent._(getPath(event), isDir));
+ }
+ }
+
+ int eventCount;
+ do {
+ eventCount = 0;
+ for (var event in _readEvents(id, pathId)) {
+ if (event == null) continue;
+ eventCount++;
+ int pathId = event[4];
+ if (!_idMap.containsKey(pathId)) {
+ // Path is no longer being wathed.
+ continue;
+ }
+ bool isDir = getIsDir(event);
+ var path = getPath(event);
+ if ((event[0] & FileSystemEvent.create) != 0) {
+ add(event[4], new FileSystemCreateEvent._(path, isDir));
+ }
+ if ((event[0] & FileSystemEvent.modify) != 0) {
+ add(event[4], new FileSystemModifyEvent._(path, isDir, true));
+ }
+ if ((event[0] & FileSystemEvent._modifyAttributes) != 0) {
+ add(event[4], new FileSystemModifyEvent._(path, isDir, false));
+ }
+ if ((event[0] & FileSystemEvent.move) != 0) {
+ int link = event[1];
+ if (link > 0) {
+ pair.putIfAbsent(pathId, () => {});
+ if (pair[pathId].containsKey(link)) {
+ add(
+ event[4],
+ new FileSystemMoveEvent._(
+ getPath(pair[pathId][link]), isDir, path));
+ pair[pathId].remove(link);
+ } else {
+ pair[pathId][link] = event;
+ }
+ } else {
+ rewriteMove(event, isDir);
+ }
+ }
+ if ((event[0] & FileSystemEvent.delete) != 0) {
+ add(event[4], new FileSystemDeleteEvent._(path, isDir));
+ }
+ if ((event[0] & FileSystemEvent._deleteSelf) != 0) {
+ add(event[4], new FileSystemDeleteEvent._(path, isDir));
+ // Signal done event.
+ stops.add([event[4], null]);
+ }
+ }
+ } while (eventCount > 0);
+ // Be sure to clear this manually, as the sockets are not read through
+ // the _NativeSocket interface.
+ native.available = 0;
+ for (var map in pair.values) {
+ for (var event in map.values) {
+ rewriteMove(event, getIsDir(event));
+ }
+ }
+ } else if (event == RawSocketEvent.closed) {
+ } else if (event == RawSocketEvent.readClosed) {
+ } else {
+ assert(false);
+ }
+ events.addAll(stops);
+ return events;
+ });
+ }
+
+ @patch
+ static bool get isSupported native "FileSystemWatcher_IsSupported";
+
+ static int _initWatcher() native "FileSystemWatcher_InitWatcher";
+ static void _closeWatcher(int id) native "FileSystemWatcher_CloseWatcher";
+
+ static int _watchPath(int id, _Namespace namespace, String path, int events,
+ bool recursive) native "FileSystemWatcher_WatchPath";
+ static void _unwatchPath(int id, int path_id)
+ native "FileSystemWatcher_UnwatchPath";
+ static List _readEvents(int id, int path_id)
+ native "FileSystemWatcher_ReadEvents";
+ static int _getSocketId(int id, int path_id)
+ native "FileSystemWatcher_GetSocketId";
+}
+
+class _InotifyFileSystemWatcher extends _FileSystemWatcher {
+ static final Map<int, StreamController> _idMap = {};
+ static StreamSubscription _subscription;
+
+ _InotifyFileSystemWatcher(path, events, recursive)
+ : super._(path, events, recursive);
+
+ void _newWatcher() {
+ int id = _FileSystemWatcher._id;
+ _subscription =
+ _FileSystemWatcher._listenOnSocket(id, id, 0).listen((event) {
+ if (_idMap.containsKey(event[0])) {
+ if (event[1] != null) {
+ _idMap[event[0]].add(event[1]);
+ } else {
+ _idMap[event[0]].close();
+ }
+ }
+ });
+ }
+
+ void _doneWatcher() {
+ _subscription.cancel();
+ }
+
+ Stream _pathWatched() {
+ var pathId = _watcherPath.pathId;
+ if (!_idMap.containsKey(pathId)) {
+ _idMap[pathId] = new StreamController<FileSystemEvent>.broadcast();
+ }
+ return _idMap[pathId].stream;
+ }
+
+ void _pathWatchedEnd() {
+ var pathId = _watcherPath.pathId;
+ if (!_idMap.containsKey(pathId)) return;
+ _idMap[pathId].close();
+ _idMap.remove(pathId);
+ }
+}
+
+class _Win32FileSystemWatcher extends _FileSystemWatcher {
+ StreamSubscription _subscription;
+ StreamController _controller;
+
+ _Win32FileSystemWatcher(path, events, recursive)
+ : super._(path, events, recursive);
+
+ Stream _pathWatched() {
+ var pathId = _watcherPath.pathId;
+ _controller = new StreamController<FileSystemEvent>();
+ _subscription =
+ _FileSystemWatcher._listenOnSocket(pathId, 0, pathId).listen((event) {
+ assert(event[0] == pathId);
+ if (event[1] != null) {
+ _controller.add(event[1]);
+ } else {
+ _controller.close();
+ }
+ });
+ return _controller.stream;
+ }
+
+ void _pathWatchedEnd() {
+ _subscription.cancel();
+ _controller.close();
+ }
+}
+
+class _FSEventStreamFileSystemWatcher extends _FileSystemWatcher {
+ StreamSubscription _subscription;
+ StreamController _controller;
+
+ _FSEventStreamFileSystemWatcher(path, events, recursive)
+ : super._(path, events, recursive);
+
+ Stream _pathWatched() {
+ var pathId = _watcherPath.pathId;
+ var socketId = _FileSystemWatcher._getSocketId(0, pathId);
+ _controller = new StreamController<FileSystemEvent>();
+ _subscription =
+ _FileSystemWatcher._listenOnSocket(socketId, 0, pathId).listen((event) {
+ if (event[1] != null) {
+ _controller.add(event[1]);
+ } else {
+ _controller.close();
+ }
+ });
+ return _controller.stream;
+ }
+
+ void _pathWatchedEnd() {
+ _subscription.cancel();
+ _controller.close();
+ }
+}
+
+@pragma("vm:entry-point", "call")
+Uint8List _makeUint8ListView(Uint8List source, int offsetInBytes, int length) {
+ return new Uint8List.view(source.buffer, offsetInBytes, length);
+}
diff --git a/sdk_nnbd/lib/_internal/vm/bin/file_system_entity_patch.dart b/sdk_nnbd/lib/_internal/vm/bin/file_system_entity_patch.dart
new file mode 100644
index 0000000..841219e
--- /dev/null
+++ b/sdk_nnbd/lib/_internal/vm/bin/file_system_entity_patch.dart
@@ -0,0 +1,26 @@
+// 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
+// BSD-style license that can be found in the LICENSE file.
+
+// @dart = 2.5
+
+// part of "common_patch.dart";
+
+@patch
+class FileStat {
+ @patch
+ static _statSync(_Namespace namespace, String path) native "File_Stat";
+}
+
+@patch
+class FileSystemEntity {
+ @patch
+ static _getTypeNative(_Namespace namespace, Uint8List rawPath,
+ bool followLinks) native "File_GetType";
+ @patch
+ static _identicalNative(_Namespace namespace, String path1, String path2)
+ native "File_AreIdentical";
+ @patch
+ static _resolveSymbolicLinks(_Namespace namespace, Uint8List path)
+ native "File_ResolveSymbolicLinks";
+}
diff --git a/sdk_nnbd/lib/_internal/vm/bin/filter_patch.dart b/sdk_nnbd/lib/_internal/vm/bin/filter_patch.dart
new file mode 100644
index 0000000..a31f838
--- /dev/null
+++ b/sdk_nnbd/lib/_internal/vm/bin/filter_patch.dart
@@ -0,0 +1,50 @@
+// 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
+// BSD-style license that can be found in the LICENSE file.
+
+// @dart = 2.5
+
+// part of "common_patch.dart";
+
+class _FilterImpl extends NativeFieldWrapperClass1 implements RawZLibFilter {
+ void process(List<int> data, int start, int end) native "Filter_Process";
+
+ List<int> processed({bool flush: true, bool end: false})
+ native "Filter_Processed";
+}
+
+class _ZLibInflateFilter extends _FilterImpl {
+ _ZLibInflateFilter(int windowBits, List<int> dictionary, bool raw) {
+ _init(windowBits, dictionary, raw);
+ }
+ void _init(int windowBits, List<int> dictionary, bool raw)
+ native "Filter_CreateZLibInflate";
+}
+
+class _ZLibDeflateFilter extends _FilterImpl {
+ _ZLibDeflateFilter(bool gzip, int level, int windowBits, int memLevel,
+ int strategy, List<int> dictionary, bool raw) {
+ _init(gzip, level, windowBits, memLevel, strategy, dictionary, raw);
+ }
+ void _init(bool gzip, int level, int windowBits, int memLevel, int strategy,
+ List<int> dictionary, bool raw) native "Filter_CreateZLibDeflate";
+}
+
+@patch
+class RawZLibFilter {
+ @patch
+ static RawZLibFilter _makeZLibDeflateFilter(
+ bool gzip,
+ int level,
+ int windowBits,
+ int memLevel,
+ int strategy,
+ List<int> dictionary,
+ bool raw) =>
+ new _ZLibDeflateFilter(
+ gzip, level, windowBits, memLevel, strategy, dictionary, raw);
+ @patch
+ static RawZLibFilter _makeZLibInflateFilter(
+ int windowBits, List<int> dictionary, bool raw) =>
+ new _ZLibInflateFilter(windowBits, dictionary, raw);
+}
diff --git a/sdk_nnbd/lib/_internal/vm/bin/io_service_patch.dart b/sdk_nnbd/lib/_internal/vm/bin/io_service_patch.dart
new file mode 100644
index 0000000..be823a4
--- /dev/null
+++ b/sdk_nnbd/lib/_internal/vm/bin/io_service_patch.dart
@@ -0,0 +1,102 @@
+// 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
+// BSD-style license that can be found in the LICENSE file.
+
+// @dart = 2.5
+
+// part of "common_patch.dart";
+
+class _IOServicePorts {
+ // We limit the number of IO Service ports per isolate so that we don't
+ // spawn too many threads all at once, which can crash the VM on Windows.
+ static const int maxPorts = 32;
+ List<SendPort> _ports = <SendPort>[];
+ List<SendPort> _freePorts = <SendPort>[];
+ Map<int, SendPort> _usedPorts = new HashMap<int, SendPort>();
+
+ _IOServicePorts();
+
+ SendPort _getPort(int forRequestId) {
+ if (_freePorts.isEmpty && _usedPorts.length < maxPorts) {
+ final SendPort port = _newServicePort();
+ _ports.add(port);
+ _freePorts.add(port);
+ }
+ if (!_freePorts.isEmpty) {
+ final SendPort port = _freePorts.removeLast();
+ assert(!_usedPorts.containsKey(forRequestId));
+ _usedPorts[forRequestId] = port;
+ return port;
+ }
+ // We have already allocated the max number of ports. Re-use an
+ // existing one.
+ final SendPort port = _ports[forRequestId % maxPorts];
+ _usedPorts[forRequestId] = port;
+ return port;
+ }
+
+ void _returnPort(int forRequestId) {
+ final SendPort port = _usedPorts.remove(forRequestId);
+ if (!_usedPorts.values.contains(port)) {
+ _freePorts.add(port);
+ }
+ }
+
+ static SendPort _newServicePort() native "IOService_NewServicePort";
+}
+
+@patch
+class _IOService {
+ static _IOServicePorts _servicePorts = new _IOServicePorts();
+ static RawReceivePort _receivePort;
+ static SendPort _replyToPort;
+ static HashMap<int, Completer> _messageMap = new HashMap<int, Completer>();
+ static int _id = 0;
+
+ @patch
+ static Future _dispatch(int request, List data) {
+ int id;
+ do {
+ id = _getNextId();
+ } while (_messageMap.containsKey(id));
+ final SendPort servicePort = _servicePorts._getPort(id);
+ _ensureInitialize();
+ final Completer completer = new Completer();
+ _messageMap[id] = completer;
+ try {
+ servicePort.send([id, _replyToPort, request, data]);
+ } catch (error) {
+ _messageMap.remove(id).complete(error);
+ if (_messageMap.length == 0) {
+ _finalize();
+ }
+ }
+ return completer.future;
+ }
+
+ static void _ensureInitialize() {
+ if (_receivePort == null) {
+ _receivePort = new RawReceivePort();
+ _replyToPort = _receivePort.sendPort;
+ _receivePort.handler = (data) {
+ assert(data is List && data.length == 2);
+ _messageMap.remove(data[0]).complete(data[1]);
+ _servicePorts._returnPort(data[0]);
+ if (_messageMap.length == 0) {
+ _finalize();
+ }
+ };
+ }
+ }
+
+ static void _finalize() {
+ _id = 0;
+ _receivePort.close();
+ _receivePort = null;
+ }
+
+ static int _getNextId() {
+ if (_id == 0x7FFFFFFF) _id = 0;
+ return _id++;
+ }
+}
diff --git a/sdk_nnbd/lib/_internal/vm/bin/namespace_patch.dart b/sdk_nnbd/lib/_internal/vm/bin/namespace_patch.dart
new file mode 100644
index 0000000..bc8e2df
--- /dev/null
+++ b/sdk_nnbd/lib/_internal/vm/bin/namespace_patch.dart
@@ -0,0 +1,50 @@
+// Copyright (c) 2017, 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.5
+
+@pragma("vm:entry-point")
+class _NamespaceImpl extends NativeFieldWrapperClass1 implements _Namespace {
+ _NamespaceImpl._();
+
+ static _NamespaceImpl _create(_NamespaceImpl namespace, var n)
+ native "Namespace_Create";
+ static int _getPointer(_NamespaceImpl namespace)
+ native "Namespace_GetPointer";
+ static int _getDefault() native "Namespace_GetDefault";
+
+ // If the platform supports "namespaces", this method is called by the
+ // embedder with the platform-specific namespace information.
+ static _NamespaceImpl _cachedNamespace = null;
+ static void _setupNamespace(var namespace) {
+ _cachedNamespace = _create(new _NamespaceImpl._(), namespace);
+ }
+
+ static _NamespaceImpl get _namespace {
+ if (_cachedNamespace == null) {
+ // The embedder has not supplied a namespace before one is needed, so
+ // instead use a safe-ish default value.
+ _cachedNamespace = _create(new _NamespaceImpl._(), _getDefault());
+ }
+ return _cachedNamespace;
+ }
+
+ static int get _namespacePointer => _getPointer(_namespace);
+}
+
+@patch
+@pragma("vm:entry-point")
+class _Namespace {
+ @patch
+ @pragma("vm:entry-point", "call")
+ static void _setupNamespace(var namespace) {
+ _NamespaceImpl._setupNamespace(namespace);
+ }
+
+ @patch
+ static _Namespace get _namespace => _NamespaceImpl._namespace;
+
+ @patch
+ static int get _namespacePointer => _NamespaceImpl._namespacePointer;
+}
diff --git a/sdk_nnbd/lib/_internal/vm/bin/platform_patch.dart b/sdk_nnbd/lib/_internal/vm/bin/platform_patch.dart
new file mode 100644
index 0000000..88c10bd
--- /dev/null
+++ b/sdk_nnbd/lib/_internal/vm/bin/platform_patch.dart
@@ -0,0 +1,61 @@
+// 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.5
+
+// part of "common_patch.dart";
+
+@patch
+@pragma("vm:entry-point")
+class _Platform {
+ @patch
+ static int _numberOfProcessors() native "Platform_NumberOfProcessors";
+ @patch
+ static String _pathSeparator() native "Platform_PathSeparator";
+ @patch
+ static String _operatingSystem() native "Platform_OperatingSystem";
+ @patch
+ static _operatingSystemVersion() native "Platform_OperatingSystemVersion";
+ @patch
+ static _localHostname() native "Platform_LocalHostname";
+ @patch
+ static _executable() native "Platform_ExecutableName";
+ @patch
+ static _resolvedExecutable() native "Platform_ResolvedExecutableName";
+ @patch
+ static _environment() native "Platform_Environment";
+ @patch
+ static List<String> _executableArguments()
+ native "Platform_ExecutableArguments";
+ @patch
+ static String _version() native "Platform_GetVersion";
+
+ @patch
+ static String _localeName() native "Platform_LocaleName";
+
+ @patch
+ static String _packageRoot() => VMLibraryHooks.packageRootString;
+ @patch
+ static String _packageConfig() => VMLibraryHooks.packageConfigString;
+
+ @patch
+ static Uri _script() => VMLibraryHooks.platformScript;
+
+ // This script singleton is written to by the embedder if applicable.
+ @pragma("vm:entry-point")
+ static void set _nativeScript(String path) {
+ VMLibraryHooks.platformScript = (() {
+ if (path.startsWith('http:') ||
+ path.startsWith('https:') ||
+ path.startsWith('package:') ||
+ path.startsWith('dart:') ||
+ path.startsWith('data:') ||
+ path.startsWith('file:')) {
+ return Uri.parse(path);
+ } else {
+ return Uri.base.resolveUri(new Uri.file(path));
+ }
+ });
+ }
+}
diff --git a/sdk_nnbd/lib/_internal/vm/bin/process_patch.dart b/sdk_nnbd/lib/_internal/vm/bin/process_patch.dart
new file mode 100644
index 0000000..046377d
--- /dev/null
+++ b/sdk_nnbd/lib/_internal/vm/bin/process_patch.dart
@@ -0,0 +1,644 @@
+// 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
+// BSD-style license that can be found in the LICENSE file.
+
+// @dart = 2.5
+
+// part of "common_patch.dart";
+
+@patch
+class _WindowsCodePageDecoder {
+ @patch
+ static String _decodeBytes(List<int> bytes) native "SystemEncodingToString";
+}
+
+@patch
+class _WindowsCodePageEncoder {
+ @patch
+ static List<int> _encodeString(String string) native "StringToSystemEncoding";
+}
+
+@patch
+class Process {
+ @patch
+ static Future<Process> start(String executable, List<String> arguments,
+ {String workingDirectory,
+ Map<String, String> environment,
+ bool includeParentEnvironment: true,
+ bool runInShell: false,
+ ProcessStartMode mode: ProcessStartMode.normal}) {
+ _ProcessImpl process = new _ProcessImpl(
+ executable,
+ arguments,
+ workingDirectory,
+ environment,
+ includeParentEnvironment,
+ runInShell,
+ mode);
+ return process._start();
+ }
+
+ @patch
+ static Future<ProcessResult> run(String executable, List<String> arguments,
+ {String workingDirectory,
+ Map<String, String> environment,
+ bool includeParentEnvironment: true,
+ bool runInShell: false,
+ Encoding stdoutEncoding: systemEncoding,
+ Encoding stderrEncoding: systemEncoding}) {
+ return _runNonInteractiveProcess(
+ executable,
+ arguments,
+ workingDirectory,
+ environment,
+ includeParentEnvironment,
+ runInShell,
+ stdoutEncoding,
+ stderrEncoding);
+ }
+
+ @patch
+ static ProcessResult runSync(String executable, List<String> arguments,
+ {String workingDirectory,
+ Map<String, String> environment,
+ bool includeParentEnvironment: true,
+ bool runInShell: false,
+ Encoding stdoutEncoding: systemEncoding,
+ Encoding stderrEncoding: systemEncoding}) {
+ return _runNonInteractiveProcessSync(
+ executable,
+ arguments,
+ workingDirectory,
+ environment,
+ includeParentEnvironment,
+ runInShell,
+ stdoutEncoding,
+ stderrEncoding);
+ }
+
+ @patch
+ static bool killPid(int pid, [ProcessSignal signal = ProcessSignal.sigterm]) {
+ if (signal is! ProcessSignal) {
+ throw new ArgumentError("Argument 'signal' must be a ProcessSignal");
+ }
+ return _ProcessUtils._killPid(pid, signal._signalNumber);
+ }
+}
+
+List<_SignalController> _signalControllers = new List(32);
+
+class _SignalController {
+ final ProcessSignal signal;
+
+ StreamController<ProcessSignal> _controller;
+ var _id;
+
+ _SignalController(this.signal) {
+ _controller = new StreamController<ProcessSignal>.broadcast(
+ onListen: _listen, onCancel: _cancel);
+ }
+
+ Stream<ProcessSignal> get stream => _controller.stream;
+
+ void _listen() {
+ var id = _setSignalHandler(signal._signalNumber);
+ if (id is! int) {
+ _controller
+ .addError(new SignalException("Failed to listen for $signal", id));
+ return;
+ }
+ _id = id;
+ var socket = new _RawSocket(new _NativeSocket.watchSignal(id));
+ socket.listen((event) {
+ if (event == RawSocketEvent.read) {
+ var bytes = socket.read();
+ for (int i = 0; i < bytes.length; i++) {
+ _controller.add(signal);
+ }
+ }
+ });
+ }
+
+ void _cancel() {
+ if (_id != null) {
+ _clearSignalHandler(signal._signalNumber);
+ _id = null;
+ }
+ }
+
+ static _setSignalHandler(int signal) native "Process_SetSignalHandler";
+ static int _clearSignalHandler(int signal)
+ native "Process_ClearSignalHandler";
+}
+
+@pragma("vm:entry-point", "call")
+Function _getWatchSignalInternal() => _ProcessUtils._watchSignalInternal;
+
+@patch
+class _ProcessUtils {
+ @patch
+ static void _exit(int status) native "Process_Exit";
+ @patch
+ static void _setExitCode(int status) native "Process_SetExitCode";
+ @patch
+ static int _getExitCode() native "Process_GetExitCode";
+ @patch
+ static void _sleep(int millis) native "Process_Sleep";
+ @patch
+ static int _pid(Process process) native "Process_Pid";
+ static bool _killPid(int pid, int signal) native "Process_KillPid";
+ @patch
+ static Stream<ProcessSignal> _watchSignal(ProcessSignal signal) {
+ if (signal != ProcessSignal.sighup &&
+ signal != ProcessSignal.sigint &&
+ signal != ProcessSignal.sigterm &&
+ (Platform.isWindows ||
+ (signal != ProcessSignal.sigusr1 &&
+ signal != ProcessSignal.sigusr2 &&
+ signal != ProcessSignal.sigwinch))) {
+ throw new SignalException(
+ "Listening for signal $signal is not supported");
+ }
+ return _watchSignalInternal(signal);
+ }
+
+ static Stream<ProcessSignal> _watchSignalInternal(ProcessSignal signal) {
+ if (_signalControllers[signal._signalNumber] == null) {
+ _signalControllers[signal._signalNumber] = new _SignalController(signal);
+ }
+ return _signalControllers[signal._signalNumber].stream;
+ }
+}
+
+@patch
+class ProcessInfo {
+ @patch
+ static int get maxRss {
+ var result = _maxRss();
+ if (result is OSError) {
+ throw result;
+ }
+ return result;
+ }
+
+ @patch
+ static int get currentRss {
+ var result = _currentRss();
+ if (result is OSError) {
+ throw result;
+ }
+ return result;
+ }
+
+ static _maxRss() native "ProcessInfo_MaxRSS";
+ static _currentRss() native "ProcessInfo_CurrentRSS";
+}
+
+@pragma("vm:entry-point")
+class _ProcessStartStatus {
+ @pragma("vm:entry-point", "set")
+ int _errorCode; // Set to OS error code if process start failed.
+ @pragma("vm:entry-point", "set")
+ String _errorMessage; // Set to OS error message if process start failed.
+}
+
+// The NativeFieldWrapperClass1 can not be used with a mixin, due to missing
+// implicit constructor.
+class _ProcessImplNativeWrapper extends NativeFieldWrapperClass1 {}
+
+class _ProcessImpl extends _ProcessImplNativeWrapper implements Process {
+ _ProcessResourceInfo _resourceInfo;
+ static bool connectedResourceHandler = false;
+
+ _ProcessImpl(
+ String path,
+ List<String> arguments,
+ this._workingDirectory,
+ Map<String, String> environment,
+ bool includeParentEnvironment,
+ bool runInShell,
+ ProcessStartMode mode)
+ : super() {
+ if (!connectedResourceHandler) {
+ registerExtension(
+ 'ext.dart.io.getProcesses', _ProcessResourceInfo.getStartedProcesses);
+ registerExtension('ext.dart.io.getProcessById',
+ _ProcessResourceInfo.getProcessInfoMapById);
+ connectedResourceHandler = true;
+ }
+
+ if (runInShell) {
+ arguments = _getShellArguments(path, arguments);
+ path = _getShellCommand();
+ }
+
+ if (path is! String) {
+ throw new ArgumentError("Path is not a String: $path");
+ }
+
+ if (Platform.isWindows && path.contains(' ') && !path.contains('"')) {
+ // Escape paths that may contain spaces
+ // Bug: https://github.com/dart-lang/sdk/issues/37751
+ _path = '"$path"';
+ } else {
+ _path = path;
+ }
+
+ if (arguments is! List) {
+ throw new ArgumentError("Arguments is not a List: $arguments");
+ }
+ int len = arguments.length;
+ _arguments = new List<String>(len);
+ for (int i = 0; i < len; i++) {
+ var arg = arguments[i];
+ if (arg is! String) {
+ throw new ArgumentError("Non-string argument: $arg");
+ }
+ _arguments[i] = arguments[i];
+ if (Platform.isWindows) {
+ _arguments[i] = _windowsArgumentEscape(_arguments[i]);
+ }
+ }
+
+ if (_workingDirectory != null && _workingDirectory is! String) {
+ throw new ArgumentError(
+ "WorkingDirectory is not a String: $_workingDirectory");
+ }
+
+ _environment = [];
+ // Ensure that we have a non-null environment.
+ environment = (environment == null) ? (const {}) : environment;
+ if (environment is! Map) {
+ throw new ArgumentError("Environment is not a map: $environment");
+ }
+ environment.forEach((key, value) {
+ if (key is! String || value is! String) {
+ throw new ArgumentError(
+ "Environment key or value is not a string: ($key, $value)");
+ }
+ _environment.add('$key=$value');
+ });
+ if (includeParentEnvironment) {
+ Platform.environment.forEach((key, value) {
+ assert(key is String);
+ assert(value is String);
+ // Do not override keys already set as part of environment.
+ if (!environment.containsKey(key)) {
+ _environment.add('$key=$value');
+ }
+ });
+ }
+
+ if (mode is! ProcessStartMode) {
+ throw new ArgumentError("Mode is not a ProcessStartMode: $mode");
+ }
+ _mode = mode;
+
+ if (_modeHasStdio(mode)) {
+ // stdin going to process.
+ _stdin = new _StdSink(new _Socket._writePipe().._owner = this);
+ // stdout coming from process.
+ _stdout = new _StdStream(new _Socket._readPipe().._owner = this);
+ // stderr coming from process.
+ _stderr = new _StdStream(new _Socket._readPipe().._owner = this);
+ }
+ if (_modeIsAttached(mode)) {
+ _exitHandler = new _Socket._readPipe();
+ }
+ _ended = false;
+ _started = false;
+ }
+
+ _NativeSocket get _stdinNativeSocket =>
+ (_stdin._sink as _Socket)._nativeSocket;
+ _NativeSocket get _stdoutNativeSocket =>
+ (_stdout._stream as _Socket)._nativeSocket;
+ _NativeSocket get _stderrNativeSocket =>
+ (_stderr._stream as _Socket)._nativeSocket;
+
+ static bool _modeIsAttached(ProcessStartMode mode) {
+ return (mode == ProcessStartMode.normal) ||
+ (mode == ProcessStartMode.inheritStdio);
+ }
+
+ static bool _modeHasStdio(ProcessStartMode mode) {
+ return (mode == ProcessStartMode.normal) ||
+ (mode == ProcessStartMode.detachedWithStdio);
+ }
+
+ static String _getShellCommand() {
+ if (Platform.isWindows) {
+ return 'cmd.exe';
+ }
+ return '/bin/sh';
+ }
+
+ static List<String> _getShellArguments(
+ String executable, List<String> arguments) {
+ List<String> shellArguments = [];
+ if (Platform.isWindows) {
+ shellArguments.add('/c');
+ shellArguments.add(executable);
+ for (var arg in arguments) {
+ shellArguments.add(arg);
+ }
+ } else {
+ var commandLine = new StringBuffer();
+ executable = executable.replaceAll("'", "'\"'\"'");
+ commandLine.write("'$executable'");
+ shellArguments.add("-c");
+ for (var arg in arguments) {
+ arg = arg.replaceAll("'", "'\"'\"'");
+ commandLine.write(" '$arg'");
+ }
+ shellArguments.add(commandLine.toString());
+ }
+ return shellArguments;
+ }
+
+ String _windowsArgumentEscape(String argument) {
+ var result = argument;
+ if (argument.contains('\t') ||
+ argument.contains(' ') ||
+ argument.contains('"')) {
+ // Produce something that the C runtime on Windows will parse
+ // back as this string.
+
+ // Replace any number of '\' followed by '"' with
+ // twice as many '\' followed by '\"'.
+ var backslash = '\\'.codeUnitAt(0);
+ var sb = new StringBuffer();
+ var nextPos = 0;
+ var quotePos = argument.indexOf('"', nextPos);
+ while (quotePos != -1) {
+ var numBackslash = 0;
+ var pos = quotePos - 1;
+ while (pos >= 0 && argument.codeUnitAt(pos) == backslash) {
+ numBackslash++;
+ pos--;
+ }
+ sb.write(argument.substring(nextPos, quotePos - numBackslash));
+ for (var i = 0; i < numBackslash; i++) {
+ sb.write(r'\\');
+ }
+ sb.write(r'\"');
+ nextPos = quotePos + 1;
+ quotePos = argument.indexOf('"', nextPos);
+ }
+ sb.write(argument.substring(nextPos, argument.length));
+ result = sb.toString();
+
+ // Add '"' at the beginning and end and replace all '\' at
+ // the end with two '\'.
+ sb = new StringBuffer('"');
+ sb.write(result);
+ nextPos = argument.length - 1;
+ while (argument.codeUnitAt(nextPos) == backslash) {
+ sb.write('\\');
+ nextPos--;
+ }
+ sb.write('"');
+ result = sb.toString();
+ }
+
+ return result;
+ }
+
+ int _intFromBytes(List<int> bytes, int offset) {
+ return (bytes[offset] +
+ (bytes[offset + 1] << 8) +
+ (bytes[offset + 2] << 16) +
+ (bytes[offset + 3] << 24));
+ }
+
+ Future<Process> _start() {
+ var completer = new Completer<Process>();
+ if (_modeIsAttached(_mode)) {
+ _exitCode = new Completer<int>();
+ }
+ // TODO(ager): Make the actual process starting really async instead of
+ // simulating it with a timer.
+ Timer.run(() {
+ var status = new _ProcessStartStatus();
+ bool success = _startNative(
+ _Namespace._namespace,
+ _path,
+ _arguments,
+ _workingDirectory,
+ _environment,
+ _mode._mode,
+ _modeHasStdio(_mode) ? _stdinNativeSocket : null,
+ _modeHasStdio(_mode) ? _stdoutNativeSocket : null,
+ _modeHasStdio(_mode) ? _stderrNativeSocket : null,
+ _modeIsAttached(_mode) ? _exitHandler._nativeSocket : null,
+ status);
+ if (!success) {
+ completer.completeError(new ProcessException(
+ _path, _arguments, status._errorMessage, status._errorCode));
+ return;
+ }
+
+ _started = true;
+ _resourceInfo = new _ProcessResourceInfo(this);
+
+ // Setup an exit handler to handle internal cleanup and possible
+ // callback when a process terminates.
+ if (_modeIsAttached(_mode)) {
+ int exitDataRead = 0;
+ final int EXIT_DATA_SIZE = 8;
+ List<int> exitDataBuffer = new List<int>(EXIT_DATA_SIZE);
+ _exitHandler.listen((data) {
+ int exitCode(List<int> ints) {
+ var code = _intFromBytes(ints, 0);
+ var negative = _intFromBytes(ints, 4);
+ assert(negative == 0 || negative == 1);
+ return (negative == 0) ? code : -code;
+ }
+
+ void handleExit() {
+ _ended = true;
+ _exitCode.complete(exitCode(exitDataBuffer));
+ // Kill stdin, helping hand if the user forgot to do it.
+ if (_modeHasStdio(_mode)) {
+ (_stdin._sink as _Socket).destroy();
+ }
+ _resourceInfo.stopped();
+ }
+
+ exitDataBuffer.setRange(
+ exitDataRead, exitDataRead + data.length, data);
+ exitDataRead += data.length;
+ if (exitDataRead == EXIT_DATA_SIZE) {
+ handleExit();
+ }
+ });
+ }
+
+ completer.complete(this);
+ });
+ return completer.future;
+ }
+
+ ProcessResult _runAndWait(Encoding stdoutEncoding, Encoding stderrEncoding) {
+ var status = new _ProcessStartStatus();
+ _exitCode = new Completer<int>();
+ bool success = _startNative(
+ _Namespace._namespace,
+ _path,
+ _arguments,
+ _workingDirectory,
+ _environment,
+ ProcessStartMode.normal._mode,
+ _stdinNativeSocket,
+ _stdoutNativeSocket,
+ _stderrNativeSocket,
+ _exitHandler._nativeSocket,
+ status);
+ if (!success) {
+ throw new ProcessException(
+ _path, _arguments, status._errorMessage, status._errorCode);
+ }
+
+ _resourceInfo = new _ProcessResourceInfo(this);
+
+ var result = _wait(_stdinNativeSocket, _stdoutNativeSocket,
+ _stderrNativeSocket, _exitHandler._nativeSocket);
+
+ getOutput(output, encoding) {
+ if (encoding == null) return output;
+ return encoding.decode(output);
+ }
+
+ _resourceInfo.stopped();
+
+ return new ProcessResult(
+ result[0],
+ result[1],
+ getOutput(result[2], stdoutEncoding),
+ getOutput(result[3], stderrEncoding));
+ }
+
+ bool _startNative(
+ _Namespace namespace,
+ String path,
+ List<String> arguments,
+ String workingDirectory,
+ List<String> environment,
+ int mode,
+ _NativeSocket stdin,
+ _NativeSocket stdout,
+ _NativeSocket stderr,
+ _NativeSocket exitHandler,
+ _ProcessStartStatus status) native "Process_Start";
+
+ _wait(_NativeSocket stdin, _NativeSocket stdout, _NativeSocket stderr,
+ _NativeSocket exitHandler) native "Process_Wait";
+
+ Stream<List<int>> get stdout {
+ return _stdout;
+ }
+
+ Stream<List<int>> get stderr {
+ return _stderr;
+ }
+
+ IOSink get stdin {
+ return _stdin;
+ }
+
+ Future<int> get exitCode => _exitCode != null ? _exitCode.future : null;
+
+ bool kill([ProcessSignal signal = ProcessSignal.sigterm]) {
+ if (signal is! ProcessSignal) {
+ throw new ArgumentError("Argument 'signal' must be a ProcessSignal");
+ }
+ assert(_started);
+ if (_ended) return false;
+ return _ProcessUtils._killPid(pid, signal._signalNumber);
+ }
+
+ int get pid => _ProcessUtils._pid(this);
+
+ String _path;
+ List<String> _arguments;
+ String _workingDirectory;
+ List<String> _environment;
+ ProcessStartMode _mode;
+ // Private methods of Socket are used by _in, _out, and _err.
+ _StdSink _stdin;
+ _StdStream _stdout;
+ _StdStream _stderr;
+ _Socket _exitHandler;
+ bool _ended;
+ bool _started;
+ Completer<int> _exitCode;
+}
+
+// _NonInteractiveProcess is a wrapper around an interactive process
+// that buffers output so it can be delivered when the process exits.
+// _NonInteractiveProcess is used to implement the Process.run
+// method.
+Future<ProcessResult> _runNonInteractiveProcess(
+ String path,
+ List<String> arguments,
+ String workingDirectory,
+ Map<String, String> environment,
+ bool includeParentEnvironment,
+ bool runInShell,
+ Encoding stdoutEncoding,
+ Encoding stderrEncoding) {
+ // Start the underlying process.
+ return Process.start(path, arguments,
+ workingDirectory: workingDirectory,
+ environment: environment,
+ includeParentEnvironment: includeParentEnvironment,
+ runInShell: runInShell)
+ .then((Process p) {
+ int pid = p.pid;
+
+ // Make sure the process stdin is closed.
+ p.stdin.close();
+
+ // Setup stdout and stderr handling.
+ Future foldStream(Stream<List<int>> stream, Encoding encoding) {
+ if (encoding == null) {
+ return stream
+ .fold(new BytesBuilder(), (builder, data) => builder..add(data))
+ .then((builder) => builder.takeBytes());
+ } else {
+ return stream.transform(encoding.decoder).fold(new StringBuffer(),
+ (buf, data) {
+ buf.write(data);
+ return buf;
+ }).then((sb) => sb.toString());
+ }
+ }
+
+ Future stdout = foldStream(p.stdout, stdoutEncoding);
+ Future stderr = foldStream(p.stderr, stderrEncoding);
+
+ return Future.wait([p.exitCode, stdout, stderr]).then((result) {
+ return new ProcessResult(pid, result[0], result[1], result[2]);
+ });
+ });
+}
+
+ProcessResult _runNonInteractiveProcessSync(
+ String executable,
+ List<String> arguments,
+ String workingDirectory,
+ Map<String, String> environment,
+ bool includeParentEnvironment,
+ bool runInShell,
+ Encoding stdoutEncoding,
+ Encoding stderrEncoding) {
+ var process = new _ProcessImpl(
+ executable,
+ arguments,
+ workingDirectory,
+ environment,
+ includeParentEnvironment,
+ runInShell,
+ ProcessStartMode.normal);
+ return process._runAndWait(stdoutEncoding, stderrEncoding);
+}
diff --git a/sdk_nnbd/lib/_internal/vm/bin/secure_socket_patch.dart b/sdk_nnbd/lib/_internal/vm/bin/secure_socket_patch.dart
new file mode 100644
index 0000000..8969aa4
--- /dev/null
+++ b/sdk_nnbd/lib/_internal/vm/bin/secure_socket_patch.dart
@@ -0,0 +1,253 @@
+// 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.5
+
+// part of "common_patch.dart";
+
+@patch
+class SecureSocket {
+ @patch
+ factory SecureSocket._(RawSecureSocket rawSocket) =>
+ new _SecureSocket(rawSocket);
+}
+
+@patch
+class _SecureFilter {
+ @patch
+ factory _SecureFilter._() => new _SecureFilterImpl._();
+}
+
+@patch
+@pragma("vm:entry-point")
+class X509Certificate {
+ @patch
+ @pragma("vm:entry-point")
+ factory X509Certificate._() => new _X509CertificateImpl._();
+}
+
+class _SecureSocket extends _Socket implements SecureSocket {
+ _RawSecureSocket get _raw => super._raw as _RawSecureSocket;
+
+ _SecureSocket(RawSecureSocket raw) : super(raw);
+
+ void renegotiate(
+ {bool useSessionCache: true,
+ bool requestClientCertificate: false,
+ bool requireClientCertificate: false}) {
+ _raw.renegotiate(
+ useSessionCache: useSessionCache,
+ requestClientCertificate: requestClientCertificate,
+ requireClientCertificate: requireClientCertificate);
+ }
+
+ X509Certificate get peerCertificate {
+ if (_raw == null) {
+ throw new StateError("peerCertificate called on destroyed SecureSocket");
+ }
+ return _raw.peerCertificate;
+ }
+
+ String get selectedProtocol {
+ if (_raw == null) {
+ throw new StateError("selectedProtocol called on destroyed SecureSocket");
+ }
+ return _raw.selectedProtocol;
+ }
+}
+
+/**
+ * _SecureFilterImpl wraps a filter that encrypts and decrypts data travelling
+ * over an encrypted socket. The filter also handles the handshaking
+ * and certificate verification.
+ *
+ * The filter exposes its input and output buffers as Dart objects that
+ * are backed by an external C array of bytes, so that both Dart code and
+ * native code can access the same data.
+ */
+@pragma("vm:entry-point")
+class _SecureFilterImpl extends NativeFieldWrapperClass1
+ implements _SecureFilter {
+ // Performance is improved if a full buffer of plaintext fits
+ // in the encrypted buffer, when encrypted.
+ // SIZE and ENCRYPTED_SIZE are referenced from C++.
+ @pragma("vm:entry-point")
+ static final int SIZE = 8 * 1024;
+ @pragma("vm:entry-point")
+ static final int ENCRYPTED_SIZE = 10 * 1024;
+
+ _SecureFilterImpl._() {
+ buffers = new List<_ExternalBuffer>(_RawSecureSocket.bufferCount);
+ for (int i = 0; i < _RawSecureSocket.bufferCount; ++i) {
+ buffers[i] = new _ExternalBuffer(
+ _RawSecureSocket._isBufferEncrypted(i) ? ENCRYPTED_SIZE : SIZE);
+ }
+ }
+
+ void connect(
+ String hostName,
+ SecurityContext context,
+ bool is_server,
+ bool requestClientCertificate,
+ bool requireClientCertificate,
+ Uint8List protocols) native "SecureSocket_Connect";
+
+ void destroy() {
+ buffers = null;
+ _destroy();
+ }
+
+ void _destroy() native "SecureSocket_Destroy";
+
+ void handshake() native "SecureSocket_Handshake";
+
+ void rehandshake() => throw new UnimplementedError();
+
+ int processBuffer(int bufferIndex) => throw new UnimplementedError();
+
+ String selectedProtocol() native "SecureSocket_GetSelectedProtocol";
+
+ void renegotiate(bool useSessionCache, bool requestClientCertificate,
+ bool requireClientCertificate) native "SecureSocket_Renegotiate";
+
+ void init() native "SecureSocket_Init";
+
+ X509Certificate get peerCertificate native "SecureSocket_PeerCertificate";
+
+ void registerBadCertificateCallback(Function callback)
+ native "SecureSocket_RegisterBadCertificateCallback";
+
+ void registerHandshakeCompleteCallback(Function handshakeCompleteHandler)
+ native "SecureSocket_RegisterHandshakeCompleteCallback";
+
+ // This is a security issue, as it exposes a raw pointer to Dart code.
+ int _pointer() native "SecureSocket_FilterPointer";
+
+ @pragma("vm:entry-point", "get")
+ List<_ExternalBuffer> buffers;
+}
+
+@patch
+class SecurityContext {
+ @patch
+ factory SecurityContext({bool withTrustedRoots: false}) {
+ return new _SecurityContext(withTrustedRoots);
+ }
+
+ @patch
+ static SecurityContext get defaultContext {
+ return _SecurityContext.defaultContext;
+ }
+
+ @patch
+ static bool get alpnSupported => true;
+}
+
+class _SecurityContext extends NativeFieldWrapperClass1
+ implements SecurityContext {
+ _SecurityContext(bool withTrustedRoots) {
+ _createNativeContext();
+ if (withTrustedRoots) {
+ _trustBuiltinRoots();
+ }
+ }
+
+ void _createNativeContext() native "SecurityContext_Allocate";
+
+ static final SecurityContext defaultContext = new _SecurityContext(true);
+
+ void usePrivateKey(String file, {String password}) {
+ List<int> bytes = (new File(file)).readAsBytesSync();
+ usePrivateKeyBytes(bytes, password: password);
+ }
+
+ void usePrivateKeyBytes(List<int> keyBytes, {String password})
+ native "SecurityContext_UsePrivateKeyBytes";
+
+ void setTrustedCertificates(String file, {String password}) {
+ List<int> bytes = (new File(file)).readAsBytesSync();
+ setTrustedCertificatesBytes(bytes, password: password);
+ }
+
+ void setTrustedCertificatesBytes(List<int> certBytes, {String password})
+ native "SecurityContext_SetTrustedCertificatesBytes";
+
+ void useCertificateChain(String file, {String password}) {
+ List<int> bytes = (new File(file)).readAsBytesSync();
+ useCertificateChainBytes(bytes, password: password);
+ }
+
+ void useCertificateChainBytes(List<int> chainBytes, {String password})
+ native "SecurityContext_UseCertificateChainBytes";
+
+ void setClientAuthorities(String file, {String password}) {
+ List<int> bytes = (new File(file)).readAsBytesSync();
+ setClientAuthoritiesBytes(bytes, password: password);
+ }
+
+ void setClientAuthoritiesBytes(List<int> authCertBytes, {String password})
+ native "SecurityContext_SetClientAuthoritiesBytes";
+
+ void setAlpnProtocols(List<String> protocols, bool isServer) {
+ Uint8List encodedProtocols =
+ SecurityContext._protocolsToLengthEncoding(protocols);
+ _setAlpnProtocols(encodedProtocols, isServer);
+ }
+
+ void _setAlpnProtocols(Uint8List protocols, bool isServer)
+ native "SecurityContext_SetAlpnProtocols";
+ void _trustBuiltinRoots() native "SecurityContext_TrustBuiltinRoots";
+}
+
+/**
+ * _X509CertificateImpl wraps an X509 certificate object held by the BoringSSL
+ * library. It exposes the fields of the certificate object.
+ */
+class _X509CertificateImpl extends NativeFieldWrapperClass1
+ implements X509Certificate {
+ // The native field must be set manually on a new object, in native code.
+ // This is done by WrappedX509 in secure_socket.cc.
+ _X509CertificateImpl._();
+
+ Uint8List _cachedDer;
+ Uint8List get _der native "X509_Der";
+ Uint8List get der {
+ if (_cachedDer == null) {
+ _cachedDer = _der;
+ }
+ return _cachedDer;
+ }
+
+ String _cachedPem;
+ String get _pem native "X509_Pem";
+ String get pem {
+ if (_cachedPem == null) {
+ _cachedPem = _pem;
+ }
+ return _cachedPem;
+ }
+
+ Uint8List _cachedSha1;
+ Uint8List get _sha1 native "X509_Sha1";
+ Uint8List get sha1 {
+ if (_cachedSha1 == null) {
+ _cachedSha1 = _sha1;
+ }
+ return _cachedSha1;
+ }
+
+ String get subject native "X509_Subject";
+ String get issuer native "X509_Issuer";
+ DateTime get startValidity {
+ return new DateTime.fromMillisecondsSinceEpoch(_startValidity(),
+ isUtc: true);
+ }
+
+ DateTime get endValidity {
+ return new DateTime.fromMillisecondsSinceEpoch(_endValidity(), isUtc: true);
+ }
+
+ int _startValidity() native "X509_StartValidity";
+ int _endValidity() native "X509_EndValidity";
+}
diff --git a/sdk_nnbd/lib/_internal/vm/bin/socket_patch.dart b/sdk_nnbd/lib/_internal/vm/bin/socket_patch.dart
new file mode 100644
index 0000000..f4136a0
--- /dev/null
+++ b/sdk_nnbd/lib/_internal/vm/bin/socket_patch.dart
@@ -0,0 +1,2041 @@
+// 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
+// BSD-style license that can be found in the LICENSE file.
+
+// @dart = 2.5
+
+// part of "common_patch.dart";
+
+@patch
+class RawServerSocket {
+ @patch
+ static Future<RawServerSocket> bind(address, int port,
+ {int backlog: 0, bool v6Only: false, bool shared: false}) {
+ return _RawServerSocket.bind(address, port, backlog, v6Only, shared);
+ }
+}
+
+@patch
+class RawSocket {
+ @patch
+ static Future<RawSocket> connect(host, int port,
+ {sourceAddress, Duration timeout}) {
+ return _RawSocket.connect(host, port, sourceAddress, timeout);
+ }
+
+ @patch
+ static Future<ConnectionTask<RawSocket>> startConnect(host, int port,
+ {sourceAddress}) {
+ return _RawSocket.startConnect(host, port, sourceAddress);
+ }
+}
+
+@patch
+class RawSocketOption {
+ static final List<int> _optionsCache =
+ List<int>(_RawSocketOptions.values.length);
+
+ @patch
+ static int _getOptionValue(int key) {
+ if (key > _RawSocketOptions.values.length) {
+ throw ArgumentError.value(key, 'key');
+ }
+ _optionsCache[key] ??= _getNativeOptionValue(key);
+ return _optionsCache[key];
+ }
+
+ static int _getNativeOptionValue(int key)
+ native "RawSocketOption_GetOptionValue";
+}
+
+@patch
+class InternetAddress {
+ @patch
+ static InternetAddress get LOOPBACK_IP_V4 {
+ return _InternetAddress.loopbackIPv4;
+ }
+
+ @patch
+ static InternetAddress get LOOPBACK_IP_V6 {
+ return _InternetAddress.loopbackIPv6;
+ }
+
+ @patch
+ static InternetAddress get ANY_IP_V4 {
+ return _InternetAddress.anyIPv4;
+ }
+
+ @patch
+ static InternetAddress get ANY_IP_V6 {
+ return _InternetAddress.anyIPv6;
+ }
+
+ @patch
+ factory InternetAddress(String address) {
+ return new _InternetAddress.parse(address);
+ }
+
+ @patch
+ static Future<List<InternetAddress>> lookup(String host,
+ {InternetAddressType type: InternetAddressType.any}) {
+ return _NativeSocket.lookup(host, type: type);
+ }
+
+ @patch
+ static InternetAddress _cloneWithNewHost(
+ InternetAddress address, String host) {
+ return (address as _InternetAddress)._cloneWithNewHost(host);
+ }
+}
+
+@patch
+class NetworkInterface {
+ @patch
+ static bool get listSupported {
+ return _listSupported();
+ }
+
+ @patch
+ static Future<List<NetworkInterface>> list(
+ {bool includeLoopback: false,
+ bool includeLinkLocal: false,
+ InternetAddressType type: InternetAddressType.any}) {
+ return _NativeSocket.listInterfaces(
+ includeLoopback: includeLoopback,
+ includeLinkLocal: includeLinkLocal,
+ type: type);
+ }
+
+ static bool _listSupported() native "NetworkInterface_ListSupported";
+}
+
+void _throwOnBadPort(int port) {
+ if ((port == null) || (port < 0) || (port > 0xFFFF)) {
+ throw new ArgumentError("Invalid port $port");
+ }
+}
+
+void _throwOnBadTtl(int ttl) {
+ if (ttl == null || ttl < 1 || ttl > 255) {
+ throw new ArgumentError('Invalid ttl $ttl');
+ }
+}
+
+class _InternetAddress implements InternetAddress {
+ static const int _addressLoopbackIPv4 = 0;
+ static const int _addressLoopbackIPv6 = 1;
+ static const int _addressAnyIPv4 = 2;
+ static const int _addressAnyIPv6 = 3;
+ static const int _IPv4AddrLength = 4;
+ static const int _IPv6AddrLength = 16;
+
+ static _InternetAddress loopbackIPv4 =
+ new _InternetAddress.fixed(_addressLoopbackIPv4);
+ static _InternetAddress loopbackIPv6 =
+ new _InternetAddress.fixed(_addressLoopbackIPv6);
+ static _InternetAddress anyIPv4 = new _InternetAddress.fixed(_addressAnyIPv4);
+ static _InternetAddress anyIPv6 = new _InternetAddress.fixed(_addressAnyIPv6);
+
+ final String address;
+ final String _host;
+ final Uint8List _in_addr;
+ final int _scope_id;
+
+ InternetAddressType get type => _in_addr.length == _IPv4AddrLength
+ ? InternetAddressType.IPv4
+ : InternetAddressType.IPv6;
+
+ String get host => _host != null ? _host : address;
+
+ Uint8List get rawAddress => new Uint8List.fromList(_in_addr);
+
+ bool get isLoopback {
+ switch (type) {
+ case InternetAddressType.IPv4:
+ return _in_addr[0] == 127;
+
+ case InternetAddressType.IPv6:
+ for (int i = 0; i < _IPv6AddrLength - 1; i++) {
+ if (_in_addr[i] != 0) return false;
+ }
+ return _in_addr[_IPv6AddrLength - 1] == 1;
+ }
+ }
+
+ bool get isLinkLocal {
+ switch (type) {
+ case InternetAddressType.IPv4:
+ // Checking for 169.254.0.0/16.
+ return _in_addr[0] == 169 && _in_addr[1] == 254;
+
+ case InternetAddressType.IPv6:
+ // Checking for fe80::/10.
+ return _in_addr[0] == 0xFE && (_in_addr[1] & 0xB0) == 0x80;
+ }
+ }
+
+ bool get isMulticast {
+ switch (type) {
+ case InternetAddressType.IPv4:
+ // Checking for 224.0.0.0 through 239.255.255.255.
+ return _in_addr[0] >= 224 && _in_addr[0] < 240;
+
+ case InternetAddressType.IPv6:
+ // Checking for ff00::/8.
+ return _in_addr[0] == 0xFF;
+ }
+ }
+
+ Future<InternetAddress> reverse() => _NativeSocket.reverseLookup(this);
+
+ _InternetAddress(this.address, this._host, this._in_addr,
+ [this._scope_id = 0]);
+
+ factory _InternetAddress.parse(String address) {
+ if (address is! String) {
+ throw new ArgumentError("Invalid internet address $address");
+ }
+ var in_addr = _parse(address);
+ if (in_addr == null) {
+ throw new ArgumentError("Invalid internet address $address");
+ }
+ return new _InternetAddress(address, null, in_addr);
+ }
+
+ factory _InternetAddress.fixed(int id) {
+ switch (id) {
+ case _addressLoopbackIPv4:
+ var in_addr = new Uint8List(_IPv4AddrLength);
+ in_addr[0] = 127;
+ in_addr[_IPv4AddrLength - 1] = 1;
+ return new _InternetAddress("127.0.0.1", null, in_addr);
+ case _addressLoopbackIPv6:
+ var in_addr = new Uint8List(_IPv6AddrLength);
+ in_addr[_IPv6AddrLength - 1] = 1;
+ return new _InternetAddress("::1", null, in_addr);
+ case _addressAnyIPv4:
+ var in_addr = new Uint8List(_IPv4AddrLength);
+ return new _InternetAddress("0.0.0.0", "0.0.0.0", in_addr);
+ case _addressAnyIPv6:
+ var in_addr = new Uint8List(_IPv6AddrLength);
+ return new _InternetAddress("::", "::", in_addr);
+ default:
+ assert(false);
+ throw new ArgumentError();
+ }
+ }
+
+ // Create a clone of this _InternetAddress replacing the host.
+ _InternetAddress _cloneWithNewHost(String host) {
+ return new _InternetAddress(
+ address, host, new Uint8List.fromList(_in_addr));
+ }
+
+ bool operator ==(other) {
+ if (!(other is _InternetAddress)) return false;
+ if (other.type != type) return false;
+ bool equals = true;
+ for (int i = 0; i < _in_addr.length && equals; i++) {
+ equals = other._in_addr[i] == _in_addr[i];
+ }
+ return equals;
+ }
+
+ int get hashCode {
+ int result = 1;
+ for (int i = 0; i < _in_addr.length; i++) {
+ result = (result * 31 + _in_addr[i]) & 0x3FFFFFFF;
+ }
+ return result;
+ }
+
+ String toString() {
+ return "InternetAddress('$address', ${type.name})";
+ }
+
+ static Uint8List _parse(String address) native "InternetAddress_Parse";
+}
+
+class _NetworkInterface implements NetworkInterface {
+ final String name;
+ final int index;
+ final List<InternetAddress> addresses = [];
+
+ _NetworkInterface(this.name, this.index);
+
+ String toString() {
+ return "NetworkInterface('$name', $addresses)";
+ }
+}
+
+// The NativeFieldWrapperClass1 cannot be used with a mixin, due to missing
+// implicit constructor.
+class _NativeSocketNativeWrapper extends NativeFieldWrapperClass1 {}
+
+// The _NativeSocket class encapsulates an OS socket.
+class _NativeSocket extends _NativeSocketNativeWrapper with _ServiceObject {
+ // Bit flags used when communicating between the eventhandler and
+ // dart code. The EVENT flags are used to indicate events of
+ // interest when sending a message from dart code to the
+ // eventhandler. When receiving a message from the eventhandler the
+ // EVENT flags indicate the events that actually happened. The
+ // COMMAND flags are used to send commands from dart to the
+ // eventhandler. COMMAND flags are never received from the
+ // eventhandler. Additional flags are used to communicate other
+ // information.
+ static const int readEvent = 0;
+ static const int writeEvent = 1;
+ static const int errorEvent = 2;
+ static const int closedEvent = 3;
+ static const int destroyedEvent = 4;
+ static const int firstEvent = readEvent;
+ static const int lastEvent = destroyedEvent;
+ static const int eventCount = lastEvent - firstEvent + 1;
+
+ static const int closeCommand = 8;
+ static const int shutdownReadCommand = 9;
+ static const int shutdownWriteCommand = 10;
+ // The lower bits of returnTokenCommand messages contains the number
+ // of tokens returned.
+ static const int returnTokenCommand = 11;
+ static const int setEventMaskCommand = 12;
+ static const int firstCommand = closeCommand;
+ static const int lastCommand = setEventMaskCommand;
+
+ // Type flag send to the eventhandler providing additional
+ // information on the type of the file descriptor.
+ static const int listeningSocket = 16;
+ static const int pipeSocket = 17;
+ static const int typeNormalSocket = 0;
+ static const int typeListeningSocket = 1 << listeningSocket;
+ static const int typePipe = 1 << pipeSocket;
+ static const int typeTypeMask = typeListeningSocket | pipeSocket;
+
+ // Protocol flags.
+ // Keep in sync with SocketType enum in socket.h.
+ static const int tcpSocket = 18;
+ static const int udpSocket = 19;
+ static const int internalSocket = 20;
+ static const int internalSignalSocket = 21;
+ static const int typeTcpSocket = 1 << tcpSocket;
+ static const int typeUdpSocket = 1 << udpSocket;
+ static const int typeInternalSocket = 1 << internalSocket;
+ static const int typeInternalSignalSocket = 1 << internalSignalSocket;
+ static const int typeProtocolMask = typeTcpSocket |
+ typeUdpSocket |
+ typeInternalSocket |
+ typeInternalSignalSocket;
+
+ // Native port messages.
+ static const hostNameLookupMessage = 0;
+ static const listInterfacesMessage = 1;
+ static const reverseLookupMessage = 2;
+
+ // Protocol flags.
+ static const int protocolIPv4 = 1 << 0;
+ static const int protocolIPv6 = 1 << 1;
+
+ static const int normalTokenBatchSize = 8;
+ static const int listeningTokenBatchSize = 2;
+
+ static const Duration _retryDuration = const Duration(milliseconds: 250);
+ static const Duration _retryDurationLoopback =
+ const Duration(milliseconds: 25);
+
+ // Socket close state
+ bool isClosed = false;
+ bool isClosing = false;
+ bool isClosedRead = false;
+ bool closedReadEventSent = false;
+ bool isClosedWrite = false;
+ Completer closeCompleter = new Completer.sync();
+
+ // Handlers and receive port for socket events from the event handler.
+ final List eventHandlers = new List(eventCount + 1);
+ RawReceivePort eventPort;
+ bool flagsSent = false;
+
+ // The type flags for this socket.
+ final int typeFlags;
+
+ // Holds the port of the socket, 0 if not known.
+ int localPort = 0;
+
+ // Holds the address used to connect or bind the socket.
+ InternetAddress localAddress;
+
+ int available = 0;
+
+ int tokens = 0;
+
+ bool sendReadEvents = false;
+ bool readEventIssued = false;
+
+ bool sendWriteEvents = false;
+ bool writeEventIssued = false;
+ bool writeAvailable = false;
+
+ static bool connectedResourceHandler = false;
+ _ReadWriteResourceInfo resourceInfo;
+
+ // The owner object is the object that the Socket is being used by, e.g.
+ // a HttpServer, a WebSocket connection, a process pipe, etc.
+ Object owner;
+
+ static Future<List<InternetAddress>> lookup(String host,
+ {InternetAddressType type: InternetAddressType.any}) {
+ return _IOService._dispatch(_IOService.socketLookup, [host, type._value])
+ .then((response) {
+ if (isErrorResponse(response)) {
+ throw createError(response, "Failed host lookup: '$host'");
+ } else {
+ return response.skip(1).map<InternetAddress>((result) {
+ var type = new InternetAddressType._from(result[0]);
+ return new _InternetAddress(result[1], host, result[2], result[3]);
+ }).toList();
+ }
+ });
+ }
+
+ static Future<InternetAddress> reverseLookup(InternetAddress addr) {
+ return _IOService._dispatch(_IOService.socketReverseLookup,
+ [(addr as _InternetAddress)._in_addr]).then((response) {
+ if (isErrorResponse(response)) {
+ throw createError(response, "Failed reverse host lookup", addr);
+ } else {
+ return (addr as _InternetAddress)._cloneWithNewHost(response);
+ }
+ });
+ }
+
+ static Future<List<NetworkInterface>> listInterfaces(
+ {bool includeLoopback: false,
+ bool includeLinkLocal: false,
+ InternetAddressType type: InternetAddressType.any}) {
+ return _IOService._dispatch(_IOService.socketListInterfaces, [type._value])
+ .then((response) {
+ if (isErrorResponse(response)) {
+ throw createError(response, "Failed listing interfaces");
+ } else {
+ var map = response.skip(1).fold(new Map<String, NetworkInterface>(),
+ (map, result) {
+ var type = new InternetAddressType._from(result[0]);
+ var name = result[3];
+ var index = result[4];
+ var address = new _InternetAddress(result[1], "", result[2]);
+ if (!includeLinkLocal && address.isLinkLocal) return map;
+ if (!includeLoopback && address.isLoopback) return map;
+ map.putIfAbsent(name, () => new _NetworkInterface(name, index));
+ map[name].addresses.add(address);
+ return map;
+ });
+ return map.values.toList();
+ }
+ });
+ }
+
+ static String escapeLinkLocalAddress(String host) {
+ // if the host contains escape, host is an IPv6 address with scope ID.
+ // Remove '25' before feeding into native calls.
+ int index = host.indexOf('%');
+ if (index >= 0) {
+ if (!checkLinkLocalAddress(host)) {
+ // The only well defined usage is link-local address. Checks Section 4 of https://tools.ietf.org/html/rfc6874.
+ // If it is not a valid link-local address and contains escape character, throw an exception.
+ throw new FormatException(
+ '${host} is not a valid link-local address but contains %. Scope id should be used as part of link-local address.',
+ host,
+ index);
+ }
+ if (host.startsWith("25", index + 1)) {
+ // Remove '25' after '%' if present
+ host = host.replaceRange(index + 1, index + 3, '');
+ }
+ }
+ return host;
+ }
+
+ static bool checkLinkLocalAddress(String host) {
+ // The shortest possible link-local address is [fe80::1]
+ if (host.length < 7) return false;
+ var char = host[2];
+ return host.startsWith('fe') &&
+ (char == '8' || char == '9' || char == 'a' || char == 'b');
+ }
+
+ static Future<ConnectionTask<_NativeSocket>> startConnect(
+ host, int port, sourceAddress) {
+ if (host is String) {
+ host = escapeLinkLocalAddress(host);
+ }
+ _throwOnBadPort(port);
+ if (sourceAddress != null && sourceAddress is! _InternetAddress) {
+ if (sourceAddress is String) {
+ sourceAddress = new InternetAddress(sourceAddress);
+ }
+ }
+ return new Future.value(host).then((host) {
+ if (host is _InternetAddress) return [host];
+ return lookup(host).then((addresses) {
+ if (addresses.isEmpty) {
+ throw createError(null, "Failed host lookup: '$host'");
+ }
+ return addresses;
+ });
+ }).then((addresses) {
+ var completer = new Completer<_NativeSocket>();
+ var it = (addresses as List<InternetAddress>).iterator;
+ var error = null;
+ var connecting = new HashMap();
+
+ void connectNext() {
+ if (!it.moveNext()) {
+ if (connecting.isEmpty) {
+ assert(error != null);
+ completer.completeError(error);
+ }
+ return;
+ }
+ final _InternetAddress address = it.current;
+ var socket = new _NativeSocket.normal();
+ socket.localAddress = address;
+ var result;
+ if (sourceAddress == null) {
+ result = socket.nativeCreateConnect(
+ address._in_addr, port, address._scope_id);
+ } else {
+ assert(sourceAddress is _InternetAddress);
+ result = socket.nativeCreateBindConnect(address._in_addr, port,
+ sourceAddress._in_addr, address._scope_id);
+ }
+ if (result is OSError) {
+ // Keep first error, if present.
+ if (error == null) {
+ int errorCode = result.errorCode;
+ if (sourceAddress != null &&
+ errorCode != null &&
+ socket.isBindError(errorCode)) {
+ error = createError(result, "Bind failed", sourceAddress);
+ } else {
+ error = createError(result, "Connection failed", address, port);
+ }
+ }
+ connectNext();
+ } else {
+ // Query the local port for error messages.
+ try {
+ socket.port;
+ } catch (e) {
+ if (error == null) {
+ error = createError(e, "Connection failed", address, port);
+ }
+ connectNext();
+ }
+ // Set up timer for when we should retry the next address
+ // (if any).
+ var duration =
+ address.isLoopback ? _retryDurationLoopback : _retryDuration;
+ var timer = new Timer(duration, connectNext);
+ setupResourceInfo(socket);
+
+ connecting[socket] = timer;
+ // Setup handlers for receiving the first write event which
+ // indicate that the socket is fully connected.
+ socket.setHandlers(write: () {
+ timer.cancel();
+ connecting.remove(socket);
+ // From 'man 2 connect':
+ // After select(2) indicates writability, use getsockopt(2) to read
+ // the SO_ERROR option at level SOL_SOCKET to determine whether
+ // connect() completed successfully (SO_ERROR is zero) or
+ // unsuccessfully.
+ OSError osError = socket.nativeGetError();
+ if (osError.errorCode != 0) {
+ socket.close();
+ if (error == null) error = osError;
+ if (connecting.isEmpty) connectNext();
+ return;
+ }
+ socket.setListening(read: false, write: false);
+ completer.complete(socket);
+ connecting.forEach((s, t) {
+ t.cancel();
+ s.close();
+ s.setHandlers();
+ s.setListening(read: false, write: false);
+ });
+ connecting.clear();
+ }, error: (e, st) {
+ timer.cancel();
+ socket.close();
+ // Keep first error, if present.
+ if (error == null) error = e;
+ connecting.remove(socket);
+ if (connecting.isEmpty) connectNext();
+ });
+ socket.setListening(read: false, write: true);
+ }
+ }
+
+ void onCancel() {
+ connecting.forEach((s, t) {
+ t.cancel();
+ s.close();
+ s.setHandlers();
+ s.setListening(read: false, write: false);
+ if (error == null) {
+ error = createError(null,
+ "Connection attempt cancelled, host: ${host}, port: ${port}");
+ }
+ });
+ connecting.clear();
+ if (!completer.isCompleted) {
+ completer.completeError(error);
+ }
+ }
+
+ connectNext();
+ return new ConnectionTask<_NativeSocket>._(
+ socket: completer.future, onCancel: onCancel);
+ });
+ }
+
+ static Future<_NativeSocket> connect(
+ host, int port, sourceAddress, Duration timeout) {
+ return startConnect(host, port, sourceAddress)
+ .then((ConnectionTask<_NativeSocket> task) {
+ Future<_NativeSocket> socketFuture = task.socket;
+ if (timeout != null) {
+ socketFuture = socketFuture.timeout(timeout, onTimeout: () {
+ task.cancel();
+ throw createError(
+ null, "Connection timed out, host: ${host}, port: ${port}");
+ });
+ }
+ return socketFuture;
+ });
+ }
+
+ static Future<_InternetAddress> _resolveHost(host) async {
+ if (host is _InternetAddress) {
+ return host;
+ } else {
+ final list = await lookup(host);
+ if (list.isEmpty) {
+ throw createError(null, "Failed host lookup: '$host'");
+ }
+ return list.first as _InternetAddress;
+ }
+ }
+
+ static Future<_NativeSocket> bind(
+ host, int port, int backlog, bool v6Only, bool shared) async {
+ _throwOnBadPort(port);
+ if (host is String) {
+ host = escapeLinkLocalAddress(host);
+ }
+ final address = await _resolveHost(host);
+
+ var socket = new _NativeSocket.listen();
+ socket.localAddress = address;
+ var result = socket.nativeCreateBindListen(
+ address._in_addr, port, backlog, v6Only, shared, address._scope_id);
+ if (result is OSError) {
+ throw new SocketException("Failed to create server socket",
+ osError: result, address: address, port: port);
+ }
+ if (port != 0) socket.localPort = port;
+ setupResourceInfo(socket);
+ socket.connectToEventHandler();
+ return socket;
+ }
+
+ static void setupResourceInfo(_NativeSocket socket) {
+ socket.resourceInfo = new _SocketResourceInfo(socket);
+ }
+
+ static Future<_NativeSocket> bindDatagram(
+ host, int port, bool reuseAddress, bool reusePort, int ttl) async {
+ _throwOnBadPort(port);
+ _throwOnBadTtl(ttl);
+
+ final address = await _resolveHost(host);
+
+ var socket = new _NativeSocket.datagram(address);
+ var result = socket.nativeCreateBindDatagram(
+ address._in_addr, port, reuseAddress, reusePort, ttl);
+ if (result is OSError) {
+ throw new SocketException("Failed to create datagram socket",
+ osError: result, address: address, port: port);
+ }
+ if (port != 0) socket.localPort = port;
+ setupResourceInfo(socket);
+ return socket;
+ }
+
+ _NativeSocket.datagram(this.localAddress)
+ : typeFlags = typeNormalSocket | typeUdpSocket;
+
+ _NativeSocket.normal() : typeFlags = typeNormalSocket | typeTcpSocket;
+
+ _NativeSocket.listen() : typeFlags = typeListeningSocket | typeTcpSocket {
+ isClosedWrite = true;
+ }
+
+ _NativeSocket.pipe() : typeFlags = typePipe;
+
+ _NativeSocket._watchCommon(int id, int type)
+ : typeFlags = typeNormalSocket | type {
+ isClosedWrite = true;
+ nativeSetSocketId(id, typeFlags);
+ }
+
+ _NativeSocket.watchSignal(int id)
+ : this._watchCommon(id, typeInternalSignalSocket);
+
+ _NativeSocket.watch(int id) : this._watchCommon(id, typeInternalSocket);
+
+ bool get isListening => (typeFlags & typeListeningSocket) != 0;
+ bool get isPipe => (typeFlags & typePipe) != 0;
+ bool get isInternal => (typeFlags & typeInternalSocket) != 0;
+ bool get isInternalSignal => (typeFlags & typeInternalSignalSocket) != 0;
+ bool get isTcp => (typeFlags & typeTcpSocket) != 0;
+ bool get isUdp => (typeFlags & typeUdpSocket) != 0;
+
+ Map _toJSON(bool ref) => throw new UnimplementedError();
+ String get _serviceTypePath => throw new UnimplementedError();
+ String get _serviceTypeName => throw new UnimplementedError();
+
+ Uint8List read(int len) {
+ if (len != null && len <= 0) {
+ throw new ArgumentError("Illegal length $len");
+ }
+ if (isClosing || isClosed) return null;
+ len = min(available, len == null ? available : len);
+ if (len == 0) return null;
+ var result = nativeRead(len);
+ if (result is OSError) {
+ reportError(result, StackTrace.current, "Read failed");
+ return null;
+ }
+ if (result != null) {
+ available -= result.length;
+ // TODO(ricow): Remove when we track internal and pipe uses.
+ assert(resourceInfo != null || isPipe || isInternal || isInternalSignal);
+ if (resourceInfo != null) {
+ resourceInfo.totalRead += result.length;
+ }
+ }
+ // TODO(ricow): Remove when we track internal and pipe uses.
+ assert(resourceInfo != null || isPipe || isInternal || isInternalSignal);
+ if (resourceInfo != null) {
+ resourceInfo.didRead();
+ }
+ return result;
+ }
+
+ Datagram receive() {
+ if (isClosing || isClosed) return null;
+ var result = nativeRecvFrom();
+ if (result is OSError) {
+ reportError(result, StackTrace.current, "Receive failed");
+ return null;
+ }
+ if (result != null) {
+ // Read the next available. Available is only for the next datagram, not
+ // the sum of all datagrams pending, so we need to call after each
+ // receive. If available becomes > 0, the _NativeSocket will continue to
+ // emit read events.
+ available = nativeAvailable();
+ // TODO(ricow): Remove when we track internal and pipe uses.
+ assert(resourceInfo != null || isPipe || isInternal || isInternalSignal);
+ if (resourceInfo != null) {
+ resourceInfo.totalRead += result.data.length;
+ }
+ }
+ // TODO(ricow): Remove when we track internal and pipe uses.
+ assert(resourceInfo != null || isPipe || isInternal || isInternalSignal);
+ if (resourceInfo != null) {
+ resourceInfo.didRead();
+ }
+ return result;
+ }
+
+ int write(List<int> buffer, int offset, int bytes) {
+ if (buffer is! List) throw new ArgumentError();
+ if (offset == null) offset = 0;
+ if (bytes == null) {
+ if (offset > buffer.length) {
+ throw new RangeError.value(offset);
+ }
+ bytes = buffer.length - offset;
+ }
+ if (offset < 0) throw new RangeError.value(offset);
+ if (bytes < 0) throw new RangeError.value(bytes);
+ if ((offset + bytes) > buffer.length) {
+ throw new RangeError.value(offset + bytes);
+ }
+ if (offset is! int || bytes is! int) {
+ throw new ArgumentError("Invalid arguments to write on Socket");
+ }
+ if (isClosing || isClosed) return 0;
+ if (bytes == 0) return 0;
+ _BufferAndStart bufferAndStart =
+ _ensureFastAndSerializableByteData(buffer, offset, offset + bytes);
+ var result =
+ nativeWrite(bufferAndStart.buffer, bufferAndStart.start, bytes);
+ if (result is OSError) {
+ OSError osError = result;
+ StackTrace st = StackTrace.current;
+ scheduleMicrotask(() => reportError(osError, st, "Write failed"));
+ result = 0;
+ }
+ // The result may be negative, if we forced a short write for testing
+ // purpose. In such case, don't mark writeAvailable as false, as we don't
+ // know if we'll receive an event. It's better to just retry.
+ if (result >= 0 && result < bytes) {
+ writeAvailable = false;
+ }
+ // Negate the result, as stated above.
+ if (result < 0) result = -result;
+ // TODO(ricow): Remove when we track internal and pipe uses.
+ assert(resourceInfo != null || isPipe || isInternal || isInternalSignal);
+ if (resourceInfo != null) {
+ resourceInfo.addWrite(result);
+ }
+ return result;
+ }
+
+ int send(List<int> buffer, int offset, int bytes, InternetAddress address,
+ int port) {
+ _throwOnBadPort(port);
+ if (isClosing || isClosed) return 0;
+ _BufferAndStart bufferAndStart =
+ _ensureFastAndSerializableByteData(buffer, offset, bytes);
+ var result = nativeSendTo(bufferAndStart.buffer, bufferAndStart.start,
+ bytes, (address as _InternetAddress)._in_addr, port);
+ if (result is OSError) {
+ OSError osError = result;
+ StackTrace st = StackTrace.current;
+ scheduleMicrotask(() => reportError(osError, st, "Send failed"));
+ result = 0;
+ }
+ // TODO(ricow): Remove when we track internal and pipe uses.
+ assert(resourceInfo != null || isPipe || isInternal || isInternalSignal);
+ if (resourceInfo != null) {
+ resourceInfo.addWrite(result);
+ }
+ return result;
+ }
+
+ _NativeSocket accept() {
+ // Don't issue accept if we're closing.
+ if (isClosing || isClosed) return null;
+ assert(available > 0);
+ available--;
+ tokens++;
+ returnTokens(listeningTokenBatchSize);
+ var socket = new _NativeSocket.normal();
+ if (nativeAccept(socket) != true) return null;
+ socket.localPort = localPort;
+ socket.localAddress = address;
+ setupResourceInfo(socket);
+ // TODO(ricow): Remove when we track internal and pipe uses.
+ assert(resourceInfo != null || isPipe || isInternal || isInternalSignal);
+ if (resourceInfo != null) {
+ // We track this as read one byte.
+ resourceInfo.addRead(1);
+ }
+ return socket;
+ }
+
+ int get port {
+ if (localPort != 0) return localPort;
+ if (isClosing || isClosed) throw const SocketException.closed();
+ var result = nativeGetPort();
+ if (result is OSError) throw result;
+ return localPort = result;
+ }
+
+ int get remotePort {
+ if (isClosing || isClosed) throw const SocketException.closed();
+ var result = nativeGetRemotePeer();
+ if (result is OSError) throw result;
+ return result[1];
+ }
+
+ InternetAddress get address => localAddress;
+
+ InternetAddress get remoteAddress {
+ if (isClosing || isClosed) throw const SocketException.closed();
+ var result = nativeGetRemotePeer();
+ if (result is OSError) throw result;
+ var addr = result[0];
+ var type = new InternetAddressType._from(addr[0]);
+ return new _InternetAddress(addr[1], null, addr[2]);
+ }
+
+ void issueReadEvent() {
+ if (closedReadEventSent) return;
+ if (readEventIssued) return;
+ readEventIssued = true;
+ void issue() {
+ readEventIssued = false;
+ if (isClosing) return;
+ if (!sendReadEvents) return;
+ if (available == 0) {
+ if (isClosedRead && !closedReadEventSent) {
+ if (isClosedWrite) close();
+ var handler = eventHandlers[closedEvent];
+ if (handler == null) return;
+ closedReadEventSent = true;
+ handler();
+ }
+ return;
+ }
+ var handler = eventHandlers[readEvent];
+ if (handler == null) return;
+ readEventIssued = true;
+ handler();
+ scheduleMicrotask(issue);
+ }
+
+ scheduleMicrotask(issue);
+ }
+
+ void issueWriteEvent({bool delayed: true}) {
+ if (writeEventIssued) return;
+ if (!writeAvailable) return;
+ void issue() {
+ writeEventIssued = false;
+ if (!writeAvailable) return;
+ if (isClosing) return;
+ if (!sendWriteEvents) return;
+ sendWriteEvents = false;
+ var handler = eventHandlers[writeEvent];
+ if (handler == null) return;
+ handler();
+ }
+
+ if (delayed) {
+ writeEventIssued = true;
+ scheduleMicrotask(issue);
+ } else {
+ issue();
+ }
+ }
+
+ // Multiplexes socket events to the socket handlers.
+ void multiplex(Object eventsObj) {
+ // TODO(paulberry): when issue #31305 is fixed, we should be able to simply
+ // declare `events` as a `covariant int` parameter.
+ int events = eventsObj;
+ for (int i = firstEvent; i <= lastEvent; i++) {
+ if (((events & (1 << i)) != 0)) {
+ if ((i == closedEvent || i == readEvent) && isClosedRead) continue;
+ if (isClosing && i != destroyedEvent) continue;
+ if (i == closedEvent && !isListening && !isClosing && !isClosed) {
+ isClosedRead = true;
+ issueReadEvent();
+ continue;
+ }
+
+ if (i == writeEvent) {
+ writeAvailable = true;
+ issueWriteEvent(delayed: false);
+ continue;
+ }
+
+ if (i == readEvent) {
+ if (isListening) {
+ available++;
+ } else {
+ available = nativeAvailable();
+ issueReadEvent();
+ continue;
+ }
+ }
+
+ var handler = eventHandlers[i];
+ if (i == destroyedEvent) {
+ assert(isClosing);
+ assert(!isClosed);
+ // TODO(ricow): Remove/update when we track internal and pipe uses.
+ assert(
+ resourceInfo != null || isPipe || isInternal || isInternalSignal);
+ if (resourceInfo != null) {
+ _SocketResourceInfo.SocketClosed(resourceInfo);
+ }
+ isClosed = true;
+ closeCompleter.complete();
+ disconnectFromEventHandler();
+ if (handler != null) handler();
+ continue;
+ }
+
+ if (i == errorEvent) {
+ if (!isClosing) {
+ reportError(nativeGetError(), null, "");
+ }
+ } else if (!isClosed) {
+ // If the connection is closed right after it's accepted, there's a
+ // chance the close-handler is not set.
+ if (handler != null) handler();
+ }
+ }
+ }
+ if (!isListening) {
+ tokens++;
+ returnTokens(normalTokenBatchSize);
+ }
+ }
+
+ void returnTokens(int tokenBatchSize) {
+ if (!isClosing && !isClosed) {
+ assert(eventPort != null);
+ // Return in batches.
+ if (tokens == tokenBatchSize) {
+ assert(tokens < (1 << firstCommand));
+ sendToEventHandler((1 << returnTokenCommand) | tokens);
+ tokens = 0;
+ }
+ }
+ }
+
+ void setHandlers({read, write, error, closed, destroyed}) {
+ eventHandlers[readEvent] = read;
+ eventHandlers[writeEvent] = write;
+ eventHandlers[errorEvent] = error;
+ eventHandlers[closedEvent] = closed;
+ eventHandlers[destroyedEvent] = destroyed;
+ }
+
+ void setListening({read: true, write: true}) {
+ sendReadEvents = read;
+ sendWriteEvents = write;
+ if (read) issueReadEvent();
+ if (write) issueWriteEvent();
+ if (!flagsSent && !isClosing) {
+ flagsSent = true;
+ int flags = 1 << setEventMaskCommand;
+ if (!isClosedRead) flags |= 1 << readEvent;
+ if (!isClosedWrite) flags |= 1 << writeEvent;
+ sendToEventHandler(flags);
+ }
+ }
+
+ Future close() {
+ if (!isClosing && !isClosed) {
+ sendToEventHandler(1 << closeCommand);
+ isClosing = true;
+ }
+ return closeCompleter.future;
+ }
+
+ void shutdown(SocketDirection direction) {
+ if (!isClosing && !isClosed) {
+ switch (direction) {
+ case SocketDirection.receive:
+ shutdownRead();
+ break;
+ case SocketDirection.send:
+ shutdownWrite();
+ break;
+ case SocketDirection.both:
+ close();
+ break;
+ default:
+ throw new ArgumentError(direction);
+ }
+ }
+ }
+
+ void shutdownWrite() {
+ if (!isClosing && !isClosed) {
+ if (closedReadEventSent) {
+ close();
+ } else {
+ sendToEventHandler(1 << shutdownWriteCommand);
+ }
+ isClosedWrite = true;
+ }
+ }
+
+ void shutdownRead() {
+ if (!isClosing && !isClosed) {
+ if (isClosedWrite) {
+ close();
+ } else {
+ sendToEventHandler(1 << shutdownReadCommand);
+ }
+ isClosedRead = true;
+ }
+ }
+
+ void sendToEventHandler(int data) {
+ int fullData = (typeFlags & typeTypeMask) | data;
+ assert(!isClosing);
+ connectToEventHandler();
+ _EventHandler._sendData(this, eventPort.sendPort, fullData);
+ }
+
+ void connectToEventHandler() {
+ assert(!isClosed);
+ if (eventPort == null) {
+ eventPort = new RawReceivePort(multiplex);
+ }
+ if (!connectedResourceHandler) {
+ registerExtension(
+ 'ext.dart.io.getOpenSockets', _SocketResourceInfo.getOpenSockets);
+ registerExtension('ext.dart.io.getSocketByID',
+ _SocketResourceInfo.getSocketInfoMapByID);
+
+ connectedResourceHandler = true;
+ }
+ }
+
+ void disconnectFromEventHandler() {
+ assert(eventPort != null);
+ eventPort.close();
+ eventPort = null;
+ // Now that we don't track this Socket anymore, we can clear the owner
+ // field.
+ owner = null;
+ }
+
+ // Check whether this is an error response from a native port call.
+ static bool isErrorResponse(response) {
+ return response is List && response[0] != _successResponse;
+ }
+
+ // Create the appropriate error/exception from different returned
+ // error objects.
+ static createError(error, String message,
+ [InternetAddress address, int port]) {
+ if (error is OSError) {
+ return new SocketException(message,
+ osError: error, address: address, port: port);
+ } else if (error is List) {
+ assert(isErrorResponse(error));
+ switch (error[0]) {
+ case _illegalArgumentResponse:
+ return new ArgumentError();
+ case _osErrorResponse:
+ return new SocketException(message,
+ osError: new OSError(error[2], error[1]),
+ address: address,
+ port: port);
+ default:
+ return new Exception("Unknown error");
+ }
+ } else {
+ return new SocketException(message, address: address, port: port);
+ }
+ }
+
+ void reportError(error, StackTrace st, String message) {
+ var e = createError(error, message, address, localPort);
+ // Invoke the error handler if any.
+ if (eventHandlers[errorEvent] != null) {
+ eventHandlers[errorEvent](e, st);
+ }
+ // For all errors we close the socket
+ close();
+ }
+
+ getOption(SocketOption option) {
+ if (option == null) throw new ArgumentError.notNull("option");
+ var result = nativeGetOption(option._value, address.type._value);
+ if (result is OSError) throw result;
+ return result;
+ }
+
+ bool setOption(SocketOption option, value) {
+ if (option == null) throw new ArgumentError.notNull("option");
+ var result = nativeSetOption(option._value, address.type._value, value);
+ if (result != null) throw result;
+ return true;
+ }
+
+ Uint8List getRawOption(RawSocketOption option) {
+ if (option == null) throw new ArgumentError.notNull("option");
+ if (option.value == null) throw new ArgumentError.notNull("option.value");
+
+ var result = nativeGetRawOption(option.level, option.option, option.value);
+ if (result != null) throw result;
+ return option.value;
+ }
+
+ void setRawOption(RawSocketOption option) {
+ if (option == null) throw new ArgumentError.notNull("option");
+ if (option.value == null) throw new ArgumentError.notNull("option.value");
+
+ var result = nativeSetRawOption(option.level, option.option, option.value);
+ if (result != null) throw result;
+ }
+
+ InternetAddress multicastAddress(
+ InternetAddress addr, NetworkInterface interface) {
+ // On Mac OS using the interface index for joining IPv4 multicast groups
+ // is not supported. Here the IP address of the interface is needed.
+ if (Platform.isMacOS && addr.type == InternetAddressType.IPv4) {
+ if (interface != null) {
+ for (int i = 0; i < interface.addresses.length; i++) {
+ if (interface.addresses[i].type == InternetAddressType.IPv4) {
+ return interface.addresses[i];
+ }
+ }
+ // No IPv4 address found on the interface.
+ throw new SocketException(
+ "The network interface does not have an address "
+ "of the same family as the multicast address");
+ } else {
+ // Default to the ANY address if no interface is specified.
+ return InternetAddress.anyIPv4;
+ }
+ } else {
+ return null;
+ }
+ }
+
+ void joinMulticast(InternetAddress addr, NetworkInterface interface) {
+ _InternetAddress interfaceAddr = multicastAddress(addr, interface);
+ var interfaceIndex = interface == null ? 0 : interface.index;
+ var result = nativeJoinMulticast((addr as _InternetAddress)._in_addr,
+ interfaceAddr?._in_addr, interfaceIndex);
+ if (result is OSError) throw result;
+ }
+
+ void leaveMulticast(InternetAddress addr, NetworkInterface interface) {
+ _InternetAddress interfaceAddr = multicastAddress(addr, interface);
+ var interfaceIndex = interface == null ? 0 : interface.index;
+ var result = nativeLeaveMulticast((addr as _InternetAddress)._in_addr,
+ interfaceAddr?._in_addr, interfaceIndex);
+ if (result is OSError) throw result;
+ }
+
+ void nativeSetSocketId(int id, int typeFlags) native "Socket_SetSocketId";
+ nativeAvailable() native "Socket_Available";
+ nativeRead(int len) native "Socket_Read";
+ nativeRecvFrom() native "Socket_RecvFrom";
+ nativeWrite(List<int> buffer, int offset, int bytes)
+ native "Socket_WriteList";
+ nativeSendTo(List<int> buffer, int offset, int bytes, Uint8List address,
+ int port) native "Socket_SendTo";
+ nativeCreateConnect(Uint8List addr, int port, int scope_id)
+ native "Socket_CreateConnect";
+ nativeCreateBindConnect(Uint8List addr, int port, Uint8List sourceAddr,
+ int scope_id) native "Socket_CreateBindConnect";
+ bool isBindError(int errorNumber) native "SocketBase_IsBindError";
+ nativeCreateBindListen(Uint8List addr, int port, int backlog, bool v6Only,
+ bool shared, int scope_id) native "ServerSocket_CreateBindListen";
+ nativeCreateBindDatagram(Uint8List addr, int port, bool reuseAddress,
+ bool reusePort, int ttl) native "Socket_CreateBindDatagram";
+ nativeAccept(_NativeSocket socket) native "ServerSocket_Accept";
+ int nativeGetPort() native "Socket_GetPort";
+ List nativeGetRemotePeer() native "Socket_GetRemotePeer";
+ int nativeGetSocketId() native "Socket_GetSocketId";
+ OSError nativeGetError() native "Socket_GetError";
+ nativeGetOption(int option, int protocol) native "Socket_GetOption";
+ OSError nativeGetRawOption(int level, int option, Uint8List data)
+ native "Socket_GetRawOption";
+ OSError nativeSetOption(int option, int protocol, value)
+ native "Socket_SetOption";
+ OSError nativeSetRawOption(int level, int option, Uint8List data)
+ native "Socket_SetRawOption";
+ OSError nativeJoinMulticast(Uint8List addr, Uint8List interfaceAddr,
+ int interfaceIndex) native "Socket_JoinMulticast";
+ bool nativeLeaveMulticast(Uint8List addr, Uint8List interfaceAddr,
+ int interfaceIndex) native "Socket_LeaveMulticast";
+}
+
+class _RawServerSocket extends Stream<RawSocket> implements RawServerSocket {
+ final _NativeSocket _socket;
+ StreamController<RawSocket> _controller;
+ ReceivePort _referencePort;
+ bool _v6Only;
+
+ static Future<_RawServerSocket> bind(
+ address, int port, int backlog, bool v6Only, bool shared) {
+ _throwOnBadPort(port);
+ if (backlog < 0) throw new ArgumentError("Invalid backlog $backlog");
+ return _NativeSocket.bind(address, port, backlog, v6Only, shared)
+ .then((socket) => new _RawServerSocket(socket, v6Only));
+ }
+
+ _RawServerSocket(this._socket, this._v6Only);
+
+ StreamSubscription<RawSocket> listen(void onData(RawSocket event),
+ {Function onError, void onDone(), bool cancelOnError}) {
+ if (_controller != null) {
+ throw new StateError("Stream was already listened to");
+ }
+ var zone = Zone.current;
+ _controller = new StreamController(
+ sync: true,
+ onListen: _onSubscriptionStateChange,
+ onCancel: _onSubscriptionStateChange,
+ onPause: _onPauseStateChange,
+ onResume: _onPauseStateChange);
+ _socket.setHandlers(read: zone.bindCallbackGuarded(() {
+ while (_socket.available > 0) {
+ var socket = _socket.accept();
+ if (socket == null) return;
+ _controller.add(new _RawSocket(socket));
+ if (_controller.isPaused) return;
+ }
+ }), error: zone.bindBinaryCallbackGuarded((e, st) {
+ _controller.addError(e, st);
+ _controller.close();
+ }), destroyed: () {
+ _controller.close();
+ if (_referencePort != null) {
+ _referencePort.close();
+ _referencePort = null;
+ }
+ });
+ return _controller.stream.listen(onData,
+ onError: onError, onDone: onDone, cancelOnError: cancelOnError);
+ }
+
+ int get port => _socket.port;
+
+ InternetAddress get address => _socket.address;
+
+ Future<RawServerSocket> close() {
+ return _socket.close().then<RawServerSocket>((_) {
+ if (_referencePort != null) {
+ _referencePort.close();
+ _referencePort = null;
+ }
+ return this;
+ });
+ }
+
+ void _pause() {
+ _socket.setListening(read: false, write: false);
+ }
+
+ void _resume() {
+ _socket.setListening(read: true, write: false);
+ }
+
+ void _onSubscriptionStateChange() {
+ if (_controller.hasListener) {
+ _resume();
+ } else {
+ _socket.close();
+ }
+ }
+
+ void _onPauseStateChange() {
+ if (_controller.isPaused) {
+ _pause();
+ } else {
+ _resume();
+ }
+ }
+
+ void set _owner(owner) {
+ _socket.owner = owner;
+ }
+}
+
+class _RawSocket extends Stream<RawSocketEvent> implements RawSocket {
+ final _NativeSocket _socket;
+ StreamController<RawSocketEvent> _controller;
+ bool _readEventsEnabled = true;
+ bool _writeEventsEnabled = true;
+
+ // Flag to handle Ctrl-D closing of stdio on Mac OS.
+ bool _isMacOSTerminalInput = false;
+
+ static Future<RawSocket> connect(
+ host, int port, sourceAddress, Duration timeout) {
+ return _NativeSocket.connect(host, port, sourceAddress, timeout)
+ .then((socket) => new _RawSocket(socket));
+ }
+
+ static Future<ConnectionTask<_RawSocket>> startConnect(
+ host, int port, sourceAddress) {
+ return _NativeSocket.startConnect(host, port, sourceAddress)
+ .then((ConnectionTask<_NativeSocket> nativeTask) {
+ final Future<_RawSocket> raw = nativeTask.socket
+ .then((_NativeSocket nativeSocket) => new _RawSocket(nativeSocket));
+ return new ConnectionTask<_RawSocket>._(
+ socket: raw, onCancel: nativeTask._onCancel);
+ });
+ }
+
+ _RawSocket(this._socket) {
+ var zone = Zone.current;
+ _controller = new StreamController(
+ sync: true,
+ onListen: _onSubscriptionStateChange,
+ onCancel: _onSubscriptionStateChange,
+ onPause: _onPauseStateChange,
+ onResume: _onPauseStateChange);
+ _socket.setHandlers(
+ read: () => _controller.add(RawSocketEvent.read),
+ write: () {
+ // The write event handler is automatically disabled by the
+ // event handler when it fires.
+ writeEventsEnabled = false;
+ _controller.add(RawSocketEvent.write);
+ },
+ closed: () => _controller.add(RawSocketEvent.readClosed),
+ destroyed: () {
+ _controller.add(RawSocketEvent.closed);
+ _controller.close();
+ },
+ error: zone.bindBinaryCallbackGuarded((e, st) {
+ _controller.addError(e, st);
+ _socket.close();
+ }));
+ }
+
+ factory _RawSocket._writePipe() {
+ var native = new _NativeSocket.pipe();
+ native.isClosedRead = true;
+ native.closedReadEventSent = true;
+ return new _RawSocket(native);
+ }
+
+ factory _RawSocket._readPipe(int fd) {
+ var native = new _NativeSocket.pipe();
+ native.isClosedWrite = true;
+ if (fd != null) _getStdioHandle(native, fd);
+ var result = new _RawSocket(native);
+ if (fd != null) {
+ var socketType = _StdIOUtils._nativeSocketType(result._socket);
+ result._isMacOSTerminalInput =
+ Platform.isMacOS && socketType == _stdioHandleTypeTerminal;
+ }
+ return result;
+ }
+
+ StreamSubscription<RawSocketEvent> listen(void onData(RawSocketEvent event),
+ {Function onError, void onDone(), bool cancelOnError}) {
+ return _controller.stream.listen(onData,
+ onError: onError, onDone: onDone, cancelOnError: cancelOnError);
+ }
+
+ int available() => _socket.available;
+
+ Uint8List read([int len]) {
+ if (_isMacOSTerminalInput) {
+ var available = this.available();
+ if (available == 0) return null;
+ var data = _socket.read(len);
+ if (data == null || data.length < available) {
+ // Reading less than available from a Mac OS terminal indicate Ctrl-D.
+ // This is interpreted as read closed.
+ scheduleMicrotask(() => _controller.add(RawSocketEvent.readClosed));
+ }
+ return data;
+ } else {
+ return _socket.read(len);
+ }
+ }
+
+ int write(List<int> buffer, [int offset, int count]) =>
+ _socket.write(buffer, offset, count);
+
+ Future<RawSocket> close() => _socket.close().then<RawSocket>((_) => this);
+
+ void shutdown(SocketDirection direction) => _socket.shutdown(direction);
+
+ int get port => _socket.port;
+
+ int get remotePort => _socket.remotePort;
+
+ InternetAddress get address => _socket.address;
+
+ InternetAddress get remoteAddress => _socket.remoteAddress;
+
+ bool get readEventsEnabled => _readEventsEnabled;
+ void set readEventsEnabled(bool value) {
+ if (value != _readEventsEnabled) {
+ _readEventsEnabled = value;
+ if (!_controller.isPaused) _resume();
+ }
+ }
+
+ bool get writeEventsEnabled => _writeEventsEnabled;
+ void set writeEventsEnabled(bool value) {
+ if (value != _writeEventsEnabled) {
+ _writeEventsEnabled = value;
+ if (!_controller.isPaused) _resume();
+ }
+ }
+
+ bool setOption(SocketOption option, bool enabled) =>
+ _socket.setOption(option, enabled);
+
+ Uint8List getRawOption(RawSocketOption option) =>
+ _socket.getRawOption(option);
+ void setRawOption(RawSocketOption option) => _socket.setRawOption(option);
+
+ _pause() {
+ _socket.setListening(read: false, write: false);
+ }
+
+ void _resume() {
+ _socket.setListening(read: _readEventsEnabled, write: _writeEventsEnabled);
+ }
+
+ void _onPauseStateChange() {
+ if (_controller.isPaused) {
+ _pause();
+ } else {
+ _resume();
+ }
+ }
+
+ void _onSubscriptionStateChange() {
+ if (_controller.hasListener) {
+ _resume();
+ } else {
+ _socket.close();
+ }
+ }
+
+ void set _owner(owner) {
+ _socket.owner = owner;
+ }
+}
+
+@patch
+class ServerSocket {
+ @patch
+ static Future<ServerSocket> bind(address, int port,
+ {int backlog: 0, bool v6Only: false, bool shared: false}) {
+ return _ServerSocket.bind(address, port, backlog, v6Only, shared);
+ }
+}
+
+class _ServerSocket extends Stream<Socket> implements ServerSocket {
+ final _socket;
+
+ static Future<_ServerSocket> bind(
+ address, int port, int backlog, bool v6Only, bool shared) {
+ return _RawServerSocket.bind(address, port, backlog, v6Only, shared)
+ .then((socket) => new _ServerSocket(socket));
+ }
+
+ _ServerSocket(this._socket);
+
+ StreamSubscription<Socket> listen(void onData(Socket event),
+ {Function onError, void onDone(), bool cancelOnError}) {
+ return _socket.map<Socket>((rawSocket) => new _Socket(rawSocket)).listen(
+ onData,
+ onError: onError,
+ onDone: onDone,
+ cancelOnError: cancelOnError);
+ }
+
+ int get port => _socket.port;
+
+ InternetAddress get address => _socket.address;
+
+ Future<ServerSocket> close() =>
+ _socket.close().then<ServerSocket>((_) => this);
+
+ void set _owner(owner) {
+ _socket._owner = owner;
+ }
+}
+
+@patch
+class Socket {
+ @patch
+ static Future<Socket> _connect(host, int port,
+ {sourceAddress, Duration timeout}) {
+ return RawSocket.connect(host, port,
+ sourceAddress: sourceAddress, timeout: timeout)
+ .then((socket) => new _Socket(socket));
+ }
+
+ @patch
+ static Future<ConnectionTask<Socket>> _startConnect(host, int port,
+ {sourceAddress}) {
+ return RawSocket.startConnect(host, port, sourceAddress: sourceAddress)
+ .then((rawTask) {
+ Future<Socket> socket =
+ rawTask.socket.then((rawSocket) => new _Socket(rawSocket));
+ return new ConnectionTask<Socket>._(
+ socket: socket, onCancel: rawTask._onCancel);
+ });
+ }
+}
+
+class _SocketStreamConsumer extends StreamConsumer<List<int>> {
+ StreamSubscription subscription;
+ final _Socket socket;
+ int offset;
+ List<int> buffer;
+ bool paused = false;
+ Completer streamCompleter;
+
+ _SocketStreamConsumer(this.socket);
+
+ Future<Socket> addStream(Stream<List<int>> stream) {
+ socket._ensureRawSocketSubscription();
+ streamCompleter = new Completer<Socket>();
+ if (socket._raw != null) {
+ subscription = stream.listen((data) {
+ assert(!paused);
+ assert(buffer == null);
+ buffer = data;
+ offset = 0;
+ try {
+ write();
+ } catch (e) {
+ socket.destroy();
+ stop();
+ done(e);
+ }
+ }, onError: (error, [stackTrace]) {
+ socket.destroy();
+ done(error, stackTrace);
+ }, onDone: () {
+ done();
+ }, cancelOnError: true);
+ }
+ return streamCompleter.future;
+ }
+
+ Future<Socket> close() {
+ socket._consumerDone();
+ return new Future.value(socket);
+ }
+
+ void write() {
+ if (subscription == null) return;
+ assert(buffer != null);
+ // Write as much as possible.
+ offset += socket._write(buffer, offset, buffer.length - offset);
+ if (offset < buffer.length) {
+ if (!paused) {
+ paused = true;
+ subscription.pause();
+ }
+ socket._enableWriteEvent();
+ } else {
+ buffer = null;
+ if (paused) {
+ paused = false;
+ subscription.resume();
+ }
+ }
+ }
+
+ void done([error, stackTrace]) {
+ if (streamCompleter != null) {
+ if (error != null) {
+ streamCompleter.completeError(error, stackTrace);
+ } else {
+ streamCompleter.complete(socket);
+ }
+ streamCompleter = null;
+ }
+ }
+
+ void stop() {
+ if (subscription == null) return;
+ subscription.cancel();
+ subscription = null;
+ paused = false;
+ socket._disableWriteEvent();
+ }
+}
+
+class _Socket extends Stream<Uint8List> implements Socket {
+ RawSocket _raw; // Set to null when the raw socket is closed.
+ bool _closed = false; // Set to true when the raw socket is closed.
+ StreamController<Uint8List> _controller;
+ bool _controllerClosed = false;
+ _SocketStreamConsumer _consumer;
+ IOSink _sink;
+ var _subscription;
+ var _detachReady;
+
+ _Socket(this._raw) {
+ _controller = new StreamController<Uint8List>(
+ sync: true,
+ onListen: _onSubscriptionStateChange,
+ onCancel: _onSubscriptionStateChange,
+ onPause: _onPauseStateChange,
+ onResume: _onPauseStateChange);
+ _consumer = new _SocketStreamConsumer(this);
+ _sink = new IOSink(_consumer);
+
+ // Disable read events until there is a subscription.
+ _raw.readEventsEnabled = false;
+
+ // Disable write events until the consumer needs it for pending writes.
+ _raw.writeEventsEnabled = false;
+ }
+
+ factory _Socket._writePipe() {
+ return new _Socket(new _RawSocket._writePipe());
+ }
+
+ factory _Socket._readPipe([int fd]) {
+ return new _Socket(new _RawSocket._readPipe(fd));
+ }
+
+ // Note: this code seems a bit suspicious because _raw can be _RawSocket and
+ // it can be _RawSecureSocket because _SecureSocket extends _Socket
+ // and these two types are incompatible because _RawSecureSocket._socket
+ // is Socket and not _NativeSocket.
+ _NativeSocket get _nativeSocket => (_raw as _RawSocket)._socket;
+
+ StreamSubscription<Uint8List> listen(void onData(Uint8List event),
+ {Function onError, void onDone(), bool cancelOnError}) {
+ return _controller.stream.listen(onData,
+ onError: onError, onDone: onDone, cancelOnError: cancelOnError);
+ }
+
+ Encoding get encoding => _sink.encoding;
+
+ void set encoding(Encoding value) {
+ _sink.encoding = value;
+ }
+
+ void write(Object obj) => _sink.write(obj);
+
+ void writeln([Object obj = ""]) => _sink.writeln(obj);
+
+ void writeCharCode(int charCode) => _sink.writeCharCode(charCode);
+
+ void writeAll(Iterable objects, [sep = ""]) => _sink.writeAll(objects, sep);
+
+ void add(List<int> bytes) => _sink.add(bytes);
+
+ void addError(Object error, [StackTrace stackTrace]) {
+ throw new UnsupportedError("Cannot send errors on sockets");
+ }
+
+ Future addStream(Stream<List<int>> stream) {
+ return _sink.addStream(stream);
+ }
+
+ Future flush() => _sink.flush();
+
+ Future close() => _sink.close();
+
+ Future get done => _sink.done;
+
+ void destroy() {
+ // Destroy can always be called to get rid of a socket.
+ if (_raw == null) return;
+ _consumer.stop();
+ _closeRawSocket();
+ _controllerClosed = true;
+ _controller.close();
+ }
+
+ bool setOption(SocketOption option, bool enabled) {
+ if (_raw == null) return false;
+ return _raw.setOption(option, enabled);
+ }
+
+ Uint8List getRawOption(RawSocketOption option) {
+ if (_raw == null) return null;
+ return _raw.getRawOption(option);
+ }
+
+ void setRawOption(RawSocketOption option) {
+ _raw?.setRawOption(option);
+ }
+
+ int get port {
+ if (_raw == null) throw const SocketException.closed();
+ ;
+ return _raw.port;
+ }
+
+ InternetAddress get address {
+ if (_raw == null) throw const SocketException.closed();
+ ;
+ return _raw.address;
+ }
+
+ int get remotePort {
+ if (_raw == null) throw const SocketException.closed();
+ ;
+ return _raw.remotePort;
+ }
+
+ InternetAddress get remoteAddress {
+ if (_raw == null) throw const SocketException.closed();
+ ;
+ return _raw.remoteAddress;
+ }
+
+ Future _detachRaw() {
+ _detachReady = new Completer();
+ _sink.close();
+ return _detachReady.future.then((_) {
+ assert(_consumer.buffer == null);
+ var raw = _raw;
+ _raw = null;
+ return [raw, _subscription];
+ });
+ }
+
+ // Ensure a subscription on the raw socket. Both the stream and the
+ // consumer needs a subscription as they share the error and done
+ // events from the raw socket.
+ void _ensureRawSocketSubscription() {
+ if (_subscription == null && _raw != null) {
+ _subscription = _raw.listen(_onData,
+ onError: _onError, onDone: _onDone, cancelOnError: true);
+ }
+ }
+
+ _closeRawSocket() {
+ var tmp = _raw;
+ _raw = null;
+ _closed = true;
+ tmp.close();
+ }
+
+ void _onSubscriptionStateChange() {
+ if (_controller.hasListener) {
+ _ensureRawSocketSubscription();
+ // Enable read events for providing data to subscription.
+ if (_raw != null) {
+ _raw.readEventsEnabled = true;
+ }
+ } else {
+ _controllerClosed = true;
+ if (_raw != null) {
+ _raw.shutdown(SocketDirection.receive);
+ }
+ }
+ }
+
+ void _onPauseStateChange() {
+ if (_raw != null) {
+ _raw.readEventsEnabled = !_controller.isPaused;
+ }
+ }
+
+ void _onData(event) {
+ switch (event) {
+ case RawSocketEvent.read:
+ if (_raw == null) break;
+ var buffer = _raw.read();
+ if (buffer != null) _controller.add(buffer);
+ break;
+ case RawSocketEvent.write:
+ _consumer.write();
+ break;
+ case RawSocketEvent.readClosed:
+ _controllerClosed = true;
+ _controller.close();
+ break;
+ }
+ }
+
+ void _onDone() {
+ if (!_controllerClosed) {
+ _controllerClosed = true;
+ _controller.close();
+ }
+ _consumer.done();
+ }
+
+ void _onError(error, stackTrace) {
+ if (!_controllerClosed) {
+ _controllerClosed = true;
+ _controller.addError(error, stackTrace);
+ _controller.close();
+ }
+ _consumer.done(error, stackTrace);
+ }
+
+ int _write(List<int> data, int offset, int length) {
+ if (_raw != null) {
+ return _raw.write(data, offset, length);
+ }
+ return 0;
+ }
+
+ void _enableWriteEvent() {
+ if (_raw != null) {
+ _raw.writeEventsEnabled = true;
+ }
+ }
+
+ void _disableWriteEvent() {
+ if (_raw != null) {
+ _raw.writeEventsEnabled = false;
+ }
+ }
+
+ void _consumerDone() {
+ if (_detachReady != null) {
+ _detachReady.complete(null);
+ } else {
+ if (_raw != null) {
+ _raw.shutdown(SocketDirection.send);
+ _disableWriteEvent();
+ }
+ }
+ }
+
+ void set _owner(owner) {
+ // Note: _raw can be _RawSocket and _RawSecureSocket which are two
+ // incompatible types.
+ (_raw as dynamic)._owner = owner;
+ }
+}
+
+@patch
+class RawDatagramSocket {
+ @patch
+ static Future<RawDatagramSocket> bind(host, int port,
+ {bool reuseAddress: true, bool reusePort: false, int ttl: 1}) {
+ return _RawDatagramSocket.bind(host, port, reuseAddress, reusePort, ttl);
+ }
+}
+
+class _RawDatagramSocket extends Stream<RawSocketEvent>
+ implements RawDatagramSocket {
+ _NativeSocket _socket;
+ StreamController<RawSocketEvent> _controller;
+ bool _readEventsEnabled = true;
+ bool _writeEventsEnabled = true;
+
+ _RawDatagramSocket(this._socket) {
+ var zone = Zone.current;
+ _controller = new StreamController<RawSocketEvent>(
+ sync: true,
+ onListen: _onSubscriptionStateChange,
+ onCancel: _onSubscriptionStateChange,
+ onPause: _onPauseStateChange,
+ onResume: _onPauseStateChange);
+ _socket.setHandlers(
+ read: () => _controller.add(RawSocketEvent.read),
+ write: () {
+ // The write event handler is automatically disabled by the
+ // event handler when it fires.
+ writeEventsEnabled = false;
+ _controller.add(RawSocketEvent.write);
+ },
+ closed: () => _controller.add(RawSocketEvent.readClosed),
+ destroyed: () {
+ _controller.add(RawSocketEvent.closed);
+ _controller.close();
+ },
+ error: zone.bindBinaryCallbackGuarded((e, st) {
+ _controller.addError(e, st);
+ _socket.close();
+ }));
+ }
+
+ static Future<RawDatagramSocket> bind(
+ host, int port, bool reuseAddress, bool reusePort, int ttl) {
+ _throwOnBadPort(port);
+ _throwOnBadTtl(ttl);
+ return _NativeSocket.bindDatagram(host, port, reuseAddress, reusePort, ttl)
+ .then((socket) => new _RawDatagramSocket(socket));
+ }
+
+ StreamSubscription<RawSocketEvent> listen(void onData(RawSocketEvent event),
+ {Function onError, void onDone(), bool cancelOnError}) {
+ return _controller.stream.listen(onData,
+ onError: onError, onDone: onDone, cancelOnError: cancelOnError);
+ }
+
+ Future close() => _socket.close().then<RawDatagramSocket>((_) => this);
+
+ int send(List<int> buffer, InternetAddress address, int port) =>
+ _socket.send(buffer, 0, buffer.length, address, port);
+
+ Datagram receive() {
+ return _socket.receive();
+ }
+
+ void joinMulticast(InternetAddress group, [NetworkInterface interface]) {
+ _socket.joinMulticast(group, interface);
+ }
+
+ void leaveMulticast(InternetAddress group, [NetworkInterface interface]) {
+ _socket.leaveMulticast(group, interface);
+ }
+
+ bool get readEventsEnabled => _readEventsEnabled;
+ void set readEventsEnabled(bool value) {
+ if (value != _readEventsEnabled) {
+ _readEventsEnabled = value;
+ if (!_controller.isPaused) _resume();
+ }
+ }
+
+ bool get writeEventsEnabled => _writeEventsEnabled;
+ void set writeEventsEnabled(bool value) {
+ if (value != _writeEventsEnabled) {
+ _writeEventsEnabled = value;
+ if (!_controller.isPaused) _resume();
+ }
+ }
+
+ bool get multicastLoopback =>
+ _socket.getOption(SocketOption._ipMulticastLoop);
+ void set multicastLoopback(bool value) =>
+ _socket.setOption(SocketOption._ipMulticastLoop, value);
+
+ int get multicastHops => _socket.getOption(SocketOption._ipMulticastHops);
+ void set multicastHops(int value) =>
+ _socket.setOption(SocketOption._ipMulticastHops, value);
+
+ NetworkInterface get multicastInterface => throw "Not implemented";
+ void set multicastInterface(NetworkInterface value) =>
+ throw "Not implemented";
+
+ bool get broadcastEnabled => _socket.getOption(SocketOption._ipBroadcast);
+ void set broadcastEnabled(bool value) =>
+ _socket.setOption(SocketOption._ipBroadcast, value);
+
+ int get port => _socket.port;
+
+ InternetAddress get address => _socket.address;
+
+ _pause() {
+ _socket.setListening(read: false, write: false);
+ }
+
+ void _resume() {
+ _socket.setListening(read: _readEventsEnabled, write: _writeEventsEnabled);
+ }
+
+ void _onPauseStateChange() {
+ if (_controller.isPaused) {
+ _pause();
+ } else {
+ _resume();
+ }
+ }
+
+ void _onSubscriptionStateChange() {
+ if (_controller.hasListener) {
+ _resume();
+ } else {
+ _socket.close();
+ }
+ }
+
+ Uint8List getRawOption(RawSocketOption option) =>
+ _socket.getRawOption(option);
+ void setRawOption(RawSocketOption option) => _socket.setRawOption(option);
+}
+
+@pragma("vm:entry-point", "call")
+Datagram _makeDatagram(
+ Uint8List data, String address, Uint8List in_addr, int port) {
+ return new Datagram(data, new _InternetAddress(address, null, in_addr), port);
+}
diff --git a/sdk_nnbd/lib/_internal/vm/bin/stdio_patch.dart b/sdk_nnbd/lib/_internal/vm/bin/stdio_patch.dart
new file mode 100644
index 0000000..58d1d0a
--- /dev/null
+++ b/sdk_nnbd/lib/_internal/vm/bin/stdio_patch.dart
@@ -0,0 +1,168 @@
+// 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
+// BSD-style license that can be found in the LICENSE file.
+
+// @dart = 2.5
+
+// part of "common_patch.dart";
+
+@patch
+class _StdIOUtils {
+ @patch
+ static Stdin _getStdioInputStream(int fd) {
+ switch (_getStdioHandleType(fd)) {
+ case _stdioHandleTypeTerminal:
+ case _stdioHandleTypePipe:
+ case _stdioHandleTypeSocket:
+ return new Stdin._(new _Socket._readPipe(fd), fd);
+ case _stdioHandleTypeFile:
+ return new Stdin._(new _FileStream.forStdin(), fd);
+ default:
+ throw new FileSystemException(
+ "Couldn't determine file type of stdin (fd $fd)");
+ }
+ }
+
+ @patch
+ static _getStdioOutputStream(int fd) {
+ switch (_getStdioHandleType(fd)) {
+ case _stdioHandleTypeTerminal:
+ case _stdioHandleTypePipe:
+ case _stdioHandleTypeSocket:
+ case _stdioHandleTypeFile:
+ return new Stdout._(new IOSink(new _StdConsumer(fd)), fd);
+ default:
+ throw new FileSystemException(
+ "Couldn't determine file type of stdio handle (fd $fd)");
+ }
+ }
+
+ @patch
+ static int _socketType(Socket socket) {
+ if (socket is _Socket) return _nativeSocketType(socket._nativeSocket);
+ return null;
+ }
+
+ static int _nativeSocketType(_NativeSocket nativeSocket) {
+ var result = _getSocketType(nativeSocket);
+ if (result is OSError) {
+ throw new FileSystemException("Error retrieving socket type", "", result);
+ }
+ return result;
+ }
+
+ @patch
+ static _getStdioHandleType(int fd) native "File_GetStdioHandleType";
+}
+
+@patch
+class Stdin {
+ @patch
+ int readByteSync() {
+ var result = _readByte(_fd);
+ if (result is OSError) {
+ throw new StdinException("Error reading byte from stdin", result);
+ }
+ return result;
+ }
+
+ @patch
+ bool get echoMode {
+ var result = _echoMode(_fd);
+ if (result is OSError) {
+ throw new StdinException("Error getting terminal echo mode", result);
+ }
+ return result;
+ }
+
+ @patch
+ void set echoMode(bool enabled) {
+ if (!_EmbedderConfig._maySetEchoMode) {
+ throw new UnsupportedError(
+ "This embedder disallows setting Stdin.echoMode");
+ }
+ var result = _setEchoMode(_fd, enabled);
+ if (result is OSError) {
+ throw new StdinException("Error setting terminal echo mode", result);
+ }
+ }
+
+ @patch
+ bool get lineMode {
+ var result = _lineMode(_fd);
+ if (result is OSError) {
+ throw new StdinException("Error getting terminal line mode", result);
+ }
+ return result;
+ }
+
+ @patch
+ void set lineMode(bool enabled) {
+ if (!_EmbedderConfig._maySetLineMode) {
+ throw new UnsupportedError(
+ "This embedder disallows setting Stdin.lineMode");
+ }
+ var result = _setLineMode(_fd, enabled);
+ if (result is OSError) {
+ throw new StdinException("Error setting terminal line mode", result);
+ }
+ }
+
+ @patch
+ bool get supportsAnsiEscapes {
+ var result = _supportsAnsiEscapes(_fd);
+ if (result is OSError) {
+ throw new StdinException("Error determining ANSI support", result);
+ }
+ return result;
+ }
+
+ static _echoMode(int fd) native "Stdin_GetEchoMode";
+ static _setEchoMode(int fd, bool enabled) native "Stdin_SetEchoMode";
+ static _lineMode(int fd) native "Stdin_GetLineMode";
+ static _setLineMode(int fd, bool enabled) native "Stdin_SetLineMode";
+ static _readByte(int fd) native "Stdin_ReadByte";
+ static _supportsAnsiEscapes(int fd) native "Stdin_AnsiSupported";
+}
+
+@patch
+class Stdout {
+ @patch
+ bool _hasTerminal(int fd) {
+ try {
+ _terminalSize(fd);
+ return true;
+ } catch (_) {
+ return false;
+ }
+ }
+
+ @patch
+ int _terminalColumns(int fd) => _terminalSize(fd)[0];
+ @patch
+ int _terminalLines(int fd) => _terminalSize(fd)[1];
+
+ static List _terminalSize(int fd) {
+ var size = _getTerminalSize(fd);
+ if (size is! List) {
+ throw new StdoutException("Could not get terminal size", size);
+ }
+ return size;
+ }
+
+ static _getTerminalSize(int fd) native "Stdout_GetTerminalSize";
+
+ @patch
+ static bool _supportsAnsiEscapes(int fd) {
+ var result = _getAnsiSupported(fd);
+ if (result is! bool) {
+ throw new StdoutException("Error determining ANSI support", result);
+ }
+ return result;
+ }
+
+ static _getAnsiSupported(int fd) native "Stdout_AnsiSupported";
+}
+
+_getStdioHandle(_NativeSocket socket, int num) native "Socket_GetStdioHandle";
+_getSocketType(_NativeSocket nativeSocket) native "Socket_GetType";
diff --git a/sdk_nnbd/lib/_internal/vm/bin/sync_socket_patch.dart b/sdk_nnbd/lib/_internal/vm/bin/sync_socket_patch.dart
new file mode 100644
index 0000000..941aba4
--- /dev/null
+++ b/sdk_nnbd/lib/_internal/vm/bin/sync_socket_patch.dart
@@ -0,0 +1,351 @@
+// Copyright (c) 2017, 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.5
+
+// part of "common_patch.dart";
+
+@patch
+class RawSynchronousSocket {
+ @patch
+ static RawSynchronousSocket connectSync(host, int port) {
+ return _RawSynchronousSocket.connectSync(host, port);
+ }
+}
+
+class _RawSynchronousSocket implements RawSynchronousSocket {
+ final _NativeSynchronousSocket _socket;
+
+ _RawSynchronousSocket(this._socket);
+
+ static RawSynchronousSocket connectSync(host, int port) {
+ _throwOnBadPort(port);
+ return new _RawSynchronousSocket(
+ _NativeSynchronousSocket.connectSync(host, port));
+ }
+
+ InternetAddress get address => _socket.address;
+ int get port => _socket.port;
+ InternetAddress get remoteAddress => _socket.remoteAddress;
+ int get remotePort => _socket.remotePort;
+
+ int available() => _socket.available;
+
+ void closeSync() => _socket.closeSync();
+
+ int readIntoSync(List<int> buffer, [int start = 0, int end]) =>
+ _socket.readIntoSync(buffer, start, end);
+
+ List<int> readSync(int bytes) => _socket.readSync(bytes);
+
+ void shutdown(SocketDirection direction) => _socket.shutdown(direction);
+
+ void writeFromSync(List<int> buffer, [int start = 0, int end]) =>
+ _socket.writeFromSync(buffer, start, end);
+}
+
+// The NativeFieldWrapperClass1 can not be used with a mixin, due to missing
+// implicit constructor.
+class _NativeSynchronousSocketNativeWrapper extends NativeFieldWrapperClass1 {}
+
+// The _NativeSynchronousSocket class encapsulates a synchronous OS socket.
+class _NativeSynchronousSocket extends _NativeSynchronousSocketNativeWrapper {
+ // Socket close state.
+ bool isClosed = false;
+ bool isClosedRead = false;
+ bool isClosedWrite = false;
+
+ // Holds the address used to connect the socket.
+ InternetAddress localAddress;
+
+ // Holds the port of the socket, 0 if not known.
+ int localPort = 0;
+
+ _ReadWriteResourceInfo resourceInfo;
+
+ static _NativeSynchronousSocket connectSync(host, int port) {
+ if (host == null) {
+ throw new ArgumentError("Parameter host cannot be null");
+ }
+ List<_InternetAddress> addresses = null;
+ var error = null;
+ if (host is _InternetAddress) {
+ addresses = [host];
+ } else {
+ try {
+ addresses = lookup(host);
+ } catch (e) {
+ error = e;
+ }
+ if (error != null || addresses == null || addresses.isEmpty) {
+ throw createError(error, "Failed host lookup: '$host'");
+ }
+ }
+ assert(addresses is List);
+ var it = addresses.iterator;
+ _NativeSynchronousSocket connectNext() {
+ if (!it.moveNext()) {
+ // Could not connect. Throw the first connection error we encountered.
+ assert(error != null);
+ throw error;
+ }
+ var address = it.current;
+ var socket = new _NativeSynchronousSocket();
+ socket.localAddress = address;
+ var result = socket._nativeCreateConnectSync(address._in_addr, port);
+ if (result is OSError) {
+ // Keep first error, if present.
+ if (error == null) {
+ error = createError(result, "Connection failed", address, port);
+ }
+ return connectNext();
+ } else {
+ // Query the local port, for error messages.
+ try {
+ socket.port;
+ } catch (e) {
+ if (error == null) {
+ error = createError(e, "Connection failed", address, port);
+ }
+ return connectNext();
+ }
+ setupResourceInfo(socket);
+ }
+ return socket;
+ }
+
+ return connectNext();
+ }
+
+ InternetAddress get address => localAddress;
+ int get available => _nativeAvailable();
+
+ int get port {
+ if (localPort != 0) {
+ return localPort;
+ }
+ if (isClosed) {
+ throw const SocketException.closed();
+ }
+ var result = _nativeGetPort();
+ if (result is OSError) {
+ throw result;
+ }
+ return localPort = result;
+ }
+
+ InternetAddress get remoteAddress {
+ if (isClosed) {
+ throw const SocketException.closed();
+ }
+ var result = _nativeGetRemotePeer();
+ if (result is OSError) {
+ throw result;
+ }
+ var addr = result[0];
+ return new _InternetAddress(addr[1], null, addr[2]);
+ }
+
+ int get remotePort {
+ if (isClosed) {
+ throw const SocketException.closed();
+ }
+ var result = _nativeGetRemotePeer();
+ if (result is OSError) {
+ throw result;
+ }
+ return result[1];
+ }
+
+ void closeSync() {
+ if (!isClosed) {
+ _nativeCloseSync();
+ _SocketResourceInfo.SocketClosed(resourceInfo);
+ isClosed = true;
+ }
+ }
+
+ // Create the appropriate error/exception from different returned
+ // error objects.
+ static createError(error, String message,
+ [InternetAddress address, int port]) {
+ if (error is OSError) {
+ return new SocketException(message,
+ osError: error, address: address, port: port);
+ } else {
+ return new SocketException(message, address: address, port: port);
+ }
+ }
+
+ static List<_InternetAddress> lookup(String host,
+ {InternetAddressType type: InternetAddressType.ANY}) {
+ var response = _nativeLookupRequest(host, type._value);
+ if (response is OSError) {
+ throw response;
+ }
+ List<_InternetAddress> addresses =
+ new List<_InternetAddress>(response.length);
+ for (int i = 0; i < response.length; ++i) {
+ var result = response[i];
+ addresses[i] = new _InternetAddress(result[1], host, result[2]);
+ }
+ return addresses;
+ }
+
+ int readIntoSync(List<int> buffer, int start, int end) {
+ _checkAvailable();
+ if (isClosedRead) {
+ throw new SocketException("Socket is closed for reading");
+ }
+
+ if ((buffer is! List) ||
+ ((start != null) && (start is! int)) ||
+ ((end != null) && (end is! int))) {
+ throw new ArgumentError("Invalid arguments to readIntoSync");
+ }
+ if (start == null) {
+ throw new ArgumentError("start cannot be null");
+ }
+ end = RangeError.checkValidRange(start, end, buffer.length);
+ if (end == start) {
+ return 0;
+ }
+ var result = _nativeReadInto(buffer, start, (end - start));
+ if (result is OSError) {
+ throw new SocketException("readIntoSync failed", osError: result);
+ }
+ resourceInfo.addRead(result);
+ return result;
+ }
+
+ List<int> readSync(int len) {
+ _checkAvailable();
+ if (isClosedRead) {
+ throw new SocketException("Socket is closed for reading");
+ }
+
+ if ((len != null) && (len < 0)) {
+ throw new ArgumentError("Illegal length $len");
+ }
+ if (len == 0) {
+ return null;
+ }
+ var result = _nativeRead(len);
+ if (result is OSError) {
+ throw result;
+ }
+ assert(resourceInfo != null);
+ if (result != null) {
+ if (resourceInfo != null) {
+ resourceInfo.totalRead += result.length;
+ }
+ }
+ if (resourceInfo != null) {
+ resourceInfo.didRead();
+ }
+ return result;
+ }
+
+ static void setupResourceInfo(_NativeSynchronousSocket socket) {
+ socket.resourceInfo = new _SocketResourceInfo(socket);
+ }
+
+ void shutdown(SocketDirection direction) {
+ if (isClosed) {
+ return;
+ }
+ switch (direction) {
+ case SocketDirection.receive:
+ shutdownRead();
+ break;
+ case SocketDirection.send:
+ shutdownWrite();
+ break;
+ case SocketDirection.both:
+ closeSync();
+ break;
+ default:
+ throw new ArgumentError(direction);
+ }
+ }
+
+ void shutdownRead() {
+ if (isClosed || isClosedRead) {
+ return;
+ }
+ if (isClosedWrite) {
+ closeSync();
+ } else {
+ _nativeShutdownRead();
+ }
+ isClosedRead = true;
+ }
+
+ void shutdownWrite() {
+ if (isClosed || isClosedWrite) {
+ return;
+ }
+ if (isClosedRead) {
+ closeSync();
+ } else {
+ _nativeShutdownWrite();
+ }
+ isClosedWrite = true;
+ }
+
+ void writeFromSync(List<int> buffer, int start, int end) {
+ _checkAvailable();
+ if (isClosedWrite) {
+ throw new SocketException("Socket is closed for writing");
+ }
+ if ((buffer is! List) ||
+ ((start != null) && (start is! int)) ||
+ ((end != null) && (end is! int))) {
+ throw new ArgumentError("Invalid arguments to writeFromSync");
+ }
+ if (start == null) {
+ throw new ArgumentError("start cannot be equal to null");
+ }
+
+ end = RangeError.checkValidRange(start, end, buffer.length);
+ if (end == start) {
+ return;
+ }
+
+ _BufferAndStart bufferAndStart =
+ _ensureFastAndSerializableByteData(buffer, start, end);
+ var result = _nativeWrite(bufferAndStart.buffer, bufferAndStart.start,
+ end - (start - bufferAndStart.start));
+ if (result is OSError) {
+ throw new SocketException("writeFromSync failed", osError: result);
+ }
+ assert(resourceInfo != null);
+ if (resourceInfo != null) {
+ resourceInfo.addWrite(result);
+ }
+ }
+
+ void _checkAvailable() {
+ if (isClosed) {
+ throw const SocketException.closed();
+ }
+ }
+
+ // Native method declarations.
+ static _nativeLookupRequest(host, int type)
+ native "SynchronousSocket_LookupRequest";
+ _nativeCreateConnectSync(host, int port)
+ native "SynchronousSocket_CreateConnectSync";
+ _nativeAvailable() native "SynchronousSocket_Available";
+ _nativeCloseSync() native "SynchronousSocket_CloseSync";
+ int _nativeGetPort() native "SynchronousSocket_GetPort";
+ List _nativeGetRemotePeer() native "SynchronousSocket_GetRemotePeer";
+ _nativeRead(int len) native "SynchronousSocket_Read";
+ _nativeReadInto(List<int> buffer, int offset, int bytes)
+ native "SynchronousSocket_ReadList";
+ _nativeShutdownRead() native "SynchronousSocket_ShutdownRead";
+ _nativeShutdownWrite() native "SynchronousSocket_ShutdownWrite";
+ _nativeWrite(List<int> buffer, int offset, int bytes)
+ native "SynchronousSocket_WriteList";
+}
diff --git a/sdk_nnbd/lib/_internal/vm/lib/array.dart b/sdk_nnbd/lib/_internal/vm/lib/array.dart
new file mode 100644
index 0000000..8113024
--- /dev/null
+++ b/sdk_nnbd/lib/_internal/vm/lib/array.dart
@@ -0,0 +1,260 @@
+// 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.5
+
+// part of "core_patch.dart";
+
+@pragma("vm:entry-point")
+class _List<E> extends FixedLengthListBase<E> {
+ @pragma("vm:exact-result-type", _List)
+ @pragma("vm:prefer-inline")
+ factory _List(length) native "List_allocate";
+
+ E operator [](int index) native "List_getIndexed";
+
+ void operator []=(int index, E value) {
+ _setIndexed(index, value);
+ }
+
+ void _setIndexed(int index, E value) native "List_setIndexed";
+
+ @pragma("vm:exact-result-type", "dart:core#_Smi")
+ @pragma("vm:prefer-inline")
+ int get length native "List_getLength";
+
+ @pragma("vm:prefer-inline")
+ List _slice(int start, int count, bool needsTypeArgument) {
+ if (count <= 64) {
+ final result = needsTypeArgument ? new _List<E>(count) : new _List(count);
+ for (int i = 0; i < result.length; i++) {
+ result[i] = this[start + i];
+ }
+ return result;
+ } else {
+ return _sliceInternal(start, count, needsTypeArgument);
+ }
+ }
+
+ List _sliceInternal(int start, int count, bool needsTypeArgument)
+ native "List_slice";
+
+ // List interface.
+ void setRange(int start, int end, Iterable<E> iterable, [int skipCount = 0]) {
+ if (start < 0 || start > this.length) {
+ throw new RangeError.range(start, 0, this.length);
+ }
+ if (end < start || end > this.length) {
+ throw new RangeError.range(end, start, this.length);
+ }
+ int length = end - start;
+ if (length == 0) return;
+ if (identical(this, iterable)) {
+ Lists.copy(this, skipCount, this, start, length);
+ } else if (ClassID.getID(iterable) == ClassID.cidArray) {
+ final _List<E> iterableAsList = iterable;
+ Lists.copy(iterableAsList, skipCount, this, start, length);
+ } else if (iterable is List<E>) {
+ Lists.copy(iterable, skipCount, this, start, length);
+ } else {
+ Iterator it = iterable.iterator;
+ while (skipCount > 0) {
+ if (!it.moveNext()) return;
+ skipCount--;
+ }
+ for (int i = start; i < end; i++) {
+ if (!it.moveNext()) return;
+ this[i] = it.current;
+ }
+ }
+ }
+
+ void setAll(int index, Iterable<E> iterable) {
+ if (index < 0 || index > this.length) {
+ throw new RangeError.range(index, 0, this.length, "index");
+ }
+ List<E> iterableAsList;
+ if (identical(this, iterable)) {
+ iterableAsList = this;
+ } else if (ClassID.getID(iterable) == ClassID.cidArray) {
+ iterableAsList = iterable;
+ } else if (iterable is List<E>) {
+ iterableAsList = iterable;
+ } else {
+ for (var value in iterable) {
+ this[index++] = value;
+ }
+ return;
+ }
+ int length = iterableAsList.length;
+ if (index + length > this.length) {
+ throw new RangeError.range(index + length, 0, this.length);
+ }
+ Lists.copy(iterableAsList, 0, this, index, length);
+ }
+
+ List<E> sublist(int start, [int end]) {
+ end = RangeError.checkValidRange(start, end, this.length);
+ int length = end - start;
+ if (length == 0) return <E>[];
+ var result = new _GrowableList<E>._withData(_slice(start, length, false));
+ result._setLength(length);
+ return result;
+ }
+
+ // Iterable interface.
+
+ @pragma("vm:prefer-inline")
+ void forEach(f(E element)) {
+ final length = this.length;
+ for (int i = 0; i < length; i++) {
+ f(this[i]);
+ }
+ }
+
+ @pragma("vm:prefer-inline")
+ Iterator<E> get iterator {
+ return new _FixedSizeArrayIterator<E>(this);
+ }
+
+ E get first {
+ if (length > 0) return this[0];
+ throw IterableElementError.noElement();
+ }
+
+ E get last {
+ if (length > 0) return this[length - 1];
+ throw IterableElementError.noElement();
+ }
+
+ E get single {
+ if (length == 1) return this[0];
+ if (length == 0) throw IterableElementError.noElement();
+ throw IterableElementError.tooMany();
+ }
+
+ List<E> toList({bool growable: true}) {
+ var length = this.length;
+ if (length > 0) {
+ var result = _slice(0, length, !growable);
+ if (growable) {
+ result = new _GrowableList<E>._withData(result).._setLength(length);
+ }
+ return result;
+ }
+ // _GrowableList._withData must not be called with empty list.
+ return growable ? <E>[] : new List<E>(0);
+ }
+}
+
+// This is essentially the same class as _List, but it does not
+// permit any modification of array elements from Dart code. We use
+// this class for arrays constructed from Dart array literals.
+// TODO(hausner): We should consider the trade-offs between two
+// classes (and inline cache misses) versus a field in the native
+// implementation (checks when modifying). We should keep watching
+// the inline cache misses.
+@pragma("vm:entry-point")
+class _ImmutableList<E> extends UnmodifiableListBase<E> {
+ factory _ImmutableList._uninstantiable() {
+ throw new UnsupportedError(
+ "ImmutableArray can only be allocated by the VM");
+ }
+
+ factory _ImmutableList._from(List from, int offset, int length)
+ native "ImmutableList_from";
+
+ E operator [](int index) native "List_getIndexed";
+
+ @pragma("vm:exact-result-type", "dart:core#_Smi")
+ @pragma("vm:prefer-inline")
+ int get length native "List_getLength";
+
+ List<E> sublist(int start, [int end]) {
+ end = RangeError.checkValidRange(start, end, this.length);
+ int length = end - start;
+ if (length == 0) return <E>[];
+ List list = new _List(length);
+ for (int i = 0; i < length; i++) {
+ list[i] = this[start + i];
+ }
+ var result = new _GrowableList<E>._withData(list);
+ result._setLength(length);
+ return result;
+ }
+
+ // Collection interface.
+
+ @pragma("vm:prefer-inline")
+ void forEach(f(E element)) {
+ final length = this.length;
+ for (int i = 0; i < length; i++) {
+ f(this[i]);
+ }
+ }
+
+ @pragma("vm:prefer-inline")
+ Iterator<E> get iterator {
+ return new _FixedSizeArrayIterator<E>(this);
+ }
+
+ E get first {
+ if (length > 0) return this[0];
+ throw IterableElementError.noElement();
+ }
+
+ E get last {
+ if (length > 0) return this[length - 1];
+ throw IterableElementError.noElement();
+ }
+
+ E get single {
+ if (length == 1) return this[0];
+ if (length == 0) throw IterableElementError.noElement();
+ throw IterableElementError.tooMany();
+ }
+
+ List<E> toList({bool growable: true}) {
+ var length = this.length;
+ if (length > 0) {
+ List list = growable ? new _List(length) : new _List<E>(length);
+ for (int i = 0; i < length; i++) {
+ list[i] = this[i];
+ }
+ if (!growable) return list;
+ var result = new _GrowableList<E>._withData(list);
+ result._setLength(length);
+ return result;
+ }
+ return growable ? <E>[] : new _List<E>(0);
+ }
+}
+
+// Iterator for arrays with fixed size.
+class _FixedSizeArrayIterator<E> implements Iterator<E> {
+ final List<E> _array;
+ final int _length; // Cache array length for faster access.
+ int _index;
+ E _current;
+
+ _FixedSizeArrayIterator(List<E> array)
+ : _array = array,
+ _length = array.length,
+ _index = 0 {
+ assert(array is _List<E> || array is _ImmutableList<E>);
+ }
+
+ E get current => _current;
+
+ @pragma("vm:prefer-inline")
+ bool moveNext() {
+ if (_index >= _length) {
+ _current = null;
+ return false;
+ }
+ _current = _array[_index];
+ _index++;
+ return true;
+ }
+}
diff --git a/sdk_nnbd/lib/_internal/vm/lib/array_patch.dart b/sdk_nnbd/lib/_internal/vm/lib/array_patch.dart
new file mode 100644
index 0000000..4c39149
--- /dev/null
+++ b/sdk_nnbd/lib/_internal/vm/lib/array_patch.dart
@@ -0,0 +1,79 @@
+// 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.5
+
+// part of "core_patch.dart";
+
+@patch
+class List<E> {
+ @patch
+ factory List([int length]) native "List_new";
+
+ @patch
+ factory List.filled(int length, E fill, {bool growable: false}) {
+ // All error handling on the length parameter is done at the implementation
+ // of new _List.
+ var result = growable ? new _GrowableList<E>(length) : new _List<E>(length);
+ if (fill != null) {
+ for (int i = 0; i < length; i++) {
+ result[i] = fill;
+ }
+ }
+ return result;
+ }
+
+ @patch
+ factory List.from(Iterable elements, {bool growable: true}) {
+ if (elements is EfficientLengthIterable<E>) {
+ int length = elements.length;
+ var list = growable ? new _GrowableList<E>(length) : new _List<E>(length);
+ if (length > 0) {
+ // Avoid creating iterator unless necessary.
+ int i = 0;
+ for (var element in elements) {
+ list[i++] = element;
+ }
+ }
+ return list;
+ }
+ // If elements is an Iterable<E>, we won't need a type-test for each
+ // element. In the "common case" that elements is an Iterable<E>, this
+ // replaces a type-test on every element with a single type-test before
+ // starting the loop.
+ if (elements is Iterable<E>) {
+ List<E> list = new _GrowableList<E>(0);
+ for (E e in elements) {
+ list.add(e);
+ }
+ if (growable) return list;
+ return makeListFixedLength(list);
+ } else {
+ List<E> list = new _GrowableList<E>(0);
+ for (E e in elements) {
+ list.add(e);
+ }
+ if (growable) return list;
+ return makeListFixedLength(list);
+ }
+ }
+
+ @patch
+ factory List.unmodifiable(Iterable elements) {
+ final result = new List<E>.from(elements, growable: false);
+ return makeFixedListUnmodifiable(result);
+ }
+
+ // Factory constructing a mutable List from a parser generated List literal.
+ // [elements] contains elements that are already type checked.
+ @pragma("vm:entry-point", "call")
+ factory List._fromLiteral(List elements) {
+ if (elements.isEmpty) {
+ return new _GrowableList<E>(0);
+ }
+ var result = new _GrowableList<E>._withData(elements);
+ result._setLength(elements.length);
+ return result;
+ }
+}
diff --git a/sdk_nnbd/lib/_internal/vm/lib/async_patch.dart b/sdk_nnbd/lib/_internal/vm/lib/async_patch.dart
new file mode 100644
index 0000000..f51fa04
--- /dev/null
+++ b/sdk_nnbd/lib/_internal/vm/lib/async_patch.dart
@@ -0,0 +1,313 @@
+// Copyright (c) 2015, 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.5
+
+/// Note: the VM concatenates all patch files into a single patch file. This
+/// file is the first patch in "dart:async" which contains all the imports used
+/// by patches of that library. We plan to change this when we have a shared
+/// front end and simply use parts.
+
+import "dart:_internal" show VMLibraryHooks, patch;
+
+/// These are the additional parts of this patch library:
+// part "deferred_load_patch.dart";
+// part "schedule_microtask_patch.dart";
+// part "timer_patch.dart";
+
+// Equivalent of calling FATAL from C++ code.
+_fatal(msg) native "DartAsync_fatal";
+
+class _AsyncAwaitCompleter<T> implements Completer<T> {
+ final _future = new _Future<T>();
+ bool isSync;
+
+ _AsyncAwaitCompleter() : isSync = false;
+
+ void complete([FutureOr<T> value]) {
+ if (!isSync || value is Future<T>) {
+ _future._asyncComplete(value);
+ } else {
+ _future._completeWithValue(value);
+ }
+ }
+
+ void completeError(e, [st]) {
+ if (isSync) {
+ _future._completeError(e, st);
+ } else {
+ _future._asyncCompleteError(e, st);
+ }
+ }
+
+ void start(f) {
+ f();
+ isSync = true;
+ }
+
+ Future<T> get future => _future;
+ bool get isCompleted => !_future._mayComplete;
+}
+
+// We need to pass the value as first argument and leave the second and third
+// arguments empty (used for error handling).
+// See vm/ast_transformer.cc for usage.
+Function _asyncThenWrapperHelper(continuation) {
+ // Any function that is used as an asynchronous callback must be registered
+ // in the current Zone. Normally, this is done by the future when a
+ // callback is registered (for example with `.then` or `.catchError`). In our
+ // case we want to reuse the same callback multiple times and therefore avoid
+ // the multiple registrations. For our internal futures (`_Future`) we can
+ // use the shortcut-version of `.then`, and skip the registration. However,
+ // that means that the continuation must be registered by us.
+ //
+ // Furthermore, we know that the root-zone doesn't actually do anything and
+ // we can therefore skip the registration call for it.
+ //
+ // Note, that the continuation accepts up to three arguments. If the current
+ // zone is the root zone, we don't wrap the continuation, and a bad
+ // `Future` implementation could potentially invoke the callback with the
+ // wrong number of arguments.
+ if (Zone.current == Zone.root) return continuation;
+ return Zone.current.registerUnaryCallback((x) => continuation(x, null, null));
+}
+
+// We need to pass the exception and stack trace objects as second and third
+// parameter to the continuation. See vm/ast_transformer.cc for usage.
+Function _asyncErrorWrapperHelper(continuation) {
+ // See comments of `_asyncThenWrapperHelper`.
+ var errorCallback = (e, s) => continuation(null, e, s);
+ if (Zone.current == Zone.root) return errorCallback;
+ return Zone.current.registerBinaryCallback(errorCallback);
+}
+
+/// Registers the [thenCallback] and [errorCallback] on the given [object].
+///
+/// If [object] is not a future, then it is wrapped into one.
+///
+/// Returns the result of registering with `.then`.
+Future _awaitHelper(
+ var object, Function thenCallback, Function errorCallback, var awaiter) {
+ if (object is! Future) {
+ object = new _Future().._setValue(object);
+ } else if (object is! _Future) {
+ return object.then(thenCallback, onError: errorCallback);
+ }
+ // `object` is a `_Future`.
+ //
+ // Since the callbacks have been registered in the current zone (see
+ // [_asyncThenWrapperHelper] and [_asyncErrorWrapperHelper]), we can avoid
+ // another registration and directly invoke the no-zone-registration `.then`.
+ //
+ // We can only do this for our internal futures (the default implementation of
+ // all futures that are constructed by the `dart:async` library).
+ object._awaiter = awaiter;
+ return object._thenAwait(thenCallback, errorCallback);
+}
+
+// Called as part of the 'await for (...)' construct. Registers the
+// awaiter on the stream.
+void _asyncStarListenHelper(var object, var awaiter) {
+ if (object is! _StreamImpl) {
+ return;
+ }
+ // `object` is a `_StreamImpl`.
+ object._awaiter = awaiter;
+}
+
+@pragma("vm:entry-point", "call")
+void _asyncStarMoveNextHelper(var stream) {
+ if (stream is! _StreamImpl) {
+ return;
+ }
+ // stream is a _StreamImpl.
+ if (stream._generator == null) {
+ // No generator registered, this isn't an async* Stream.
+ return;
+ }
+ _moveNextDebuggerStepCheck(stream._generator);
+}
+
+// _AsyncStarStreamController is used by the compiler to implement
+// async* generator functions.
+@pragma("vm:entry-point")
+class _AsyncStarStreamController<T> {
+ StreamController<T> controller;
+ Function asyncStarBody;
+ bool isAdding = false;
+ bool onListenReceived = false;
+ bool isScheduled = false;
+ bool isSuspendedAtYield = false;
+ _Future cancellationFuture = null;
+
+ Stream<T> get stream {
+ final Stream<T> local = controller.stream;
+ if (local is _StreamImpl<T>) {
+ local._generator = asyncStarBody;
+ }
+ return local;
+ }
+
+ void runBody() {
+ isScheduled = false;
+ isSuspendedAtYield = false;
+ asyncStarBody();
+ }
+
+ void scheduleGenerator() {
+ if (isScheduled || controller.isPaused || isAdding) {
+ return;
+ }
+ isScheduled = true;
+ scheduleMicrotask(runBody);
+ }
+
+ // Adds element to stream, returns true if the caller should terminate
+ // execution of the generator.
+ //
+ // TODO(hausner): Per spec, the generator should be suspended before
+ // exiting when the stream is closed. We could add a getter like this:
+ // get isCancelled => controller.hasListener;
+ // The generator would translate a 'yield e' statement to
+ // controller.add(e);
+ // suspend;
+ // if (controller.isCancelled) return;
+ bool add(T event) {
+ if (!onListenReceived) _fatal("yield before stream is listened to");
+ if (isSuspendedAtYield) _fatal("unexpected yield");
+ // If stream is cancelled, tell caller to exit the async generator.
+ if (!controller.hasListener) {
+ return true;
+ }
+ controller.add(event);
+ scheduleGenerator();
+ isSuspendedAtYield = true;
+ return false;
+ }
+
+ // Adds the elements of stream into this controller's stream.
+ // The generator will be scheduled again when all of the
+ // elements of the added stream have been consumed.
+ // Returns true if the caller should terminate
+ // execution of the generator.
+ bool addStream(Stream<T> stream) {
+ if (!onListenReceived) _fatal("yield before stream is listened to");
+ // If stream is cancelled, tell caller to exit the async generator.
+ if (!controller.hasListener) return true;
+ isAdding = true;
+ var whenDoneAdding = controller.addStream(stream, cancelOnError: false);
+ whenDoneAdding.then((_) {
+ isAdding = false;
+ scheduleGenerator();
+ if (!isScheduled) isSuspendedAtYield = true;
+ });
+ return false;
+ }
+
+ void addError(Object error, StackTrace stackTrace) {
+ if ((cancellationFuture != null) && cancellationFuture._mayComplete) {
+ // If the stream has been cancelled, complete the cancellation future
+ // with the error.
+ cancellationFuture._completeError(error, stackTrace);
+ return;
+ }
+ // If stream is cancelled, tell caller to exit the async generator.
+ if (!controller.hasListener) return;
+ controller.addError(error, stackTrace);
+ // No need to schedule the generator body here. This code is only
+ // called from the catch clause of the implicit try-catch-finally
+ // around the generator body. That is, we are on the error path out
+ // of the generator and do not need to run the generator again.
+ }
+
+ close() {
+ if ((cancellationFuture != null) && cancellationFuture._mayComplete) {
+ // If the stream has been cancelled, complete the cancellation future
+ // with the error.
+ cancellationFuture._completeWithValue(null);
+ }
+ controller.close();
+ }
+
+ _AsyncStarStreamController(this.asyncStarBody) {
+ controller = new StreamController(
+ onListen: this.onListen,
+ onResume: this.onResume,
+ onCancel: this.onCancel);
+ }
+
+ onListen() {
+ assert(!onListenReceived);
+ onListenReceived = true;
+ scheduleGenerator();
+ }
+
+ onResume() {
+ if (isSuspendedAtYield) {
+ scheduleGenerator();
+ }
+ }
+
+ onCancel() {
+ if (controller.isClosed) {
+ return null;
+ }
+ if (cancellationFuture == null) {
+ cancellationFuture = new _Future();
+ // Only resume the generator if it is suspended at a yield.
+ // Cancellation does not affect an async generator that is
+ // suspended at an await.
+ if (isSuspendedAtYield) {
+ scheduleGenerator();
+ }
+ }
+ return cancellationFuture;
+ }
+}
+
+@patch
+void _rethrow(Object error, StackTrace stackTrace) native "Async_rethrow";
+
+@patch
+class _Future<T> {
+ /// The closure implementing the async[*]-body that is `await`ing this future.
+ Function _awaiter;
+}
+
+@patch
+class _StreamImpl<T> {
+ /// The closure implementing the async[*]-body that is `await`ing this future.
+ Function _awaiter;
+
+ /// The closure implementing the async-generator body that is creating events
+ /// for this stream.
+ Function _generator;
+}
+
+@pragma("vm:entry-point", "call")
+void _completeOnAsyncReturn(Completer completer, Object value) {
+ completer.complete(value);
+}
+
+/// Returns a [StackTrace] object containing the synchronous prefix for this
+/// asynchronous method.
+//
+// This method is recognized. It performs a runtime call if
+// FLAG_causal_async_stacks is enabled or returns `null` otherwise.
+@pragma("vm:prefer-inline")
+Object _asyncStackTraceHelper(Function async_op)
+ native "StackTrace_asyncStackTraceHelper";
+
+// This method is asm intrinsified.
+@pragma("vm:entry-point", "call")
+void _clearAsyncThreadStackTrace()
+ native "StackTrace_clearAsyncThreadStackTrace";
+
+// This method is asm intrinsified.
+@pragma("vm:entry-point", "call")
+void _setAsyncThreadStackTrace(StackTrace stackTrace)
+ native "StackTrace_setAsyncThreadStackTrace";
+
+void _moveNextDebuggerStepCheck(Function async_op)
+ native "AsyncStarMoveNext_debuggerStepCheck";
diff --git a/sdk_nnbd/lib/_internal/vm/lib/bigint_patch.dart b/sdk_nnbd/lib/_internal/vm/lib/bigint_patch.dart
new file mode 100644
index 0000000..1730be8
--- /dev/null
+++ b/sdk_nnbd/lib/_internal/vm/lib/bigint_patch.dart
@@ -0,0 +1,2812 @@
+// Copyright (c) 2017, 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.5
+
+// part of dart.core;
+
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+/*
+ * Copyright (c) 2003-2005 Tom Wu
+ * Copyright (c) 2012 Adam Singer (adam@solvr.io)
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
+ * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * IN NO EVENT SHALL TOM WU BE LIABLE FOR ANY SPECIAL, INCIDENTAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER OR NOT ADVISED OF
+ * THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF LIABILITY, ARISING OUT
+ * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * In addition, the following condition applies:
+ *
+ * All redistributions must retain an intact copy of this copyright notice
+ * and disclaimer.
+ */
+
+@patch
+class BigInt implements Comparable<BigInt> {
+ @patch
+ static BigInt get zero => _BigIntImpl.zero;
+ @patch
+ static BigInt get one => _BigIntImpl.one;
+ @patch
+ static BigInt get two => _BigIntImpl.two;
+
+ @patch
+ static BigInt parse(String source, {int radix}) =>
+ _BigIntImpl.parse(source, radix: radix);
+
+ @patch
+ static BigInt tryParse(String source, {int radix}) =>
+ _BigIntImpl._tryParse(source, radix: radix);
+
+ @patch
+ factory BigInt.from(num value) => new _BigIntImpl.from(value);
+}
+
+int _max(int a, int b) => a > b ? a : b;
+int _min(int a, int b) => a < b ? a : b;
+
+/// Allocate a new digits list of even length.
+Uint32List _newDigits(int length) => new Uint32List(length + (length & 1));
+
+/**
+ * An implementation for the arbitrarily large integer.
+ *
+ * The integer number is represented by a sign, an array of 32-bit unsigned
+ * integers in little endian format, and a number of used digits in that array.
+ */
+class _BigIntImpl implements BigInt {
+ // Bits per digit.
+ static const int _digitBits = 32;
+ static const int _digitBase = 1 << _digitBits;
+ static const int _digitMask = (1 << _digitBits) - 1;
+
+ // Bits per half digit.
+ static const int _halfDigitBits = _digitBits >> 1;
+ static const int _halfDigitMask = (1 << _halfDigitBits) - 1;
+
+ static final _BigIntImpl zero = new _BigIntImpl._fromInt(0);
+ static final _BigIntImpl one = new _BigIntImpl._fromInt(1);
+ static final _BigIntImpl two = new _BigIntImpl._fromInt(2);
+
+ static final _BigIntImpl _minusOne = -one;
+ static final _BigIntImpl _oneDigitMask = new _BigIntImpl._fromInt(_digitMask);
+ static final _BigIntImpl _twoDigitMask = (one << (2 * _digitBits)) - one;
+ static final _BigIntImpl _oneBillion = new _BigIntImpl._fromInt(1000000000);
+ static const int _minInt = -0x8000000000000000;
+ static const int _maxInt = 0x7fffffffffffffff;
+
+ // Result cache for last _divRem call.
+ // Result cache for last _divRem call.
+ static Uint32List _lastDividendDigits;
+ static int _lastDividendUsed;
+ static Uint32List _lastDivisorDigits;
+ static int _lastDivisorUsed;
+ static Uint32List _lastQuoRemDigits;
+ static int _lastQuoRemUsed;
+ static int _lastRemUsed;
+ static int _lastRem_nsh;
+
+ /// Whether this bigint is negative.
+ final bool _isNegative;
+
+ /// The unsigned digits of this bigint.
+ ///
+ /// The least significant digit is in slot 0.
+ /// The list may have more digits than needed. That is, `_digits.length` may
+ /// be strictly greater than `_used`.
+ /// Also, `_digits.length` must always be even, because intrinsics on 64-bit
+ /// platforms may process a digit pair as a 64-bit value.
+ final Uint32List _digits;
+
+ /// The number of used entries in [_digits].
+ ///
+ /// To avoid reallocating [Uint32List]s, lists that are too big are not
+ /// replaced, but `_used` reflects the smaller number of digits actually used.
+ ///
+ /// Note that functions shortening an existing list of digits to a smaller
+ /// `_used` number of digits must ensure that the highermost pair of digits
+ /// is correct when read as a 64-bit value by intrinsics. Therefore, if the
+ /// smaller '_used' number is odd, the high digit of that pair must be
+ /// explicitly cleared, i.e. _digits[_used] = 0, which cannot result in an
+ /// out of bounds access, since the length of the list is guaranteed to be
+ /// even.
+ final int _used;
+
+ /**
+ * Parses [source] as a, possibly signed, integer literal and returns its
+ * value.
+ *
+ * The [source] must be a non-empty sequence of base-[radix] digits,
+ * optionally prefixed with a minus or plus sign ('-' or '+').
+ *
+ * The [radix] must be in the range 2..36. The digits used are
+ * first the decimal digits 0..9, and then the letters 'a'..'z' with
+ * values 10 through 35. Also accepts upper-case letters with the same
+ * values as the lower-case ones.
+ *
+ * If no [radix] is given then it defaults to 10. In this case, the [source]
+ * digits may also start with `0x`, in which case the number is interpreted
+ * as a hexadecimal literal, which effectively means that the `0x` is ignored
+ * and the radix is instead set to 16.
+ *
+ * For any int `n` and radix `r`, it is guaranteed that
+ * `n == int.parse(n.toRadixString(r), radix: r)`.
+ *
+ * Throws a [FormatException] if the [source] is not a valid integer literal,
+ * optionally prefixed by a sign.
+ */
+ static _BigIntImpl parse(String source, {int radix}) {
+ var result = _tryParse(source, radix: radix);
+ if (result == null) {
+ throw new FormatException("Could not parse BigInt", source);
+ }
+ return result;
+ }
+
+ /// Parses a decimal bigint literal.
+ ///
+ /// The [source] must not contain leading or trailing whitespace.
+ static _BigIntImpl _parseDecimal(String source, bool isNegative) {
+ const _0 = 48;
+
+ int part = 0;
+ _BigIntImpl result = zero;
+ // Read in the source 9 digits at a time.
+ // The first part may have a few leading virtual '0's to make the remaining
+ // parts all have exactly 9 digits.
+ int digitInPartCount = 9 - source.length.remainder(9);
+ if (digitInPartCount == 9) digitInPartCount = 0;
+ for (int i = 0; i < source.length; i++) {
+ part = part * 10 + source.codeUnitAt(i) - _0;
+ if (++digitInPartCount == 9) {
+ result = result * _oneBillion + new _BigIntImpl._fromInt(part);
+ part = 0;
+ digitInPartCount = 0;
+ }
+ }
+ if (isNegative) return -result;
+ return result;
+ }
+
+ /// Returns the value of a given source digit.
+ ///
+ /// Source digits between "0" and "9" (inclusive) return their decimal value.
+ ///
+ /// Source digits between "a" and "z", or "A" and "Z" (inclusive) return
+ /// 10 + their position in the ASCII alphabet.
+ ///
+ /// The incoming [codeUnit] must be an ASCII code-unit.
+ static int _codeUnitToRadixValue(int codeUnit) {
+ // We know that the characters must be ASCII as otherwise the
+ // regexp wouldn't have matched. Lowercasing by doing `| 0x20` is thus
+ // guaranteed to be a safe operation, since it preserves digits
+ // and lower-cases ASCII letters.
+ const int _0 = 48;
+ const int _9 = 57;
+ const int _a = 97;
+ if (_0 <= codeUnit && codeUnit <= _9) return codeUnit - _0;
+ codeUnit |= 0x20;
+ var result = codeUnit - _a + 10;
+ return result;
+ }
+
+ /// Parses the given [source] string, starting at [startPos], as a hex
+ /// literal.
+ ///
+ /// If [isNegative] is true, negates the result before returning it.
+ ///
+ /// The [source] (substring) must be a valid hex literal.
+ static _BigIntImpl _parseHex(String source, int startPos, bool isNegative) {
+ int hexCharsPerDigit = _digitBits ~/ 4;
+ int sourceLength = source.length - startPos;
+ int used = (sourceLength + hexCharsPerDigit - 1) ~/ hexCharsPerDigit;
+ var digits = _newDigits(used);
+
+ int lastDigitLength = sourceLength - (used - 1) * hexCharsPerDigit;
+ int digitIndex = used - 1;
+ int i = startPos;
+ int digit = 0;
+ for (int j = 0; j < lastDigitLength; j++) {
+ var value = _codeUnitToRadixValue(source.codeUnitAt(i++));
+ if (value >= 16) return null;
+ digit = digit * 16 + value;
+ }
+ digits[digitIndex--] = digit;
+
+ while (i < source.length) {
+ digit = 0;
+ for (int j = 0; j < hexCharsPerDigit; j++) {
+ var value = _codeUnitToRadixValue(source.codeUnitAt(i++));
+ if (value >= 16) return null;
+ digit = digit * 16 + value;
+ }
+ digits[digitIndex--] = digit;
+ }
+ if (used == 1 && digits[0] == 0) return zero;
+ return new _BigIntImpl._(isNegative, used, digits);
+ }
+
+ /// Parses the given [source] as a [radix] literal.
+ ///
+ /// The [source] will be checked for invalid characters. If it is invalid,
+ /// this function returns `null`.
+ static _BigIntImpl _parseRadix(String source, int radix, bool isNegative) {
+ var result = zero;
+ var base = new _BigIntImpl._fromInt(radix);
+ for (int i = 0; i < source.length; i++) {
+ var value = _codeUnitToRadixValue(source.codeUnitAt(i));
+ if (value >= radix) return null;
+ result = result * base + new _BigIntImpl._fromInt(value);
+ }
+ if (isNegative) return -result;
+ return result;
+ }
+
+ /// Tries to parse the given [source] as a [radix] literal.
+ ///
+ /// Returns the parsed big integer, or `null` if it failed.
+ ///
+ /// If the [radix] is `null` accepts decimal literals or `0x` hex literals.
+ static _BigIntImpl _tryParse(String source, {int radix}) {
+ if (source == "") return null;
+
+ var re = new RegExp(r'^\s*([+-]?)((0x[a-f0-9]+)|(\d+)|([a-z0-9]+))\s*$',
+ caseSensitive: false);
+ var match = re.firstMatch(source);
+ int signIndex = 1;
+ int hexIndex = 3;
+ int decimalIndex = 4;
+ int nonDecimalHexIndex = 5;
+ if (match == null) return null;
+
+ bool isNegative = match[signIndex] == "-";
+
+ String decimalMatch = match[decimalIndex];
+ String hexMatch = match[hexIndex];
+ String nonDecimalMatch = match[nonDecimalHexIndex];
+
+ if (radix == null) {
+ if (decimalMatch != null) {
+ // Cannot fail because we know that the digits are all decimal.
+ return _parseDecimal(decimalMatch, isNegative);
+ }
+ if (hexMatch != null) {
+ // Cannot fail because we know that the digits are all hex.
+ return _parseHex(hexMatch, 2, isNegative);
+ }
+ return null;
+ }
+
+ if (radix is! int) {
+ throw new ArgumentError.value(radix, 'radix', 'is not an integer');
+ }
+ if (radix < 2 || radix > 36) {
+ throw new RangeError.range(radix, 2, 36, 'radix');
+ }
+ if (radix == 10 && decimalMatch != null) {
+ return _parseDecimal(decimalMatch, isNegative);
+ }
+ if (radix == 16 && (decimalMatch != null || nonDecimalMatch != null)) {
+ return _parseHex(decimalMatch ?? nonDecimalMatch, 0, isNegative);
+ }
+
+ return _parseRadix(
+ decimalMatch ?? nonDecimalMatch ?? hexMatch, radix, isNegative);
+ }
+
+ /// Finds the amount significant digits in the provided [digits] array.
+ static int _normalize(int used, Uint32List digits) {
+ while (used > 0 && digits[used - 1] == 0) used--;
+ return used;
+ }
+
+ /// Factory returning an instance initialized with the given field values.
+ /// If the [digits] array contains leading 0s, the [used] value is adjusted
+ /// accordingly. The [digits] array is not modified.
+ _BigIntImpl._(bool isNegative, int used, Uint32List digits)
+ : this._normalized(isNegative, _normalize(used, digits), digits);
+
+ _BigIntImpl._normalized(bool isNegative, this._used, this._digits)
+ : _isNegative = _used == 0 ? false : isNegative {
+ assert(_digits.length.isEven);
+ assert(_used.isEven || _digits[_used] == 0); // Leading zero for 64-bit.
+ }
+
+ /// Whether this big integer is zero.
+ bool get _isZero => _used == 0;
+
+ /// Allocates an array of the given [length] and copies the [digits] in the
+ /// range [from] to [to-1], starting at index 0, followed by leading zero
+ /// digits.
+ static Uint32List _cloneDigits(
+ Uint32List digits, int from, int to, int length) {
+ var resultDigits = _newDigits(length);
+ var n = to - from;
+ for (var i = 0; i < n; i++) {
+ resultDigits[i] = digits[from + i];
+ }
+ return resultDigits;
+ }
+
+ /// Allocates a big integer from the provided [value] number.
+ factory _BigIntImpl.from(num value) {
+ if (value == 0) return zero;
+ if (value == 1) return one;
+ if (value == 2) return two;
+
+ if (value.abs() < 0x100000000)
+ return new _BigIntImpl._fromInt(value.toInt());
+ if (value is double) return new _BigIntImpl._fromDouble(value);
+ return new _BigIntImpl._fromInt(value);
+ }
+
+ factory _BigIntImpl._fromInt(int value) {
+ bool isNegative = value < 0;
+ assert(_digitBits == 32);
+ var digits = _newDigits(2);
+ if (isNegative) {
+ // Handle the min 64-bit value differently, since its negation is not
+ // positive.
+ if (value == _minInt) {
+ digits[1] = 0x80000000;
+ return new _BigIntImpl._(true, 2, digits);
+ }
+ value = -value;
+ }
+ if (value < _digitBase) {
+ digits[0] = value;
+ return new _BigIntImpl._(isNegative, 1, digits);
+ }
+ digits[0] = value & _digitMask;
+ digits[1] = value >> _digitBits;
+ return new _BigIntImpl._(isNegative, 2, digits);
+ }
+
+ /// An 8-byte Uint8List we can reuse for [_fromDouble] to avoid generating
+ /// garbage.
+ static final Uint8List _bitsForFromDouble = new Uint8List(8);
+
+ factory _BigIntImpl._fromDouble(double value) {
+ const int exponentBias = 1075;
+
+ if (value.isNaN || value.isInfinite) {
+ throw new ArgumentError("Value must be finite: $value");
+ }
+ bool isNegative = value < 0;
+ if (isNegative) value = -value;
+
+ value = value.floorToDouble();
+ if (value == 0) return zero;
+
+ var bits = _bitsForFromDouble;
+ for (int i = 0; i < 8; i++) {
+ bits[i] = 0;
+ }
+ bits.buffer.asByteData().setFloat64(0, value, Endian.little);
+ // The exponent is in bits 53..63.
+ var biasedExponent = (bits[7] << 4) + (bits[6] >> 4);
+ var exponent = biasedExponent - exponentBias;
+
+ assert(_digitBits == 32);
+ // The significant bits are in 0 .. 52.
+ var unshiftedDigits = _newDigits(2);
+ unshiftedDigits[0] =
+ (bits[3] << 24) + (bits[2] << 16) + (bits[1] << 8) + bits[0];
+ // Don't forget to add the hidden bit.
+ unshiftedDigits[1] =
+ ((0x10 | (bits[6] & 0xF)) << 16) + (bits[5] << 8) + bits[4];
+
+ var unshiftedBig = new _BigIntImpl._normalized(false, 2, unshiftedDigits);
+ _BigIntImpl absResult = unshiftedBig;
+ if (exponent < 0) {
+ absResult = unshiftedBig >> -exponent;
+ } else if (exponent > 0) {
+ absResult = unshiftedBig << exponent;
+ }
+ if (isNegative) return -absResult;
+ return absResult;
+ }
+
+ /**
+ * Return the negative value of this integer.
+ *
+ * The result of negating an integer always has the opposite sign, except
+ * for zero, which is its own negation.
+ */
+ _BigIntImpl operator -() {
+ if (_used == 0) return this;
+ return new _BigIntImpl._(!_isNegative, _used, _digits);
+ }
+
+ /**
+ * Returns the absolute value of this integer.
+ *
+ * For any integer `x`, the result is the same as `x < 0 ? -x : x`.
+ */
+ _BigIntImpl abs() => _isNegative ? -this : this;
+
+ /// Returns this << n*_digitBits.
+ _BigIntImpl _dlShift(int n) {
+ final used = _used;
+ if (used == 0) {
+ return zero;
+ }
+ final resultUsed = used + n;
+ final digits = _digits;
+ final resultDigits = _newDigits(resultUsed);
+ for (int i = used - 1; i >= 0; i--) {
+ resultDigits[i + n] = digits[i];
+ }
+ return new _BigIntImpl._(_isNegative, resultUsed, resultDigits);
+ }
+
+ /// Same as [_dlShift] but works on the decomposed big integers.
+ ///
+ /// Returns `resultUsed`.
+ ///
+ /// `resultDigits[0..resultUsed-1] = xDigits[0..xUsed-1] << n*_digitBits`.
+ static int _dlShiftDigits(
+ Uint32List xDigits, int xUsed, int n, Uint32List resultDigits) {
+ if (xUsed == 0) {
+ return 0;
+ }
+ if (n == 0 && identical(resultDigits, xDigits)) {
+ return xUsed;
+ }
+ final resultUsed = xUsed + n;
+ assert(resultDigits.length >= resultUsed + (resultUsed & 1));
+ for (int i = xUsed - 1; i >= 0; i--) {
+ resultDigits[i + n] = xDigits[i];
+ }
+ for (int i = n - 1; i >= 0; i--) {
+ resultDigits[i] = 0;
+ }
+ if (resultUsed.isOdd) {
+ resultDigits[resultUsed] = 0;
+ }
+ return resultUsed;
+ }
+
+ /// Returns `this >> n*_digitBits`.
+ _BigIntImpl _drShift(int n) {
+ final used = _used;
+ if (used == 0) {
+ return zero;
+ }
+ final resultUsed = used - n;
+ if (resultUsed <= 0) {
+ return _isNegative ? _minusOne : zero;
+ }
+ final digits = _digits;
+ final resultDigits = _newDigits(resultUsed);
+ for (var i = n; i < used; i++) {
+ resultDigits[i - n] = digits[i];
+ }
+ final result = new _BigIntImpl._(_isNegative, resultUsed, resultDigits);
+ if (_isNegative) {
+ // Round down if any bit was shifted out.
+ for (var i = 0; i < n; i++) {
+ if (digits[i] != 0) {
+ return result - one;
+ }
+ }
+ }
+ return result;
+ }
+
+ /// Same as [_drShift] but works on the decomposed big integers.
+ ///
+ /// Returns `resultUsed`.
+ ///
+ /// `resultDigits[0..resultUsed-1] = xDigits[0..xUsed-1] >> n*_digitBits`.
+ static int _drShiftDigits(
+ Uint32List xDigits, int xUsed, int n, Uint32List resultDigits) {
+ final resultUsed = xUsed - n;
+ if (resultUsed <= 0) {
+ return 0;
+ }
+ assert(resultDigits.length >= resultUsed + (resultUsed & 1));
+ for (var i = n; i < xUsed; i++) {
+ resultDigits[i - n] = xDigits[i];
+ }
+ if (resultUsed.isOdd) {
+ resultDigits[resultUsed] = 0;
+ }
+ return resultUsed;
+ }
+
+ /// Shifts the digits of [xDigits] into the right place in [resultDigits].
+ ///
+ /// `resultDigits[ds..xUsed+ds] = xDigits[0..xUsed-1] << (n % _digitBits)`
+ /// where `ds = n ~/ _digitBits`
+ ///
+ /// Does *not* clear digits below ds.
+ ///
+ /// Note: This function may be intrinsified.
+ @pragma("vm:never-inline")
+ static void _lsh(
+ Uint32List xDigits, int xUsed, int n, Uint32List resultDigits) {
+ assert(xUsed > 0);
+ final digitShift = n ~/ _digitBits;
+ final bitShift = n % _digitBits;
+ final carryBitShift = _digitBits - bitShift;
+ final bitMask = (1 << carryBitShift) - 1;
+ var carry = 0;
+ for (int i = xUsed - 1; i >= 0; i--) {
+ final digit = xDigits[i];
+ resultDigits[i + digitShift + 1] = (digit >> carryBitShift) | carry;
+ carry = (digit & bitMask) << bitShift;
+ }
+ resultDigits[digitShift] = carry;
+ }
+
+ /**
+ * Shift the bits of this integer to the left by [shiftAmount].
+ *
+ * Shifting to the left makes the number larger, effectively multiplying
+ * the number by `pow(2, shiftIndex)`.
+ *
+ * There is no limit on the size of the result. It may be relevant to
+ * limit intermediate values by using the "and" operator with a suitable
+ * mask.
+ *
+ * It is an error if [shiftAmount] is negative.
+ */
+ _BigIntImpl operator <<(int shiftAmount) {
+ if (shiftAmount < 0) {
+ throw new ArgumentError("shift-amount must be positive $shiftAmount");
+ }
+ if (_isZero) return this;
+ final digitShift = shiftAmount ~/ _digitBits;
+ final bitShift = shiftAmount % _digitBits;
+ if (bitShift == 0) {
+ return _dlShift(digitShift);
+ }
+ // Need one extra digit to hold bits shifted by bitShift.
+ var resultUsed = _used + digitShift + 1;
+ // The 64-bit intrinsic requires one extra pair to work with.
+ var resultDigits = _newDigits(resultUsed + 1);
+ _lsh(_digits, _used, shiftAmount, resultDigits);
+ return new _BigIntImpl._(_isNegative, resultUsed, resultDigits);
+ }
+
+ /// resultDigits[0..resultUsed-1] = xDigits[0..xUsed-1] << n.
+ /// Returns resultUsed.
+ static int _lShiftDigits(
+ Uint32List xDigits, int xUsed, int n, Uint32List resultDigits) {
+ final digitsShift = n ~/ _digitBits;
+ final bitShift = n % _digitBits;
+ if (bitShift == 0) {
+ return _dlShiftDigits(xDigits, xUsed, digitsShift, resultDigits);
+ }
+ // Need one extra digit to hold bits shifted by bitShift.
+ var resultUsed = xUsed + digitsShift + 1;
+ // The 64-bit intrinsic requires one extra pair to work with.
+ assert(resultDigits.length >= resultUsed + 2 - (resultUsed & 1));
+ _lsh(xDigits, xUsed, n, resultDigits);
+ var i = digitsShift;
+ while (--i >= 0) {
+ resultDigits[i] = 0;
+ }
+ if (resultDigits[resultUsed - 1] == 0) {
+ resultUsed--; // Clamp result.
+ } else if (resultUsed.isOdd) {
+ resultDigits[resultUsed] = 0;
+ }
+ return resultUsed;
+ }
+
+ /// resultDigits[0..resultUsed-1] = xDigits[0..xUsed-1] >> n.
+ ///
+ /// Note: This function may be intrinsified.
+ @pragma("vm:never-inline")
+ static void _rsh(
+ Uint32List xDigits, int xUsed, int n, Uint32List resultDigits) {
+ assert(xUsed > 0);
+ final digitsShift = n ~/ _digitBits;
+ final bitShift = n % _digitBits;
+ final carryBitShift = _digitBits - bitShift;
+ final bitMask = (1 << bitShift) - 1;
+ var carry = xDigits[digitsShift] >> bitShift;
+ final last = xUsed - digitsShift - 1;
+ for (var i = 0; i < last; i++) {
+ final digit = xDigits[i + digitsShift + 1];
+ resultDigits[i] = ((digit & bitMask) << carryBitShift) | carry;
+ carry = digit >> bitShift;
+ }
+ resultDigits[last] = carry;
+ }
+
+ /**
+ * Shift the bits of this integer to the right by [shiftAmount].
+ *
+ * Shifting to the right makes the number smaller and drops the least
+ * significant bits, effectively doing an integer division by
+ *`pow(2, shiftIndex)`.
+ *
+ * It is an error if [shiftAmount] is negative.
+ */
+ _BigIntImpl operator >>(int shiftAmount) {
+ if (shiftAmount < 0) {
+ throw new ArgumentError("shift-amount must be positive $shiftAmount");
+ }
+ if (_isZero) return this;
+ final digitShift = shiftAmount ~/ _digitBits;
+ final bitShift = shiftAmount % _digitBits;
+ if (bitShift == 0) {
+ return _drShift(digitShift);
+ }
+ final used = _used;
+ final resultUsed = used - digitShift;
+ if (resultUsed <= 0) {
+ return _isNegative ? _minusOne : zero;
+ }
+ final digits = _digits;
+ final resultDigits = _newDigits(resultUsed);
+ _rsh(digits, used, shiftAmount, resultDigits);
+ final result = new _BigIntImpl._(_isNegative, resultUsed, resultDigits);
+ if (_isNegative) {
+ // Round down if any bit was shifted out.
+ if ((digits[digitShift] & ((1 << bitShift) - 1)) != 0) {
+ return result - one;
+ }
+ for (var i = 0; i < digitShift; i++) {
+ if (digits[i] != 0) {
+ return result - one;
+ }
+ }
+ }
+ return result;
+ }
+
+ /// resultDigits[0..resultUsed-1] = xDigits[0..xUsed-1] >> n.
+ /// Returns resultUsed.
+ static int _rShiftDigits(
+ Uint32List xDigits, int xUsed, int n, Uint32List resultDigits) {
+ final digitShift = n ~/ _digitBits;
+ final bitShift = n % _digitBits;
+ if (bitShift == 0) {
+ return _drShiftDigits(xDigits, xUsed, digitShift, resultDigits);
+ }
+ var resultUsed = xUsed - digitShift;
+ if (resultUsed <= 0) {
+ return 0;
+ }
+ assert(resultDigits.length >= resultUsed + (resultUsed & 1));
+ _rsh(xDigits, xUsed, n, resultDigits);
+ if (resultDigits[resultUsed - 1] == 0) {
+ resultUsed--; // Clamp result.
+ } else if (resultUsed.isOdd) {
+ resultDigits[resultUsed] = 0;
+ }
+ return resultUsed;
+ }
+
+ /// Compares this to [other] taking the absolute value of both operands.
+ ///
+ /// Returns 0 if abs(this) == abs(other); a positive number if
+ /// abs(this) > abs(other); and a negative number if abs(this) < abs(other).
+ int _absCompare(BigInt bigInt) {
+ _BigIntImpl other = bigInt;
+ return _compareDigits(_digits, _used, other._digits, other._used);
+ }
+
+ /**
+ * Compares this to `other`.
+ *
+ * Returns a negative number if `this` is less than `other`, zero if they are
+ * equal, and a positive number if `this` is greater than `other`.
+ */
+ int compareTo(BigInt bigInt) {
+ _BigIntImpl other = bigInt;
+ if (_isNegative == other._isNegative) {
+ var result = _absCompare(other);
+ // Use 0 - result to avoid negative zero in JavaScript.
+ return _isNegative ? 0 - result : result;
+ }
+ return _isNegative ? -1 : 1;
+ }
+
+ /// Compares `digits[0..used-1]` with `otherDigits[0..otherUsed-1]`.
+ ///
+ /// Returns 0 if equal; a positive number if larger;
+ /// and a negative number if smaller.
+ static int _compareDigits(
+ Uint32List digits, int used, Uint32List otherDigits, int otherUsed) {
+ var result = used - otherUsed;
+ if (result == 0) {
+ for (int i = used - 1; i >= 0; i--) {
+ result = digits[i] - otherDigits[i];
+ if (result != 0) return result;
+ }
+ }
+ return result;
+ }
+
+ /// resultDigits[0..used] = digits[0..used-1] + otherDigits[0..otherUsed-1].
+ /// used >= otherUsed > 0.
+ ///
+ /// Note: This function may be intrinsified.
+ @pragma("vm:never-inline")
+ static void _absAdd(Uint32List digits, int used, Uint32List otherDigits,
+ int otherUsed, Uint32List resultDigits) {
+ assert(used >= otherUsed && otherUsed > 0);
+ var carry = 0;
+ for (var i = 0; i < otherUsed; i++) {
+ carry += digits[i] + otherDigits[i];
+ resultDigits[i] = carry & _digitMask;
+ carry >>= _digitBits;
+ }
+ for (var i = otherUsed; i < used; i++) {
+ carry += digits[i];
+ resultDigits[i] = carry & _digitMask;
+ carry >>= _digitBits;
+ }
+ resultDigits[used] = carry;
+ }
+
+ /// resultDigits[0..used-1] = digits[0..used-1] - otherDigits[0..otherUsed-1].
+ /// used >= otherUsed > 0.
+ ///
+ /// Note: This function may be intrinsified.
+ @pragma("vm:never-inline")
+ static void _absSub(Uint32List digits, int used, Uint32List otherDigits,
+ int otherUsed, Uint32List resultDigits) {
+ assert(used >= otherUsed && otherUsed > 0);
+ var carry = 0;
+ for (var i = 0; i < otherUsed; i++) {
+ carry += digits[i] - otherDigits[i];
+ resultDigits[i] = carry & _digitMask;
+ carry >>= _digitBits;
+ }
+ for (var i = otherUsed; i < used; i++) {
+ carry += digits[i];
+ resultDigits[i] = carry & _digitMask;
+ carry >>= _digitBits;
+ }
+ }
+
+ /// Returns `abs(this) + abs(other)` with sign set according to [isNegative].
+ _BigIntImpl _absAddSetSign(_BigIntImpl other, bool isNegative) {
+ var used = _used;
+ var otherUsed = other._used;
+ if (used < otherUsed) {
+ return other._absAddSetSign(this, isNegative);
+ }
+ if (used == 0) {
+ assert(!isNegative);
+ return zero;
+ }
+ if (otherUsed == 0) {
+ return _isNegative == isNegative ? this : -this;
+ }
+ var resultUsed = used + 1;
+ var resultDigits = _newDigits(resultUsed);
+ _absAdd(_digits, used, other._digits, otherUsed, resultDigits);
+ return new _BigIntImpl._(isNegative, resultUsed, resultDigits);
+ }
+
+ /// Returns `abs(this) - abs(other)` with sign set according to [isNegative].
+ ///
+ /// Requirement: `abs(this) >= abs(other)`.
+ _BigIntImpl _absSubSetSign(_BigIntImpl other, bool isNegative) {
+ assert(_absCompare(other) >= 0);
+ var used = _used;
+ if (used == 0) {
+ assert(!isNegative);
+ return zero;
+ }
+ var otherUsed = other._used;
+ if (otherUsed == 0) {
+ return _isNegative == isNegative ? this : -this;
+ }
+ var resultDigits = _newDigits(used);
+ _absSub(_digits, used, other._digits, otherUsed, resultDigits);
+ return new _BigIntImpl._(isNegative, used, resultDigits);
+ }
+
+ /// Returns `abs(this) & abs(other)` with sign set according to [isNegative].
+ _BigIntImpl _absAndSetSign(_BigIntImpl other, bool isNegative) {
+ var resultUsed = _min(_used, other._used);
+ var digits = _digits;
+ var otherDigits = other._digits;
+ var resultDigits = _newDigits(resultUsed);
+ for (var i = 0; i < resultUsed; i++) {
+ resultDigits[i] = digits[i] & otherDigits[i];
+ }
+ return new _BigIntImpl._(isNegative, resultUsed, resultDigits);
+ }
+
+ /// Returns `abs(this) &~ abs(other)` with sign set according to [isNegative].
+ _BigIntImpl _absAndNotSetSign(_BigIntImpl other, bool isNegative) {
+ var resultUsed = _used;
+ var digits = _digits;
+ var otherDigits = other._digits;
+ var resultDigits = _newDigits(resultUsed);
+ var m = _min(resultUsed, other._used);
+ for (var i = 0; i < m; i++) {
+ resultDigits[i] = digits[i] & ~otherDigits[i];
+ }
+ for (var i = m; i < resultUsed; i++) {
+ resultDigits[i] = digits[i];
+ }
+ return new _BigIntImpl._(isNegative, resultUsed, resultDigits);
+ }
+
+ /// Returns `abs(this) | abs(other)` with sign set according to [isNegative].
+ _BigIntImpl _absOrSetSign(_BigIntImpl other, bool isNegative) {
+ var used = _used;
+ var otherUsed = other._used;
+ var resultUsed = _max(used, otherUsed);
+ var digits = _digits;
+ var otherDigits = other._digits;
+ var resultDigits = _newDigits(resultUsed);
+ var l, m;
+ if (used < otherUsed) {
+ l = other;
+ m = used;
+ } else {
+ l = this;
+ m = otherUsed;
+ }
+ for (var i = 0; i < m; i++) {
+ resultDigits[i] = digits[i] | otherDigits[i];
+ }
+ var lDigits = l._digits;
+ for (var i = m; i < resultUsed; i++) {
+ resultDigits[i] = lDigits[i];
+ }
+ return new _BigIntImpl._(isNegative, resultUsed, resultDigits);
+ }
+
+ /// Returns `abs(this) ^ abs(other)` with sign set according to [isNegative].
+ _BigIntImpl _absXorSetSign(_BigIntImpl other, bool isNegative) {
+ var used = _used;
+ var otherUsed = other._used;
+ var resultUsed = _max(used, otherUsed);
+ var digits = _digits;
+ var otherDigits = other._digits;
+ var resultDigits = _newDigits(resultUsed);
+ var l, m;
+ if (used < otherUsed) {
+ l = other;
+ m = used;
+ } else {
+ l = this;
+ m = otherUsed;
+ }
+ for (var i = 0; i < m; i++) {
+ resultDigits[i] = digits[i] ^ otherDigits[i];
+ }
+ var lDigits = l._digits;
+ for (var i = m; i < resultUsed; i++) {
+ resultDigits[i] = lDigits[i];
+ }
+ return new _BigIntImpl._(isNegative, resultUsed, resultDigits);
+ }
+
+ /**
+ * Bit-wise and operator.
+ *
+ * Treating both `this` and [other] as sufficiently large two's component
+ * integers, the result is a number with only the bits set that are set in
+ * both `this` and [other]
+ *
+ * Of both operands are negative, the result is negative, otherwise
+ * the result is non-negative.
+ */
+ _BigIntImpl operator &(BigInt bigInt) {
+ _BigIntImpl other = bigInt;
+ if (_isZero || other._isZero) return zero;
+ if (_isNegative == other._isNegative) {
+ if (_isNegative) {
+ // (-this) & (-other) == ~(this-1) & ~(other-1)
+ // == ~((this-1) | (other-1))
+ // == -(((this-1) | (other-1)) + 1)
+ _BigIntImpl this1 = _absSubSetSign(one, true);
+ _BigIntImpl other1 = other._absSubSetSign(one, true);
+ // Result cannot be zero if this and other are negative.
+ return this1._absOrSetSign(other1, true)._absAddSetSign(one, true);
+ }
+ return _absAndSetSign(other, false);
+ }
+ // _isNegative != other._isNegative
+ var p, n;
+ if (_isNegative) {
+ p = other;
+ n = this;
+ } else {
+ // & is symmetric.
+ p = this;
+ n = other;
+ }
+ // p & (-n) == p & ~(n-1) == p &~ (n-1)
+ var n1 = n._absSubSetSign(one, false);
+ return p._absAndNotSetSign(n1, false);
+ }
+
+ /**
+ * Bit-wise or operator.
+ *
+ * Treating both `this` and [other] as sufficiently large two's component
+ * integers, the result is a number with the bits set that are set in either
+ * of `this` and [other]
+ *
+ * If both operands are non-negative, the result is non-negative,
+ * otherwise the result us negative.
+ */
+ _BigIntImpl operator |(BigInt bigInt) {
+ _BigIntImpl other = bigInt;
+ if (_isZero) return other;
+ if (other._isZero) return this;
+ if (_isNegative == other._isNegative) {
+ if (_isNegative) {
+ // (-this) | (-other) == ~(this-1) | ~(other-1)
+ // == ~((this-1) & (other-1))
+ // == -(((this-1) & (other-1)) + 1)
+ var this1 = _absSubSetSign(one, true);
+ var other1 = other._absSubSetSign(one, true);
+ // Result cannot be zero if this and a are negative.
+ return this1._absAndSetSign(other1, true)._absAddSetSign(one, true);
+ }
+ return _absOrSetSign(other, false);
+ }
+ // _neg != a._neg
+ var p, n;
+ if (_isNegative) {
+ p = other;
+ n = this;
+ } else {
+ // | is symmetric.
+ p = this;
+ n = other;
+ }
+ // p | (-n) == p | ~(n-1) == ~((n-1) &~ p) == -(~((n-1) &~ p) + 1)
+ var n1 = n._absSubSetSign(one, true);
+ // Result cannot be zero if only one of this or a is negative.
+ return n1._absAndNotSetSign(p, true)._absAddSetSign(one, true);
+ }
+
+ /**
+ * Bit-wise exclusive-or operator.
+ *
+ * Treating both `this` and [other] as sufficiently large two's component
+ * integers, the result is a number with the bits set that are set in one,
+ * but not both, of `this` and [other]
+ *
+ * If the operands have the same sign, the result is non-negative,
+ * otherwise the result is negative.
+ */
+ _BigIntImpl operator ^(BigInt bigInt) {
+ _BigIntImpl other = bigInt;
+ if (_isZero) return other;
+ if (other._isZero) return this;
+ if (_isNegative == other._isNegative) {
+ if (_isNegative) {
+ // (-this) ^ (-other) == ~(this-1) ^ ~(other-1) == (this-1) ^ (other-1)
+ var this1 = _absSubSetSign(one, true);
+ var other1 = other._absSubSetSign(one, true);
+ return this1._absXorSetSign(other1, false);
+ }
+ return _absXorSetSign(other, false);
+ }
+ // _isNegative != a._isNegative
+ var p, n;
+ if (_isNegative) {
+ p = other;
+ n = this;
+ } else {
+ // ^ is symmetric.
+ p = this;
+ n = other;
+ }
+ // p ^ (-n) == p ^ ~(n-1) == ~(p ^ (n-1)) == -((p ^ (n-1)) + 1)
+ var n1 = n._absSubSetSign(one, true);
+ // Result cannot be zero if only one of this or a is negative.
+ return p._absXorSetSign(n1, true)._absAddSetSign(one, true);
+ }
+
+ /**
+ * The bit-wise negate operator.
+ *
+ * Treating `this` as a sufficiently large two's component integer,
+ * the result is a number with the opposite bits set.
+ *
+ * This maps any integer `x` to `-x - 1`.
+ */
+ _BigIntImpl operator ~() {
+ if (_isZero) return _minusOne;
+ if (_isNegative) {
+ // ~(-this) == ~(~(this-1)) == this-1
+ return _absSubSetSign(one, false);
+ }
+ // ~this == -this-1 == -(this+1)
+ // Result cannot be zero if this is positive.
+ return _absAddSetSign(one, true);
+ }
+
+ /// Addition operator.
+ _BigIntImpl operator +(BigInt bigInt) {
+ _BigIntImpl other = bigInt;
+ if (_isZero) return other;
+ if (other._isZero) return this;
+ var isNegative = _isNegative;
+ if (isNegative == other._isNegative) {
+ // this + other == this + other
+ // (-this) + (-other) == -(this + other)
+ return _absAddSetSign(other, isNegative);
+ }
+ // this + (-other) == this - other == -(this - other)
+ // (-this) + other == other - this == -(this - other)
+ if (_absCompare(other) >= 0) {
+ return _absSubSetSign(other, isNegative);
+ }
+ return other._absSubSetSign(this, !isNegative);
+ }
+
+ /// Subtraction operator.
+ _BigIntImpl operator -(BigInt bigInt) {
+ _BigIntImpl other = bigInt;
+ if (_isZero) return -other;
+ if (other._isZero) return this;
+ var isNegative = _isNegative;
+ if (isNegative != other._isNegative) {
+ // this - (-other) == this + other
+ // (-this) - other == -(this + other)
+ return _absAddSetSign(other, isNegative);
+ }
+ // this - other == this - a == -(this - other)
+ // (-this) - (-other) == other - this == -(this - other)
+ if (_absCompare(other) >= 0) {
+ return _absSubSetSign(other, isNegative);
+ }
+ return other._absSubSetSign(this, !isNegative);
+ }
+
+ /// Multiplies `xDigits[xIndex]` with `multiplicandDigits` and adds the result
+ /// to `accumulatorDigits`.
+ ///
+ /// The `multiplicandDigits` in the range `i` to `i`+`n`-1 are the
+ /// multiplicand digits.
+ ///
+ /// The `accumulatorDigits` in the range `j` to `j`+`n`-1 are the accumulator
+ /// digits.
+ ///
+ /// Concretely:
+ /// `accumulatorDigits[j..j+n] += xDigits[xIndex] * m_digits[i..i+n-1]`.
+ /// Returns 1.
+ ///
+ /// Note: This function may be intrinsified. Intrinsics on 64-bit platforms
+ /// process digit pairs at even indices and returns 2.
+ @pragma("vm:exact-result-type", "dart:core#_Smi")
+ @pragma("vm:never-inline")
+ static int _mulAdd(
+ Uint32List xDigits,
+ int xIndex,
+ Uint32List multiplicandDigits,
+ int i,
+ Uint32List accumulatorDigits,
+ int j,
+ int n) {
+ int x = xDigits[xIndex];
+ if (x == 0) {
+ // No-op if x is 0.
+ return 1;
+ }
+ int carry = 0;
+ int xl = x & _halfDigitMask;
+ int xh = x >> _halfDigitBits;
+ while (--n >= 0) {
+ int ml = multiplicandDigits[i] & _halfDigitMask;
+ int mh = multiplicandDigits[i++] >> _halfDigitBits;
+ int ph = xh * ml + mh * xl;
+ int pl = xl * ml +
+ ((ph & _halfDigitMask) << _halfDigitBits) +
+ accumulatorDigits[j] +
+ carry;
+ carry = (pl >> _digitBits) + (ph >> _halfDigitBits) + xh * mh;
+ accumulatorDigits[j++] = pl & _digitMask;
+ }
+ while (carry != 0) {
+ int l = accumulatorDigits[j] + carry;
+ carry = l >> _digitBits;
+ accumulatorDigits[j++] = l & _digitMask;
+ }
+ return 1;
+ }
+
+ /// Multiplies `xDigits[i]` with `xDigits` and adds the result to
+ /// `accumulatorDigits`.
+ ///
+ /// The `xDigits` in the range `i` to `used`-1 are the multiplicand digits.
+ ///
+ /// The `accumulatorDigits` in the range 2*`i` to `i`+`used`-1 are the
+ /// accumulator digits.
+ ///
+ /// Concretely:
+ /// `accumulatorDigits[2*i..i+used-1] += xDigits[i]*xDigits[i] +
+ /// 2*xDigits[i]*xDigits[i+1..used-1]`.
+ /// Returns 1.
+ ///
+ /// Note: This function may be intrinsified. Intrinsics on 64-bit platforms
+ /// process digit pairs at even indices and returns 2.
+ @pragma("vm:exact-result-type", "dart:core#_Smi")
+ @pragma("vm:never-inline")
+ static int _sqrAdd(
+ Uint32List xDigits, int i, Uint32List acculumatorDigits, int used) {
+ int x = xDigits[i];
+ if (x == 0) return 1;
+ int j = 2 * i;
+ int carry = 0;
+ int xl = x & _halfDigitMask;
+ int xh = x >> _halfDigitBits;
+ int ph = 2 * xh * xl;
+ int pl = xl * xl +
+ ((ph & _halfDigitMask) << _halfDigitBits) +
+ acculumatorDigits[j];
+ carry = (pl >> _digitBits) + (ph >> _halfDigitBits) + xh * xh;
+ acculumatorDigits[j] = pl & _digitMask;
+ x <<= 1;
+ xl = x & _halfDigitMask;
+ xh = x >> _halfDigitBits;
+ int n = used - i - 1;
+ int k = i + 1;
+ j++;
+ while (--n >= 0) {
+ int l = xDigits[k] & _halfDigitMask;
+ int h = xDigits[k++] >> _halfDigitBits;
+ int ph = xh * l + h * xl;
+ int pl = xl * l +
+ ((ph & _halfDigitMask) << _halfDigitBits) +
+ acculumatorDigits[j] +
+ carry;
+ carry = (pl >> _digitBits) + (ph >> _halfDigitBits) + xh * h;
+ acculumatorDigits[j++] = pl & _digitMask;
+ }
+ carry += acculumatorDigits[i + used];
+ if (carry >= _digitBase) {
+ acculumatorDigits[i + used] = carry - _digitBase;
+ acculumatorDigits[i + used + 1] = 1;
+ } else {
+ acculumatorDigits[i + used] = carry;
+ }
+ return 1;
+ }
+
+ /// Multiplication operator.
+ _BigIntImpl operator *(BigInt bigInt) {
+ _BigIntImpl other = bigInt;
+ var used = _used;
+ var otherUsed = other._used;
+ if (used == 0 || otherUsed == 0) {
+ return zero;
+ }
+ var resultUsed = used + otherUsed;
+ var digits = _digits;
+ var otherDigits = other._digits;
+ var resultDigits = _newDigits(resultUsed);
+ var i = 0;
+ while (i < otherUsed) {
+ i += _mulAdd(otherDigits, i, digits, 0, resultDigits, i, used);
+ }
+ return new _BigIntImpl._(
+ _isNegative != other._isNegative, resultUsed, resultDigits);
+ }
+
+ // resultDigits[0..resultUsed-1] =
+ // xDigits[0..xUsed-1]*otherDigits[0..otherUsed-1].
+ // Returns resultUsed = xUsed + otherUsed.
+ static int _mulDigits(Uint32List xDigits, int xUsed, Uint32List otherDigits,
+ int otherUsed, Uint32List resultDigits) {
+ var resultUsed = xUsed + otherUsed;
+ var i = resultUsed + (resultUsed & 1);
+ assert(resultDigits.length >= i);
+ while (--i >= 0) {
+ resultDigits[i] = 0;
+ }
+ i = 0;
+ while (i < otherUsed) {
+ i += _mulAdd(otherDigits, i, xDigits, 0, resultDigits, i, xUsed);
+ }
+ return resultUsed;
+ }
+
+ // resultDigits[0..resultUsed-1] = xDigits[0..xUsed-1]^2.
+ // Returns resultUsed = 2*xUsed.
+ static int _sqrDigits(
+ Uint32List xDigits, int xUsed, Uint32List resultDigits) {
+ var resultUsed = 2 * xUsed;
+ assert(resultDigits.length >= resultUsed);
+ // Since resultUsed is even, no need for a leading zero for
+ // 64-bit processing.
+ var i = resultUsed;
+ while (--i >= 0) {
+ resultDigits[i] = 0;
+ }
+ i = 0;
+ while (i < xUsed - 1) {
+ i += _sqrAdd(xDigits, i, resultDigits, xUsed);
+ }
+ // The last step is already done if digit pairs were processed above.
+ if (i < xUsed) {
+ _mulAdd(xDigits, i, xDigits, i, resultDigits, 2 * i, 1);
+ }
+ return resultUsed;
+ }
+
+ // Indices of the arguments of _estimateQuotientDigit.
+ // For 64-bit processing by intrinsics on 64-bit platforms, the top digit pair
+ // of the divisor is provided in the args array, and a 64-bit estimated
+ // quotient is returned. However, on 32-bit platforms, the low 32-bit digit is
+ // ignored and only one 32-bit digit is returned as the estimated quotient.
+ static const int _divisorLowTopDigit = 0; // Low digit of top pair of divisor.
+ static const int _divisorTopDigit = 1; // Top digit of divisor.
+ static const int _quotientDigit = 2; // Estimated quotient.
+ static const int _quotientHighDigit = 3; // High digit of estimated quotient.
+
+ /// Estimate `args[_quotientDigit] = digits[i-1..i] ~/ args[_divisorTopDigit]`
+ /// Returns 1.
+ ///
+ /// Note: This function may be intrinsified. Intrinsics on 64-bit platforms
+ /// process a digit pair (i always odd):
+ /// Estimate `args[_quotientDigit.._quotientHighDigit] = digits[i-3..i] ~/
+ /// args[_divisorLowTopDigit.._divisorTopDigit]`.
+ /// Returns 2.
+ @pragma("vm:exact-result-type", "dart:core#_Smi")
+ @pragma("vm:never-inline")
+ static int _estimateQuotientDigit(Uint32List args, Uint32List digits, int i) {
+ // Verify that digit pairs are accessible for 64-bit processing.
+ assert(digits.length >= 4);
+ if (digits[i] == args[_divisorTopDigit]) {
+ args[_quotientDigit] = _digitMask;
+ } else {
+ // Chop off one bit, since a Mint cannot hold 2 digits.
+ var quotientDigit =
+ ((digits[i] << (_digitBits - 1)) | (digits[i - 1] >> 1)) ~/
+ (args[_divisorTopDigit] >> 1);
+ if (quotientDigit > _digitMask) {
+ args[_quotientDigit] = _digitMask;
+ } else {
+ args[_quotientDigit] = quotientDigit;
+ }
+ }
+ return 1;
+ }
+
+ /// Returns `trunc(this / other)`, with `other != 0`.
+ _BigIntImpl _div(BigInt bigInt) {
+ _BigIntImpl other = bigInt;
+ assert(other._used > 0);
+ if (_used < other._used) {
+ return zero;
+ }
+ _divRem(other);
+ // Return quotient, i.e.
+ // _lastQuoRem_digits[_lastRem_used.._lastQuoRem_used-1] with proper sign.
+ var lastQuo_used = _lastQuoRemUsed - _lastRemUsed;
+ var quo_digits = _cloneDigits(
+ _lastQuoRemDigits, _lastRemUsed, _lastQuoRemUsed, lastQuo_used);
+ var quo = new _BigIntImpl._(false, lastQuo_used, quo_digits);
+ if ((_isNegative != other._isNegative) && (quo._used > 0)) {
+ quo = -quo;
+ }
+ return quo;
+ }
+
+ /// Returns `this - other * trunc(this / other)`, with `other != 0`.
+ _BigIntImpl _rem(BigInt bigInt) {
+ _BigIntImpl other = bigInt;
+ assert(other._used > 0);
+ if (_used < other._used) {
+ return this;
+ }
+ _divRem(other);
+ // Return remainder, i.e.
+ // denormalized _lastQuoRem_digits[0.._lastRem_used-1] with proper sign.
+ var remDigits =
+ _cloneDigits(_lastQuoRemDigits, 0, _lastRemUsed, _lastRemUsed);
+ var rem = new _BigIntImpl._(false, _lastRemUsed, remDigits);
+ if (_lastRem_nsh > 0) {
+ rem = rem >> _lastRem_nsh; // Denormalize remainder.
+ }
+ if (_isNegative && (rem._used > 0)) {
+ rem = -rem;
+ }
+ return rem;
+ }
+
+ /// Computes this ~/ other and this.remainder(other).
+ ///
+ /// Stores the result in [_lastQuoRemDigits], [_lastQuoRemUsed] and
+ /// [_lastRemUsed]. The [_lastQuoRemDigits] contains the digits of *both*, the
+ /// quotient and the remainder.
+ ///
+ /// Caches the input to avoid doing the work again when users write
+ /// `a ~/ b` followed by a `a % b`.
+ void _divRem(_BigIntImpl other) {
+ // Check if result is already cached.
+ if ((this._used == _lastDividendUsed) &&
+ (other._used == _lastDivisorUsed) &&
+ identical(this._digits, _lastDividendDigits) &&
+ identical(other._digits, _lastDivisorDigits)) {
+ return;
+ }
+ assert(_used >= other._used);
+
+ var nsh = _digitBits - other._digits[other._used - 1].bitLength;
+ // For 64-bit processing, make sure other has an even number of digits.
+ if (other._used.isOdd) {
+ nsh += _digitBits;
+ }
+ // Concatenated positive quotient and normalized positive remainder.
+ // The resultDigits can have at most one more digit than the dividend.
+ Uint32List resultDigits;
+ int resultUsed;
+ // Normalized positive divisor (referred to as 'y').
+ // The normalized divisor has the most-significant bit of its most
+ // significant digit set.
+ // This makes estimating the quotient easier.
+ Uint32List yDigits;
+ int yUsed;
+ if (nsh > 0) {
+ // Extra digits for normalization, also used for possible _mulAdd carry.
+ var numExtraDigits = (nsh + _digitBits - 1) ~/ _digitBits + 1;
+ yDigits = _newDigits(other._used + numExtraDigits);
+ yUsed = _lShiftDigits(other._digits, other._used, nsh, yDigits);
+ resultDigits = _newDigits(_used + numExtraDigits);
+ resultUsed = _lShiftDigits(_digits, _used, nsh, resultDigits);
+ } else {
+ yDigits = other._digits;
+ yUsed = other._used;
+ // Extra digit to hold possible _mulAdd carry.
+ resultDigits = _cloneDigits(_digits, 0, _used, _used + 1);
+ resultUsed = _used;
+ }
+ Uint32List args = _newDigits(4);
+ args[_divisorLowTopDigit] = yDigits[yUsed - 2];
+ args[_divisorTopDigit] = yDigits[yUsed - 1];
+ // For 64-bit processing, make sure yUsed, i, and j are even.
+ assert(yUsed.isEven);
+ var i = resultUsed + (resultUsed & 1);
+ var j = i - yUsed;
+ // tmpDigits is a temporary array of i (even resultUsed) digits.
+ var tmpDigits = _newDigits(i);
+ var tmpUsed = _dlShiftDigits(yDigits, yUsed, j, tmpDigits);
+ // Explicit first division step in case normalized dividend is larger or
+ // equal to shifted normalized divisor.
+ if (_compareDigits(resultDigits, resultUsed, tmpDigits, tmpUsed) >= 0) {
+ assert(i == resultUsed);
+ resultDigits[resultUsed++] = 1; // Quotient = 1.
+ // Subtract divisor from remainder.
+ _absSub(resultDigits, resultUsed, tmpDigits, tmpUsed, resultDigits);
+ } else {
+ // Account for possible carry in _mulAdd step.
+ resultDigits[resultUsed++] = 0;
+ }
+ if (resultUsed.isOdd) {
+ resultDigits[resultUsed] = 0; // Leading zero for 64-bit processing.
+ }
+ // Negate y so we can later use _mulAdd instead of non-existent _mulSub.
+ var nyDigits = _newDigits(yUsed + 2);
+ nyDigits[yUsed] = 1;
+ _absSub(nyDigits, yUsed + 1, yDigits, yUsed, nyDigits);
+ // nyDigits is read-only and has yUsed digits (possibly including several
+ // leading zeros) plus a leading zero for 64-bit processing.
+ // resultDigits is modified during iteration.
+ // resultDigits[0..yUsed-1] is the current remainder.
+ // resultDigits[yUsed..resultUsed-1] is the current quotient.
+ --i;
+ while (j > 0) {
+ var d0 = _estimateQuotientDigit(args, resultDigits, i);
+ j -= d0;
+ var d1 =
+ _mulAdd(args, _quotientDigit, nyDigits, 0, resultDigits, j, yUsed);
+ // _estimateQuotientDigit and _mulAdd must agree on the number of digits
+ // to process.
+ assert(d0 == d1);
+ if (d0 == 1) {
+ if (resultDigits[i] < args[_quotientDigit]) {
+ // Reusing the already existing tmpDigits array.
+ var tmpUsed = _dlShiftDigits(nyDigits, yUsed, j, tmpDigits);
+ _absSub(resultDigits, resultUsed, tmpDigits, tmpUsed, resultDigits);
+ while (resultDigits[i] < --args[_quotientDigit]) {
+ _absSub(resultDigits, resultUsed, tmpDigits, tmpUsed, resultDigits);
+ }
+ }
+ } else {
+ assert(d0 == 2);
+ assert(resultDigits[i] <= args[_quotientHighDigit]);
+ if (resultDigits[i] < args[_quotientHighDigit] ||
+ resultDigits[i - 1] < args[_quotientDigit]) {
+ // Reusing the already existing tmpDigits array.
+ var tmpUsed = _dlShiftDigits(nyDigits, yUsed, j, tmpDigits);
+ _absSub(resultDigits, resultUsed, tmpDigits, tmpUsed, resultDigits);
+ if (args[_quotientDigit] == 0) {
+ --args[_quotientHighDigit];
+ }
+ --args[_quotientDigit];
+ assert(resultDigits[i] <= args[_quotientHighDigit]);
+ while (resultDigits[i] < args[_quotientHighDigit] ||
+ resultDigits[i - 1] < args[_quotientDigit]) {
+ _absSub(resultDigits, resultUsed, tmpDigits, tmpUsed, resultDigits);
+ if (args[_quotientDigit] == 0) {
+ --args[_quotientHighDigit];
+ }
+ --args[_quotientDigit];
+ assert(resultDigits[i] <= args[_quotientHighDigit]);
+ }
+ }
+ }
+ i -= d0;
+ }
+ // Cache result.
+ _lastDividendDigits = _digits;
+ _lastDividendUsed = _used;
+ _lastDivisorDigits = other._digits;
+ _lastDivisorUsed = other._used;
+ _lastQuoRemDigits = resultDigits;
+ _lastQuoRemUsed = resultUsed;
+ _lastRemUsed = yUsed;
+ _lastRem_nsh = nsh;
+ }
+
+ // Customized version of _rem() minimizing allocations for use in reduction.
+ // Input:
+ // xDigits[0..xUsed-1]: positive dividend.
+ // yDigits[0..yUsed-1]: normalized positive divisor.
+ // nyDigits[0..yUsed-1]: negated yDigits.
+ // nsh: normalization shift amount.
+ // args: top y digit(s) and place holder for estimated quotient digit(s).
+ // tmpDigits: temp array of 2*yUsed digits.
+ // resultDigits: result digits array large enough to temporarily hold
+ // concatenated quotient and normalized remainder.
+ // Output:
+ // resultDigits[0..resultUsed-1]: positive remainder.
+ // Returns resultUsed.
+ static int _remDigits(
+ Uint32List xDigits,
+ int xUsed,
+ Uint32List yDigits,
+ int yUsed,
+ Uint32List nyDigits,
+ int nsh,
+ Uint32List args,
+ Uint32List tmpDigits,
+ Uint32List resultDigits) {
+ // Initialize resultDigits to normalized positive dividend.
+ var resultUsed = _lShiftDigits(xDigits, xUsed, nsh, resultDigits);
+ // For 64-bit processing, make sure yUsed, i, and j are even.
+ assert(yUsed.isEven);
+ var i = resultUsed + (resultUsed & 1);
+ var j = i - yUsed;
+ var tmpUsed = _dlShiftDigits(yDigits, yUsed, j, tmpDigits);
+ // Explicit first division step in case normalized dividend is larger or
+ // equal to shifted normalized divisor.
+ if (_compareDigits(resultDigits, resultUsed, tmpDigits, tmpUsed) >= 0) {
+ assert(i == resultUsed);
+ resultDigits[resultUsed++] = 1; // Quotient = 1.
+ // Subtract divisor from remainder.
+ _absSub(resultDigits, resultUsed, tmpDigits, tmpUsed, resultDigits);
+ } else {
+ // Account for possible carry in _mulAdd step.
+ resultDigits[resultUsed++] = 0;
+ }
+ if (resultUsed.isOdd) {
+ resultDigits[resultUsed] = 0; // Leading zero for 64-bit processing.
+ }
+ // Negated yDigits passed in nyDigits allow the use of _mulAdd instead of
+ // unimplemented _mulSub.
+ // nyDigits is read-only and has yUsed digits (possibly including several
+ // leading zeros) plus a leading zero for 64-bit processing.
+ // resultDigits is modified during iteration.
+ // resultDigits[0..yUsed-1] is the current remainder.
+ // resultDigits[yUsed..resultUsed-1] is the current quotient.
+ --i;
+ while (j > 0) {
+ var d0 = _estimateQuotientDigit(args, resultDigits, i);
+ j -= d0;
+ var d1 =
+ _mulAdd(args, _quotientDigit, nyDigits, 0, resultDigits, j, yUsed);
+ // _estimateQuotientDigit and _mulAdd must agree on the number of digits
+ // to process.
+ assert(d0 == d1);
+ if (d0 == 1) {
+ if (resultDigits[i] < args[_quotientDigit]) {
+ var tmpUsed = _dlShiftDigits(nyDigits, yUsed, j, tmpDigits);
+ _absSub(resultDigits, resultUsed, tmpDigits, tmpUsed, resultDigits);
+ while (resultDigits[i] < --args[_quotientDigit]) {
+ _absSub(resultDigits, resultUsed, tmpDigits, tmpUsed, resultDigits);
+ }
+ }
+ } else {
+ assert(d0 == 2);
+ assert(resultDigits[i] <= args[_quotientHighDigit]);
+ if ((resultDigits[i] < args[_quotientHighDigit]) ||
+ (resultDigits[i - 1] < args[_quotientDigit])) {
+ var tmpUsed = _dlShiftDigits(nyDigits, yUsed, j, tmpDigits);
+ _absSub(resultDigits, resultUsed, tmpDigits, tmpUsed, resultDigits);
+ if (args[_quotientDigit] == 0) {
+ --args[_quotientHighDigit];
+ }
+ --args[_quotientDigit];
+ assert(resultDigits[i] <= args[_quotientHighDigit]);
+ while ((resultDigits[i] < args[_quotientHighDigit]) ||
+ (resultDigits[i - 1] < args[_quotientDigit])) {
+ _absSub(resultDigits, resultUsed, tmpDigits, tmpUsed, resultDigits);
+ if (args[_quotientDigit] == 0) {
+ --args[_quotientHighDigit];
+ }
+ --args[_quotientDigit];
+ assert(resultDigits[i] <= args[_quotientHighDigit]);
+ }
+ }
+ }
+ i -= d0;
+ }
+ // Return remainder, i.e. denormalized resultDigits[0..yUsed-1].
+ resultUsed = yUsed;
+ if (nsh > 0) {
+ // Denormalize remainder.
+ resultUsed = _rShiftDigits(resultDigits, resultUsed, nsh, resultDigits);
+ }
+ return resultUsed;
+ }
+
+ int get hashCode {
+ // This is the [Jenkins hash function][1] but using masking to keep
+ // values in SMI range.
+ //
+ // [1]: http://en.wikipedia.org/wiki/Jenkins_hash_function
+
+ int combine(int hash, int value) {
+ hash = 0x1fffffff & (hash + value);
+ hash = 0x1fffffff & (hash + ((0x0007ffff & hash) << 10));
+ return hash ^ (hash >> 6);
+ }
+
+ int finish(int hash) {
+ hash = 0x1fffffff & (hash + ((0x03ffffff & hash) << 3));
+ hash = hash ^ (hash >> 11);
+ return 0x1fffffff & (hash + ((0x00003fff & hash) << 15));
+ }
+
+ if (_isZero) return 6707; // Just a random number.
+ var hash = _isNegative ? 83585 : 429689; // Also random.
+ for (int i = 0; i < _used; i++) {
+ hash = combine(hash, _digits[i]);
+ }
+ return finish(hash);
+ }
+
+ /**
+ * Test whether this value is numerically equal to `other`.
+ *
+ * If [other] is a [_BigIntImpl] returns whether the two operands have the
+ * same value.
+ *
+ * Returns false if `other` is not a [_BigIntImpl].
+ */
+ bool operator ==(Object other) =>
+ other is _BigIntImpl && compareTo(other) == 0;
+
+ /**
+ * Returns the minimum number of bits required to store this big integer.
+ *
+ * The number of bits excludes the sign bit, which gives the natural length
+ * for non-negative (unsigned) values. Negative values are complemented to
+ * return the bit position of the first bit that differs from the sign bit.
+ *
+ * To find the number of bits needed to store the value as a signed value,
+ * add one, i.e. use `x.bitLength + 1`.
+ *
+ * ```
+ * x.bitLength == (-x-1).bitLength
+ *
+ * new BigInt.from(3).bitLength == 2; // 00000011
+ * new BigInt.from(2).bitLength == 2; // 00000010
+ * new BigInt.from(1).bitLength == 1; // 00000001
+ * new BigInt.from(0).bitLength == 0; // 00000000
+ * new BigInt.from(-1).bitLength == 0; // 11111111
+ * new BigInt.from(-2).bitLength == 1; // 11111110
+ * new BigInt.from(-3).bitLength == 2; // 11111101
+ * new BigInt.from(-4).bitLength == 2; // 11111100
+ * ```
+ */
+ int get bitLength {
+ if (_used == 0) return 0;
+ if (_isNegative) return (~this).bitLength;
+ return _digitBits * (_used - 1) + _digits[_used - 1].bitLength;
+ }
+
+ /**
+ * Truncating division operator.
+ *
+ * Performs a truncating integer division, where the remainder is discarded.
+ *
+ * The remainder can be computed using the [remainder] method.
+ *
+ * Examples:
+ * ```
+ * var seven = new BigInt.from(7);
+ * var three = new BigInt.from(3);
+ * seven ~/ three; // => 2
+ * (-seven) ~/ three; // => -2
+ * seven ~/ -three; // => -2
+ * seven.remainder(three); // => 1
+ * (-seven).remainder(three); // => -1
+ * seven.remainder(-three); // => 1
+ * ```
+ */
+ _BigIntImpl operator ~/(BigInt bigInt) {
+ _BigIntImpl other = bigInt;
+ if (other._used == 0) {
+ throw const IntegerDivisionByZeroException();
+ }
+ return _div(other);
+ }
+
+ /**
+ * Returns the remainder of the truncating division of `this` by [other].
+ *
+ * The result `r` of this operation satisfies:
+ * `this == (this ~/ other) * other + r`.
+ * As a consequence the remainder `r` has the same sign as the divider `this`.
+ */
+ _BigIntImpl remainder(BigInt bigInt) {
+ _BigIntImpl other = bigInt;
+ if (other._used == 0) {
+ throw const IntegerDivisionByZeroException();
+ }
+ return _rem(other);
+ }
+
+ /// Division operator.
+ double operator /(BigInt other) => this.toDouble() / other.toDouble();
+
+ /** Relational less than operator. */
+ bool operator <(BigInt other) => compareTo(other) < 0;
+
+ /** Relational less than or equal operator. */
+ bool operator <=(BigInt other) => compareTo(other) <= 0;
+
+ /** Relational greater than operator. */
+ bool operator >(BigInt other) => compareTo(other) > 0;
+
+ /** Relational greater than or equal operator. */
+ bool operator >=(BigInt other) => compareTo(other) >= 0;
+
+ /**
+ * Euclidean modulo operator.
+ *
+ * Returns the remainder of the Euclidean division. The Euclidean division of
+ * two integers `a` and `b` yields two integers `q` and `r` such that
+ * `a == b * q + r` and `0 <= r < b.abs()`.
+ *
+ * The sign of the returned value `r` is always positive.
+ *
+ * See [remainder] for the remainder of the truncating division.
+ */
+ _BigIntImpl operator %(BigInt bigInt) {
+ _BigIntImpl other = bigInt;
+ if (other._used == 0) {
+ throw const IntegerDivisionByZeroException();
+ }
+ var result = _rem(other);
+ if (result._isNegative) {
+ if (other._isNegative) {
+ result = result - other;
+ } else {
+ result = result + other;
+ }
+ }
+ return result;
+ }
+
+ /**
+ * Returns the sign of this big integer.
+ *
+ * Returns 0 for zero, -1 for values less than zero and
+ * +1 for values greater than zero.
+ */
+ int get sign {
+ if (_used == 0) return 0;
+ return _isNegative ? -1 : 1;
+ }
+
+ /// Whether this big integer is even.
+ bool get isEven => _used == 0 || (_digits[0] & 1) == 0;
+
+ /// Whether this big integer is odd.
+ bool get isOdd => !isEven;
+
+ /// Whether this number is negative.
+ bool get isNegative => _isNegative;
+
+ _BigIntImpl pow(int exponent) {
+ if (exponent < 0) {
+ throw new ArgumentError("Exponent must not be negative: $exponent");
+ }
+ if (exponent == 0) return one;
+
+ // Exponentiation by squaring.
+ var result = one;
+ var base = this;
+ while (exponent != 0) {
+ if ((exponent & 1) == 1) {
+ result *= base;
+ }
+ exponent >>= 1;
+ // Skip unnecessary operation.
+ if (exponent != 0) {
+ base *= base;
+ }
+ }
+ return result;
+ }
+
+ /**
+ * Returns this integer to the power of [exponent] modulo [modulus].
+ *
+ * The [exponent] must be non-negative and [modulus] must be
+ * positive.
+ */
+ _BigIntImpl modPow(BigInt bigExponent, BigInt bigModulus) {
+ _BigIntImpl exponent = bigExponent;
+ _BigIntImpl modulus = bigModulus;
+ if (exponent._isNegative) {
+ throw new ArgumentError("exponent must be positive: $exponent");
+ }
+ if (modulus <= zero) {
+ throw new ArgumentError("modulus must be strictly positive: $modulus");
+ }
+ if (exponent._isZero) return one;
+
+ final exponentBitlen = exponent.bitLength;
+ if (exponentBitlen <= 0) return one;
+ final bool cannotUseMontgomery = modulus.isEven || abs() >= modulus;
+ if (cannotUseMontgomery || exponentBitlen < 64) {
+ _BigIntReduction z = (cannotUseMontgomery || exponentBitlen < 8)
+ ? new _BigIntClassicReduction(modulus)
+ : new _BigIntMontgomeryReduction(modulus);
+ var resultDigits = _newDigits(2 * z._normModulusUsed + 2);
+ var result2Digits = _newDigits(2 * z._normModulusUsed + 2);
+ var gDigits = _newDigits(z._normModulusUsed);
+ var gUsed = z._convert(this, gDigits);
+ // Initialize result with g.
+ // Copy leading zero if any.
+ for (int j = gUsed + (gUsed & 1) - 1; j >= 0; j--) {
+ resultDigits[j] = gDigits[j];
+ }
+ var resultUsed = gUsed;
+ var result2Used;
+ for (int i = exponentBitlen - 2; i >= 0; i--) {
+ result2Used = z._sqr(resultDigits, resultUsed, result2Digits);
+ if (exponent._digits[i ~/ _digitBits] & (1 << (i % _digitBits)) != 0) {
+ resultUsed =
+ z._mul(result2Digits, result2Used, gDigits, gUsed, resultDigits);
+ } else {
+ // Swap result and result2.
+ var tmpDigits = resultDigits;
+ var tmpUsed = resultUsed;
+ resultDigits = result2Digits;
+ resultUsed = result2Used;
+ result2Digits = tmpDigits;
+ result2Used = tmpUsed;
+ }
+ }
+ return z._revert(resultDigits, resultUsed);
+ }
+ var k;
+ if (exponentBitlen < 18)
+ k = 1;
+ else if (exponentBitlen < 48)
+ k = 3;
+ else if (exponentBitlen < 144)
+ k = 4;
+ else if (exponentBitlen < 768)
+ k = 5;
+ else
+ k = 6;
+ _BigIntReduction z = new _BigIntMontgomeryReduction(modulus);
+ var n = 3;
+ final k1 = k - 1;
+ final km = (1 << k) - 1;
+ List gDigits = new List(km + 1);
+ List gUsed = new List(km + 1);
+ gDigits[1] = _newDigits(z._normModulusUsed);
+ gUsed[1] = z._convert(this, gDigits[1]);
+ if (k > 1) {
+ var g2Digits = _newDigits(2 * z._normModulusUsed + 2);
+ var g2Used = z._sqr(gDigits[1], gUsed[1], g2Digits);
+ while (n <= km) {
+ gDigits[n] = _newDigits(2 * z._normModulusUsed + 2);
+ gUsed[n] =
+ z._mul(g2Digits, g2Used, gDigits[n - 2], gUsed[n - 2], gDigits[n]);
+ n += 2;
+ }
+ }
+ var w;
+ var isOne = true;
+ var resultDigits = one._digits;
+ var resultUsed = one._used;
+ var result2Digits = _newDigits(2 * z._normModulusUsed + 2);
+ var result2Used;
+ var exponentDigits = exponent._digits;
+ var j = exponent._used - 1;
+ var i = exponentDigits[j].bitLength - 1;
+ while (j >= 0) {
+ if (i >= k1) {
+ w = (exponentDigits[j] >> (i - k1)) & km;
+ } else {
+ w = (exponentDigits[j] & ((1 << (i + 1)) - 1)) << (k1 - i);
+ if (j > 0) {
+ w |= exponentDigits[j - 1] >> (_digitBits + i - k1);
+ }
+ }
+ n = k;
+ while ((w & 1) == 0) {
+ w >>= 1;
+ --n;
+ }
+ if ((i -= n) < 0) {
+ i += _digitBits;
+ --j;
+ }
+ if (isOne) {
+ // r == 1, don't bother squaring or multiplying it.
+ resultDigits = _newDigits(2 * z._normModulusUsed + 2);
+ resultUsed = gUsed[w];
+ var gwDigits = gDigits[w];
+ var ri = resultUsed + (resultUsed & 1); // Copy leading zero if any.
+ while (--ri >= 0) {
+ resultDigits[ri] = gwDigits[ri];
+ }
+ isOne = false;
+ } else {
+ while (n > 1) {
+ result2Used = z._sqr(resultDigits, resultUsed, result2Digits);
+ resultUsed = z._sqr(result2Digits, result2Used, resultDigits);
+ n -= 2;
+ }
+ if (n > 0) {
+ result2Used = z._sqr(resultDigits, resultUsed, result2Digits);
+ } else {
+ var swapDigits = resultDigits;
+ var swapUsed = resultUsed;
+ resultDigits = result2Digits;
+ resultUsed = result2Used;
+ result2Digits = swapDigits;
+ result2Used = swapUsed;
+ }
+ resultUsed = z._mul(
+ result2Digits, result2Used, gDigits[w], gUsed[w], resultDigits);
+ }
+ while (j >= 0 && (exponentDigits[j] & (1 << i)) == 0) {
+ result2Used = z._sqr(resultDigits, resultUsed, result2Digits);
+ var swapDigits = resultDigits;
+ var swapUsed = resultUsed;
+ resultDigits = result2Digits;
+ resultUsed = result2Used;
+ result2Digits = swapDigits;
+ result2Used = swapUsed;
+ if (--i < 0) {
+ i = _digitBits - 1;
+ --j;
+ }
+ }
+ }
+ assert(!isOne);
+ return z._revert(resultDigits, resultUsed);
+ }
+
+ // If inv is false, returns gcd(x, y).
+ // If inv is true and gcd(x, y) = 1, returns d, so that c*x + d*y = 1.
+ // If inv is true and gcd(x, y) != 1, throws Exception("Not coprime").
+ static _BigIntImpl _binaryGcd(_BigIntImpl x, _BigIntImpl y, bool inv) {
+ var xDigits = x._digits;
+ var yDigits = y._digits;
+ var xUsed = x._used;
+ var yUsed = y._used;
+ var maxUsed = _max(xUsed, yUsed);
+ final maxLen = maxUsed + (maxUsed & 1);
+ xDigits = _cloneDigits(xDigits, 0, xUsed, maxLen);
+ yDigits = _cloneDigits(yDigits, 0, yUsed, maxLen);
+ int shiftAmount = 0;
+ if (inv) {
+ if ((yUsed == 1) && (yDigits[0] == 1)) return one;
+ if ((yUsed == 0) || (yDigits[0].isEven && xDigits[0].isEven)) {
+ throw new Exception("Not coprime");
+ }
+ } else {
+ if (x._isZero) {
+ throw new ArgumentError.value(0, "this", "must not be zero");
+ }
+ if (y._isZero) {
+ throw new ArgumentError.value(0, "other", "must not be zero");
+ }
+ if (((xUsed == 1) && (xDigits[0] == 1)) ||
+ ((yUsed == 1) && (yDigits[0] == 1))) return one;
+ while (((xDigits[0] & 1) == 0) && ((yDigits[0] & 1) == 0)) {
+ _rsh(xDigits, xUsed, 1, xDigits);
+ _rsh(yDigits, yUsed, 1, yDigits);
+ shiftAmount++;
+ }
+ if (shiftAmount >= _digitBits) {
+ var digitShiftAmount = shiftAmount ~/ _digitBits;
+ xUsed -= digitShiftAmount;
+ yUsed -= digitShiftAmount;
+ maxUsed -= digitShiftAmount;
+ }
+ if ((yDigits[0] & 1) == 1) {
+ // Swap x and y.
+ var tmpDigits = xDigits;
+ var tmpUsed = xUsed;
+ xDigits = yDigits;
+ xUsed = yUsed;
+ yDigits = tmpDigits;
+ yUsed = tmpUsed;
+ }
+ }
+ var uDigits = _cloneDigits(xDigits, 0, xUsed, maxLen);
+ var vDigits = _cloneDigits(yDigits, 0, yUsed, maxLen + 2); // +2 for lsh.
+ final bool ac = (xDigits[0] & 1) == 0;
+
+ // Variables a, b, c, and d require one more digit.
+ final abcdUsed = maxUsed + 1;
+ final abcdLen = abcdUsed + (abcdUsed & 1) + 2; // +2 to satisfy _absAdd.
+ var aDigits, bDigits, cDigits, dDigits;
+ bool aIsNegative, bIsNegative, cIsNegative, dIsNegative;
+ if (ac) {
+ aDigits = _newDigits(abcdLen);
+ aIsNegative = false;
+ aDigits[0] = 1;
+ cDigits = _newDigits(abcdLen);
+ cIsNegative = false;
+ }
+ bDigits = _newDigits(abcdLen);
+ bIsNegative = false;
+ dDigits = _newDigits(abcdLen);
+ dIsNegative = false;
+ dDigits[0] = 1;
+
+ while (true) {
+ while ((uDigits[0] & 1) == 0) {
+ _rsh(uDigits, maxUsed, 1, uDigits);
+ if (ac) {
+ if (((aDigits[0] & 1) == 1) || ((bDigits[0] & 1) == 1)) {
+ // a += y
+ if (aIsNegative) {
+ if ((aDigits[maxUsed] != 0) ||
+ (_compareDigits(aDigits, maxUsed, yDigits, maxUsed)) > 0) {
+ _absSub(aDigits, abcdUsed, yDigits, maxUsed, aDigits);
+ } else {
+ _absSub(yDigits, maxUsed, aDigits, maxUsed, aDigits);
+ aIsNegative = false;
+ }
+ } else {
+ _absAdd(aDigits, abcdUsed, yDigits, maxUsed, aDigits);
+ }
+ // b -= x
+ if (bIsNegative) {
+ _absAdd(bDigits, abcdUsed, xDigits, maxUsed, bDigits);
+ } else if ((bDigits[maxUsed] != 0) ||
+ (_compareDigits(bDigits, maxUsed, xDigits, maxUsed) > 0)) {
+ _absSub(bDigits, abcdUsed, xDigits, maxUsed, bDigits);
+ } else {
+ _absSub(xDigits, maxUsed, bDigits, maxUsed, bDigits);
+ bIsNegative = true;
+ }
+ }
+ _rsh(aDigits, abcdUsed, 1, aDigits);
+ } else if ((bDigits[0] & 1) == 1) {
+ // b -= x
+ if (bIsNegative) {
+ _absAdd(bDigits, abcdUsed, xDigits, maxUsed, bDigits);
+ } else if ((bDigits[maxUsed] != 0) ||
+ (_compareDigits(bDigits, maxUsed, xDigits, maxUsed) > 0)) {
+ _absSub(bDigits, abcdUsed, xDigits, maxUsed, bDigits);
+ } else {
+ _absSub(xDigits, maxUsed, bDigits, maxUsed, bDigits);
+ bIsNegative = true;
+ }
+ }
+ _rsh(bDigits, abcdUsed, 1, bDigits);
+ }
+ while ((vDigits[0] & 1) == 0) {
+ _rsh(vDigits, maxUsed, 1, vDigits);
+ if (ac) {
+ if (((cDigits[0] & 1) == 1) || ((dDigits[0] & 1) == 1)) {
+ // c += y
+ if (cIsNegative) {
+ if ((cDigits[maxUsed] != 0) ||
+ (_compareDigits(cDigits, maxUsed, yDigits, maxUsed) > 0)) {
+ _absSub(cDigits, abcdUsed, yDigits, maxUsed, cDigits);
+ } else {
+ _absSub(yDigits, maxUsed, cDigits, maxUsed, cDigits);
+ cIsNegative = false;
+ }
+ } else {
+ _absAdd(cDigits, abcdUsed, yDigits, maxUsed, cDigits);
+ }
+ // d -= x
+ if (dIsNegative) {
+ _absAdd(dDigits, abcdUsed, xDigits, maxUsed, dDigits);
+ } else if ((dDigits[maxUsed] != 0) ||
+ (_compareDigits(dDigits, maxUsed, xDigits, maxUsed) > 0)) {
+ _absSub(dDigits, abcdUsed, xDigits, maxUsed, dDigits);
+ } else {
+ _absSub(xDigits, maxUsed, dDigits, maxUsed, dDigits);
+ dIsNegative = true;
+ }
+ }
+ _rsh(cDigits, abcdUsed, 1, cDigits);
+ } else if ((dDigits[0] & 1) == 1) {
+ // d -= x
+ if (dIsNegative) {
+ _absAdd(dDigits, abcdUsed, xDigits, maxUsed, dDigits);
+ } else if ((dDigits[maxUsed] != 0) ||
+ (_compareDigits(dDigits, maxUsed, xDigits, maxUsed) > 0)) {
+ _absSub(dDigits, abcdUsed, xDigits, maxUsed, dDigits);
+ } else {
+ _absSub(xDigits, maxUsed, dDigits, maxUsed, dDigits);
+ dIsNegative = true;
+ }
+ }
+ _rsh(dDigits, abcdUsed, 1, dDigits);
+ }
+ if (_compareDigits(uDigits, maxUsed, vDigits, maxUsed) >= 0) {
+ // u -= v
+ _absSub(uDigits, maxUsed, vDigits, maxUsed, uDigits);
+ if (ac) {
+ // a -= c
+ if (aIsNegative == cIsNegative) {
+ var a_cmp_c = _compareDigits(aDigits, abcdUsed, cDigits, abcdUsed);
+ if (a_cmp_c > 0) {
+ _absSub(aDigits, abcdUsed, cDigits, abcdUsed, aDigits);
+ } else {
+ _absSub(cDigits, abcdUsed, aDigits, abcdUsed, aDigits);
+ aIsNegative = !aIsNegative && (a_cmp_c != 0);
+ }
+ } else {
+ _absAdd(aDigits, abcdUsed, cDigits, abcdUsed, aDigits);
+ }
+ }
+ // b -= d
+ if (bIsNegative == dIsNegative) {
+ var b_cmp_d = _compareDigits(bDigits, abcdUsed, dDigits, abcdUsed);
+ if (b_cmp_d > 0) {
+ _absSub(bDigits, abcdUsed, dDigits, abcdUsed, bDigits);
+ } else {
+ _absSub(dDigits, abcdUsed, bDigits, abcdUsed, bDigits);
+ bIsNegative = !bIsNegative && (b_cmp_d != 0);
+ }
+ } else {
+ _absAdd(bDigits, abcdUsed, dDigits, abcdUsed, bDigits);
+ }
+ } else {
+ // v -= u
+ _absSub(vDigits, maxUsed, uDigits, maxUsed, vDigits);
+ if (ac) {
+ // c -= a
+ if (cIsNegative == aIsNegative) {
+ var c_cmp_a = _compareDigits(cDigits, abcdUsed, aDigits, abcdUsed);
+ if (c_cmp_a > 0) {
+ _absSub(cDigits, abcdUsed, aDigits, abcdUsed, cDigits);
+ } else {
+ _absSub(aDigits, abcdUsed, cDigits, abcdUsed, cDigits);
+ cIsNegative = !cIsNegative && (c_cmp_a != 0);
+ }
+ } else {
+ _absAdd(cDigits, abcdUsed, aDigits, abcdUsed, cDigits);
+ }
+ }
+ // d -= b
+ if (dIsNegative == bIsNegative) {
+ var d_cmp_b = _compareDigits(dDigits, abcdUsed, bDigits, abcdUsed);
+ if (d_cmp_b > 0) {
+ _absSub(dDigits, abcdUsed, bDigits, abcdUsed, dDigits);
+ } else {
+ _absSub(bDigits, abcdUsed, dDigits, abcdUsed, dDigits);
+ dIsNegative = !dIsNegative && (d_cmp_b != 0);
+ }
+ } else {
+ _absAdd(dDigits, abcdUsed, bDigits, abcdUsed, dDigits);
+ }
+ }
+ // Exit loop if u == 0.
+ var i = maxUsed;
+ while ((i > 0) && (uDigits[i - 1] == 0)) --i;
+ if (i == 0) break;
+ }
+ if (!inv) {
+ if (shiftAmount > 0) {
+ maxUsed = _lShiftDigits(vDigits, maxUsed, shiftAmount, vDigits);
+ }
+ return new _BigIntImpl._(false, maxUsed, vDigits);
+ }
+ // No inverse if v != 1.
+ var i = maxUsed - 1;
+ while ((i > 0) && (vDigits[i] == 0)) --i;
+ if ((i != 0) || (vDigits[0] != 1)) {
+ throw new Exception("Not coprime");
+ }
+
+ if (dIsNegative) {
+ while ((dDigits[maxUsed] != 0) ||
+ (_compareDigits(dDigits, maxUsed, xDigits, maxUsed) > 0)) {
+ // d += x, d still negative
+ _absSub(dDigits, abcdUsed, xDigits, maxUsed, dDigits);
+ }
+ // d += x
+ _absSub(xDigits, maxUsed, dDigits, maxUsed, dDigits);
+ dIsNegative = false;
+ } else {
+ while ((dDigits[maxUsed] != 0) ||
+ (_compareDigits(dDigits, maxUsed, xDigits, maxUsed) >= 0)) {
+ // d -= x
+ _absSub(dDigits, abcdUsed, xDigits, maxUsed, dDigits);
+ }
+ }
+ return new _BigIntImpl._(false, maxUsed, dDigits);
+ }
+
+ /**
+ * Returns the modular multiplicative inverse of this big integer
+ * modulo [modulus].
+ *
+ * The [modulus] must be positive.
+ *
+ * It is an error if no modular inverse exists.
+ */
+ // Returns 1/this % modulus, with modulus > 0.
+ _BigIntImpl modInverse(BigInt bigInt) {
+ _BigIntImpl modulus = bigInt;
+ if (modulus <= zero) {
+ throw new ArgumentError("Modulus must be strictly positive: $modulus");
+ }
+ if (modulus == one) return zero;
+ var tmp = this;
+ if (tmp._isNegative || (tmp._absCompare(modulus) >= 0)) {
+ tmp %= modulus;
+ }
+ return _binaryGcd(modulus, tmp, true);
+ }
+
+ /**
+ * Returns the greatest common divisor of this big integer and [other].
+ *
+ * If either number is non-zero, the result is the numerically greatest
+ * integer dividing both `this` and `other`.
+ *
+ * The greatest common divisor is independent of the order,
+ * so `x.gcd(y)` is always the same as `y.gcd(x)`.
+ *
+ * For any integer `x`, `x.gcd(x)` is `x.abs()`.
+ *
+ * If both `this` and `other` is zero, the result is also zero.
+ */
+ _BigIntImpl gcd(BigInt bigInt) {
+ _BigIntImpl other = bigInt;
+ if (_isZero) return other.abs();
+ if (other._isZero) return this.abs();
+ return _binaryGcd(this, other, false);
+ }
+
+ /**
+ * Returns the least significant [width] bits of this big integer as a
+ * non-negative number (i.e. unsigned representation). The returned value has
+ * zeros in all bit positions higher than [width].
+ *
+ * ```
+ * new BigInt.from(-1).toUnsigned(5) == 31 // 11111111 -> 00011111
+ * ```
+ *
+ * This operation can be used to simulate arithmetic from low level languages.
+ * For example, to increment an 8 bit quantity:
+ *
+ * ```
+ * q = (q + 1).toUnsigned(8);
+ * ```
+ *
+ * `q` will count from `0` up to `255` and then wrap around to `0`.
+ *
+ * If the input fits in [width] bits without truncation, the result is the
+ * same as the input. The minimum width needed to avoid truncation of `x` is
+ * given by `x.bitLength`, i.e.
+ *
+ * ```
+ * x == x.toUnsigned(x.bitLength);
+ * ```
+ */
+ _BigIntImpl toUnsigned(int width) {
+ return this & ((one << width) - one);
+ }
+
+ /**
+ * Returns the least significant [width] bits of this integer, extending the
+ * highest retained bit to the sign. This is the same as truncating the value
+ * to fit in [width] bits using an signed 2-s complement representation. The
+ * returned value has the same bit value in all positions higher than [width].
+ *
+ * ```
+ * var big15 = new BigInt.from(15);
+ * var big16 = new BigInt.from(16);
+ * var big239 = new BigInt.from(239);
+ * V--sign bit-V
+ * big16.toSigned(5) == -big16 // 00010000 -> 11110000
+ * big239.toSigned(5) == big15 // 11101111 -> 00001111
+ * ^ ^
+ * ```
+ *
+ * This operation can be used to simulate arithmetic from low level languages.
+ * For example, to increment an 8 bit signed quantity:
+ *
+ * ```
+ * q = (q + 1).toSigned(8);
+ * ```
+ *
+ * `q` will count from `0` up to `127`, wrap to `-128` and count back up to
+ * `127`.
+ *
+ * If the input value fits in [width] bits without truncation, the result is
+ * the same as the input. The minimum width needed to avoid truncation of `x`
+ * is `x.bitLength + 1`, i.e.
+ *
+ * ```
+ * x == x.toSigned(x.bitLength + 1);
+ * ```
+ */
+ _BigIntImpl toSigned(int width) {
+ // The value of binary number weights each bit by a power of two. The
+ // twos-complement value weights the sign bit negatively. We compute the
+ // value of the negative weighting by isolating the sign bit with the
+ // correct power of two weighting and subtracting it from the value of the
+ // lower bits.
+ var signMask = one << (width - 1);
+ return (this & (signMask - one)) - (this & signMask);
+ }
+
+ bool get isValidInt {
+ assert(_digitBits == 32);
+ return _used < 2 ||
+ (_used == 2 &&
+ (_digits[1] < 0x80000000 ||
+ (_isNegative && _digits[1] == 0x80000000 && _digits[0] == 0)));
+ }
+
+ int toInt() {
+ assert(_digitBits == 32);
+ if (_used == 0) return 0;
+ if (_used == 1) return _isNegative ? -_digits[0] : _digits[0];
+ if (_used == 2 && _digits[1] < 0x80000000) {
+ var result = (_digits[1] << _digitBits) | _digits[0];
+ return _isNegative ? -result : result;
+ }
+ return _isNegative ? _minInt : _maxInt;
+ }
+
+ /**
+ * Returns this [_BigIntImpl] as a [double].
+ *
+ * If the number is not representable as a [double], an
+ * approximation is returned. For numerically large integers, the
+ * approximation may be infinite.
+ */
+ double toDouble() {
+ const int exponentBias = 1075;
+ // There are 11 bits for the exponent.
+ // 2047 (all bits set to 1) is reserved for infinity and NaN.
+ // When storing the exponent in the 11 bits, it is biased by exponentBias
+ // to support negative exponents.
+ const int maxDoubleExponent = 2046 - exponentBias;
+ if (_isZero) return 0.0;
+
+ // We fill the 53 bits little-endian.
+ var resultBits = new Uint8List(8);
+
+ var length = _digitBits * (_used - 1) + _digits[_used - 1].bitLength;
+ if (length > maxDoubleExponent + 53) {
+ return _isNegative ? double.negativeInfinity : double.infinity;
+ }
+
+ // The most significant bit is for the sign.
+ if (_isNegative) resultBits[7] = 0x80;
+
+ // Write the exponent into bits 1..12:
+ var biasedExponent = length - 53 + exponentBias;
+ resultBits[6] = (biasedExponent & 0xF) << 4;
+ resultBits[7] |= biasedExponent >> 4;
+
+ int cachedBits = 0;
+ int cachedBitsLength = 0;
+ int digitIndex = _used - 1;
+ int readBits(int n) {
+ // Ensure that we have enough bits in [cachedBits].
+ while (cachedBitsLength < n) {
+ int nextDigit;
+ int nextDigitLength = _digitBits; // May get updated.
+ if (digitIndex < 0) {
+ nextDigit = 0;
+ digitIndex--;
+ } else {
+ nextDigit = _digits[digitIndex];
+ if (digitIndex == _used - 1) nextDigitLength = nextDigit.bitLength;
+ digitIndex--;
+ }
+ cachedBits = (cachedBits << nextDigitLength) + nextDigit;
+ cachedBitsLength += nextDigitLength;
+ }
+ // Read the top [n] bits.
+ var result = cachedBits >> (cachedBitsLength - n);
+ // Remove the bits from the cache.
+ cachedBits -= result << (cachedBitsLength - n);
+ cachedBitsLength -= n;
+ return result;
+ }
+
+ // The first leading 1 bit is implicit in the double-representation and can
+ // be discarded.
+ var leadingBits = readBits(5) & 0xF;
+ resultBits[6] |= leadingBits;
+
+ for (int i = 5; i >= 0; i--) {
+ // Get the remaining 48 bits.
+ resultBits[i] = readBits(8);
+ }
+
+ void roundUp() {
+ // Simply consists of adding 1 to the whole 64 bit "number".
+ // It will update the exponent, if necessary.
+ // It might even round up to infinity (which is what we want).
+ var carry = 1;
+ for (int i = 0; i < 8; i++) {
+ if (carry == 0) break;
+ var sum = resultBits[i] + carry;
+ resultBits[i] = sum & 0xFF;
+ carry = sum >> 8;
+ }
+ }
+
+ if (readBits(1) == 1) {
+ if (resultBits[0].isOdd) {
+ // Rounds to even all the time.
+ roundUp();
+ } else {
+ // Round up, if there is at least one other digit that is not 0.
+ if (cachedBits != 0) {
+ // There is already one in the cachedBits.
+ roundUp();
+ } else {
+ for (int i = digitIndex; digitIndex >= 0; i--) {
+ if (_digits[i] != 0) {
+ roundUp();
+ break;
+ }
+ }
+ }
+ }
+ }
+ return resultBits.buffer.asByteData().getFloat64(0, Endian.little);
+ }
+
+ /**
+ * Returns a String-representation of this integer.
+ *
+ * The returned string is parsable by [parse].
+ * For any `_BigIntImpl` `i`, it is guaranteed that
+ * `i == _BigIntImpl.parse(i.toString())`.
+ */
+ String toString() {
+ if (_used == 0) return "0";
+ if (_used == 1) {
+ if (_isNegative) return (-_digits[0]).toString();
+ return _digits[0].toString();
+ }
+
+ // Generate in chunks of 9 digits.
+ // The chunks are in reversed order.
+ var decimalDigitChunks = <String>[];
+ var rest = isNegative ? -this : this;
+ while (rest._used > 1) {
+ var digits9 = rest.remainder(_oneBillion).toString();
+ decimalDigitChunks.add(digits9);
+ var zeros = 9 - digits9.length;
+ if (zeros == 8) {
+ decimalDigitChunks.add("00000000");
+ } else {
+ if (zeros >= 4) {
+ zeros -= 4;
+ decimalDigitChunks.add("0000");
+ }
+ if (zeros >= 2) {
+ zeros -= 2;
+ decimalDigitChunks.add("00");
+ }
+ if (zeros >= 1) {
+ decimalDigitChunks.add("0");
+ }
+ }
+ rest = rest ~/ _oneBillion;
+ }
+ decimalDigitChunks.add(rest._digits[0].toString());
+ if (_isNegative) decimalDigitChunks.add("-");
+ return decimalDigitChunks.reversed.join();
+ }
+
+ int _toRadixCodeUnit(int digit) {
+ const int _0 = 48;
+ const int _a = 97;
+ if (digit < 10) return _0 + digit;
+ return _a + digit - 10;
+ }
+
+ /**
+ * Converts [this] to a string representation in the given [radix].
+ *
+ * In the string representation, lower-case letters are used for digits above
+ * '9', with 'a' being 10 an 'z' being 35.
+ *
+ * The [radix] argument must be an integer in the range 2 to 36.
+ */
+ String toRadixString(int radix) {
+ if (radix > 36) throw new RangeError.range(radix, 2, 36);
+
+ if (_used == 0) return "0";
+
+ if (_used == 1) {
+ var digitString = _digits[0].toRadixString(radix);
+ if (_isNegative) return "-" + digitString;
+ return digitString;
+ }
+
+ if (radix == 16) return _toHexString();
+
+ var base = new _BigIntImpl._fromInt(radix);
+ var reversedDigitCodeUnits = <int>[];
+ var rest = this.abs();
+ while (!rest._isZero) {
+ var digit = rest.remainder(base).toInt();
+ rest = rest ~/ base;
+ reversedDigitCodeUnits.add(_toRadixCodeUnit(digit));
+ }
+ var digitString = new String.fromCharCodes(reversedDigitCodeUnits.reversed);
+ if (_isNegative) return "-" + digitString;
+ return digitString;
+ }
+
+ String _toHexString() {
+ var chars = <int>[];
+ for (int i = 0; i < _used - 1; i++) {
+ int chunk = _digits[i];
+ for (int j = 0; j < (_digitBits ~/ 4); j++) {
+ chars.add(_toRadixCodeUnit(chunk & 0xF));
+ chunk >>= 4;
+ }
+ }
+ var msbChunk = _digits[_used - 1];
+ while (msbChunk != 0) {
+ chars.add(_toRadixCodeUnit(msbChunk & 0xF));
+ msbChunk >>= 4;
+ }
+ if (_isNegative) {
+ const _dash = 45;
+ chars.add(_dash);
+ }
+ return new String.fromCharCodes(chars.reversed);
+ }
+}
+
+// Interface for modular reduction.
+abstract class _BigIntReduction {
+ int get _normModulusUsed;
+ // Return the number of digits used by resultDigits.
+ int _convert(_BigIntImpl x, Uint32List resultDigits);
+ int _mul(Uint32List xDigits, int xUsed, Uint32List yDigits, int yUsed,
+ Uint32List resultDigits);
+ int _sqr(Uint32List xDigits, int xUsed, Uint32List resultDigits);
+
+ // Return x reverted to _BigIntImpl.
+ _BigIntImpl _revert(Uint32List xDigits, int xUsed);
+}
+
+// Montgomery reduction on _BigIntImpl.
+class _BigIntMontgomeryReduction implements _BigIntReduction {
+ final _BigIntImpl _modulus;
+ int _normModulusUsed; // Even if processing 64-bit (digit pairs).
+ Uint32List _modulusDigits;
+ Uint32List _args;
+ int _digitsPerStep; // Number of digits processed in one step. 1 or 2.
+ static const int _xDigit = 0; // Index of digit of x.
+ static const int _xHighDigit = 1; // Index of high digit of x (64-bit only).
+ static const int _rhoDigit = 2; // Index of digit of rho.
+ static const int _rhoHighDigit = 3; // Index of high digit of rho (64-bit).
+ static const int _muDigit = 4; // Index of mu.
+ static const int _muHighDigit = 5; // Index of high 32-bits of mu (64-bit).
+
+ _BigIntMontgomeryReduction(this._modulus) {
+ _modulusDigits = _modulus._digits;
+ _args = _newDigits(6);
+ // Determine if we can process digit pairs by calling an intrinsic.
+ _digitsPerStep = _mulMod(_args, _args, 0);
+ _args[_xDigit] = _modulusDigits[0];
+ if (_digitsPerStep == 1) {
+ _normModulusUsed = _modulus._used;
+ _invDigit(_args);
+ } else {
+ assert(_digitsPerStep == 2);
+ _normModulusUsed = _modulus._used + (_modulus._used & 1);
+ _args[_xHighDigit] = _modulusDigits[1];
+ _invDigitPair(_args);
+ }
+ }
+
+ // Calculates -1/x % _digitBase, x is 32-bit digit.
+ // xy == 1 (mod m)
+ // xy = 1+km
+ // xy(2-xy) = (1+km)(1-km)
+ // x(y(2-xy)) = 1-k^2 m^2
+ // x(y(2-xy)) == 1 (mod m^2)
+ // if y is 1/x mod m, then y(2-xy) is 1/x mod m^2
+ // Should reduce x and y(2-xy) by m^2 at each step to keep size bounded.
+ //
+ // Operation:
+ // args[_rhoDigit] = 1/args[_xDigit] mod _digitBase.
+ static void _invDigit(Uint32List args) {
+ var x = args[_xDigit];
+ var y = x & 3; // y == 1/x mod 2^2
+ y = (y * (2 - (x & 0xf) * y)) & 0xf; // y == 1/x mod 2^4
+ y = (y * (2 - (x & 0xff) * y)) & 0xff; // y == 1/x mod 2^8
+ y = (y * (2 - (((x & 0xffff) * y) & 0xffff))) & 0xffff; // y == 1/x mod 2^16
+ y = (y * (2 - x * y % _BigIntImpl._digitBase)) % _BigIntImpl._digitBase;
+ // y == 1/x mod _digitBase
+ y = -y; // We really want the negative inverse.
+ args[_rhoDigit] = y & _BigIntImpl._digitMask;
+ assert(((x * y) & _BigIntImpl._digitMask) == _BigIntImpl._digitMask);
+ }
+
+ // Calculates -1/x % _digitBase^2, x is a pair of 32-bit digits.
+ // Operation:
+ // args[_rhoDigit.._rhoHighDigit] =
+ // 1/args[_xDigit.._xHighDigit] mod _digitBase^2.
+ static void _invDigitPair(Uint32List args) {
+ var xl = args[_xDigit]; // Lower 32-bit digit of x.
+ var y = xl & 3; // y == 1/x mod 2^2
+ y = (y * (2 - (xl & 0xf) * y)) & 0xf; // y == 1/x mod 2^4
+ y = (y * (2 - (xl & 0xff) * y)) & 0xff; // y == 1/x mod 2^8
+ y = (y * (2 - (((xl & 0xffff) * y) & 0xffff))) & 0xffff;
+ // y == 1/x mod 2^16
+ y = (y * (2 - ((xl * y) & 0xffffffff))) & 0xffffffff; // y == 1/x mod 2^32
+ var x = (args[_xHighDigit] << _BigIntImpl._digitBits) | xl;
+ y *= 2 - x * y; // Masking with 2^64-1 is implied by 64-bit arithmetic.
+ // y == 1/x mod _digitBase^2
+ y = -y; // We really want the negative inverse.
+ args[_rhoDigit] = y & _BigIntImpl._digitMask;
+ args[_rhoHighDigit] =
+ (y >> _BigIntImpl._digitBits) & _BigIntImpl._digitMask;
+ assert(x * y == -1);
+ }
+
+ // Operation:
+ // args[_muDigit] = args[_rhoDigit]*digits[i] mod _digitBase.
+ // Returns 1.
+ // Note: Intrinsics on 64-bit platforms process digit pairs at even indices:
+ // args[_muDigit.._muHighDigit] =
+ // args[_rhoDigit.._rhoHighDigit] * digits[i..i+1] mod _digitBase^2.
+ // Returns 2.
+ @pragma("vm:exact-result-type", "dart:core#_Smi")
+ @pragma("vm:never-inline")
+ static int _mulMod(Uint32List args, Uint32List digits, int i) {
+ var rhol = args[_rhoDigit] & _BigIntImpl._halfDigitMask;
+ var rhoh = args[_rhoDigit] >> _BigIntImpl._halfDigitBits;
+ var dh = digits[i] >> _BigIntImpl._halfDigitBits;
+ var dl = digits[i] & _BigIntImpl._halfDigitMask;
+ args[_muDigit] = (dl * rhol +
+ (((dl * rhoh + dh * rhol) & _BigIntImpl._halfDigitMask) <<
+ _BigIntImpl._halfDigitBits)) &
+ _BigIntImpl._digitMask;
+ return 1;
+ }
+
+ // result = x*R mod _modulus.
+ // Returns resultUsed.
+ int _convert(_BigIntImpl x, Uint32List resultDigits) {
+ // Montgomery reduction only works if abs(x) < _modulus.
+ assert(x.abs() < _modulus);
+ assert(_digitsPerStep == 1 || _normModulusUsed.isEven);
+ var result = x.abs()._dlShift(_normModulusUsed)._rem(_modulus);
+ if (x._isNegative && !result._isNegative && result._used > 0) {
+ result = _modulus - result;
+ }
+ var used = result._used;
+ var digits = result._digits;
+ var i = used + (used & 1);
+ while (--i >= 0) {
+ resultDigits[i] = digits[i];
+ }
+ return used;
+ }
+
+ _BigIntImpl _revert(Uint32List xDigits, int xUsed) {
+ // Reserve enough digits for modulus squaring and accumulator carry.
+ var resultDigits = _newDigits(2 * _normModulusUsed + 2);
+ var i = xUsed + (xUsed & 1);
+ while (--i >= 0) {
+ resultDigits[i] = xDigits[i];
+ }
+ var resultUsed = _reduce(resultDigits, xUsed);
+ return new _BigIntImpl._(false, resultUsed, resultDigits);
+ }
+
+ // x = x/R mod _modulus.
+ // Returns xUsed.
+ int _reduce(Uint32List xDigits, int xUsed) {
+ while (xUsed < 2 * _normModulusUsed + 2) {
+ // Pad x so _mulAdd has enough room later for a possible carry.
+ xDigits[xUsed++] = 0;
+ }
+ var i = 0;
+ while (i < _normModulusUsed) {
+ var d = _mulMod(_args, xDigits, i);
+ assert(d == _digitsPerStep);
+ d = _BigIntImpl._mulAdd(
+ _args, _muDigit, _modulusDigits, 0, xDigits, i, _normModulusUsed);
+ assert(d == _digitsPerStep);
+ i += d;
+ }
+ // Clamp x.
+ while (xUsed > 0 && xDigits[xUsed - 1] == 0) {
+ --xUsed;
+ }
+ xUsed = _BigIntImpl._drShiftDigits(xDigits, xUsed, i, xDigits);
+ if (_BigIntImpl._compareDigits(
+ xDigits, xUsed, _modulusDigits, _normModulusUsed) >=
+ 0) {
+ _BigIntImpl._absSub(
+ xDigits, xUsed, _modulusDigits, _normModulusUsed, xDigits);
+ }
+ // Clamp x.
+ while (xUsed > 0 && xDigits[xUsed - 1] == 0) {
+ --xUsed;
+ }
+ return xUsed;
+ }
+
+ int _sqr(Uint32List xDigits, int xUsed, Uint32List resultDigits) {
+ var resultUsed = _BigIntImpl._sqrDigits(xDigits, xUsed, resultDigits);
+ return _reduce(resultDigits, resultUsed);
+ }
+
+ int _mul(Uint32List xDigits, int xUsed, Uint32List yDigits, int yUsed,
+ Uint32List resultDigits) {
+ var resultUsed =
+ _BigIntImpl._mulDigits(xDigits, xUsed, yDigits, yUsed, resultDigits);
+ return _reduce(resultDigits, resultUsed);
+ }
+}
+
+// Modular reduction using "classic" algorithm.
+class _BigIntClassicReduction implements _BigIntReduction {
+ final _BigIntImpl _modulus; // Modulus.
+ int _normModulusUsed;
+ _BigIntImpl _normModulus; // Normalized _modulus.
+ Uint32List _normModulusDigits;
+ Uint32List _negNormModulusDigits; // Negated _normModulus digits.
+ int _modulusNsh; // Normalization shift amount.
+ Uint32List _args; // Top _normModulus digit(s) and place holder for estimated
+ // quotient digit(s).
+ Uint32List _tmpDigits; // Temporary digits used during reduction.
+
+ _BigIntClassicReduction(this._modulus) {
+ // Preprocess arguments to _remDigits.
+ var nsh =
+ _BigIntImpl._digitBits - _modulus._digits[_modulus._used - 1].bitLength;
+ // For 64-bit processing, make sure _negNormModulusDigits has an even number
+ // of digits.
+ if (_modulus._used.isOdd) {
+ nsh += _BigIntImpl._digitBits;
+ }
+ _modulusNsh = nsh;
+ _normModulus = _modulus << nsh;
+ _normModulusUsed = _normModulus._used;
+ _normModulusDigits = _normModulus._digits;
+ assert(_normModulusUsed.isEven);
+ _args = _newDigits(4);
+ _args[_BigIntImpl._divisorLowTopDigit] =
+ _normModulusDigits[_normModulusUsed - 2];
+ _args[_BigIntImpl._divisorTopDigit] =
+ _normModulusDigits[_normModulusUsed - 1];
+ // Negate _normModulus so we can use _mulAdd instead of
+ // unimplemented _mulSub.
+ var negNormModulus =
+ _BigIntImpl.one._dlShift(_normModulusUsed) - _normModulus;
+ if (negNormModulus._used < _normModulusUsed) {
+ _negNormModulusDigits = _BigIntImpl._cloneDigits(
+ negNormModulus._digits, 0, _normModulusUsed, _normModulusUsed);
+ } else {
+ _negNormModulusDigits = negNormModulus._digits;
+ }
+ // _negNormModulusDigits is read-only and has _normModulusUsed digits (possibly
+ // including several leading zeros) plus a leading zero for 64-bit
+ // processing.
+ _tmpDigits = _newDigits(2 * _normModulusUsed);
+ }
+
+ int _convert(_BigIntImpl x, Uint32List resultDigits) {
+ var digits;
+ var used;
+ if (x._isNegative || x._absCompare(_modulus) >= 0) {
+ var remainder = x._rem(_modulus);
+ if (x._isNegative && remainder._used > 0) {
+ assert(remainder._isNegative);
+ remainder += _modulus;
+ }
+ assert(!remainder._isNegative);
+ used = remainder._used;
+ digits = remainder._digits;
+ } else {
+ used = x._used;
+ digits = x._digits;
+ }
+ var i = used + (used & 1); // Copy leading zero if any.
+ while (--i >= 0) {
+ resultDigits[i] = digits[i];
+ }
+ return used;
+ }
+
+ _BigIntImpl _revert(Uint32List xDigits, int xUsed) {
+ return new _BigIntImpl._(false, xUsed, xDigits);
+ }
+
+ int _reduce(Uint32List xDigits, int xUsed) {
+ if (xUsed < _modulus._used) {
+ return xUsed;
+ }
+ // The function _BigIntImpl._remDigits(...) is optimized for reduction and
+ // equivalent to calling
+ // 'convert(revert(xDigits, xUsed)._rem(_normModulus), xDigits);'
+ return _BigIntImpl._remDigits(
+ xDigits,
+ xUsed,
+ _normModulusDigits,
+ _normModulusUsed,
+ _negNormModulusDigits,
+ _modulusNsh,
+ _args,
+ _tmpDigits,
+ xDigits);
+ }
+
+ int _sqr(Uint32List xDigits, int xUsed, Uint32List resultDigits) {
+ var resultUsed = _BigIntImpl._sqrDigits(xDigits, xUsed, resultDigits);
+ return _reduce(resultDigits, resultUsed);
+ }
+
+ int _mul(Uint32List xDigits, int xUsed, Uint32List yDigits, int yUsed,
+ Uint32List resultDigits) {
+ var resultUsed =
+ _BigIntImpl._mulDigits(xDigits, xUsed, yDigits, yUsed, resultDigits);
+ return _reduce(resultDigits, resultUsed);
+ }
+}
diff --git a/sdk_nnbd/lib/_internal/vm/lib/bool_patch.dart b/sdk_nnbd/lib/_internal/vm/lib/bool_patch.dart
new file mode 100644
index 0000000..7c20001
--- /dev/null
+++ b/sdk_nnbd/lib/_internal/vm/lib/bool_patch.dart
@@ -0,0 +1,20 @@
+// 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.5
+
+// part of "core_patch.dart";
+
+@patch
+@pragma("vm:entry-point")
+class bool {
+ @patch
+ const factory bool.fromEnvironment(String name, {bool defaultValue: false})
+ native "Bool_fromEnvironment";
+
+ @patch
+ int get hashCode => this ? 1231 : 1237;
+
+ int get _identityHashCode => this ? 1231 : 1237;
+}
diff --git a/sdk_nnbd/lib/_internal/vm/lib/class_id.dart b/sdk_nnbd/lib/_internal/vm/lib/class_id.dart
new file mode 100644
index 0000000..478ade5
--- /dev/null
+++ b/sdk_nnbd/lib/_internal/vm/lib/class_id.dart
@@ -0,0 +1,16 @@
+// Copyright (c) 2014, 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.5
+
+// part of "internal_patch.dart";
+
+@pragma("vm:entry-point")
+class ClassID {
+ @pragma("vm:entry-point")
+ @pragma("vm:exact-result-type", "dart:core#_Smi")
+ static int getID(Object value) native "ClassID_getID";
+
+ // VM injects class id constants into this class.
+}
diff --git a/sdk_nnbd/lib/_internal/vm/lib/class_id_fasta.dart b/sdk_nnbd/lib/_internal/vm/lib/class_id_fasta.dart
new file mode 100644
index 0000000..1dbb2b3
--- /dev/null
+++ b/sdk_nnbd/lib/_internal/vm/lib/class_id_fasta.dart
@@ -0,0 +1,29 @@
+// Copyright (c) 2017, 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.5
+
+// part of "internal_patch.dart";
+
+@pragma("vm:entry-point")
+class ClassID {
+ @pragma("vm:entry-point", "call")
+ @pragma("vm:exact-result-type", "dart:core#_Smi")
+ static int getID(Object value) native "ClassID_getID";
+
+ @pragma("vm:entry-point")
+ static final int cidArray = 0;
+ @pragma("vm:entry-point")
+ static final int cidExternalOneByteString = 0;
+ @pragma("vm:entry-point")
+ static final int cidGrowableObjectArray = 0;
+ @pragma("vm:entry-point")
+ static final int cidImmutableArray = 0;
+ @pragma("vm:entry-point")
+ static final int cidOneByteString = 0;
+ @pragma("vm:entry-point")
+ static final int cidTwoByteString = 0;
+ @pragma("vm:entry-point")
+ static final int cidUint8ArrayView = 0;
+}
diff --git a/sdk_nnbd/lib/_internal/vm/lib/collection_patch.dart b/sdk_nnbd/lib/_internal/vm/lib/collection_patch.dart
new file mode 100644
index 0000000..b421d7d
--- /dev/null
+++ b/sdk_nnbd/lib/_internal/vm/lib/collection_patch.dart
@@ -0,0 +1,940 @@
+// 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
+// BSD-style license that can be found in the LICENSE file.
+
+// @dart = 2.5
+
+/// Note: the VM concatenates all patch files into a single patch file. This
+/// file is the first patch in "dart:collection" which contains all the imports
+/// used by patches of that library. We plan to change this when we have a
+/// shared front end and simply use parts.
+
+import "dart:_internal" as internal;
+
+import "dart:_internal" show patch, IterableElementError;
+
+import "dart:typed_data" show Uint32List;
+
+/// These are the additional parts of this patch library:
+// part "compact_hash.dart";
+
+@patch
+class HashMap<K, V> {
+ @patch
+ factory HashMap(
+ {bool equals(K key1, K key2),
+ int hashCode(K key),
+ bool isValidKey(potentialKey)}) {
+ if (isValidKey == null) {
+ if (hashCode == null) {
+ if (equals == null) {
+ return new _HashMap<K, V>();
+ }
+ hashCode = _defaultHashCode;
+ } else {
+ if (identical(identityHashCode, hashCode) &&
+ identical(identical, equals)) {
+ return new _IdentityHashMap<K, V>();
+ }
+ equals ??= _defaultEquals;
+ }
+ } else {
+ hashCode ??= _defaultHashCode;
+ equals ??= _defaultEquals;
+ }
+ return new _CustomHashMap<K, V>(equals, hashCode, isValidKey);
+ }
+
+ @patch
+ factory HashMap.identity() => new _IdentityHashMap<K, V>();
+
+ Set<K> _newKeySet();
+}
+
+const int _MODIFICATION_COUNT_MASK = 0x3fffffff;
+
+class _HashMap<K, V> extends MapBase<K, V> implements HashMap<K, V> {
+ static const int _INITIAL_CAPACITY = 8;
+
+ int _elementCount = 0;
+ List<_HashMapEntry<K, V>> _buckets =
+ new List<_HashMapEntry<K, V>>(_INITIAL_CAPACITY);
+ int _modificationCount = 0;
+
+ int get length => _elementCount;
+ bool get isEmpty => _elementCount == 0;
+ bool get isNotEmpty => _elementCount != 0;
+
+ Iterable<K> get keys => new _HashMapKeyIterable<K, V>(this);
+ Iterable<V> get values => new _HashMapValueIterable<K, V>(this);
+
+ bool containsKey(Object key) {
+ final hashCode = key.hashCode;
+ final buckets = _buckets;
+ final index = hashCode & (buckets.length - 1);
+ var entry = buckets[index];
+ while (entry != null) {
+ if (hashCode == entry.hashCode && entry.key == key) return true;
+ entry = entry.next;
+ }
+ return false;
+ }
+
+ bool containsValue(Object value) {
+ final buckets = _buckets;
+ final length = buckets.length;
+ for (int i = 0; i < length; i++) {
+ var entry = buckets[i];
+ while (entry != null) {
+ if (entry.value == value) return true;
+ entry = entry.next;
+ }
+ }
+ return false;
+ }
+
+ V operator [](Object key) {
+ final hashCode = key.hashCode;
+ final buckets = _buckets;
+ final index = hashCode & (buckets.length - 1);
+ var entry = buckets[index];
+ while (entry != null) {
+ if (hashCode == entry.hashCode && entry.key == key) {
+ return entry.value;
+ }
+ entry = entry.next;
+ }
+ return null;
+ }
+
+ void operator []=(K key, V value) {
+ final hashCode = key.hashCode;
+ final buckets = _buckets;
+ final length = buckets.length;
+ final index = hashCode & (length - 1);
+ var entry = buckets[index];
+ while (entry != null) {
+ if (hashCode == entry.hashCode && entry.key == key) {
+ entry.value = value;
+ return;
+ }
+ entry = entry.next;
+ }
+ _addEntry(buckets, index, length, key, value, hashCode);
+ }
+
+ V putIfAbsent(K key, V ifAbsent()) {
+ final hashCode = key.hashCode;
+ final buckets = _buckets;
+ final length = buckets.length;
+ final index = hashCode & (length - 1);
+ var entry = buckets[index];
+ while (entry != null) {
+ if (hashCode == entry.hashCode && entry.key == key) {
+ return entry.value;
+ }
+ entry = entry.next;
+ }
+ final stamp = _modificationCount;
+ final V value = ifAbsent();
+ if (stamp == _modificationCount) {
+ _addEntry(buckets, index, length, key, value, hashCode);
+ } else {
+ this[key] = value;
+ }
+ return value;
+ }
+
+ void addAll(Map<K, V> other) {
+ other.forEach((K key, V value) {
+ this[key] = value;
+ });
+ }
+
+ void forEach(void action(K key, V value)) {
+ final stamp = _modificationCount;
+ final buckets = _buckets;
+ final length = buckets.length;
+ for (int i = 0; i < length; i++) {
+ var entry = buckets[i];
+ while (entry != null) {
+ action(entry.key, entry.value);
+ if (stamp != _modificationCount) {
+ throw new ConcurrentModificationError(this);
+ }
+ entry = entry.next;
+ }
+ }
+ }
+
+ V remove(Object key) {
+ final hashCode = key.hashCode;
+ final buckets = _buckets;
+ final index = hashCode & (buckets.length - 1);
+ var entry = buckets[index];
+ _HashMapEntry<K, V> previous = null;
+ while (entry != null) {
+ final next = entry.next;
+ if (hashCode == entry.hashCode && entry.key == key) {
+ _removeEntry(entry, previous, index);
+ _elementCount--;
+ _modificationCount =
+ (_modificationCount + 1) & _MODIFICATION_COUNT_MASK;
+ return entry.value;
+ }
+ previous = entry;
+ entry = next;
+ }
+ return null;
+ }
+
+ void clear() {
+ _buckets = new List(_INITIAL_CAPACITY);
+ if (_elementCount > 0) {
+ _elementCount = 0;
+ _modificationCount = (_modificationCount + 1) & _MODIFICATION_COUNT_MASK;
+ }
+ }
+
+ void _removeEntry(_HashMapEntry<K, V> entry,
+ _HashMapEntry<K, V> previousInBucket, int bucketIndex) {
+ if (previousInBucket == null) {
+ _buckets[bucketIndex] = entry.next;
+ } else {
+ previousInBucket.next = entry.next;
+ }
+ }
+
+ void _addEntry(List<_HashMapEntry<K, V>> buckets, int index, int length,
+ K key, V value, int hashCode) {
+ final entry = new _HashMapEntry<K, V>(key, value, hashCode, buckets[index]);
+ buckets[index] = entry;
+ final newElements = _elementCount + 1;
+ _elementCount = newElements;
+ // If we end up with more than 75% non-empty entries, we
+ // resize the backing store.
+ if ((newElements << 2) > ((length << 1) + length)) _resize();
+ _modificationCount = (_modificationCount + 1) & _MODIFICATION_COUNT_MASK;
+ }
+
+ void _resize() {
+ final oldBuckets = _buckets;
+ final oldLength = oldBuckets.length;
+ final newLength = oldLength << 1;
+ final newBuckets = new List<_HashMapEntry<K, V>>(newLength);
+ for (int i = 0; i < oldLength; i++) {
+ var entry = oldBuckets[i];
+ while (entry != null) {
+ final next = entry.next;
+ final hashCode = entry.hashCode;
+ final index = hashCode & (newLength - 1);
+ entry.next = newBuckets[index];
+ newBuckets[index] = entry;
+ entry = next;
+ }
+ }
+ _buckets = newBuckets;
+ }
+
+ Set<K> _newKeySet() => new _HashSet<K>();
+}
+
+class _CustomHashMap<K, V> extends _HashMap<K, V> {
+ final _Equality<K> _equals;
+ final _Hasher<K> _hashCode;
+ final _Predicate _validKey;
+ _CustomHashMap(this._equals, this._hashCode, validKey)
+ : _validKey = (validKey != null) ? validKey : new _TypeTest<K>().test;
+
+ bool containsKey(Object key) {
+ if (!_validKey(key)) return false;
+ final hashCode = _hashCode(key);
+ final buckets = _buckets;
+ final index = hashCode & (buckets.length - 1);
+ var entry = buckets[index];
+ while (entry != null) {
+ if (hashCode == entry.hashCode && _equals(entry.key, key)) return true;
+ entry = entry.next;
+ }
+ return false;
+ }
+
+ V operator [](Object key) {
+ if (!_validKey(key)) return null;
+ final hashCode = _hashCode(key);
+ final buckets = _buckets;
+ final index = hashCode & (buckets.length - 1);
+ var entry = buckets[index];
+ while (entry != null) {
+ if (hashCode == entry.hashCode && _equals(entry.key, key)) {
+ return entry.value;
+ }
+ entry = entry.next;
+ }
+ return null;
+ }
+
+ void operator []=(K key, V value) {
+ final hashCode = _hashCode(key);
+ final buckets = _buckets;
+ final length = buckets.length;
+ final index = hashCode & (length - 1);
+ var entry = buckets[index];
+ while (entry != null) {
+ if (hashCode == entry.hashCode && _equals(entry.key, key)) {
+ entry.value = value;
+ return;
+ }
+ entry = entry.next;
+ }
+ _addEntry(buckets, index, length, key, value, hashCode);
+ }
+
+ V putIfAbsent(K key, V ifAbsent()) {
+ final hashCode = _hashCode(key);
+ final buckets = _buckets;
+ final length = buckets.length;
+ final index = hashCode & (length - 1);
+ var entry = buckets[index];
+ while (entry != null) {
+ if (hashCode == entry.hashCode && _equals(entry.key, key)) {
+ return entry.value;
+ }
+ entry = entry.next;
+ }
+ int stamp = _modificationCount;
+ V value = ifAbsent();
+ if (stamp == _modificationCount) {
+ _addEntry(buckets, index, length, key, value, hashCode);
+ } else {
+ this[key] = value;
+ }
+ return value;
+ }
+
+ V remove(Object key) {
+ if (!_validKey(key)) return null;
+ final hashCode = _hashCode(key);
+ final buckets = _buckets;
+ final index = hashCode & (buckets.length - 1);
+ var entry = buckets[index];
+ _HashMapEntry<K, V> previous = null;
+ while (entry != null) {
+ final next = entry.next;
+ if (hashCode == entry.hashCode && _equals(entry.key, key)) {
+ _removeEntry(entry, previous, index);
+ _elementCount--;
+ _modificationCount =
+ (_modificationCount + 1) & _MODIFICATION_COUNT_MASK;
+ return entry.value;
+ }
+ previous = entry;
+ entry = next;
+ }
+ return null;
+ }
+
+ Set<K> _newKeySet() => new _CustomHashSet<K>(_equals, _hashCode, _validKey);
+}
+
+class _IdentityHashMap<K, V> extends _HashMap<K, V> {
+ bool containsKey(Object key) {
+ final hashCode = identityHashCode(key);
+ final buckets = _buckets;
+ final index = hashCode & (buckets.length - 1);
+ var entry = buckets[index];
+ while (entry != null) {
+ if (hashCode == entry.hashCode && identical(entry.key, key)) return true;
+ entry = entry.next;
+ }
+ return false;
+ }
+
+ V operator [](Object key) {
+ final hashCode = identityHashCode(key);
+ final buckets = _buckets;
+ final index = hashCode & (buckets.length - 1);
+ var entry = buckets[index];
+ while (entry != null) {
+ if (hashCode == entry.hashCode && identical(entry.key, key)) {
+ return entry.value;
+ }
+ entry = entry.next;
+ }
+ return null;
+ }
+
+ void operator []=(K key, V value) {
+ final hashCode = identityHashCode(key);
+ final buckets = _buckets;
+ final length = buckets.length;
+ final index = hashCode & (length - 1);
+ var entry = buckets[index];
+ while (entry != null) {
+ if (hashCode == entry.hashCode && identical(entry.key, key)) {
+ entry.value = value;
+ return;
+ }
+ entry = entry.next;
+ }
+ _addEntry(buckets, index, length, key, value, hashCode);
+ }
+
+ V putIfAbsent(K key, V ifAbsent()) {
+ final hashCode = identityHashCode(key);
+ final buckets = _buckets;
+ final length = buckets.length;
+ final index = hashCode & (length - 1);
+ var entry = buckets[index];
+ while (entry != null) {
+ if (hashCode == entry.hashCode && identical(entry.key, key)) {
+ return entry.value;
+ }
+ entry = entry.next;
+ }
+ final stamp = _modificationCount;
+ V value = ifAbsent();
+ if (stamp == _modificationCount) {
+ _addEntry(buckets, index, length, key, value, hashCode);
+ } else {
+ this[key] = value;
+ }
+ return value;
+ }
+
+ V remove(Object key) {
+ final hashCode = identityHashCode(key);
+ final buckets = _buckets;
+ final index = hashCode & (buckets.length - 1);
+ var entry = buckets[index];
+ _HashMapEntry<K, V> previous = null;
+ while (entry != null) {
+ final next = entry.next;
+ if (hashCode == entry.hashCode && identical(entry.key, key)) {
+ _removeEntry(entry, previous, index);
+ _elementCount--;
+ _modificationCount =
+ (_modificationCount + 1) & _MODIFICATION_COUNT_MASK;
+ return entry.value;
+ }
+ previous = entry;
+ entry = next;
+ }
+ return null;
+ }
+
+ Set<K> _newKeySet() => new _IdentityHashSet<K>();
+}
+
+class _HashMapEntry<K, V> {
+ final K key;
+ V value;
+ final int hashCode;
+ _HashMapEntry<K, V> next;
+ _HashMapEntry(this.key, this.value, this.hashCode, this.next);
+}
+
+abstract class _HashMapIterable<K, V, E>
+ extends internal.EfficientLengthIterable<E> {
+ final _HashMap<K, V> _map;
+ _HashMapIterable(this._map);
+ int get length => _map.length;
+ bool get isEmpty => _map.isEmpty;
+ bool get isNotEmpty => _map.isNotEmpty;
+}
+
+class _HashMapKeyIterable<K, V> extends _HashMapIterable<K, V, K> {
+ _HashMapKeyIterable(_HashMap<K, V> map) : super(map);
+ Iterator<K> get iterator => new _HashMapKeyIterator<K, V>(_map);
+ bool contains(Object key) => _map.containsKey(key);
+ void forEach(void action(K key)) {
+ _map.forEach((K key, _) {
+ action(key);
+ });
+ }
+
+ Set<K> toSet() => _map._newKeySet()..addAll(this);
+}
+
+class _HashMapValueIterable<K, V> extends _HashMapIterable<K, V, V> {
+ _HashMapValueIterable(_HashMap<K, V> map) : super(map);
+ Iterator<V> get iterator => new _HashMapValueIterator<K, V>(_map);
+ bool contains(Object value) => _map.containsValue(value);
+ void forEach(void action(V value)) {
+ _map.forEach((_, V value) {
+ action(value);
+ });
+ }
+}
+
+abstract class _HashMapIterator<K, V, E> implements Iterator<E> {
+ final _HashMap<K, V> _map;
+ final int _stamp;
+
+ int _index = 0;
+ _HashMapEntry<K, V> _entry;
+
+ _HashMapIterator(this._map) : _stamp = _map._modificationCount;
+
+ bool moveNext() {
+ if (_stamp != _map._modificationCount) {
+ throw new ConcurrentModificationError(_map);
+ }
+ var entry = _entry;
+ if (entry != null) {
+ final next = entry.next;
+ if (next != null) {
+ _entry = next;
+ return true;
+ }
+ _entry = null;
+ }
+ final buckets = _map._buckets;
+ final length = buckets.length;
+ for (int i = _index; i < length; i++) {
+ entry = buckets[i];
+ if (entry != null) {
+ _index = i + 1;
+ _entry = entry;
+ return true;
+ }
+ }
+ _index = length;
+ return false;
+ }
+}
+
+class _HashMapKeyIterator<K, V> extends _HashMapIterator<K, V, K> {
+ _HashMapKeyIterator(_HashMap<K, V> map) : super(map);
+ K get current => _entry?.key;
+}
+
+class _HashMapValueIterator<K, V> extends _HashMapIterator<K, V, V> {
+ _HashMapValueIterator(_HashMap<K, V> map) : super(map);
+ V get current => _entry?.value;
+}
+
+@patch
+class HashSet<E> {
+ @patch
+ factory HashSet(
+ {bool equals(E e1, E e2),
+ int hashCode(E e),
+ bool isValidKey(potentialKey)}) {
+ if (isValidKey == null) {
+ if (hashCode == null) {
+ if (equals == null) {
+ return new _HashSet<E>();
+ }
+ hashCode = _defaultHashCode;
+ } else {
+ if (identical(identityHashCode, hashCode) &&
+ identical(identical, equals)) {
+ return new _IdentityHashSet<E>();
+ }
+ equals ??= _defaultEquals;
+ }
+ } else {
+ hashCode ??= _defaultHashCode;
+ equals ??= _defaultEquals;
+ }
+ return new _CustomHashSet<E>(equals, hashCode, isValidKey);
+ }
+
+ @patch
+ factory HashSet.identity() => new _IdentityHashSet<E>();
+}
+
+class _HashSet<E> extends _SetBase<E> implements HashSet<E> {
+ static const int _INITIAL_CAPACITY = 8;
+
+ List<_HashSetEntry<E>> _buckets =
+ new List<_HashSetEntry<E>>(_INITIAL_CAPACITY);
+ int _elementCount = 0;
+ int _modificationCount = 0;
+
+ bool _equals(e1, e2) => e1 == e2;
+ int _hashCode(e) => e.hashCode;
+
+ static Set<R> _newEmpty<R>() => new _HashSet<R>();
+
+ // Iterable.
+
+ Iterator<E> get iterator => new _HashSetIterator<E>(this);
+
+ int get length => _elementCount;
+
+ bool get isEmpty => _elementCount == 0;
+
+ bool get isNotEmpty => _elementCount != 0;
+
+ bool contains(Object object) {
+ int index = _hashCode(object) & (_buckets.length - 1);
+ _HashSetEntry<E> entry = _buckets[index];
+ while (entry != null) {
+ if (_equals(entry.key, object)) return true;
+ entry = entry.next;
+ }
+ return false;
+ }
+
+ E lookup(Object object) {
+ int index = _hashCode(object) & (_buckets.length - 1);
+ _HashSetEntry<E> entry = _buckets[index];
+ while (entry != null) {
+ var key = entry.key;
+ if (_equals(key, object)) return key;
+ entry = entry.next;
+ }
+ return null;
+ }
+
+ E get first {
+ for (int i = 0; i < _buckets.length; i++) {
+ var entry = _buckets[i];
+ if (entry != null) {
+ return entry.key;
+ }
+ }
+ throw IterableElementError.noElement();
+ }
+
+ E get last {
+ for (int i = _buckets.length - 1; i >= 0; i--) {
+ var entry = _buckets[i];
+ if (entry != null) {
+ while (entry.next != null) {
+ entry = entry.next;
+ }
+ return entry.key;
+ }
+ }
+ throw IterableElementError.noElement();
+ }
+
+ // Set.
+
+ bool add(E element) {
+ final hashCode = _hashCode(element);
+ final index = hashCode & (_buckets.length - 1);
+ _HashSetEntry<E> entry = _buckets[index];
+ while (entry != null) {
+ if (_equals(entry.key, element)) return false;
+ entry = entry.next;
+ }
+ _addEntry(element, hashCode, index);
+ return true;
+ }
+
+ void addAll(Iterable<E> objects) {
+ for (E object in objects) {
+ add(object);
+ }
+ }
+
+ bool _remove(Object object, int hashCode) {
+ final index = hashCode & (_buckets.length - 1);
+ _HashSetEntry<E> entry = _buckets[index];
+ _HashSetEntry<E> previous = null;
+ while (entry != null) {
+ if (_equals(entry.key, object)) {
+ _HashSetEntry<E> next = entry.remove();
+ if (previous == null) {
+ _buckets[index] = next;
+ } else {
+ previous.next = next;
+ }
+ _elementCount--;
+ _modificationCount =
+ (_modificationCount + 1) & _MODIFICATION_COUNT_MASK;
+ return true;
+ }
+ previous = entry;
+ entry = entry.next;
+ }
+ return false;
+ }
+
+ bool remove(Object object) => _remove(object, _hashCode(object));
+
+ void removeAll(Iterable<Object> objectsToRemove) {
+ for (Object object in objectsToRemove) {
+ _remove(object, _hashCode(object));
+ }
+ }
+
+ void _filterWhere(bool test(E element), bool removeMatching) {
+ int length = _buckets.length;
+ for (int index = 0; index < length; index++) {
+ _HashSetEntry<E> entry = _buckets[index];
+ _HashSetEntry<E> previous = null;
+ while (entry != null) {
+ int modificationCount = _modificationCount;
+ bool testResult = test(entry.key);
+ if (modificationCount != _modificationCount) {
+ throw new ConcurrentModificationError(this);
+ }
+ if (testResult == removeMatching) {
+ _HashSetEntry<E> next = entry.remove();
+ if (previous == null) {
+ _buckets[index] = next;
+ } else {
+ previous.next = next;
+ }
+ _elementCount--;
+ _modificationCount =
+ (_modificationCount + 1) & _MODIFICATION_COUNT_MASK;
+ entry = next;
+ } else {
+ previous = entry;
+ entry = entry.next;
+ }
+ }
+ }
+ }
+
+ void removeWhere(bool test(E element)) {
+ _filterWhere(test, true);
+ }
+
+ void retainWhere(bool test(E element)) {
+ _filterWhere(test, false);
+ }
+
+ void clear() {
+ _buckets = new List(_INITIAL_CAPACITY);
+ if (_elementCount > 0) {
+ _elementCount = 0;
+ _modificationCount = (_modificationCount + 1) & _MODIFICATION_COUNT_MASK;
+ }
+ }
+
+ void _addEntry(E key, int hashCode, int index) {
+ _buckets[index] = new _HashSetEntry<E>(key, hashCode, _buckets[index]);
+ int newElements = _elementCount + 1;
+ _elementCount = newElements;
+ int length = _buckets.length;
+ // If we end up with more than 75% non-empty entries, we
+ // resize the backing store.
+ if ((newElements << 2) > ((length << 1) + length)) _resize();
+ _modificationCount = (_modificationCount + 1) & _MODIFICATION_COUNT_MASK;
+ }
+
+ void _resize() {
+ int oldLength = _buckets.length;
+ int newLength = oldLength << 1;
+ List oldBuckets = _buckets;
+ List newBuckets = new List<_HashSetEntry<E>>(newLength);
+ for (int i = 0; i < oldLength; i++) {
+ _HashSetEntry<E> entry = oldBuckets[i];
+ while (entry != null) {
+ _HashSetEntry<E> next = entry.next;
+ int newIndex = entry.hashCode & (newLength - 1);
+ entry.next = newBuckets[newIndex];
+ newBuckets[newIndex] = entry;
+ entry = next;
+ }
+ }
+ _buckets = newBuckets;
+ }
+
+ HashSet<E> _newSet() => new _HashSet<E>();
+ HashSet<R> _newSimilarSet<R>() => new _HashSet<R>();
+}
+
+class _IdentityHashSet<E> extends _HashSet<E> {
+ int _hashCode(e) => identityHashCode(e);
+ bool _equals(e1, e2) => identical(e1, e2);
+
+ HashSet<E> _newSet() => new _IdentityHashSet<E>();
+ HashSet<R> _newSimilarSet<R>() => new _IdentityHashSet<R>();
+}
+
+class _CustomHashSet<E> extends _HashSet<E> {
+ final _Equality<E> _equality;
+ final _Hasher<E> _hasher;
+ final _Predicate _validKey;
+ _CustomHashSet(this._equality, this._hasher, bool validKey(Object o))
+ : _validKey = (validKey != null) ? validKey : new _TypeTest<E>().test;
+
+ bool remove(Object element) {
+ if (!_validKey(element)) return false;
+ return super.remove(element);
+ }
+
+ bool contains(Object element) {
+ if (!_validKey(element)) return false;
+ return super.contains(element);
+ }
+
+ E lookup(Object element) {
+ if (!_validKey(element)) return null;
+ return super.lookup(element);
+ }
+
+ bool containsAll(Iterable<Object> elements) {
+ for (Object element in elements) {
+ if (!_validKey(element) || !this.contains(element)) return false;
+ }
+ return true;
+ }
+
+ void removeAll(Iterable<Object> elements) {
+ for (Object element in elements) {
+ if (_validKey(element)) {
+ super._remove(element, _hasher(element));
+ }
+ }
+ }
+
+ bool _equals(e1, e2) => _equality(e1, e2);
+ int _hashCode(e) => _hasher(e);
+
+ HashSet<E> _newSet() => new _CustomHashSet<E>(_equality, _hasher, _validKey);
+ HashSet<R> _newSimilarSet<R>() => new _HashSet<R>();
+}
+
+class _HashSetEntry<E> {
+ final E key;
+ final int hashCode;
+ _HashSetEntry<E> next;
+ _HashSetEntry(this.key, this.hashCode, this.next);
+
+ _HashSetEntry<E> remove() {
+ final result = next;
+ next = null;
+ return result;
+ }
+}
+
+class _HashSetIterator<E> implements Iterator<E> {
+ final _HashSet<E> _set;
+ final int _modificationCount;
+ int _index = 0;
+ _HashSetEntry<E> _next;
+ E _current;
+
+ _HashSetIterator(this._set) : _modificationCount = _set._modificationCount;
+
+ bool moveNext() {
+ if (_modificationCount != _set._modificationCount) {
+ throw new ConcurrentModificationError(_set);
+ }
+ if (_next != null) {
+ _current = _next.key;
+ _next = _next.next;
+ return true;
+ }
+ List<_HashSetEntry<E>> buckets = _set._buckets;
+ while (_index < buckets.length) {
+ _next = buckets[_index];
+ _index = _index + 1;
+ if (_next != null) {
+ _current = _next.key;
+ _next = _next.next;
+ return true;
+ }
+ }
+ _current = null;
+ return false;
+ }
+
+ E get current => _current;
+}
+
+/**
+ * A hash-based map that iterates keys and values in key insertion order.
+ * This is never actually instantiated any more - the constructor always
+ * returns an instance of _CompactLinkedHashMap or _InternalLinkedHashMap,
+ * which despite the names do not use links (but are insertion-ordered as if
+ * they did).
+ */
+@patch
+class LinkedHashMap<K, V> {
+ @patch
+ factory LinkedHashMap(
+ {bool equals(K key1, K key2),
+ int hashCode(K key),
+ bool isValidKey(potentialKey)}) {
+ if (isValidKey == null) {
+ if (hashCode == null) {
+ if (equals == null) {
+ return new _InternalLinkedHashMap<K, V>();
+ }
+ hashCode = _defaultHashCode;
+ } else {
+ if (identical(identityHashCode, hashCode) &&
+ identical(identical, equals)) {
+ return new _CompactLinkedIdentityHashMap<K, V>();
+ }
+ equals ??= _defaultEquals;
+ }
+ } else {
+ hashCode ??= _defaultHashCode;
+ equals ??= _defaultEquals;
+ }
+ return new _CompactLinkedCustomHashMap<K, V>(equals, hashCode, isValidKey);
+ }
+
+ @patch
+ factory LinkedHashMap.identity() => new _CompactLinkedIdentityHashMap<K, V>();
+}
+
+@patch
+class LinkedHashSet<E> {
+ @patch
+ factory LinkedHashSet(
+ {bool equals(E e1, E e2),
+ int hashCode(E e),
+ bool isValidKey(potentialKey)}) {
+ if (isValidKey == null) {
+ if (hashCode == null) {
+ if (equals == null) {
+ return new _CompactLinkedHashSet<E>();
+ }
+ hashCode = _defaultHashCode;
+ } else {
+ if (identical(identityHashCode, hashCode) &&
+ identical(identical, equals)) {
+ return new _CompactLinkedIdentityHashSet<E>();
+ }
+ equals ??= _defaultEquals;
+ }
+ } else {
+ hashCode ??= _defaultHashCode;
+ equals ??= _defaultEquals;
+ }
+ return new _CompactLinkedCustomHashSet<E>(equals, hashCode, isValidKey);
+ }
+
+ @patch
+ factory LinkedHashSet.identity() => new _CompactLinkedIdentityHashSet<E>();
+}
+
+@patch
+abstract class _SplayTree<K, Node extends _SplayTreeNode<K>> {
+ // We override _splayMin and _splayMax to optimize type-checks.
+ @patch
+ Node _splayMin(Node node) {
+ Node current = node;
+ while (current.left != null) {
+ Node left = internal.unsafeCast<Node>(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 = internal.unsafeCast<Node>(current.right);
+ current.right = right.left;
+ right.left = current;
+ current = right;
+ }
+ return current;
+ }
+}
diff --git a/sdk_nnbd/lib/_internal/vm/lib/compact_hash.dart b/sdk_nnbd/lib/_internal/vm/lib/compact_hash.dart
new file mode 100644
index 0000000..d5a284f
--- /dev/null
+++ b/sdk_nnbd/lib/_internal/vm/lib/compact_hash.dart
@@ -0,0 +1,664 @@
+// Copyright (c) 2015, 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.5
+
+// part of "collection_patch.dart";
+
+// Hash table with open addressing that separates the index from keys/values.
+
+// This function takes care of rehashing of the linked hashmaps in [objects]. We
+// do this eagerly after snapshot deserialization.
+@pragma("vm:entry-point", "call")
+void _rehashObjects(List objects) {
+ final int length = objects.length;
+ for (int i = 0; i < length; ++i) {
+ objects[i]._regenerateIndex();
+ }
+}
+
+abstract class _HashFieldBase {
+ // Each occupied entry in _index is a fixed-size integer that encodes a pair:
+ // [ hash pattern for key | index of entry in _data ]
+ // The hash pattern is based on hashCode, but is guaranteed to be non-zero.
+ // The length of _index is always a power of two, and there is always at
+ // least one unoccupied entry.
+ // NOTE: When maps are deserialized, their _index and _hashMask is regenerated
+ // eagerly by _regenerateIndex.
+ Uint32List _index = new Uint32List(_HashBase._INITIAL_INDEX_SIZE);
+
+ // Cached in-place mask for the hash pattern component.
+ int _hashMask = _HashBase._indexSizeToHashMask(_HashBase._INITIAL_INDEX_SIZE);
+
+ // Fixed-length list of keys (set) or key/value at even/odd indices (map).
+ List _data;
+
+ // Length of _data that is used (i.e., keys + values for a map).
+ int _usedData = 0;
+
+ // Number of deleted keys.
+ int _deletedKeys = 0;
+
+ // Note: All fields are initialized in a single constructor so that the VM
+ // recognizes they cannot hold null values. This makes a big (20%) performance
+ // difference on some operations.
+ _HashFieldBase(int dataSize) : this._data = new List(dataSize);
+}
+
+// Base class for VM-internal classes; keep in sync with _HashFieldBase.
+abstract class _HashVMBase {
+ @pragma("vm:exact-result-type", "dart:typed_data#_Uint32List")
+ @pragma("vm:prefer-inline")
+ Uint32List get _index native "LinkedHashMap_getIndex";
+ @pragma("vm:prefer-inline")
+ void set _index(Uint32List value) native "LinkedHashMap_setIndex";
+
+ @pragma("vm:exact-result-type", "dart:core#_Smi")
+ @pragma("vm:prefer-inline")
+ int get _hashMask native "LinkedHashMap_getHashMask";
+ @pragma("vm:prefer-inline")
+ void set _hashMask(int value) native "LinkedHashMap_setHashMask";
+
+ @pragma("vm:exact-result-type", "dart:core#_List")
+ @pragma("vm:prefer-inline")
+ List get _data native "LinkedHashMap_getData";
+ @pragma("vm:prefer-inline")
+ void set _data(List value) native "LinkedHashMap_setData";
+
+ @pragma("vm:exact-result-type", "dart:core#_Smi")
+ @pragma("vm:prefer-inline")
+ int get _usedData native "LinkedHashMap_getUsedData";
+ @pragma("vm:prefer-inline")
+ void set _usedData(int value) native "LinkedHashMap_setUsedData";
+
+ @pragma("vm:exact-result-type", "dart:core#_Smi")
+ @pragma("vm:prefer-inline")
+ int get _deletedKeys native "LinkedHashMap_getDeletedKeys";
+ @pragma("vm:prefer-inline")
+ void set _deletedKeys(int value) native "LinkedHashMap_setDeletedKeys";
+}
+
+// This mixin can be applied to _HashFieldBase or _HashVMBase (for
+// normal and VM-internalized classes, respectiveley), which provide the
+// actual fields/accessors that this mixin assumes.
+// TODO(koda): Consider moving field comments to _HashFieldBase.
+abstract class _HashBase implements _HashVMBase {
+ // The number of bits used for each component is determined by table size.
+ // The length of _index is twice the number of entries in _data, and both
+ // are doubled when _data is full. Thus, _index will have a max load factor
+ // of 1/2, which enables one more bit to be used for the hash.
+ // TODO(koda): Consider growing _data by factor sqrt(2), twice as often.
+ static const int _INITIAL_INDEX_BITS = 3;
+ static const int _INITIAL_INDEX_SIZE = 1 << (_INITIAL_INDEX_BITS + 1);
+
+ // Unused and deleted entries are marked by 0 and 1, respectively.
+ static const int _UNUSED_PAIR = 0;
+ static const int _DELETED_PAIR = 1;
+
+ // On 32-bit, the top bits are wasted to avoid Mint allocation.
+ // TODO(koda): Reclaim the bits by making the compiler treat hash patterns
+ // as unsigned words.
+ static int _indexSizeToHashMask(int indexSize) {
+ int indexBits = indexSize.bitLength - 2;
+ return internal.is64Bit
+ ? (1 << (32 - indexBits)) - 1
+ : (1 << (30 - indexBits)) - 1;
+ }
+
+ static int _hashPattern(int fullHash, int hashMask, int size) {
+ final int maskedHash = fullHash & hashMask;
+ // TODO(koda): Consider keeping bit length and use left shift.
+ return (maskedHash == 0) ? (size >> 1) : maskedHash * (size >> 1);
+ }
+
+ // Linear probing.
+ static int _firstProbe(int fullHash, int sizeMask) {
+ final int i = fullHash & sizeMask;
+ // Light, fast shuffle to mitigate bad hashCode (e.g., sequential).
+ return ((i << 1) + i) & sizeMask;
+ }
+
+ static int _nextProbe(int i, int sizeMask) => (i + 1) & sizeMask;
+
+ // A self-loop is used to mark a deleted key or value.
+ static bool _isDeleted(List data, Object keyOrValue) =>
+ identical(keyOrValue, data);
+ static void _setDeletedAt(List data, int d) {
+ data[d] = data;
+ }
+
+ // Concurrent modification detection relies on this checksum monotonically
+ // increasing between reallocations of _data.
+ int get _checkSum => _usedData + _deletedKeys;
+ bool _isModifiedSince(List oldData, int oldCheckSum) =>
+ !identical(_data, oldData) || (_checkSum != oldCheckSum);
+
+ int get length;
+}
+
+class _OperatorEqualsAndHashCode {
+ int _hashCode(e) => e.hashCode;
+ bool _equals(e1, e2) => e1 == e2;
+}
+
+class _IdenticalAndIdentityHashCode {
+ int _hashCode(e) => identityHashCode(e);
+ bool _equals(e1, e2) => identical(e1, e2);
+}
+
+// VM-internalized implementation of a default-constructed LinkedHashMap.
+@pragma("vm:entry-point")
+class _InternalLinkedHashMap<K, V> extends _HashVMBase
+ with
+ MapMixin<K, V>,
+ _LinkedHashMapMixin<K, V>,
+ _HashBase,
+ _OperatorEqualsAndHashCode
+ implements LinkedHashMap<K, V> {
+ _InternalLinkedHashMap() {
+ _index = new Uint32List(_HashBase._INITIAL_INDEX_SIZE);
+ _hashMask = _HashBase._indexSizeToHashMask(_HashBase._INITIAL_INDEX_SIZE);
+ _data = new List(_HashBase._INITIAL_INDEX_SIZE);
+ _usedData = 0;
+ _deletedKeys = 0;
+ }
+}
+
+abstract class _LinkedHashMapMixin<K, V> implements _HashBase {
+ int _hashCode(e);
+ bool _equals(e1, e2);
+ int get _checkSum;
+ bool _isModifiedSince(List oldData, int oldCheckSum);
+
+ int get length => (_usedData >> 1) - _deletedKeys;
+ bool get isEmpty => length == 0;
+ bool get isNotEmpty => !isEmpty;
+
+ void _rehash() {
+ if ((_deletedKeys << 2) > _usedData) {
+ // TODO(koda): Consider shrinking.
+ // TODO(koda): Consider in-place compaction and more costly CME check.
+ _init(_index.length, _hashMask, _data, _usedData);
+ } else {
+ // TODO(koda): Support 32->64 bit transition (and adjust _hashMask).
+ _init(_index.length << 1, _hashMask >> 1, _data, _usedData);
+ }
+ }
+
+ void clear() {
+ if (!isEmpty) {
+ _init(_HashBase._INITIAL_INDEX_SIZE, _hashMask, null, 0);
+ }
+ }
+
+ // Allocate new _index and _data, and optionally copy existing contents.
+ void _init(int size, int hashMask, List oldData, int oldUsed) {
+ assert(size & (size - 1) == 0);
+ assert(_HashBase._UNUSED_PAIR == 0);
+ _index = new Uint32List(size);
+ _hashMask = hashMask;
+ _data = new List(size);
+ _usedData = 0;
+ _deletedKeys = 0;
+ if (oldData != null) {
+ for (int i = 0; i < oldUsed; i += 2) {
+ var key = oldData[i];
+ if (!_HashBase._isDeleted(oldData, key)) {
+ // TODO(koda): While there are enough hash bits, avoid hashCode calls.
+ this[key] = oldData[i + 1];
+ }
+ }
+ }
+ }
+
+ // This method is called by [_rehashObjects] (see above).
+ void _regenerateIndex() {
+ _index = new Uint32List(_data.length);
+ assert(_hashMask == 0);
+ _hashMask = _HashBase._indexSizeToHashMask(_index.length);
+ final int tmpUsed = _usedData;
+ _usedData = 0;
+ for (int i = 0; i < tmpUsed; i += 2) {
+ this[_data[i]] = _data[i + 1];
+ }
+ }
+
+ void _insert(K key, V value, int hashPattern, int i) {
+ if (_usedData == _data.length) {
+ _rehash();
+ this[key] = value;
+ } else {
+ assert(1 <= hashPattern && hashPattern < (1 << 32));
+ final int index = _usedData >> 1;
+ assert((index & hashPattern) == 0);
+ _index[i] = hashPattern | index;
+ _data[_usedData++] = key;
+ _data[_usedData++] = value;
+ }
+ }
+
+ // If key is present, returns the index of the value in _data, else returns
+ // the negated insertion point in _index.
+ int _findValueOrInsertPoint(K key, int fullHash, int hashPattern, int size) {
+ final int sizeMask = size - 1;
+ final int maxEntries = size >> 1;
+ int i = _HashBase._firstProbe(fullHash, sizeMask);
+ int firstDeleted = -1;
+ int pair = _index[i];
+ while (pair != _HashBase._UNUSED_PAIR) {
+ if (pair == _HashBase._DELETED_PAIR) {
+ if (firstDeleted < 0) {
+ firstDeleted = i;
+ }
+ } else {
+ final int entry = hashPattern ^ pair;
+ if (entry < maxEntries) {
+ final int d = entry << 1;
+ if (_equals(key, _data[d])) {
+ return d + 1;
+ }
+ }
+ }
+ i = _HashBase._nextProbe(i, sizeMask);
+ pair = _index[i];
+ }
+ return firstDeleted >= 0 ? -firstDeleted : -i;
+ }
+
+ void operator []=(K key, V value) {
+ final int size = _index.length;
+ final int fullHash = _hashCode(key);
+ final int hashPattern = _HashBase._hashPattern(fullHash, _hashMask, size);
+ final int d = _findValueOrInsertPoint(key, fullHash, hashPattern, size);
+ if (d > 0) {
+ _data[d] = value;
+ } else {
+ final int i = -d;
+ _insert(key, value, hashPattern, i);
+ }
+ }
+
+ V putIfAbsent(K key, V ifAbsent()) {
+ final int size = _index.length;
+ final int fullHash = _hashCode(key);
+ final int hashPattern = _HashBase._hashPattern(fullHash, _hashMask, size);
+ final int d = _findValueOrInsertPoint(key, fullHash, hashPattern, size);
+ if (d > 0) {
+ return _data[d];
+ }
+ // 'ifAbsent' is allowed to modify the map.
+ List oldData = _data;
+ int oldCheckSum = _checkSum;
+ V value = ifAbsent();
+ if (_isModifiedSince(oldData, oldCheckSum)) {
+ this[key] = value;
+ } else {
+ final int i = -d;
+ _insert(key, value, hashPattern, i);
+ }
+ return value;
+ }
+
+ V remove(Object key) {
+ final int size = _index.length;
+ final int sizeMask = size - 1;
+ final int maxEntries = size >> 1;
+ final int fullHash = _hashCode(key);
+ final int hashPattern = _HashBase._hashPattern(fullHash, _hashMask, size);
+ int i = _HashBase._firstProbe(fullHash, sizeMask);
+ int pair = _index[i];
+ while (pair != _HashBase._UNUSED_PAIR) {
+ if (pair != _HashBase._DELETED_PAIR) {
+ final int entry = hashPattern ^ pair;
+ if (entry < maxEntries) {
+ final int d = entry << 1;
+ if (_equals(key, _data[d])) {
+ _index[i] = _HashBase._DELETED_PAIR;
+ _HashBase._setDeletedAt(_data, d);
+ V value = _data[d + 1];
+ _HashBase._setDeletedAt(_data, d + 1);
+ ++_deletedKeys;
+ return value;
+ }
+ }
+ }
+ i = _HashBase._nextProbe(i, sizeMask);
+ pair = _index[i];
+ }
+ return null;
+ }
+
+ // If key is absent, return _data (which is never a value).
+ Object _getValueOrData(Object key) {
+ final int size = _index.length;
+ final int sizeMask = size - 1;
+ final int maxEntries = size >> 1;
+ final int fullHash = _hashCode(key);
+ final int hashPattern = _HashBase._hashPattern(fullHash, _hashMask, size);
+ int i = _HashBase._firstProbe(fullHash, sizeMask);
+ int pair = _index[i];
+ while (pair != _HashBase._UNUSED_PAIR) {
+ if (pair != _HashBase._DELETED_PAIR) {
+ final int entry = hashPattern ^ pair;
+ if (entry < maxEntries) {
+ final int d = entry << 1;
+ if (_equals(key, _data[d])) {
+ return _data[d + 1];
+ }
+ }
+ }
+ i = _HashBase._nextProbe(i, sizeMask);
+ pair = _index[i];
+ }
+ return _data;
+ }
+
+ bool containsKey(Object key) => !identical(_data, _getValueOrData(key));
+
+ V operator [](Object key) {
+ var v = _getValueOrData(key);
+ return identical(_data, v) ? null : internal.unsafeCast<V>(v);
+ }
+
+ bool containsValue(Object value) {
+ for (var v in values) {
+ // Spec. says this should always use "==", also for identity maps, etc.
+ if (v == value) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ void forEach(void f(K key, V value)) {
+ var ki = keys.iterator;
+ var vi = values.iterator;
+ while (ki.moveNext()) {
+ vi.moveNext();
+ f(ki.current, vi.current);
+ }
+ }
+
+ Iterable<K> get keys =>
+ new _CompactIterable<K>(this, _data, _usedData, -2, 2);
+ Iterable<V> get values =>
+ new _CompactIterable<V>(this, _data, _usedData, -1, 2);
+}
+
+class _CompactLinkedIdentityHashMap<K, V> extends _HashFieldBase
+ with
+ MapMixin<K, V>,
+ _LinkedHashMapMixin<K, V>,
+ _HashBase,
+ _IdenticalAndIdentityHashCode
+ implements LinkedHashMap<K, V> {
+ _CompactLinkedIdentityHashMap() : super(_HashBase._INITIAL_INDEX_SIZE);
+}
+
+class _CompactLinkedCustomHashMap<K, V> extends _HashFieldBase
+ with MapMixin<K, V>, _LinkedHashMapMixin<K, V>, _HashBase
+ implements LinkedHashMap<K, V> {
+ final _equality;
+ final _hasher;
+ final _validKey;
+
+ // TODO(koda): Ask gbracha why I cannot have fields _equals/_hashCode.
+ int _hashCode(e) => _hasher(e);
+ bool _equals(e1, e2) => _equality(e1, e2);
+
+ bool containsKey(Object o) => _validKey(o) ? super.containsKey(o) : false;
+ V operator [](Object o) => _validKey(o) ? super[o] : null;
+ V remove(Object o) => _validKey(o) ? super.remove(o) : null;
+
+ _CompactLinkedCustomHashMap(this._equality, this._hasher, validKey)
+ : _validKey = (validKey != null) ? validKey : new _TypeTest<K>().test,
+ super(_HashBase._INITIAL_INDEX_SIZE);
+}
+
+// Iterates through _data[_offset + _step], _data[_offset + 2*_step], ...
+// and checks for concurrent modification.
+class _CompactIterable<E> extends Iterable<E> {
+ final _HashBase _table;
+ final List _data;
+ final int _len;
+ final int _offset;
+ final int _step;
+
+ _CompactIterable(
+ this._table, this._data, this._len, this._offset, this._step);
+
+ Iterator<E> get iterator =>
+ new _CompactIterator<E>(_table, _data, _len, _offset, _step);
+
+ int get length => _table.length;
+ bool get isEmpty => length == 0;
+ bool get isNotEmpty => !isEmpty;
+}
+
+class _CompactIterator<E> implements Iterator<E> {
+ final _HashBase _table;
+ final List _data;
+ final int _len;
+ int _offset;
+ final int _step;
+ final int _checkSum;
+ E current;
+
+ _CompactIterator(
+ _HashBase table, this._data, this._len, this._offset, this._step)
+ : _table = table,
+ _checkSum = table._checkSum;
+
+ bool moveNext() {
+ if (_table._isModifiedSince(_data, _checkSum)) {
+ throw new ConcurrentModificationError(_table);
+ }
+ do {
+ _offset += _step;
+ } while (_offset < _len && _HashBase._isDeleted(_data, _data[_offset]));
+ if (_offset < _len) {
+ current = internal.unsafeCast<E>(_data[_offset]);
+ return true;
+ } else {
+ current = null;
+ return false;
+ }
+ }
+}
+
+// Set implementation, analogous to _CompactLinkedHashMap.
+class _CompactLinkedHashSet<E> extends _HashFieldBase
+ with _HashBase, _OperatorEqualsAndHashCode, SetMixin<E>
+ implements LinkedHashSet<E> {
+ _CompactLinkedHashSet() : super(_HashBase._INITIAL_INDEX_SIZE >> 1) {
+ assert(_HashBase._UNUSED_PAIR == 0);
+ }
+
+ static Set<R> _newEmpty<R>() => new _CompactLinkedHashSet<R>();
+
+ Set<R> cast<R>() => Set.castFrom<E, R>(this, newSet: _newEmpty);
+ int get length => _usedData - _deletedKeys;
+
+ E get first {
+ for (int offset = 0; offset < _usedData; offset++) {
+ Object current = _data[offset];
+ if (!_HashBase._isDeleted(_data, current)) {
+ return current;
+ }
+ }
+ throw IterableElementError.noElement();
+ }
+
+ E get last {
+ for (int offset = _usedData - 1; offset >= 0; offset--) {
+ Object current = _data[offset];
+ if (!_HashBase._isDeleted(_data, current)) {
+ return current;
+ }
+ }
+ throw IterableElementError.noElement();
+ }
+
+ void _rehash() {
+ if ((_deletedKeys << 1) > _usedData) {
+ _init(_index.length, _hashMask, _data, _usedData);
+ } else {
+ _init(_index.length << 1, _hashMask >> 1, _data, _usedData);
+ }
+ }
+
+ void clear() {
+ if (!isEmpty) {
+ _init(_HashBase._INITIAL_INDEX_SIZE, _hashMask, null, 0);
+ }
+ }
+
+ void _init(int size, int hashMask, List oldData, int oldUsed) {
+ _index = new Uint32List(size);
+ _hashMask = hashMask;
+ _data = new List(size >> 1);
+ _usedData = 0;
+ _deletedKeys = 0;
+ if (oldData != null) {
+ for (int i = 0; i < oldUsed; i += 1) {
+ var key = oldData[i];
+ if (!_HashBase._isDeleted(oldData, key)) {
+ add(key);
+ }
+ }
+ }
+ }
+
+ bool add(E key) {
+ final int size = _index.length;
+ final int sizeMask = size - 1;
+ final int maxEntries = size >> 1;
+ final int fullHash = _hashCode(key);
+ final int hashPattern = _HashBase._hashPattern(fullHash, _hashMask, size);
+ int i = _HashBase._firstProbe(fullHash, sizeMask);
+ int firstDeleted = -1;
+ int pair = _index[i];
+ while (pair != _HashBase._UNUSED_PAIR) {
+ if (pair == _HashBase._DELETED_PAIR) {
+ if (firstDeleted < 0) {
+ firstDeleted = i;
+ }
+ } else {
+ final int d = hashPattern ^ pair;
+ if (d < maxEntries && _equals(key, _data[d])) {
+ return false;
+ }
+ }
+ i = _HashBase._nextProbe(i, sizeMask);
+ pair = _index[i];
+ }
+ if (_usedData == _data.length) {
+ _rehash();
+ add(key);
+ } else {
+ final int insertionPoint = (firstDeleted >= 0) ? firstDeleted : i;
+ assert(1 <= hashPattern && hashPattern < (1 << 32));
+ assert((hashPattern & _usedData) == 0);
+ _index[insertionPoint] = hashPattern | _usedData;
+ _data[_usedData++] = key;
+ }
+ return true;
+ }
+
+ // If key is absent, return _data (which is never a value).
+ Object _getKeyOrData(Object key) {
+ final int size = _index.length;
+ final int sizeMask = size - 1;
+ final int maxEntries = size >> 1;
+ final int fullHash = _hashCode(key);
+ final int hashPattern = _HashBase._hashPattern(fullHash, _hashMask, size);
+ int i = _HashBase._firstProbe(fullHash, sizeMask);
+ int pair = _index[i];
+ while (pair != _HashBase._UNUSED_PAIR) {
+ if (pair != _HashBase._DELETED_PAIR) {
+ final int d = hashPattern ^ pair;
+ if (d < maxEntries && _equals(key, _data[d])) {
+ return _data[d]; // Note: Must return the existing key.
+ }
+ }
+ i = _HashBase._nextProbe(i, sizeMask);
+ pair = _index[i];
+ }
+ return _data;
+ }
+
+ E lookup(Object key) {
+ var k = _getKeyOrData(key);
+ return identical(_data, k) ? null : k;
+ }
+
+ bool contains(Object key) => !identical(_data, _getKeyOrData(key));
+
+ bool remove(Object key) {
+ final int size = _index.length;
+ final int sizeMask = size - 1;
+ final int maxEntries = size >> 1;
+ final int fullHash = _hashCode(key);
+ final int hashPattern = _HashBase._hashPattern(fullHash, _hashMask, size);
+ int i = _HashBase._firstProbe(fullHash, sizeMask);
+ int pair = _index[i];
+ while (pair != _HashBase._UNUSED_PAIR) {
+ if (pair != _HashBase._DELETED_PAIR) {
+ final int d = hashPattern ^ pair;
+ if (d < maxEntries && _equals(key, _data[d])) {
+ _index[i] = _HashBase._DELETED_PAIR;
+ _HashBase._setDeletedAt(_data, d);
+ ++_deletedKeys;
+ return true;
+ }
+ }
+ i = _HashBase._nextProbe(i, sizeMask);
+ pair = _index[i];
+ }
+ return false;
+ }
+
+ Iterator<E> get iterator =>
+ new _CompactIterator<E>(this, _data, _usedData, -1, 1);
+
+ // Returns a set of the same type, although this
+ // is not required by the spec. (For instance, always using an identity set
+ // would be technically correct, albeit surprising.)
+ Set<E> toSet() => new _CompactLinkedHashSet<E>()..addAll(this);
+
+ // This method is called by [_rehashObjects] (see above).
+ void _regenerateIndex() {
+ _rehash();
+ }
+}
+
+class _CompactLinkedIdentityHashSet<E> extends _CompactLinkedHashSet<E>
+ with _IdenticalAndIdentityHashCode {
+ Set<E> toSet() => new _CompactLinkedIdentityHashSet<E>()..addAll(this);
+
+ static Set<R> _newEmpty<R>() => new _CompactLinkedIdentityHashSet<R>();
+
+ Set<R> cast<R>() => Set.castFrom<E, R>(this, newSet: _newEmpty);
+}
+
+class _CompactLinkedCustomHashSet<E> extends _CompactLinkedHashSet<E> {
+ final _equality;
+ final _hasher;
+ final _validKey;
+
+ int _hashCode(e) => _hasher(e);
+ bool _equals(e1, e2) => _equality(e1, e2);
+
+ bool contains(Object o) => _validKey(o) ? super.contains(o) : false;
+ E lookup(Object o) => _validKey(o) ? super.lookup(o) : null;
+ bool remove(Object o) => _validKey(o) ? super.remove(o) : false;
+
+ _CompactLinkedCustomHashSet(this._equality, this._hasher, validKey)
+ : _validKey = (validKey != null) ? validKey : new _TypeTest<E>().test;
+
+ Set<R> cast<R>() => Set.castFrom<E, R>(this);
+ Set<E> toSet() =>
+ new _CompactLinkedCustomHashSet<E>(_equality, _hasher, _validKey)
+ ..addAll(this);
+}
diff --git a/sdk_nnbd/lib/_internal/vm/lib/convert_patch.dart b/sdk_nnbd/lib/_internal/vm/lib/convert_patch.dart
new file mode 100644
index 0000000..4eeb85f
--- /dev/null
+++ b/sdk_nnbd/lib/_internal/vm/lib/convert_patch.dart
@@ -0,0 +1,1878 @@
+// Copyright (c) 2014, 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.5
+
+/// Note: the VM concatenates all patch files into a single patch file. This
+/// file is the first patch in "dart:convert" which contains all the imports
+/// used by patches of that library. We plan to change this when we have a
+/// shared front end and simply use parts.
+
+import "dart:_internal" show POWERS_OF_TEN, patch, ClassID;
+
+import "dart:typed_data" show Uint8List, Uint16List;
+
+/// This patch library has no additional parts.
+
+// JSON conversion.
+
+@patch
+_parseJson(String source, reviver(key, value)) {
+ _BuildJsonListener listener;
+ if (reviver == null) {
+ listener = new _BuildJsonListener();
+ } else {
+ listener = new _ReviverJsonListener(reviver);
+ }
+ var parser = new _JsonStringParser(listener);
+ parser.chunk = source;
+ parser.chunkEnd = source.length;
+ parser.parse(0);
+ parser.close();
+ return listener.result;
+}
+
+@patch
+class Utf8Decoder {
+ @patch
+ Converter<List<int>, T> fuse<T>(Converter<String, T> next) {
+ if (next is JsonDecoder) {
+ return new _JsonUtf8Decoder(
+ (next as JsonDecoder)._reviver, this._allowMalformed)
+ as dynamic/*=Converter<List<int>, T>*/;
+ }
+ // TODO(lrn): Recognize a fused decoder where the next step is JsonDecoder.
+ return super.fuse<T>(next);
+ }
+
+ // Allow intercepting of UTF-8 decoding when built-in lists are passed.
+ @patch
+ static String _convertIntercepted(
+ bool allowMalformed, List<int> codeUnits, int start, int end) {
+ return null; // This call was not intercepted.
+ }
+}
+
+class _JsonUtf8Decoder extends Converter<List<int>, Object> {
+ final Function(Object key, Object value) _reviver;
+ final bool _allowMalformed;
+
+ _JsonUtf8Decoder(this._reviver, this._allowMalformed);
+
+ Object convert(List<int> input) {
+ var parser = _JsonUtf8DecoderSink._createParser(_reviver, _allowMalformed);
+ parser.chunk = input;
+ parser.chunkEnd = input.length;
+ parser.parse(0);
+ parser.close();
+ return parser.result;
+ }
+
+ ByteConversionSink startChunkedConversion(Sink<Object> sink) {
+ return new _JsonUtf8DecoderSink(_reviver, sink, _allowMalformed);
+ }
+}
+
+//// Implementation ///////////////////////////////////////////////////////////
+
+// Simple API for JSON parsing.
+
+/**
+ * Listener for parsing events from [_ChunkedJsonParser].
+ */
+abstract class _JsonListener {
+ void handleString(String value) {}
+ void handleNumber(num value) {}
+ void handleBool(bool value) {}
+ void handleNull() {}
+ void beginObject() {}
+ void propertyName() {}
+ void propertyValue() {}
+ void endObject() {}
+ void beginArray() {}
+ void arrayElement() {}
+ void endArray() {}
+
+ /**
+ * Read out the final result of parsing a JSON string.
+ *
+ * Must only be called when the entire input has been parsed.
+ */
+ get result;
+}
+
+/**
+ * A [_JsonListener] that builds data objects from the parser events.
+ *
+ * This is a simple stack-based object builder. It keeps the most recently
+ * seen value in a variable, and uses it depending on the following event.
+ */
+class _BuildJsonListener extends _JsonListener {
+ /**
+ * Stack used to handle nested containers.
+ *
+ * The current container is pushed on the stack when a new one is
+ * started. If the container is a [Map], there is also a current [key]
+ * which is also stored on the stack.
+ */
+ List stack = [];
+ /** The current [Map] or [List] being built. */
+ var currentContainer;
+ /** The most recently read property key. */
+ String key;
+ /** The most recently read value. */
+ var value;
+
+ /** Pushes the currently active container (and key, if a [Map]). */
+ void pushContainer() {
+ if (currentContainer is Map) stack.add(key);
+ stack.add(currentContainer);
+ }
+
+ /** Pops the top container from the [stack], including a key if applicable. */
+ void popContainer() {
+ value = currentContainer;
+ currentContainer = stack.removeLast();
+ if (currentContainer is Map) key = stack.removeLast();
+ }
+
+ void handleString(String value) {
+ this.value = value;
+ }
+
+ void handleNumber(num value) {
+ this.value = value;
+ }
+
+ void handleBool(bool value) {
+ this.value = value;
+ }
+
+ void handleNull() {
+ this.value = null;
+ }
+
+ void beginObject() {
+ pushContainer();
+ currentContainer = <String, dynamic>{};
+ }
+
+ void propertyName() {
+ key = value;
+ value = null;
+ }
+
+ void propertyValue() {
+ Map map = currentContainer;
+ map[key] = value;
+ key = value = null;
+ }
+
+ void endObject() {
+ popContainer();
+ }
+
+ void beginArray() {
+ pushContainer();
+ currentContainer = [];
+ }
+
+ void arrayElement() {
+ currentContainer.add(value);
+ value = null;
+ }
+
+ void endArray() {
+ popContainer();
+ }
+
+ /** Read out the final result of parsing a JSON string. */
+ get result {
+ assert(currentContainer == null);
+ return value;
+ }
+}
+
+class _ReviverJsonListener extends _BuildJsonListener {
+ final Function(Object key, Object value) reviver;
+ _ReviverJsonListener(this.reviver);
+
+ void arrayElement() {
+ List list = currentContainer;
+ value = reviver(list.length, value);
+ super.arrayElement();
+ }
+
+ void propertyValue() {
+ value = reviver(key, value);
+ super.propertyValue();
+ }
+
+ get result {
+ return reviver(null, value);
+ }
+}
+
+/**
+ * Buffer holding parts of a numeral.
+ *
+ * The buffer contains the characters of a JSON number.
+ * These are all ASCII, so an [Uint8List] is used as backing store.
+ *
+ * This buffer is used when a JSON number is split between separate chunks.
+ *
+ */
+class _NumberBuffer {
+ static const int minCapacity = 16;
+ static const int kDefaultOverhead = 5;
+ Uint8List list;
+ int length = 0;
+ _NumberBuffer(int initialCapacity)
+ : list = new Uint8List(_initialCapacity(initialCapacity));
+
+ int get capacity => list.length;
+
+ // Pick an initial capacity greater than the first part's size.
+ // The typical use case has two parts, this is the attempt at
+ // guessing the size of the second part without overdoing it.
+ // The default estimate of the second part is [kDefaultOverhead],
+ // then round to multiplum of four, and return the result,
+ // or [minCapacity] if that is greater.
+ static int _initialCapacity(int minCapacity) {
+ minCapacity += kDefaultOverhead;
+ if (minCapacity < minCapacity) return minCapacity;
+ minCapacity = (minCapacity + 3) & ~3; // Round to multiple of four.
+ return minCapacity;
+ }
+
+ // Grows to the exact size asked for.
+ void ensureCapacity(int newCapacity) {
+ Uint8List list = this.list;
+ if (newCapacity <= list.length) return;
+ Uint8List newList = new Uint8List(newCapacity);
+ newList.setRange(0, list.length, list, 0);
+ this.list = newList;
+ }
+
+ String getString() {
+ String result = new String.fromCharCodes(list, 0, length);
+ return result;
+ }
+
+ // TODO(lrn): See if parsing of numbers can be abstracted to something
+ // not only working on strings, but also on char-code lists, without lossing
+ // performance.
+ num parseNum() => num.parse(getString());
+ double parseDouble() => double.parse(getString());
+}
+
+/**
+ * Chunked JSON parser.
+ *
+ * Receives inputs in chunks, gives access to individual parts of the input,
+ * and stores input state between chunks.
+ *
+ * Implementations include [String] and UTF-8 parsers.
+ */
+abstract class _ChunkedJsonParser<T> {
+ // A simple non-recursive state-based parser for JSON.
+ //
+ // Literal values accepted in states ARRAY_EMPTY, ARRAY_COMMA, OBJECT_COLON
+ // and strings also in OBJECT_EMPTY, OBJECT_COMMA.
+ // VALUE STRING : , } ] Transitions to
+ // EMPTY X X -> END
+ // ARRAY_EMPTY X X @ -> ARRAY_VALUE / pop
+ // ARRAY_VALUE @ @ -> ARRAY_COMMA / pop
+ // ARRAY_COMMA X X -> ARRAY_VALUE
+ // OBJECT_EMPTY X @ -> OBJECT_KEY / pop
+ // OBJECT_KEY @ -> OBJECT_COLON
+ // OBJECT_COLON X X -> OBJECT_VALUE
+ // OBJECT_VALUE @ @ -> OBJECT_COMMA / pop
+ // OBJECT_COMMA X -> OBJECT_KEY
+ // END
+ // Starting a new array or object will push the current state. The "pop"
+ // above means restoring this state and then marking it as an ended value.
+ // X means generic handling, @ means special handling for just that
+ // state - that is, values are handled generically, only punctuation
+ // cares about the current state.
+ // Values for states are chosen so bits 0 and 1 tell whether
+ // a string/value is allowed, and setting bits 0 through 2 after a value
+ // gets to the next state (not empty, doesn't allow a value).
+
+ // State building-block constants.
+ static const int TOP_LEVEL = 0;
+ static const int INSIDE_ARRAY = 1;
+ static const int INSIDE_OBJECT = 2;
+ static const int AFTER_COLON = 3; // Always inside object.
+
+ static const int ALLOW_STRING_MASK = 8; // Allowed if zero.
+ static const int ALLOW_VALUE_MASK = 4; // Allowed if zero.
+ static const int ALLOW_VALUE = 0;
+ static const int STRING_ONLY = 4;
+ static const int NO_VALUES = 12;
+
+ // Objects and arrays are "empty" until their first property/element.
+ // At this position, they may either have an entry or a close-bracket.
+ static const int EMPTY = 0;
+ static const int NON_EMPTY = 16;
+ static const int EMPTY_MASK = 16; // Empty if zero.
+
+ // Actual states : Context | Is empty? | Next?
+ static const int STATE_INITIAL = TOP_LEVEL | EMPTY | ALLOW_VALUE;
+ static const int STATE_END = TOP_LEVEL | NON_EMPTY | NO_VALUES;
+
+ static const int STATE_ARRAY_EMPTY = INSIDE_ARRAY | EMPTY | ALLOW_VALUE;
+ static const int STATE_ARRAY_VALUE = INSIDE_ARRAY | NON_EMPTY | NO_VALUES;
+ static const int STATE_ARRAY_COMMA = INSIDE_ARRAY | NON_EMPTY | ALLOW_VALUE;
+
+ static const int STATE_OBJECT_EMPTY = INSIDE_OBJECT | EMPTY | STRING_ONLY;
+ static const int STATE_OBJECT_KEY = INSIDE_OBJECT | NON_EMPTY | NO_VALUES;
+ static const int STATE_OBJECT_COLON = AFTER_COLON | NON_EMPTY | ALLOW_VALUE;
+ static const int STATE_OBJECT_VALUE = AFTER_COLON | NON_EMPTY | NO_VALUES;
+ static const int STATE_OBJECT_COMMA = INSIDE_OBJECT | NON_EMPTY | STRING_ONLY;
+
+ // Bits set in state after successfully reading a value.
+ // This transitions the state to expect the next punctuation.
+ static const int VALUE_READ_BITS = NON_EMPTY | NO_VALUES;
+
+ // Character code constants.
+ static const int BACKSPACE = 0x08;
+ static const int TAB = 0x09;
+ static const int NEWLINE = 0x0a;
+ static const int CARRIAGE_RETURN = 0x0d;
+ static const int FORM_FEED = 0x0c;
+ static const int SPACE = 0x20;
+ static const int QUOTE = 0x22;
+ static const int PLUS = 0x2b;
+ static const int COMMA = 0x2c;
+ static const int MINUS = 0x2d;
+ static const int DECIMALPOINT = 0x2e;
+ static const int SLASH = 0x2f;
+ static const int CHAR_0 = 0x30;
+ static const int CHAR_9 = 0x39;
+ static const int COLON = 0x3a;
+ static const int CHAR_E = 0x45;
+ static const int LBRACKET = 0x5b;
+ static const int BACKSLASH = 0x5c;
+ static const int RBRACKET = 0x5d;
+ static const int CHAR_a = 0x61;
+ static const int CHAR_b = 0x62;
+ static const int CHAR_e = 0x65;
+ static const int CHAR_f = 0x66;
+ static const int CHAR_l = 0x6c;
+ static const int CHAR_n = 0x6e;
+ static const int CHAR_r = 0x72;
+ static const int CHAR_s = 0x73;
+ static const int CHAR_t = 0x74;
+ static const int CHAR_u = 0x75;
+ static const int LBRACE = 0x7b;
+ static const int RBRACE = 0x7d;
+
+ // State of partial value at chunk split.
+ static const int NO_PARTIAL = 0;
+ static const int PARTIAL_STRING = 1;
+ static const int PARTIAL_NUMERAL = 2;
+ static const int PARTIAL_KEYWORD = 3;
+ static const int MASK_PARTIAL = 3;
+
+ // Partial states for numerals. Values can be |'ed with PARTIAL_NUMERAL.
+ static const int NUM_SIGN = 0; // After initial '-'.
+ static const int NUM_ZERO = 4; // After '0' as first digit.
+ static const int NUM_DIGIT = 8; // After digit, no '.' or 'e' seen.
+ static const int NUM_DOT = 12; // After '.'.
+ static const int NUM_DOT_DIGIT = 16; // After a decimal digit (after '.').
+ static const int NUM_E = 20; // After 'e' or 'E'.
+ static const int NUM_E_SIGN = 24; // After '-' or '+' after 'e' or 'E'.
+ static const int NUM_E_DIGIT = 28; // After exponent digit.
+ static const int NUM_SUCCESS = 32; // Never stored as partial state.
+
+ // Partial states for strings.
+ static const int STR_PLAIN = 0; // Inside string, but not escape.
+ static const int STR_ESCAPE = 4; // After '\'.
+ static const int STR_U = 16; // After '\u' and 0-3 hex digits.
+ static const int STR_U_COUNT_SHIFT = 2; // Hex digit count in bits 2-3.
+ static const int STR_U_VALUE_SHIFT = 5; // Hex digit value in bits 5+.
+
+ // Partial states for keywords.
+ static const int KWD_TYPE_MASK = 12;
+ static const int KWD_TYPE_SHIFT = 2;
+ static const int KWD_NULL = 0; // Prefix of "null" seen.
+ static const int KWD_TRUE = 4; // Prefix of "true" seen.
+ static const int KWD_FALSE = 8; // Prefix of "false" seen.
+ static const int KWD_BOM = 12; // Prefix of BOM seen.
+ static const int KWD_COUNT_SHIFT = 4; // Prefix length in bits 4+.
+
+ // Mask used to mask off two lower bits.
+ static const int TWO_BIT_MASK = 3;
+
+ final _JsonListener listener;
+
+ // The current parsing state.
+ int state = STATE_INITIAL;
+ List<int> states = <int>[];
+
+ /**
+ * Stores tokenizer state between chunks.
+ *
+ * This state is stored when a chunk stops in the middle of a
+ * token (string, numeral, boolean or null).
+ *
+ * The partial state is used to continue parsing on the next chunk.
+ * The previous chunk is not retained, any data needed are stored in
+ * this integer, or in the [buffer] field as a string-building buffer
+ * or a [_NumberBuffer].
+ *
+ * Prefix state stored in [prefixState] as bits.
+ *
+ * ..00 : No partial value (NO_PARTIAL).
+ *
+ * ..00001 : Partial string, not inside escape.
+ * ..00101 : Partial string, after '\'.
+ * ..vvvv1dd01 : Partial \u escape.
+ * The 'dd' bits (2-3) encode the number of hex digits seen.
+ * Bits 5-16 encode the value of the hex digits seen so far.
+ *
+ * ..0ddd10 : Partial numeral.
+ * The `ddd` bits store the parts of in the numeral seen so
+ * far, as the constants `NUM_*` defined above.
+ * The characters of the numeral are stored in [buffer]
+ * as a [_NumberBuffer].
+ *
+ * ..0ddd0011 : Partial 'null' keyword.
+ * ..0ddd0111 : Partial 'true' keyword.
+ * ..0ddd1011 : Partial 'false' keyword.
+ * ..0ddd1111 : Partial UTF-8 BOM byte seqeuence ("\xEF\xBB\xBF").
+ * For all keywords, the `ddd` bits encode the number
+ * of letters seen.
+ * The BOM byte sequence is only used by [_JsonUtf8Parser],
+ * and only at the very beginning of input.
+ */
+ int partialState = NO_PARTIAL;
+
+ /**
+ * Extra data stored while parsing a primitive value.
+ * May be set during parsing, always set at chunk end if a value is partial.
+ *
+ * May contain a string buffer while parsing strings.
+ */
+ var buffer = null;
+
+ _ChunkedJsonParser(this.listener);
+
+ /**
+ * Push the current parse [state] on a stack.
+ *
+ * State is pushed when a new array or object literal starts,
+ * so the parser can go back to the correct value when the literal ends.
+ */
+ void saveState(int state) {
+ states.add(state);
+ }
+
+ /**
+ * Restore a state pushed with [saveState].
+ */
+ int restoreState() {
+ return states.removeLast(); // Throws if empty.
+ }
+
+ /**
+ * Finalizes the parsing.
+ *
+ * Throws if the source read so far doesn't end up with a complete
+ * parsed value. That means it must not be inside a list or object
+ * literal, and any partial value read should also be a valid complete
+ * value.
+ *
+ * The only valid partial state is a number that ends in a digit, and
+ * only if the number is the entire JSON value being parsed
+ * (otherwise it would be inside a list or object).
+ * Such a number will be completed. Any other partial state is an error.
+ */
+ void close() {
+ if (partialState != NO_PARTIAL) {
+ int partialType = partialState & MASK_PARTIAL;
+ if (partialType == PARTIAL_NUMERAL) {
+ int numState = partialState & ~MASK_PARTIAL;
+ // A partial number might be a valid number if we know it's done.
+ // There is an unnecessary overhead if input is a single number,
+ // but this is assumed to be rare.
+ _NumberBuffer buffer = this.buffer;
+ this.buffer = null;
+ finishChunkNumber(numState, 0, 0, buffer);
+ } else if (partialType == PARTIAL_STRING) {
+ fail(chunkEnd, "Unterminated string");
+ } else {
+ assert(partialType == PARTIAL_KEYWORD);
+ fail(chunkEnd); // Incomplete literal.
+ }
+ }
+ if (state != STATE_END) {
+ fail(chunkEnd);
+ }
+ }
+
+ /**
+ * Read out the result after successfully closing the parser.
+ *
+ * The parser is closed by calling [close] or calling [addSourceChunk] with
+ * `true` as second (`isLast`) argument.
+ */
+ Object get result {
+ return listener.result;
+ }
+
+ /** Sets the current source chunk. */
+ void set chunk(T source);
+
+ /**
+ * Length of current chunk.
+ *
+ * The valid arguments to [getChar] are 0 .. `chunkEnd - 1`.
+ */
+ int get chunkEnd;
+
+ /**
+ * Returns the chunk itself.
+ *
+ * Only used by [fail] to include the chunk in the thrown [FormatException].
+ */
+ T get chunk;
+
+ /**
+ * Get charcacter/code unit of current chunk.
+ *
+ * The [index] must be non-negative and less than `chunkEnd`.
+ * In practive, [index] will be no smaller than the `start` argument passed
+ * to [parse].
+ */
+ int getChar(int index);
+
+ /**
+ * Copy ASCII characters from start to end of chunk into a list.
+ *
+ * Used for number buffer (always copies ASCII, so encoding is not important).
+ */
+ void copyCharsToList(int start, int end, List<int> target, int offset);
+
+ /**
+ * Build a string using input code units.
+ *
+ * Creates a string buffer and enables adding characters and slices
+ * to that buffer.
+ * The buffer is stored in the [buffer] field. If the string is unterminated,
+ * the same buffer is used to continue parsing in the next chunk.
+ */
+ void beginString();
+ /**
+ * Add single character code to string being built.
+ *
+ * Used for unparsed escape sequences.
+ */
+ void addCharToString(int charCode);
+
+ /**
+ * Adds slice of current chunk to string being built.
+ *
+ * The [start] positions is inclusive, [end] is exclusive.
+ */
+ void addSliceToString(int start, int end);
+
+ /** Finalizes the string being built and returns it as a String. */
+ String endString();
+
+ /**
+ * Extracts a literal string from a slice of the current chunk.
+ *
+ * No interpretation of the content is performed, except for converting
+ * the source format to string.
+ * This can be implemented more or less efficiently depending on the
+ * underlying source.
+ *
+ * This is used for string literals that contain no escapes.
+ *
+ * The [bits] integer is an upper bound on the code point in the range
+ * from `start` to `end`.
+ * Usually found by doing bitwise or of all the values.
+ * The function may choose to optimize depending on the value.
+ */
+ String getString(int start, int end, int bits);
+
+ /**
+ * Parse a slice of the current chunk as a number.
+ *
+ * Since integers have a maximal value, and we don't track the value
+ * in the buffer, a sequence of digits can be either an int or a double.
+ * The `num.parse` function does the right thing.
+ *
+ * The format is expected to be correct.
+ */
+ num parseNum(int start, int end) {
+ const int asciiBits = 0x7f; // Number literals are ASCII only.
+ return num.parse(getString(start, end, asciiBits));
+ }
+
+ /**
+ * Parse a slice of the current chunk as a double.
+ *
+ * The format is expected to be correct.
+ * This is used by [parseNumber] when the double value cannot be
+ * built exactly during parsing.
+ */
+ double parseDouble(int start, int end) {
+ const int asciiBits = 0x7f; // Double literals are ASCII only.
+ return double.parse(getString(start, end, asciiBits));
+ }
+
+ /**
+ * Continues parsing a partial value.
+ */
+ int parsePartial(int position) {
+ if (position == chunkEnd) return position;
+ int partialState = this.partialState;
+ assert(partialState != NO_PARTIAL);
+ int partialType = partialState & MASK_PARTIAL;
+ this.partialState = NO_PARTIAL;
+ partialState = partialState & ~MASK_PARTIAL;
+ assert(partialType != 0);
+ if (partialType == PARTIAL_STRING) {
+ position = parsePartialString(position, partialState);
+ } else if (partialType == PARTIAL_NUMERAL) {
+ position = parsePartialNumber(position, partialState);
+ } else if (partialType == PARTIAL_KEYWORD) {
+ position = parsePartialKeyword(position, partialState);
+ }
+ return position;
+ }
+
+ /**
+ * Parses the remainder of a number into the number buffer.
+ *
+ * Syntax is checked while pasing.
+ * Starts at position, which is expected to be the start of the chunk,
+ * and returns the index of the first non-number-literal character found,
+ * or chunkEnd if the entire chunk is a valid number continuation.
+ * Throws if a syntax error is detected.
+ */
+ int parsePartialNumber(int position, int state) {
+ int start = position;
+ // Primitive implementation, can be optimized.
+ _NumberBuffer buffer = this.buffer;
+ this.buffer = null;
+ int end = chunkEnd;
+ toBailout:
+ {
+ if (position == end) break toBailout;
+ int char = getChar(position);
+ int digit = char ^ CHAR_0;
+ if (state == NUM_SIGN) {
+ if (digit <= 9) {
+ if (digit == 0) {
+ state = NUM_ZERO;
+ } else {
+ state = NUM_DIGIT;
+ }
+ position++;
+ if (position == end) break toBailout;
+ char = getChar(position);
+ digit = char ^ CHAR_0;
+ } else {
+ return fail(position);
+ }
+ }
+ if (state == NUM_ZERO) {
+ // JSON does not allow insignificant leading zeros (e.g., "09").
+ if (digit <= 9) return fail(position);
+ state = NUM_DIGIT;
+ }
+ while (state == NUM_DIGIT) {
+ if (digit > 9) {
+ if (char == DECIMALPOINT) {
+ state = NUM_DOT;
+ } else if ((char | 0x20) == CHAR_e) {
+ state = NUM_E;
+ } else {
+ finishChunkNumber(state, start, position, buffer);
+ return position;
+ }
+ }
+ position++;
+ if (position == end) break toBailout;
+ char = getChar(position);
+ digit = char ^ CHAR_0;
+ }
+ if (state == NUM_DOT) {
+ if (digit > 9) return fail(position);
+ state = NUM_DOT_DIGIT;
+ }
+ while (state == NUM_DOT_DIGIT) {
+ if (digit > 9) {
+ if ((char | 0x20) == CHAR_e) {
+ state = NUM_E;
+ } else {
+ finishChunkNumber(state, start, position, buffer);
+ return position;
+ }
+ }
+ position++;
+ if (position == end) break toBailout;
+ char = getChar(position);
+ digit = char ^ CHAR_0;
+ }
+ if (state == NUM_E) {
+ if (char == PLUS || char == MINUS) {
+ state = NUM_E_SIGN;
+ position++;
+ if (position == end) break toBailout;
+ char = getChar(position);
+ digit = char ^ CHAR_0;
+ }
+ }
+ assert(state >= NUM_E);
+ while (digit <= 9) {
+ state = NUM_E_DIGIT;
+ position++;
+ if (position == end) break toBailout;
+ char = getChar(position);
+ digit = char ^ CHAR_0;
+ }
+ finishChunkNumber(state, start, position, buffer);
+ return position;
+ }
+ // Bailout code in case the current chunk ends while parsing the numeral.
+ assert(position == end);
+ continueChunkNumber(state, start, buffer);
+ return chunkEnd;
+ }
+
+ /**
+ * Continues parsing a partial string literal.
+ *
+ * Handles partial escapes and then hands the parsing off to
+ * [parseStringToBuffer].
+ */
+ int parsePartialString(int position, int partialState) {
+ if (partialState == STR_PLAIN) {
+ return parseStringToBuffer(position);
+ }
+ if (partialState == STR_ESCAPE) {
+ position = parseStringEscape(position);
+ // parseStringEscape sets partialState if it sees the end.
+ if (position == chunkEnd) return position;
+ return parseStringToBuffer(position);
+ }
+ assert((partialState & STR_U) != 0);
+ int value = partialState >> STR_U_VALUE_SHIFT;
+ int count = (partialState >> STR_U_COUNT_SHIFT) & TWO_BIT_MASK;
+ for (int i = count; i < 4; i++, position++) {
+ if (position == chunkEnd) return chunkStringEscapeU(i, value);
+ int char = getChar(position);
+ int digit = parseHexDigit(char);
+ if (digit < 0) fail(position, "Invalid hex digit");
+ value = 16 * value + digit;
+ }
+ addCharToString(value);
+ return parseStringToBuffer(position);
+ }
+
+ /**
+ * Continues parsing a partial keyword.
+ */
+ int parsePartialKeyword(int position, int partialState) {
+ int keywordType = partialState & KWD_TYPE_MASK;
+ int count = partialState >> KWD_COUNT_SHIFT;
+ int keywordTypeIndex = keywordType >> KWD_TYPE_SHIFT;
+ String keyword =
+ const ["null", "true", "false", "\xEF\xBB\xBF"][keywordTypeIndex];
+ assert(count < keyword.length);
+ do {
+ if (position == chunkEnd) {
+ this.partialState =
+ PARTIAL_KEYWORD | keywordType | (count << KWD_COUNT_SHIFT);
+ return chunkEnd;
+ }
+ int expectedChar = keyword.codeUnitAt(count);
+ if (getChar(position) != expectedChar) {
+ if (count == 0) {
+ assert(keywordType == KWD_BOM);
+ return position;
+ }
+ return fail(position);
+ }
+ position++;
+ count++;
+ } while (count < keyword.length);
+ if (keywordType == KWD_NULL) {
+ listener.handleNull();
+ } else if (keywordType != KWD_BOM) {
+ listener.handleBool(keywordType == KWD_TRUE);
+ }
+ return position;
+ }
+
+ /** Convert hex-digit to its value. Returns -1 if char is not a hex digit. */
+ int parseHexDigit(int char) {
+ int digit = char ^ 0x30;
+ if (digit <= 9) return digit;
+ int letter = (char | 0x20) ^ 0x60;
+ // values 1 .. 6 are 'a' through 'f'
+ if (letter <= 6 && letter > 0) return letter + 9;
+ return -1;
+ }
+
+ /**
+ * Parses the current chunk as a chunk of JSON.
+ *
+ * Starts parsing at [position] and continues until [chunkEnd].
+ * Continues parsing where the previous chunk (if any) ended.
+ */
+ void parse(int position) {
+ int length = chunkEnd;
+ if (partialState != NO_PARTIAL) {
+ position = parsePartial(position);
+ if (position == length) return;
+ }
+ int state = this.state;
+ while (position < length) {
+ int char = getChar(position);
+ switch (char) {
+ case SPACE:
+ case CARRIAGE_RETURN:
+ case NEWLINE:
+ case TAB:
+ position++;
+ break;
+ case QUOTE:
+ if ((state & ALLOW_STRING_MASK) != 0) return fail(position);
+ state |= VALUE_READ_BITS;
+ position = parseString(position + 1);
+ break;
+ case LBRACKET:
+ if ((state & ALLOW_VALUE_MASK) != 0) return fail(position);
+ listener.beginArray();
+ saveState(state);
+ state = STATE_ARRAY_EMPTY;
+ position++;
+ break;
+ case LBRACE:
+ if ((state & ALLOW_VALUE_MASK) != 0) return fail(position);
+ listener.beginObject();
+ saveState(state);
+ state = STATE_OBJECT_EMPTY;
+ position++;
+ break;
+ case CHAR_n:
+ if ((state & ALLOW_VALUE_MASK) != 0) return fail(position);
+ state |= VALUE_READ_BITS;
+ position = parseNull(position);
+ break;
+ case CHAR_f:
+ if ((state & ALLOW_VALUE_MASK) != 0) return fail(position);
+ state |= VALUE_READ_BITS;
+ position = parseFalse(position);
+ break;
+ case CHAR_t:
+ if ((state & ALLOW_VALUE_MASK) != 0) return fail(position);
+ state |= VALUE_READ_BITS;
+ position = parseTrue(position);
+ break;
+ case COLON:
+ if (state != STATE_OBJECT_KEY) return fail(position);
+ listener.propertyName();
+ state = STATE_OBJECT_COLON;
+ position++;
+ break;
+ case COMMA:
+ if (state == STATE_OBJECT_VALUE) {
+ listener.propertyValue();
+ state = STATE_OBJECT_COMMA;
+ position++;
+ } else if (state == STATE_ARRAY_VALUE) {
+ listener.arrayElement();
+ state = STATE_ARRAY_COMMA;
+ position++;
+ } else {
+ return fail(position);
+ }
+ break;
+ case RBRACKET:
+ if (state == STATE_ARRAY_EMPTY) {
+ listener.endArray();
+ } else if (state == STATE_ARRAY_VALUE) {
+ listener.arrayElement();
+ listener.endArray();
+ } else {
+ return fail(position);
+ }
+ state = restoreState() | VALUE_READ_BITS;
+ position++;
+ break;
+ case RBRACE:
+ if (state == STATE_OBJECT_EMPTY) {
+ listener.endObject();
+ } else if (state == STATE_OBJECT_VALUE) {
+ listener.propertyValue();
+ listener.endObject();
+ } else {
+ return fail(position);
+ }
+ state = restoreState() | VALUE_READ_BITS;
+ position++;
+ break;
+ default:
+ if ((state & ALLOW_VALUE_MASK) != 0) fail(position);
+ state |= VALUE_READ_BITS;
+ position = parseNumber(char, position);
+ break;
+ }
+ }
+ this.state = state;
+ }
+
+ /**
+ * Parses a "true" literal starting at [position].
+ *
+ * The character `source[position]` must be "t".
+ */
+ int parseTrue(int position) {
+ assert(getChar(position) == CHAR_t);
+ if (chunkEnd < position + 4) {
+ return parseKeywordPrefix(position, "true", KWD_TRUE);
+ }
+ if (getChar(position + 1) != CHAR_r ||
+ getChar(position + 2) != CHAR_u ||
+ getChar(position + 3) != CHAR_e) {
+ return fail(position);
+ }
+ listener.handleBool(true);
+ return position + 4;
+ }
+
+ /**
+ * Parses a "false" literal starting at [position].
+ *
+ * The character `source[position]` must be "f".
+ */
+ int parseFalse(int position) {
+ assert(getChar(position) == CHAR_f);
+ if (chunkEnd < position + 5) {
+ return parseKeywordPrefix(position, "false", KWD_FALSE);
+ }
+ if (getChar(position + 1) != CHAR_a ||
+ getChar(position + 2) != CHAR_l ||
+ getChar(position + 3) != CHAR_s ||
+ getChar(position + 4) != CHAR_e) {
+ return fail(position);
+ }
+ listener.handleBool(false);
+ return position + 5;
+ }
+
+ /**
+ * Parses a "null" literal starting at [position].
+ *
+ * The character `source[position]` must be "n".
+ */
+ int parseNull(int position) {
+ assert(getChar(position) == CHAR_n);
+ if (chunkEnd < position + 4) {
+ return parseKeywordPrefix(position, "null", KWD_NULL);
+ }
+ if (getChar(position + 1) != CHAR_u ||
+ getChar(position + 2) != CHAR_l ||
+ getChar(position + 3) != CHAR_l) {
+ return fail(position);
+ }
+ listener.handleNull();
+ return position + 4;
+ }
+
+ int parseKeywordPrefix(int position, String chars, int type) {
+ assert(getChar(position) == chars.codeUnitAt(0));
+ int length = chunkEnd;
+ int start = position;
+ int count = 1;
+ while (++position < length) {
+ int char = getChar(position);
+ if (char != chars.codeUnitAt(count)) return fail(start);
+ count++;
+ }
+ this.partialState = PARTIAL_KEYWORD | type | (count << KWD_COUNT_SHIFT);
+ return length;
+ }
+
+ /**
+ * Parses a string value.
+ *
+ * Initial [position] is right after the initial quote.
+ * Returned position right after the final quote.
+ */
+ int parseString(int position) {
+ // Format: '"'([^\x00-\x1f\\\"]|'\\'[bfnrt/\\"])*'"'
+ // Initial position is right after first '"'.
+ int start = position;
+ int end = chunkEnd;
+ int bits = 0;
+ while (position < end) {
+ int char = getChar(position++);
+ bits |= char; // Includes final '"', but that never matters.
+ // BACKSLASH is larger than QUOTE and SPACE.
+ if (char > BACKSLASH) {
+ continue;
+ }
+ if (char == BACKSLASH) {
+ beginString();
+ int sliceEnd = position - 1;
+ if (start < sliceEnd) addSliceToString(start, sliceEnd);
+ return parseStringToBuffer(sliceEnd);
+ }
+ if (char == QUOTE) {
+ listener.handleString(getString(start, position - 1, bits));
+ return position;
+ }
+ if (char < SPACE) {
+ return fail(position - 1, "Control character in string");
+ }
+ }
+ beginString();
+ if (start < end) addSliceToString(start, end);
+ return chunkString(STR_PLAIN);
+ }
+
+ /**
+ * Sets up a partial string state.
+ *
+ * The state is either not inside an escape, or right after a backslash.
+ * For partial strings ending inside a Unicode escape, use
+ * [chunkStringEscapeU].
+ */
+ int chunkString(int stringState) {
+ partialState = PARTIAL_STRING | stringState;
+ return chunkEnd;
+ }
+
+ /**
+ * Sets up a partial string state for a partially parsed Unicode escape.
+ *
+ * The partial string state includes the current [buffer] and the
+ * number of hex digits of the Unicode seen so far (e.g., for `"\u30')
+ * the state knows that two digits have been seen, and what their value is.
+ *
+ * Returns [chunkEnd] so it can be used as part of a return statement.
+ */
+ int chunkStringEscapeU(int count, int value) {
+ partialState = PARTIAL_STRING |
+ STR_U |
+ (count << STR_U_COUNT_SHIFT) |
+ (value << STR_U_VALUE_SHIFT);
+ return chunkEnd;
+ }
+
+ /**
+ * Parses the remainder of a string literal into a buffer.
+ *
+ * The buffer is stored in [buffer] and its underlying format depends on
+ * the input chunk type. For example UTF-8 decoding happens in the
+ * buffer, not in the parser, since all significant JSON characters are ASCII.
+ *
+ * This function scans through the string literal for escapes, and copies
+ * slices of non-escape characters using [addSliceToString].
+ */
+ int parseStringToBuffer(int position) {
+ int end = chunkEnd;
+ int start = position;
+ while (true) {
+ if (position == end) {
+ if (position > start) {
+ addSliceToString(start, position);
+ }
+ return chunkString(STR_PLAIN);
+ }
+ int char = getChar(position++);
+ if (char > BACKSLASH) continue;
+ if (char < SPACE) {
+ return fail(position - 1); // Control character in string.
+ }
+ if (char == QUOTE) {
+ int quotePosition = position - 1;
+ if (quotePosition > start) {
+ addSliceToString(start, quotePosition);
+ }
+ listener.handleString(endString());
+ return position;
+ }
+ if (char != BACKSLASH) {
+ continue;
+ }
+ // Handle escape.
+ if (position - 1 > start) {
+ addSliceToString(start, position - 1);
+ }
+ if (position == end) return chunkString(STR_ESCAPE);
+ position = parseStringEscape(position);
+ if (position == end) return position;
+ start = position;
+ }
+ return -1; // UNREACHABLE.
+ }
+
+ /**
+ * Parse a string escape.
+ *
+ * Position is right after the initial backslash.
+ * The following escape is parsed into a character code which is added to
+ * the current string buffer using [addCharToString].
+ *
+ * Returns position after the last character of the escape.
+ */
+ int parseStringEscape(int position) {
+ int char = getChar(position++);
+ int length = chunkEnd;
+ switch (char) {
+ case CHAR_b:
+ char = BACKSPACE;
+ break;
+ case CHAR_f:
+ char = FORM_FEED;
+ break;
+ case CHAR_n:
+ char = NEWLINE;
+ break;
+ case CHAR_r:
+ char = CARRIAGE_RETURN;
+ break;
+ case CHAR_t:
+ char = TAB;
+ break;
+ case SLASH:
+ case BACKSLASH:
+ case QUOTE:
+ break;
+ case CHAR_u:
+ int hexStart = position - 1;
+ int value = 0;
+ for (int i = 0; i < 4; i++) {
+ if (position == length) return chunkStringEscapeU(i, value);
+ char = getChar(position++);
+ int digit = char ^ 0x30;
+ value *= 16;
+ if (digit <= 9) {
+ value += digit;
+ } else {
+ digit = (char | 0x20) - CHAR_a;
+ if (digit < 0 || digit > 5) {
+ return fail(hexStart, "Invalid unicode escape");
+ }
+ value += digit + 10;
+ }
+ }
+ char = value;
+ break;
+ default:
+ if (char < SPACE) return fail(position, "Control character in string");
+ return fail(position, "Unrecognized string escape");
+ }
+ addCharToString(char);
+ if (position == length) return chunkString(STR_PLAIN);
+ return position;
+ }
+
+ /// Sets up a partial numeral state.
+ /// Returns chunkEnd to allow easy one-line bailout tests.
+ int beginChunkNumber(int state, int start) {
+ int end = chunkEnd;
+ int length = end - start;
+ var buffer = new _NumberBuffer(length);
+ copyCharsToList(start, end, buffer.list, 0);
+ buffer.length = length;
+ this.buffer = buffer;
+ this.partialState = PARTIAL_NUMERAL | state;
+ return end;
+ }
+
+ void addNumberChunk(_NumberBuffer buffer, int start, int end, int overhead) {
+ int length = end - start;
+ int count = buffer.length;
+ int newCount = count + length;
+ int newCapacity = newCount + overhead;
+ buffer.ensureCapacity(newCapacity);
+ copyCharsToList(start, end, buffer.list, count);
+ buffer.length = newCount;
+ }
+
+ // Continues an already chunked number across an entire chunk.
+ int continueChunkNumber(int state, int start, _NumberBuffer buffer) {
+ int end = chunkEnd;
+ addNumberChunk(buffer, start, end, _NumberBuffer.kDefaultOverhead);
+ this.buffer = buffer;
+ this.partialState = PARTIAL_NUMERAL | state;
+ return end;
+ }
+
+ int finishChunkNumber(int state, int start, int end, _NumberBuffer buffer) {
+ if (state == NUM_ZERO) {
+ listener.handleNumber(0);
+ return end;
+ }
+ if (end > start) {
+ addNumberChunk(buffer, start, end, 0);
+ }
+ if (state == NUM_DIGIT) {
+ num value = buffer.parseNum();
+ listener.handleNumber(value);
+ } else if (state == NUM_DOT_DIGIT || state == NUM_E_DIGIT) {
+ listener.handleNumber(buffer.parseDouble());
+ } else {
+ fail(chunkEnd, "Unterminated number literal");
+ }
+ return end;
+ }
+
+ int parseNumber(int char, int position) {
+ // Also called on any unexpected character.
+ // Format:
+ // '-'?('0'|[1-9][0-9]*)('.'[0-9]+)?([eE][+-]?[0-9]+)?
+ int start = position;
+ int length = chunkEnd;
+ // Collects an int value while parsing. Used for both an integer literal,
+ // and the exponent part of a double literal.
+ // Stored as negative to ensure we can represent -2^63.
+ int intValue = 0;
+ double doubleValue = 0.0; // Collect double value while parsing.
+ // 1 if there is no leading -, -1 if there is.
+ int sign = 1;
+ bool isDouble = false;
+ // Break this block when the end of the number literal is reached.
+ // At that time, position points to the next character, and isDouble
+ // is set if the literal contains a decimal point or an exponential.
+ if (char == MINUS) {
+ sign = -1;
+ position++;
+ if (position == length) return beginChunkNumber(NUM_SIGN, start);
+ char = getChar(position);
+ }
+ int digit = char ^ CHAR_0;
+ if (digit > 9) {
+ if (sign < 0) {
+ fail(position, "Missing expected digit");
+ } else {
+ // If it doesn't even start out as a numeral.
+ fail(position);
+ }
+ }
+ if (digit == 0) {
+ position++;
+ if (position == length) return beginChunkNumber(NUM_ZERO, start);
+ char = getChar(position);
+ digit = char ^ CHAR_0;
+ // If starting with zero, next character must not be digit.
+ if (digit <= 9) fail(position);
+ } else {
+ int digitCount = 0;
+ do {
+ if (digitCount >= 18) {
+ // Check for overflow.
+ // Is 1 if digit is 8 or 9 and sign == 0, or digit is 9 and sign < 0;
+ int highDigit = digit >> 3;
+ if (sign < 0) highDigit &= digit;
+ if (digitCount == 19 || intValue - highDigit < -922337203685477580) {
+ isDouble = true;
+ // Big value that we know is not trusted to be exact later,
+ // forcing reparsing using `double.parse`.
+ doubleValue = 9223372036854775808.0;
+ }
+ }
+ intValue = 10 * intValue - digit;
+ digitCount++;
+ position++;
+ if (position == length) return beginChunkNumber(NUM_DIGIT, start);
+ char = getChar(position);
+ digit = char ^ CHAR_0;
+ } while (digit <= 9);
+ }
+ if (char == DECIMALPOINT) {
+ if (!isDouble) {
+ isDouble = true;
+ doubleValue = (intValue == 0) ? 0.0 : -intValue.toDouble();
+ }
+ intValue = 0;
+ position++;
+ if (position == length) return beginChunkNumber(NUM_DOT, start);
+ char = getChar(position);
+ digit = char ^ CHAR_0;
+ if (digit > 9) fail(position);
+ do {
+ doubleValue = 10.0 * doubleValue + digit;
+ intValue -= 1;
+ position++;
+ if (position == length) return beginChunkNumber(NUM_DOT_DIGIT, start);
+ char = getChar(position);
+ digit = char ^ CHAR_0;
+ } while (digit <= 9);
+ }
+ if ((char | 0x20) == CHAR_e) {
+ if (!isDouble) {
+ isDouble = true;
+ doubleValue = (intValue == 0) ? 0.0 : -intValue.toDouble();
+ intValue = 0;
+ }
+ position++;
+ if (position == length) return beginChunkNumber(NUM_E, start);
+ char = getChar(position);
+ int expSign = 1;
+ int exponent = 0;
+ if (((char + 1) | 2) == 0x2e /*+ or -*/) {
+ expSign = 0x2C - char; // -1 for MINUS, +1 for PLUS
+ position++;
+ if (position == length) return beginChunkNumber(NUM_E_SIGN, start);
+ char = getChar(position);
+ }
+ digit = char ^ CHAR_0;
+ if (digit > 9) {
+ fail(position, "Missing expected digit");
+ }
+ bool exponentOverflow = false;
+ do {
+ exponent = 10 * exponent + digit;
+ if (exponent > 400) exponentOverflow = true;
+ position++;
+ if (position == length) return beginChunkNumber(NUM_E_DIGIT, start);
+ char = getChar(position);
+ digit = char ^ CHAR_0;
+ } while (digit <= 9);
+ if (exponentOverflow) {
+ if (doubleValue == 0.0 || expSign < 0) {
+ listener.handleNumber(sign < 0 ? -0.0 : 0.0);
+ } else {
+ listener.handleNumber(
+ sign < 0 ? double.negativeInfinity : double.infinity);
+ }
+ return position;
+ }
+ intValue += expSign * exponent;
+ }
+ if (!isDouble) {
+ int bitFlag = -(sign + 1) >> 1; // 0 if sign == -1, -1 if sign == 1
+ // Negate if bitFlag is -1 by doing ~intValue + 1
+ listener.handleNumber((intValue ^ bitFlag) - bitFlag);
+ return position;
+ }
+ // Double values at or above this value (2 ** 53) may have lost precision.
+ // Only trust results that are below this value.
+ const double maxExactDouble = 9007199254740992.0;
+ if (doubleValue < maxExactDouble) {
+ int exponent = intValue;
+ double signedMantissa = doubleValue * sign;
+ if (exponent >= -22) {
+ if (exponent < 0) {
+ listener.handleNumber(signedMantissa / POWERS_OF_TEN[-exponent]);
+ return position;
+ }
+ if (exponent == 0) {
+ listener.handleNumber(signedMantissa);
+ return position;
+ }
+ if (exponent <= 22) {
+ listener.handleNumber(signedMantissa * POWERS_OF_TEN[exponent]);
+ return position;
+ }
+ }
+ }
+ // If the value is outside the range +/-maxExactDouble or
+ // exponent is outside the range +/-22, then we can't trust simple double
+ // arithmetic to get the exact result, so we use the system double parsing.
+ listener.handleNumber(parseDouble(start, position));
+ return position;
+ }
+
+ fail(int position, [String message]) {
+ if (message == null) {
+ message = "Unexpected character";
+ if (position == chunkEnd) message = "Unexpected end of input";
+ }
+ throw new FormatException(message, chunk, position);
+ }
+}
+
+/**
+ * Chunked JSON parser that parses [String] chunks.
+ */
+class _JsonStringParser extends _ChunkedJsonParser<String> {
+ String chunk;
+ int chunkEnd;
+
+ _JsonStringParser(_JsonListener listener) : super(listener);
+
+ int getChar(int position) => chunk.codeUnitAt(position);
+
+ String getString(int start, int end, int bits) {
+ return chunk.substring(start, end);
+ }
+
+ void beginString() {
+ this.buffer = new StringBuffer();
+ }
+
+ void addSliceToString(int start, int end) {
+ StringBuffer buffer = this.buffer;
+ buffer.write(chunk.substring(start, end));
+ }
+
+ void addCharToString(int charCode) {
+ StringBuffer buffer = this.buffer;
+ buffer.writeCharCode(charCode);
+ }
+
+ String endString() {
+ StringBuffer buffer = this.buffer;
+ this.buffer = null;
+ return buffer.toString();
+ }
+
+ void copyCharsToList(int start, int end, List target, int offset) {
+ int length = end - start;
+ for (int i = 0; i < length; i++) {
+ target[offset + i] = chunk.codeUnitAt(start + i);
+ }
+ }
+
+ double parseDouble(int start, int end) {
+ return _parseDouble(chunk, start, end);
+ }
+}
+
+@patch
+class JsonDecoder {
+ @patch
+ StringConversionSink startChunkedConversion(Sink<Object> sink) {
+ return new _JsonStringDecoderSink(this._reviver, sink);
+ }
+}
+
+/**
+ * Implements the chunked conversion from a JSON string to its corresponding
+ * object.
+ *
+ * The sink only creates one object, but its input can be chunked.
+ */
+class _JsonStringDecoderSink extends StringConversionSinkBase {
+ _JsonStringParser _parser;
+ final Function(Object key, Object value) _reviver;
+ final Sink<Object> _sink;
+
+ _JsonStringDecoderSink(this._reviver, this._sink)
+ : _parser = _createParser(_reviver);
+
+ static _JsonStringParser _createParser(reviver) {
+ _BuildJsonListener listener;
+ if (reviver == null) {
+ listener = new _BuildJsonListener();
+ } else {
+ listener = new _ReviverJsonListener(reviver);
+ }
+ return new _JsonStringParser(listener);
+ }
+
+ void addSlice(String chunk, int start, int end, bool isLast) {
+ _parser.chunk = chunk;
+ _parser.chunkEnd = end;
+ _parser.parse(start);
+ if (isLast) _parser.close();
+ }
+
+ void add(String chunk) {
+ addSlice(chunk, 0, chunk.length, false);
+ }
+
+ void close() {
+ _parser.close();
+ var decoded = _parser.result;
+ _sink.add(decoded);
+ _sink.close();
+ }
+
+ ByteConversionSink asUtf8Sink(bool allowMalformed) {
+ _parser = null;
+ return new _JsonUtf8DecoderSink(_reviver, _sink, allowMalformed);
+ }
+}
+
+class _Utf8StringBuffer {
+ static const int INITIAL_CAPACITY = 32;
+ // Partial state encoding.
+ static const int MASK_TWO_BIT = 0x03;
+ static const int MASK_SIZE = MASK_TWO_BIT;
+ static const int SHIFT_MISSING = 2;
+ static const int SHIFT_VALUE = 4;
+ static const int NO_PARTIAL = 0;
+
+ // UTF-8 encoding and limits.
+ static const int MAX_ASCII = 127;
+ static const int MAX_TWO_BYTE = 0x7ff;
+ static const int MAX_THREE_BYTE = 0xffff;
+ static const int MAX_UNICODE = 0X10ffff;
+ static const int MASK_TWO_BYTE = 0x1f;
+ static const int MASK_THREE_BYTE = 0x0f;
+ static const int MASK_FOUR_BYTE = 0x07;
+ static const int MASK_CONTINUE_TAG = 0xC0;
+ static const int MASK_CONTINUE_VALUE = 0x3f;
+ static const int CONTINUE_TAG = 0x80;
+
+ // UTF-16 surrogate encoding.
+ static const int LEAD_SURROGATE = 0xD800;
+ static const int TAIL_SURROGATE = 0xDC00;
+ static const int SHIFT_HIGH_SURROGATE = 10;
+ static const int MASK_LOW_SURROGATE = 0x3ff;
+
+ // The internal buffer starts as Uint8List, but may change to Uint16List
+ // if the string contains non-Latin-1 characters.
+ List<int> buffer = new Uint8List(INITIAL_CAPACITY);
+ // Number of elements in buffer.
+ int length = 0;
+ // Partial decoding state, for cases where an UTF-8 sequences is split
+ // between chunks.
+ int partialState = NO_PARTIAL;
+ // Whether all characters so far have been Latin-1 (and the buffer is
+ // still a Uint8List). Set to false when the first non-Latin-1 character
+ // is encountered, and the buffer is then also converted to a Uint16List.
+ bool isLatin1 = true;
+ // If allowing malformed, invalid UTF-8 sequences are converted to
+ // U+FFFD.
+ bool allowMalformed;
+
+ _Utf8StringBuffer(this.allowMalformed);
+
+ /**
+ * Parse the continuation of a multi-byte UTF-8 sequence.
+ *
+ * Parse [utf8] from [position] to [end]. If the sequence extends beyond
+ * `end`, store the partial state in [partialState], and continue from there
+ * on the next added slice.
+ *
+ * The [size] is the number of expected continuation bytes total,
+ * and [missing] is the number of remaining continuation bytes.
+ * The [size] is used to detect overlong encodings.
+ * The [value] is the value collected so far.
+ *
+ * When called after seeing the first multi-byte marker, the [size] and
+ * [missing] values are always the same, but they may differ if continuing
+ * after a partial sequence.
+ */
+ int addContinuation(
+ List<int> utf8, int position, int end, int size, int missing, int value) {
+ int codeEnd = position + missing;
+ do {
+ if (position == end) {
+ missing = codeEnd - position;
+ partialState =
+ size | (missing << SHIFT_MISSING) | (value << SHIFT_VALUE);
+ return end;
+ }
+ int char = utf8[position];
+ if ((char & MASK_CONTINUE_TAG) != CONTINUE_TAG) {
+ if (allowMalformed) {
+ addCharCode(0xFFFD);
+ return position;
+ }
+ throw new FormatException(
+ "Expected UTF-8 continuation byte, "
+ "found $char",
+ utf8,
+ position);
+ }
+ value = 64 * value + (char & MASK_CONTINUE_VALUE);
+ position++;
+ } while (position < codeEnd);
+ if (value <= const [0, MAX_ASCII, MAX_TWO_BYTE, MAX_THREE_BYTE][size]) {
+ // Over-long encoding.
+ if (allowMalformed) {
+ value = 0xFFFD;
+ } else {
+ throw new FormatException(
+ "Invalid encoding: U+${value.toRadixString(16).padLeft(4, '0')}"
+ " encoded in ${size + 1} bytes.",
+ utf8,
+ position - 1);
+ }
+ }
+ addCharCode(value);
+ return position;
+ }
+
+ void addCharCode(int char) {
+ assert(char >= 0);
+ assert(char <= MAX_UNICODE);
+ if (partialState != NO_PARTIAL) {
+ if (allowMalformed) {
+ partialState = NO_PARTIAL;
+ addCharCode(0xFFFD);
+ } else {
+ throw new FormatException("Incomplete UTF-8 sequence");
+ }
+ }
+ if (isLatin1 && char > 0xff) {
+ _to16Bit(); // Also grows a little if close to full.
+ }
+ int length = this.length;
+ if (char <= MAX_THREE_BYTE) {
+ if (length == buffer.length) _grow();
+ buffer[length] = char;
+ this.length = length + 1;
+ return;
+ }
+ if (length + 2 > buffer.length) _grow();
+ int bits = char - 0x10000;
+ buffer[length] = LEAD_SURROGATE | (bits >> SHIFT_HIGH_SURROGATE);
+ buffer[length + 1] = TAIL_SURROGATE | (bits & MASK_LOW_SURROGATE);
+ this.length = length + 2;
+ }
+
+ void _to16Bit() {
+ assert(isLatin1);
+ Uint16List newBuffer;
+ if ((length + INITIAL_CAPACITY) * 2 <= buffer.length) {
+ // Reuse existing buffer if it's big enough.
+ newBuffer = new Uint16List.view((buffer as Uint8List).buffer);
+ } else {
+ int newCapacity = buffer.length;
+ if (newCapacity - length < INITIAL_CAPACITY) {
+ newCapacity = length + INITIAL_CAPACITY;
+ }
+ newBuffer = new Uint16List(newCapacity);
+ }
+ newBuffer.setRange(0, length, buffer);
+ buffer = newBuffer;
+ isLatin1 = false;
+ }
+
+ void _grow() {
+ int newCapacity = buffer.length * 2;
+ List newBuffer;
+ if (isLatin1) {
+ newBuffer = new Uint8List(newCapacity);
+ } else {
+ newBuffer = new Uint16List(newCapacity);
+ }
+ newBuffer.setRange(0, length, buffer);
+ buffer = newBuffer;
+ }
+
+ void addSlice(List<int> utf8, int position, int end) {
+ assert(position < end);
+ if (partialState > 0) {
+ int continueByteCount = (partialState & MASK_TWO_BIT);
+ int missing = (partialState >> SHIFT_MISSING) & MASK_TWO_BIT;
+ int value = partialState >> SHIFT_VALUE;
+ partialState = NO_PARTIAL;
+ position = addContinuation(
+ utf8, position, end, continueByteCount, missing, value);
+ if (position == end) return;
+ }
+ // Keep index and capacity in local variables while looping over
+ // ASCII characters.
+ int index = length;
+ int capacity = buffer.length;
+ while (position < end) {
+ int char = utf8[position];
+ if (char <= MAX_ASCII) {
+ if (index == capacity) {
+ length = index;
+ _grow();
+ capacity = buffer.length;
+ }
+ buffer[index++] = char;
+ position++;
+ continue;
+ }
+ length = index;
+ if ((char & MASK_CONTINUE_TAG) == CONTINUE_TAG) {
+ if (allowMalformed) {
+ addCharCode(0xFFFD);
+ position++;
+ } else {
+ throw new FormatException(
+ "Unexpected UTF-8 continuation byte", utf8, position);
+ }
+ } else if (char < 0xE0) {
+ // C0-DF
+ // Two-byte.
+ position = addContinuation(
+ utf8, position + 1, end, 1, 1, char & MASK_TWO_BYTE);
+ } else if (char < 0xF0) {
+ // E0-EF
+ // Three-byte.
+ position = addContinuation(
+ utf8, position + 1, end, 2, 2, char & MASK_THREE_BYTE);
+ } else if (char < 0xF8) {
+ // F0-F7
+ // Four-byte.
+ position = addContinuation(
+ utf8, position + 1, end, 3, 3, char & MASK_FOUR_BYTE);
+ } else {
+ if (allowMalformed) {
+ addCharCode(0xFFFD);
+ position++;
+ } else {
+ throw new FormatException(
+ "Invalid UTF-8 byte: $char", utf8, position);
+ }
+ }
+ index = length;
+ capacity = buffer.length;
+ }
+ length = index;
+ }
+
+ String toString() {
+ if (partialState != NO_PARTIAL) {
+ if (allowMalformed) {
+ partialState = NO_PARTIAL;
+ addCharCode(0xFFFD);
+ } else {
+ int continueByteCount = (partialState & MASK_TWO_BIT);
+ int missing = (partialState >> SHIFT_MISSING) & MASK_TWO_BIT;
+ int value = partialState >> SHIFT_VALUE;
+ int seenByteCount = continueByteCount - missing + 1;
+ List source = new Uint8List(seenByteCount);
+ while (seenByteCount > 1) {
+ seenByteCount--;
+ source[seenByteCount] = CONTINUE_TAG | (value & MASK_CONTINUE_VALUE);
+ value >>= 6;
+ }
+ source[0] = value | (0x3c0 >> (continueByteCount - 1));
+ throw new FormatException(
+ "Incomplete UTF-8 sequence", source, source.length);
+ }
+ }
+ return new String.fromCharCodes(buffer, 0, length);
+ }
+}
+
+/**
+ * Chunked JSON parser that parses UTF-8 chunks.
+ */
+class _JsonUtf8Parser extends _ChunkedJsonParser<List<int>> {
+ final bool allowMalformed;
+ List<int> chunk;
+ int chunkEnd;
+
+ _JsonUtf8Parser(_JsonListener listener, this.allowMalformed)
+ : super(listener) {
+ // Starts out checking for an optional BOM (KWD_BOM, count = 0).
+ partialState =
+ _ChunkedJsonParser.PARTIAL_KEYWORD | _ChunkedJsonParser.KWD_BOM;
+ }
+
+ int getChar(int position) => chunk[position];
+
+ String getString(int start, int end, int bits) {
+ const int maxAsciiChar = 0x7f;
+ if (bits <= maxAsciiChar) {
+ return new String.fromCharCodes(chunk, start, end);
+ }
+ beginString();
+ if (start < end) addSliceToString(start, end);
+ String result = endString();
+ return result;
+ }
+
+ void beginString() {
+ this.buffer = new _Utf8StringBuffer(allowMalformed);
+ }
+
+ void addSliceToString(int start, int end) {
+ _Utf8StringBuffer buffer = this.buffer;
+ buffer.addSlice(chunk, start, end);
+ }
+
+ void addCharToString(int charCode) {
+ _Utf8StringBuffer buffer = this.buffer;
+ buffer.addCharCode(charCode);
+ }
+
+ String endString() {
+ _Utf8StringBuffer buffer = this.buffer;
+ this.buffer = null;
+ return buffer.toString();
+ }
+
+ void copyCharsToList(int start, int end, List target, int offset) {
+ int length = end - start;
+ target.setRange(offset, offset + length, chunk, start);
+ }
+
+ double parseDouble(int start, int end) {
+ String string = getString(start, end, 0x7f);
+ return _parseDouble(string, 0, string.length);
+ }
+}
+
+double _parseDouble(String source, int start, int end) native "Double_parse";
+
+/**
+ * Implements the chunked conversion from a UTF-8 encoding of JSON
+ * to its corresponding object.
+ */
+class _JsonUtf8DecoderSink extends ByteConversionSinkBase {
+ final _JsonUtf8Parser _parser;
+ final Sink<Object> _sink;
+
+ _JsonUtf8DecoderSink(reviver, this._sink, bool allowMalformed)
+ : _parser = _createParser(reviver, allowMalformed);
+
+ static _JsonUtf8Parser _createParser(reviver, bool allowMalformed) {
+ _BuildJsonListener listener;
+ if (reviver == null) {
+ listener = new _BuildJsonListener();
+ } else {
+ listener = new _ReviverJsonListener(reviver);
+ }
+ return new _JsonUtf8Parser(listener, allowMalformed);
+ }
+
+ void addSlice(List<int> chunk, int start, int end, bool isLast) {
+ _addChunk(chunk, start, end);
+ if (isLast) close();
+ }
+
+ void add(List<int> chunk) {
+ _addChunk(chunk, 0, chunk.length);
+ }
+
+ void _addChunk(List<int> chunk, int start, int end) {
+ _parser.chunk = chunk;
+ _parser.chunkEnd = end;
+ _parser.parse(start);
+ }
+
+ void close() {
+ _parser.close();
+ var decoded = _parser.result;
+ _sink.add(decoded);
+ _sink.close();
+ }
+}
+
+@patch
+int _scanOneByteCharacters(List<int> units, int from, int endIndex) {
+ final to = endIndex;
+
+ // Special case for _Uint8ArrayView.
+ if (units is Uint8List) {
+ if (from >= 0 && to >= 0 && to <= units.length) {
+ for (int i = from; i < to; i++) {
+ final unit = units[i];
+ if ((unit & _ONE_BYTE_LIMIT) != unit) return i - from;
+ }
+ return to - from;
+ }
+ }
+
+ // Fall through to normal case.
+ for (var i = from; i < to; i++) {
+ final unit = units[i];
+ if ((unit & _ONE_BYTE_LIMIT) != unit) return i - from;
+ }
+ return to - from;
+}
diff --git a/sdk_nnbd/lib/_internal/vm/lib/core_patch.dart b/sdk_nnbd/lib/_internal/vm/lib/core_patch.dart
new file mode 100644
index 0000000..bcfe3be
--- /dev/null
+++ b/sdk_nnbd/lib/_internal/vm/lib/core_patch.dart
@@ -0,0 +1,168 @@
+// 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
+// BSD-style license that can be found in the LICENSE file.
+
+// @dart = 2.5
+
+/// Note: the VM concatenates all patch files into a single patch file. This
+/// file is the first patch in "dart:core" which contains all the imports
+/// used by patches of that library. We plan to change this when we have a
+/// shared front end and simply use parts.
+
+import "dart:_internal" as internal show Symbol;
+
+import "dart:_internal"
+ show
+ ClassID,
+ CodeUnits,
+ EfficientLengthIterable,
+ FixedLengthListBase,
+ IterableElementError,
+ ListIterator,
+ Lists,
+ POWERS_OF_TEN,
+ SubListIterable,
+ UnmodifiableListBase,
+ is64Bit,
+ makeFixedListUnmodifiable,
+ makeListFixedLength,
+ patch,
+ unsafeCast;
+
+import "dart:async" show Completer, Future, Timer;
+
+import "dart:collection"
+ show
+ HashMap,
+ IterableBase,
+ LinkedHashMap,
+ LinkedList,
+ LinkedListEntry,
+ ListBase,
+ MapBase,
+ Maps,
+ UnmodifiableMapBase,
+ UnmodifiableMapView;
+
+import "dart:convert" show ascii, Encoding, json, latin1, utf8;
+
+import "dart:isolate" show Isolate;
+
+import "dart:math" show Random;
+
+import "dart:typed_data"
+ show Endian, Uint8List, Int64List, Uint16List, Uint32List;
+
+/// These are the additional parts of this patch library:
+// part "array.dart";
+// part "array_patch.dart";
+// part "bigint_patch.dart";
+// part "bool_patch.dart";
+// part "date_patch.dart";
+// part "double.dart";
+// part "double_patch.dart";
+// part "errors_patch.dart";
+// part "expando_patch.dart";
+// part "function.dart";
+// part "function_patch.dart";
+// part "growable_array.dart";
+// part "identical_patch.dart";
+// part "immutable_map.dart";
+// part "integers.dart";
+// part "integers_patch.dart";
+// part "invocation_mirror_patch.dart";
+// part "lib_prefix.dart";
+// part "map_patch.dart";
+// part "null_patch.dart";
+// part "object_patch.dart";
+// part "regexp_patch.dart";
+// part "stacktrace.dart";
+// part "stopwatch_patch.dart";
+// part "string_buffer_patch.dart";
+// part "string_patch.dart";
+// part "type_patch.dart";
+// part "uri_patch.dart";
+// part "weak_property.dart";
+
+@patch
+class num {
+ num _addFromInteger(int other);
+ num _subFromInteger(int other);
+ num _mulFromInteger(int other);
+ int _truncDivFromInteger(int other);
+ num _moduloFromInteger(int other);
+ num _remainderFromInteger(int other);
+ bool _greaterThanFromInteger(int other);
+ bool _equalToInteger(int other);
+}
+
+// _SyncIterable and _syncIterator are used by the compiler to
+// implement sync* generator functions. A sync* generator allocates
+// and returns a new _SyncIterable object.
+
+typedef bool _SyncGeneratorCallback<T>(_SyncIterator<T> iterator);
+
+class _SyncIterable<T> extends IterableBase<T> {
+ // _moveNextFn is the closurized body of the generator function.
+ final _SyncGeneratorCallback<T> _moveNextFn;
+
+ const _SyncIterable(this._moveNextFn);
+
+ Iterator<T> get iterator {
+ // Note: _Closure._clone returns _Closure which is not related to
+ // _SyncGeneratorCallback, which means we need explicit cast.
+ return new _SyncIterator<T>(unsafeCast<_SyncGeneratorCallback<T>>(
+ unsafeCast<_Closure>(_moveNextFn)._clone()));
+ }
+}
+
+class _SyncIterator<T> implements Iterator<T> {
+ _SyncGeneratorCallback<T> _moveNextFn;
+ Iterator<T> _yieldEachIterator;
+
+ // These two fields are set by generated code for the yield and yield*
+ // statement.
+ T _current;
+ Iterable<T> _yieldEachIterable;
+
+ T get current =>
+ _yieldEachIterator != null ? _yieldEachIterator.current : _current;
+
+ _SyncIterator(this._moveNextFn);
+
+ bool moveNext() {
+ if (_moveNextFn == null) {
+ return false;
+ }
+ while (true) {
+ if (_yieldEachIterator != null) {
+ if (_yieldEachIterator.moveNext()) {
+ return true;
+ }
+ _yieldEachIterator = null;
+ }
+ // _moveNextFn() will update the values of _yieldEachIterable
+ // and _current.
+ if (!_moveNextFn(this)) {
+ _moveNextFn = null;
+ _current = null;
+ return false;
+ }
+ if (_yieldEachIterable != null) {
+ // Spec mandates: it is a dynamic error if the class of [the object
+ // returned by yield*] does not implement Iterable.
+ _yieldEachIterator = _yieldEachIterable.iterator;
+ _yieldEachIterable = null;
+ _current = null;
+ continue;
+ }
+ return true;
+ }
+ }
+}
+
+@patch
+class StackTrace {
+ @patch
+ static StackTrace get current native "StackTrace_current";
+}
diff --git a/sdk_nnbd/lib/_internal/vm/lib/date_patch.dart b/sdk_nnbd/lib/_internal/vm/lib/date_patch.dart
new file mode 100644
index 0000000..a53cba1
--- /dev/null
+++ b/sdk_nnbd/lib/_internal/vm/lib/date_patch.dart
@@ -0,0 +1,448 @@
+// 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.5
+
+// part of "core_patch.dart";
+
+// VM implementation of DateTime.
+@patch
+class DateTime {
+ // Natives.
+ // The natives have been moved up here to work around Issue 10401.
+ static int _getCurrentMicros() native "DateTime_currentTimeMicros";
+
+ static String _timeZoneNameForClampedSeconds(int secondsSinceEpoch)
+ native "DateTime_timeZoneName";
+
+ static int _timeZoneOffsetInSecondsForClampedSeconds(int secondsSinceEpoch)
+ native "DateTime_timeZoneOffsetInSeconds";
+
+ static int _localTimeZoneAdjustmentInSeconds()
+ native "DateTime_localTimeZoneAdjustmentInSeconds";
+
+ static const _MICROSECOND_INDEX = 0;
+ static const _MILLISECOND_INDEX = 1;
+ static const _SECOND_INDEX = 2;
+ static const _MINUTE_INDEX = 3;
+ static const _HOUR_INDEX = 4;
+ static const _DAY_INDEX = 5;
+ static const _WEEKDAY_INDEX = 6;
+ static const _MONTH_INDEX = 7;
+ static const _YEAR_INDEX = 8;
+
+ List __parts;
+
+ @patch
+ DateTime.fromMillisecondsSinceEpoch(int millisecondsSinceEpoch,
+ {bool isUtc: false})
+ : this._withValue(
+ millisecondsSinceEpoch * Duration.microsecondsPerMillisecond,
+ isUtc: isUtc);
+
+ @patch
+ DateTime.fromMicrosecondsSinceEpoch(int microsecondsSinceEpoch,
+ {bool isUtc: false})
+ : this._withValue(microsecondsSinceEpoch, isUtc: isUtc);
+
+ @patch
+ DateTime._internal(int year, int month, int day, int hour, int minute,
+ int second, int millisecond, int microsecond, bool isUtc)
+ : this.isUtc = isUtc,
+ this._value = _brokenDownDateToValue(year, month, day, hour, minute,
+ second, millisecond, microsecond, isUtc) {
+ if (_value == null) throw new ArgumentError();
+ if (isUtc == null) throw new ArgumentError();
+ }
+
+ @patch
+ DateTime._now()
+ : isUtc = false,
+ _value = _getCurrentMicros();
+
+ @patch
+ String get timeZoneName {
+ if (isUtc) return "UTC";
+ return _timeZoneName(microsecondsSinceEpoch);
+ }
+
+ @patch
+ Duration get timeZoneOffset {
+ if (isUtc) return new Duration();
+ int offsetInSeconds = _timeZoneOffsetInSeconds(microsecondsSinceEpoch);
+ return new Duration(seconds: offsetInSeconds);
+ }
+
+ @patch
+ bool operator ==(dynamic other) =>
+ other is DateTime &&
+ _value == other.microsecondsSinceEpoch &&
+ isUtc == other.isUtc;
+
+ @patch
+ bool isBefore(DateTime other) => _value < other.microsecondsSinceEpoch;
+
+ @patch
+ bool isAfter(DateTime other) => _value > other.microsecondsSinceEpoch;
+
+ @patch
+ bool isAtSameMomentAs(DateTime other) =>
+ _value == other.microsecondsSinceEpoch;
+
+ @patch
+ int compareTo(DateTime other) =>
+ _value.compareTo(other.microsecondsSinceEpoch);
+
+ /** The first list contains the days until each month in non-leap years. The
+ * second list contains the days in leap years. */
+ static const List<List<int>> _DAYS_UNTIL_MONTH = const [
+ const [0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334],
+ const [0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335]
+ ];
+
+ static List _computeUpperPart(int localMicros) {
+ const int DAYS_IN_4_YEARS = 4 * 365 + 1;
+ const int DAYS_IN_100_YEARS = 25 * DAYS_IN_4_YEARS - 1;
+ const int DAYS_IN_400_YEARS = 4 * DAYS_IN_100_YEARS + 1;
+ const int DAYS_1970_TO_2000 = 30 * 365 + 7;
+ const int DAYS_OFFSET =
+ 1000 * DAYS_IN_400_YEARS + 5 * DAYS_IN_400_YEARS - DAYS_1970_TO_2000;
+ const int YEARS_OFFSET = 400000;
+
+ int resultYear = 0;
+ int resultMonth = 0;
+ int resultDay = 0;
+
+ // Always round down.
+ final int daysSince1970 =
+ _flooredDivision(localMicros, Duration.microsecondsPerDay);
+ int days = daysSince1970;
+ days += DAYS_OFFSET;
+ resultYear = 400 * (days ~/ DAYS_IN_400_YEARS) - YEARS_OFFSET;
+ days = days.remainder(DAYS_IN_400_YEARS);
+ days--;
+ int yd1 = days ~/ DAYS_IN_100_YEARS;
+ days = days.remainder(DAYS_IN_100_YEARS);
+ resultYear += 100 * yd1;
+ days++;
+ int yd2 = days ~/ DAYS_IN_4_YEARS;
+ days = days.remainder(DAYS_IN_4_YEARS);
+ resultYear += 4 * yd2;
+ days--;
+ int yd3 = days ~/ 365;
+ days = days.remainder(365);
+ resultYear += yd3;
+
+ bool isLeap = (yd1 == 0 || yd2 != 0) && yd3 == 0;
+ if (isLeap) days++;
+
+ List<int> daysUntilMonth = _DAYS_UNTIL_MONTH[isLeap ? 1 : 0];
+ for (resultMonth = 12;
+ daysUntilMonth[resultMonth - 1] > days;
+ resultMonth--) {
+ // Do nothing.
+ }
+ resultDay = days - daysUntilMonth[resultMonth - 1] + 1;
+
+ int resultMicrosecond = localMicros % Duration.microsecondsPerMillisecond;
+ int resultMillisecond =
+ _flooredDivision(localMicros, Duration.microsecondsPerMillisecond) %
+ Duration.millisecondsPerSecond;
+ int resultSecond =
+ _flooredDivision(localMicros, Duration.microsecondsPerSecond) %
+ Duration.secondsPerMinute;
+
+ int resultMinute =
+ _flooredDivision(localMicros, Duration.microsecondsPerMinute);
+ resultMinute %= Duration.minutesPerHour;
+
+ int resultHour =
+ _flooredDivision(localMicros, Duration.microsecondsPerHour);
+ resultHour %= Duration.hoursPerDay;
+
+ // In accordance with ISO 8601 a week
+ // starts with Monday. Monday has the value 1 up to Sunday with 7.
+ // 1970-1-1 was a Thursday.
+ int resultWeekday = ((daysSince1970 + DateTime.thursday - DateTime.monday) %
+ DateTime.daysPerWeek) +
+ DateTime.monday;
+
+ List list = new List(_YEAR_INDEX + 1);
+ list[_MICROSECOND_INDEX] = resultMicrosecond;
+ list[_MILLISECOND_INDEX] = resultMillisecond;
+ list[_SECOND_INDEX] = resultSecond;
+ list[_MINUTE_INDEX] = resultMinute;
+ list[_HOUR_INDEX] = resultHour;
+ list[_DAY_INDEX] = resultDay;
+ list[_WEEKDAY_INDEX] = resultWeekday;
+ list[_MONTH_INDEX] = resultMonth;
+ list[_YEAR_INDEX] = resultYear;
+ return list;
+ }
+
+ get _parts {
+ __parts ??= _computeUpperPart(_localDateInUtcMicros);
+ return __parts;
+ }
+
+ @patch
+ DateTime add(Duration duration) {
+ return new DateTime._withValue(_value + duration.inMicroseconds,
+ isUtc: isUtc);
+ }
+
+ @patch
+ DateTime subtract(Duration duration) {
+ return new DateTime._withValue(_value - duration.inMicroseconds,
+ isUtc: isUtc);
+ }
+
+ @patch
+ Duration difference(DateTime other) {
+ return new Duration(microseconds: _value - other._value);
+ }
+
+ @patch
+ int get millisecondsSinceEpoch =>
+ _value ~/ Duration.microsecondsPerMillisecond;
+
+ @patch
+ int get microsecondsSinceEpoch => _value;
+
+ @patch
+ int get microsecond => _parts[_MICROSECOND_INDEX];
+
+ @patch
+ int get millisecond => _parts[_MILLISECOND_INDEX];
+
+ @patch
+ int get second => _parts[_SECOND_INDEX];
+
+ @patch
+ int get minute => _parts[_MINUTE_INDEX];
+
+ @patch
+ int get hour => _parts[_HOUR_INDEX];
+
+ @patch
+ int get day => _parts[_DAY_INDEX];
+
+ @patch
+ int get weekday => _parts[_WEEKDAY_INDEX];
+
+ @patch
+ int get month => _parts[_MONTH_INDEX];
+
+ @patch
+ int get year => _parts[_YEAR_INDEX];
+
+ /**
+ * Returns the amount of microseconds in UTC that represent the same values
+ * as [this].
+ *
+ * Say `t` is the result of this function, then
+ * * `this.year == new DateTime.fromMicrosecondsSinceEpoch(t, true).year`,
+ * * `this.month == new DateTime.fromMicrosecondsSinceEpoch(t, true).month`,
+ * * `this.day == new DateTime.fromMicrosecondsSinceEpoch(t, true).day`,
+ * * `this.hour == new DateTime.fromMicrosecondsSinceEpoch(t, true).hour`,
+ * * ...
+ *
+ * Daylight savings is computed as if the date was computed in [1970..2037].
+ * If [this] lies outside this range then it is a year with similar
+ * properties (leap year, weekdays) is used instead.
+ */
+ int get _localDateInUtcMicros {
+ int micros = _value;
+ if (isUtc) return micros;
+ int offset =
+ _timeZoneOffsetInSeconds(micros) * Duration.microsecondsPerSecond;
+ return micros + offset;
+ }
+
+ static int _flooredDivision(int a, int b) {
+ return (a - (a < 0 ? b - 1 : 0)) ~/ b;
+ }
+
+ // Returns the days since 1970 for the start of the given [year].
+ // [year] may be before epoch.
+ static int _dayFromYear(int year) {
+ return 365 * (year - 1970) +
+ _flooredDivision(year - 1969, 4) -
+ _flooredDivision(year - 1901, 100) +
+ _flooredDivision(year - 1601, 400);
+ }
+
+ static bool _isLeapYear(y) {
+ // (y % 16 == 0) matches multiples of 400, and is faster than % 400.
+ return (y % 4 == 0) && ((y % 16 == 0) || (y % 100 != 0));
+ }
+
+ /// Converts the given broken down date to microseconds.
+ @patch
+ static int _brokenDownDateToValue(int year, int month, int day, int hour,
+ int minute, int second, int millisecond, int microsecond, bool isUtc) {
+ // Simplify calculations by working with zero-based month.
+ --month;
+ // Deal with under and overflow.
+ if (month >= 12) {
+ year += month ~/ 12;
+ month = month % 12;
+ } else if (month < 0) {
+ int realMonth = month % 12;
+ year += (month - realMonth) ~/ 12;
+ month = realMonth;
+ }
+
+ // First compute the seconds in UTC, independent of the [isUtc] flag. If
+ // necessary we will add the time-zone offset later on.
+ int days = day - 1;
+ days += _DAYS_UNTIL_MONTH[_isLeapYear(year) ? 1 : 0][month];
+ days += _dayFromYear(year);
+ int microsecondsSinceEpoch = days * Duration.microsecondsPerDay +
+ hour * Duration.microsecondsPerHour +
+ minute * Duration.microsecondsPerMinute +
+ second * Duration.microsecondsPerSecond +
+ millisecond * Duration.microsecondsPerMillisecond +
+ microsecond;
+
+ // Since [_timeZoneOffsetInSeconds] will crash if the input is far out of
+ // the valid range we do a preliminary test that weeds out values that can
+ // not become valid even with timezone adjustments.
+ // The timezone adjustment is always less than a day, so adding a security
+ // margin of one day should be enough.
+ if (microsecondsSinceEpoch.abs() >
+ _maxMillisecondsSinceEpoch * 1000 + Duration.microsecondsPerDay) {
+ return null;
+ }
+
+ if (!isUtc) {
+ // Note that we can't literally follow the ECMAScript spec (which this
+ // code is based on), because it leads to incorrect computations at
+ // the DST transition points.
+ //
+ // See V8's comment here:
+ // https://github.com/v8/v8/blob/089dd7d2447d6eaf57c8ba6d8f37957f3a269777/src/date.h#L118
+
+ // We need to remove the local timezone adjustment before asking for the
+ // correct zone offset.
+ int adjustment =
+ _localTimeZoneAdjustmentInSeconds() * Duration.microsecondsPerSecond;
+ // The adjustment is independent of the actual date and of the daylight
+ // saving time. It is positive east of the Prime Meridian and negative
+ // west of it, e.g. -28800 sec for America/Los_Angeles timezone.
+
+ // We remove one hour to ensure that we have the correct offset at
+ // DST transitioning points. This is a temporary solution and only
+ // correct in timezones that shift for exactly one hour.
+ adjustment += Duration.microsecondsPerHour;
+ int zoneOffset =
+ _timeZoneOffsetInSeconds(microsecondsSinceEpoch - adjustment);
+
+ // The zoneOffset depends on the actual date and reflects any daylight
+ // saving time and/or historical deviation relative to UTC time.
+ // It is positive east of the Prime Meridian and negative west of it,
+ // e.g. -25200 sec for America/Los_Angeles timezone during DST.
+ microsecondsSinceEpoch -= zoneOffset * Duration.microsecondsPerSecond;
+ // The resulting microsecondsSinceEpoch value is therefore the calculated
+ // UTC value decreased by a (positive if east of GMT) timezone adjustment
+ // and decreased by typically one hour if DST is in effect.
+ }
+ if (microsecondsSinceEpoch.abs() >
+ _maxMillisecondsSinceEpoch * Duration.microsecondsPerMillisecond) {
+ return null;
+ }
+ return microsecondsSinceEpoch;
+ }
+
+ static int _weekDay(y) {
+ // 1/1/1970 was a Thursday.
+ return (_dayFromYear(y) + 4) % 7;
+ }
+
+ /**
+ * Returns a year in the range 2008-2035 matching
+ * * leap year, and
+ * * week day of first day.
+ *
+ * Leap seconds are ignored.
+ * Adapted from V8's date implementation. See ECMA 262 - 15.9.1.9.
+ */
+ static int _equivalentYear(int year) {
+ // Returns year y so that _weekDay(y) == _weekDay(year).
+ // _weekDay returns the week day (in range 0 - 6).
+ // 1/1/1956 was a Sunday (i.e. weekday 0). 1956 was a leap-year.
+ // 1/1/1967 was a Sunday (i.e. weekday 0).
+ // Without leap years a subsequent year has a week day + 1 (for example
+ // 1/1/1968 was a Monday). With leap-years it jumps over one week day
+ // (e.g. 1/1/1957 was a Tuesday).
+ // After 12 years the weekdays have advanced by 12 days + 3 leap days =
+ // 15 days. 15 % 7 = 1. So after 12 years the week day has always
+ // (now independently of leap-years) advanced by one.
+ // weekDay * 12 gives thus a year starting with the wanted weekDay.
+ int recentYear = (_isLeapYear(year) ? 1956 : 1967) + (_weekDay(year) * 12);
+ // Close to the year 2008 the calendar cycles every 4 * 7 years (4 for the
+ // leap years, 7 for the weekdays).
+ // Find the year in the range 2008..2037 that is equivalent mod 28.
+ return 2008 + (recentYear - 2008) % 28;
+ }
+
+ /**
+ * Returns the UTC year for the corresponding [secondsSinceEpoch].
+ * It is relatively fast for values in the range 0 to year 2098.
+ *
+ * Code is adapted from V8.
+ */
+ static int _yearsFromSecondsSinceEpoch(int secondsSinceEpoch) {
+ const int DAYS_IN_4_YEARS = 4 * 365 + 1;
+ const int DAYS_IN_100_YEARS = 25 * DAYS_IN_4_YEARS - 1;
+ const int DAYS_YEAR_2098 = DAYS_IN_100_YEARS + 6 * DAYS_IN_4_YEARS;
+
+ int days = secondsSinceEpoch ~/ Duration.secondsPerDay;
+ if (days > 0 && days < DAYS_YEAR_2098) {
+ // According to V8 this fast case works for dates from 1970 to 2099.
+ return 1970 + (4 * days + 2) ~/ DAYS_IN_4_YEARS;
+ }
+ int micros = secondsSinceEpoch * Duration.microsecondsPerSecond;
+ return _computeUpperPart(micros)[_YEAR_INDEX];
+ }
+
+ /**
+ * Returns a date in seconds that is equivalent to the given
+ * date in microseconds [microsecondsSinceEpoch]. An equivalent
+ * date has the same fields (`month`, `day`, etc.) as the given
+ * date, but the `year` is in the range [1901..2038].
+ *
+ * * The time since the beginning of the year is the same.
+ * * If the given date is in a leap year then the returned
+ * seconds are in a leap year, too.
+ * * The week day of given date is the same as the one for the
+ * returned date.
+ */
+ static int _equivalentSeconds(int microsecondsSinceEpoch) {
+ const int CUT_OFF_SECONDS = 0x7FFFFFFF;
+
+ int secondsSinceEpoch = _flooredDivision(
+ microsecondsSinceEpoch, Duration.microsecondsPerSecond);
+
+ if (secondsSinceEpoch.abs() > CUT_OFF_SECONDS) {
+ int year = _yearsFromSecondsSinceEpoch(secondsSinceEpoch);
+ int days = _dayFromYear(year);
+ int equivalentYear = _equivalentYear(year);
+ int equivalentDays = _dayFromYear(equivalentYear);
+ int diffDays = equivalentDays - days;
+ secondsSinceEpoch += diffDays * Duration.secondsPerDay;
+ }
+ return secondsSinceEpoch;
+ }
+
+ static int _timeZoneOffsetInSeconds(int microsecondsSinceEpoch) {
+ int equivalentSeconds = _equivalentSeconds(microsecondsSinceEpoch);
+ return _timeZoneOffsetInSecondsForClampedSeconds(equivalentSeconds);
+ }
+
+ static String _timeZoneName(int microsecondsSinceEpoch) {
+ int equivalentSeconds = _equivalentSeconds(microsecondsSinceEpoch);
+ return _timeZoneNameForClampedSeconds(equivalentSeconds);
+ }
+}
diff --git a/sdk_nnbd/lib/_internal/vm/lib/deferred_load_patch.dart b/sdk_nnbd/lib/_internal/vm/lib/deferred_load_patch.dart
new file mode 100644
index 0000000..3651d7e
--- /dev/null
+++ b/sdk_nnbd/lib/_internal/vm/lib/deferred_load_patch.dart
@@ -0,0 +1,21 @@
+// 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
+// BSD-style license that can be found in the LICENSE file.
+
+// @dart = 2.5
+
+// part of "async_patch.dart";
+
+final Set<String> _loadedLibraries = new Set<String>();
+
+@patch
+class DeferredLibrary {
+ @patch
+ Future<Null> load() {
+ // Dummy implementation that should eventually be replaced by real
+ // implementation.
+ Future future = new Future<Null>.value(null);
+ _loadedLibraries.add(libraryName);
+ return future;
+ }
+}
diff --git a/sdk_nnbd/lib/_internal/vm/lib/developer.dart b/sdk_nnbd/lib/_internal/vm/lib/developer.dart
new file mode 100644
index 0000000..538303d
--- /dev/null
+++ b/sdk_nnbd/lib/_internal/vm/lib/developer.dart
@@ -0,0 +1,171 @@
+// Copyright (c) 2015, 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.5
+
+/// Note: the VM concatenates all patch files into a single patch file. This
+/// file is the first patch in "dart:developer" which contains all the imports
+/// used by patches of that library. We plan to change this when we have a
+/// shared front end and simply use parts.
+
+import "dart:_internal" show patch;
+
+import "dart:async" show Future, Zone;
+
+import "dart:isolate" show SendPort;
+
+/// These are the additional parts of this patch library:
+// part "profiler.dart"
+// part "timeline.dart"
+
+@patch
+bool debugger({bool when: true, String message}) native "Developer_debugger";
+
+@patch
+Object inspect(Object object) native "Developer_inspect";
+
+@patch
+void log(String message,
+ {DateTime time,
+ int sequenceNumber,
+ int level: 0,
+ String name: '',
+ Zone zone,
+ Object error,
+ StackTrace stackTrace}) {
+ if (message is! String) {
+ throw new ArgumentError.value(message, "message", "Must be a String");
+ }
+ time ??= new DateTime.now();
+ if (time is! DateTime) {
+ throw new ArgumentError.value(time, "time", "Must be a DateTime");
+ }
+ if (sequenceNumber == null) {
+ sequenceNumber = _nextSequenceNumber++;
+ } else {
+ _nextSequenceNumber = sequenceNumber + 1;
+ }
+ _log(message, time.millisecondsSinceEpoch, sequenceNumber, level, name, zone,
+ error, stackTrace);
+}
+
+int _nextSequenceNumber = 0;
+
+_log(String message, int timestamp, int sequenceNumber, int level, String name,
+ Zone zone, Object error, StackTrace stackTrace) native "Developer_log";
+
+@patch
+void _postEvent(String eventKind, String eventData)
+ native "Developer_postEvent";
+
+@patch
+ServiceExtensionHandler _lookupExtension(String method)
+ native "Developer_lookupExtension";
+
+@patch
+_registerExtension(String method, ServiceExtensionHandler handler)
+ native "Developer_registerExtension";
+
+// This code is only invoked when there is no other Dart code on the stack.
+@pragma("vm:entry-point", !const bool.fromEnvironment("dart.vm.product"))
+_runExtension(
+ ServiceExtensionHandler handler,
+ String method,
+ List<String> parameterKeys,
+ List<String> parameterValues,
+ SendPort replyPort,
+ Object id,
+ bool trace_service) {
+ var parameters = <String, String>{};
+ for (var i = 0; i < parameterKeys.length; i++) {
+ parameters[parameterKeys[i]] = parameterValues[i];
+ }
+ var response;
+ try {
+ response = handler(method, parameters);
+ } catch (e, st) {
+ var errorDetails = (st == null) ? '$e' : '$e\n$st';
+ response = new ServiceExtensionResponse.error(
+ ServiceExtensionResponse.kExtensionError, errorDetails);
+ _postResponse(replyPort, id, response, trace_service);
+ return;
+ }
+ if (response is! Future) {
+ response = new ServiceExtensionResponse.error(
+ ServiceExtensionResponse.kExtensionError,
+ "Extension handler must return a Future");
+ _postResponse(replyPort, id, response, trace_service);
+ return;
+ }
+ response.catchError((e, st) {
+ // Catch any errors eagerly and wrap them in a ServiceExtensionResponse.
+ var errorDetails = (st == null) ? '$e' : '$e\n$st';
+ return new ServiceExtensionResponse.error(
+ ServiceExtensionResponse.kExtensionError, errorDetails);
+ }).then((response) {
+ // Post the valid response or the wrapped error after verifying that
+ // the response is a ServiceExtensionResponse.
+ if (response is! ServiceExtensionResponse) {
+ response = new ServiceExtensionResponse.error(
+ ServiceExtensionResponse.kExtensionError,
+ "Extension handler must complete to a ServiceExtensionResponse");
+ }
+ _postResponse(replyPort, id, response, trace_service);
+ }).catchError((e, st) {
+ // We do not expect any errors to occur in the .then or .catchError blocks
+ // but, suppress them just in case.
+ });
+}
+
+// This code is only invoked by _runExtension.
+_postResponse(SendPort replyPort, Object id, ServiceExtensionResponse response,
+ bool trace_service) {
+ assert(replyPort != null);
+ if (id == null) {
+ if (trace_service) {
+ print("vm-service: posting no response for request");
+ }
+ // No id -> no response.
+ replyPort.send(null);
+ return;
+ }
+ assert(id != null);
+ StringBuffer sb = new StringBuffer();
+ sb.write('{"jsonrpc":"2.0",');
+ if (response.isError()) {
+ if (trace_service) {
+ print("vm-service: posting error response for request $id");
+ }
+ sb.write('"error":');
+ } else {
+ if (trace_service) {
+ print("vm-service: posting response for request $id");
+ }
+ sb.write('"result":');
+ }
+ sb.write('${response._toString()},');
+ if (id is String) {
+ sb.write('"id":"$id"}');
+ } else {
+ sb.write('"id":$id}');
+ }
+ replyPort.send(sb.toString());
+}
+
+@patch
+int _getServiceMajorVersion() native "Developer_getServiceMajorVersion";
+
+@patch
+int _getServiceMinorVersion() native "Developer_getServiceMinorVersion";
+
+@patch
+void _getServerInfo(SendPort sendPort) native "Developer_getServerInfo";
+
+@patch
+void _webServerControl(SendPort sendPort, bool enable)
+ native "Developer_webServerControl";
+
+@patch
+String _getIsolateIDFromSendPort(SendPort sendPort)
+ native "Developer_getIsolateIDFromSendPort";
diff --git a/sdk_nnbd/lib/_internal/vm/lib/double.dart b/sdk_nnbd/lib/_internal/vm/lib/double.dart
new file mode 100644
index 0000000..01e8d58
--- /dev/null
+++ b/sdk_nnbd/lib/_internal/vm/lib/double.dart
@@ -0,0 +1,365 @@
+// 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.5
+
+// part of "core_patch.dart";
+
+@pragma("vm:entry-point")
+class _Double implements double {
+ @pragma("vm:exact-result-type", _Double)
+ factory _Double.fromInteger(int value) native "Double_doubleFromInteger";
+
+ int get hashCode native "Double_hashCode";
+ int get _identityHashCode native "Double_hashCode";
+
+ @pragma("vm:exact-result-type", _Double)
+ @pragma("vm:never-inline")
+ double operator +(num other) {
+ return _add(other.toDouble());
+ }
+
+ @pragma("vm:exact-result-type", _Double)
+ double _add(double other) native "Double_add";
+
+ @pragma("vm:exact-result-type", _Double)
+ @pragma("vm:never-inline")
+ double operator -(num other) {
+ return _sub(other.toDouble());
+ }
+
+ @pragma("vm:exact-result-type", _Double)
+ double _sub(double other) native "Double_sub";
+
+ @pragma("vm:exact-result-type", _Double)
+ @pragma("vm:never-inline")
+ double operator *(num other) {
+ return _mul(other.toDouble());
+ }
+
+ @pragma("vm:exact-result-type", _Double)
+ double _mul(double other) native "Double_mul";
+
+ int operator ~/(num other) {
+ return _trunc_div(other.toDouble());
+ }
+
+ @pragma("vm:non-nullable-result-type")
+ int _trunc_div(double other) native "Double_trunc_div";
+
+ @pragma("vm:exact-result-type", _Double)
+ @pragma("vm:never-inline")
+ double operator /(num other) {
+ return _div(other.toDouble());
+ }
+
+ @pragma("vm:exact-result-type", _Double)
+ double _div(double other) native "Double_div";
+
+ double operator %(num other) {
+ return _modulo(other.toDouble());
+ }
+
+ @pragma("vm:exact-result-type", _Double)
+ double _modulo(double other) native "Double_modulo";
+
+ double remainder(num other) {
+ return _remainder(other.toDouble());
+ }
+
+ double _remainder(double other) native "Double_remainder";
+
+ @pragma("vm:exact-result-type", _Double)
+ double operator -() native "Double_flipSignBit";
+
+ @pragma("vm:exact-result-type", bool)
+ @pragma("vm:never-inline")
+ bool operator ==(Object other) {
+ return (other is num) && _equal(other.toDouble());
+ }
+
+ @pragma("vm:exact-result-type", bool)
+ bool _equal(double other) native "Double_equal";
+ @pragma("vm:exact-result-type", bool)
+ bool _equalToInteger(int other) native "Double_equalToInteger";
+
+ @pragma("vm:exact-result-type", bool)
+ @pragma("vm:never-inline")
+ bool operator <(num other) {
+ return other > this;
+ }
+
+ @pragma("vm:exact-result-type", bool)
+ @pragma("vm:never-inline")
+ bool operator >(num other) {
+ return _greaterThan(other.toDouble());
+ }
+
+ @pragma("vm:exact-result-type", bool)
+ bool _greaterThan(double other) native "Double_greaterThan";
+
+ @pragma("vm:exact-result-type", bool)
+ @pragma("vm:never-inline")
+ bool operator >=(num other) {
+ return (this == other) || (this > other);
+ }
+
+ @pragma("vm:exact-result-type", bool)
+ @pragma("vm:never-inline")
+ bool operator <=(num other) {
+ return (this == other) || (this < other);
+ }
+
+ double _addFromInteger(int other) {
+ return new _Double.fromInteger(other)._add(this);
+ }
+
+ double _subFromInteger(int other) {
+ return new _Double.fromInteger(other)._sub(this);
+ }
+
+ @pragma("vm:exact-result-type", "dart:core#_Double")
+ double _mulFromInteger(int other) {
+ return new _Double.fromInteger(other)._mul(this);
+ }
+
+ int _truncDivFromInteger(int other) {
+ return new _Double.fromInteger(other)._trunc_div(this);
+ }
+
+ double _moduloFromInteger(int other) {
+ return new _Double.fromInteger(other)._modulo(this);
+ }
+
+ double _remainderFromInteger(int other) {
+ return new _Double.fromInteger(other)._remainder(this);
+ }
+
+ bool _greaterThanFromInteger(int other)
+ native "Double_greaterThanFromInteger";
+
+ @pragma("vm:exact-result-type", bool)
+ bool get isNegative native "Double_getIsNegative";
+ @pragma("vm:exact-result-type", bool)
+ bool get isInfinite native "Double_getIsInfinite";
+ @pragma("vm:exact-result-type", bool)
+ bool get isNaN native "Double_getIsNaN";
+ bool get isFinite => !isInfinite && !isNaN; // Can be optimized.
+
+ double abs() {
+ // Handle negative 0.0.
+ if (this == 0.0) return 0.0;
+ return this < 0.0 ? -this : this;
+ }
+
+ double get sign {
+ if (this > 0.0) return 1.0;
+ if (this < 0.0) return -1.0;
+ return this; // +/-0.0 or NaN.
+ }
+
+ int round() => roundToDouble().toInt();
+ int floor() => floorToDouble().toInt();
+ int ceil() => ceilToDouble().toInt();
+ int truncate() => truncateToDouble().toInt();
+
+ @pragma("vm:exact-result-type", _Double)
+ double roundToDouble() native "Double_round";
+ @pragma("vm:exact-result-type", _Double)
+ double floorToDouble() native "Double_floor";
+ @pragma("vm:exact-result-type", _Double)
+ double ceilToDouble() native "Double_ceil";
+ @pragma("vm:exact-result-type", _Double)
+ double truncateToDouble() native "Double_truncate";
+
+ num clamp(num lowerLimit, num upperLimit) {
+ if (lowerLimit is! num) {
+ throw new ArgumentError.value(lowerLimit, "lowerLimit", "not a number");
+ }
+ if (upperLimit is! num) {
+ throw new ArgumentError.value(upperLimit, "upperLimit", "not a number");
+ }
+
+ if (lowerLimit.compareTo(upperLimit) > 0) {
+ throw new ArgumentError(lowerLimit);
+ }
+ if (lowerLimit.isNaN) return lowerLimit;
+ if (this.compareTo(lowerLimit) < 0) return lowerLimit;
+ if (this.compareTo(upperLimit) > 0) return upperLimit;
+ return this;
+ }
+
+ @pragma("vm:non-nullable-result-type")
+ int toInt() native "Double_toInt";
+
+ double toDouble() {
+ return this;
+ }
+
+ static const int CACHE_SIZE_LOG2 = 3;
+ static const int CACHE_LENGTH = 1 << (CACHE_SIZE_LOG2 + 1);
+ static const int CACHE_MASK = CACHE_LENGTH - 1;
+ // Each key (double) followed by its toString result.
+ static final List _cache = new List(CACHE_LENGTH);
+ static int _cacheEvictIndex = 0;
+
+ String _toString() native "Double_toString";
+
+ String toString() {
+ // TODO(koda): Consider starting at most recently inserted.
+ for (int i = 0; i < CACHE_LENGTH; i += 2) {
+ // Need 'identical' to handle negative zero, etc.
+ if (identical(_cache[i], this)) {
+ return _cache[i + 1];
+ }
+ }
+ // TODO(koda): Consider optimizing all small integral values.
+ if (identical(0.0, this)) {
+ return "0.0";
+ }
+ String result = _toString();
+ // Replace the least recently inserted entry.
+ _cache[_cacheEvictIndex] = this;
+ _cache[_cacheEvictIndex + 1] = result;
+ _cacheEvictIndex = (_cacheEvictIndex + 2) & CACHE_MASK;
+ return result;
+ }
+
+ String toStringAsFixed(int fractionDigits) {
+ // See ECMAScript-262, 15.7.4.5 for details.
+
+ if (fractionDigits is! int) {
+ throw new ArgumentError.value(
+ fractionDigits, "fractionDigits", "not an integer");
+ }
+ // Step 2.
+ if (fractionDigits < 0 || fractionDigits > 20) {
+ throw new RangeError.range(fractionDigits, 0, 20, "fractionDigits");
+ }
+
+ // Step 3.
+ double x = this;
+
+ // Step 4.
+ if (isNaN) return "NaN";
+
+ // Step 5 and 6 skipped. Will be dealt with by native function.
+
+ // Step 7.
+ if (x >= 1e21 || x <= -1e21) {
+ return x.toString();
+ }
+
+ return _toStringAsFixed(fractionDigits);
+ }
+
+ String _toStringAsFixed(int fractionDigits) native "Double_toStringAsFixed";
+
+ String toStringAsExponential([int fractionDigits]) {
+ // See ECMAScript-262, 15.7.4.6 for details.
+
+ // The EcmaScript specification checks for NaN and Infinity before looking
+ // at the fractionDigits. In Dart we are consistent with toStringAsFixed and
+ // look at the fractionDigits first.
+
+ // Step 7.
+ if (fractionDigits != null) {
+ if (fractionDigits is! int) {
+ throw new ArgumentError.value(
+ fractionDigits, "fractionDigits", "not an integer");
+ }
+ if (fractionDigits < 0 || fractionDigits > 20) {
+ throw new RangeError.range(fractionDigits, 0, 20, "fractionDigits");
+ }
+ }
+
+ if (isNaN) return "NaN";
+ if (this == double.infinity) return "Infinity";
+ if (this == -double.infinity) return "-Infinity";
+
+ // The dart function prints the shortest representation when fractionDigits
+ // equals null. The native function wants -1 instead.
+ fractionDigits = (fractionDigits == null) ? -1 : fractionDigits;
+
+ return _toStringAsExponential(fractionDigits);
+ }
+
+ String _toStringAsExponential(int fractionDigits)
+ native "Double_toStringAsExponential";
+
+ String toStringAsPrecision(int precision) {
+ // See ECMAScript-262, 15.7.4.7 for details.
+
+ // The EcmaScript specification checks for NaN and Infinity before looking
+ // at the fractionDigits. In Dart we are consistent with toStringAsFixed and
+ // look at the fractionDigits first.
+
+ if (precision is! int) {
+ throw new ArgumentError.value(precision, "precision", "not an integer");
+ }
+ // Step 8.
+ if (precision < 1 || precision > 21) {
+ throw new RangeError.range(precision, 1, 21, "precision");
+ }
+
+ if (isNaN) return "NaN";
+ if (this == double.infinity) return "Infinity";
+ if (this == -double.infinity) return "-Infinity";
+
+ return _toStringAsPrecision(precision);
+ }
+
+ String _toStringAsPrecision(int fractionDigits)
+ native "Double_toStringAsPrecision";
+
+ // Order is: NaN > Infinity > ... > 0.0 > -0.0 > ... > -Infinity.
+ int compareTo(num other) {
+ const int EQUAL = 0, LESS = -1, GREATER = 1;
+ if (this < other) {
+ return LESS;
+ } else if (this > other) {
+ return GREATER;
+ } else if (this == other) {
+ if (this == 0.0) {
+ bool thisIsNegative = isNegative;
+ bool otherIsNegative = other.isNegative;
+ if (thisIsNegative == otherIsNegative) {
+ return EQUAL;
+ }
+ return thisIsNegative ? LESS : GREATER;
+ } else if (other is int) {
+ // Compare as integers as it is more precise if the integer value is
+ // outside of MIN_EXACT_INT_TO_DOUBLE..MAX_EXACT_INT_TO_DOUBLE range.
+ const int MAX_EXACT_INT_TO_DOUBLE = 9007199254740992; // 2^53.
+ const int MIN_EXACT_INT_TO_DOUBLE = -MAX_EXACT_INT_TO_DOUBLE;
+ if ((MIN_EXACT_INT_TO_DOUBLE <= other) &&
+ (other <= MAX_EXACT_INT_TO_DOUBLE)) {
+ return EQUAL;
+ }
+ const bool limitIntsTo64Bits = ((1 << 64) == 0);
+ if (limitIntsTo64Bits) {
+ // With integers limited to 64 bits, double.toInt() clamps
+ // double value to fit into the MIN_INT64..MAX_INT64 range.
+ // MAX_INT64 is not precisely representable as double, so
+ // integers near MAX_INT64 compare as equal to (MAX_INT64 + 1) when
+ // represented as doubles.
+ // There is no similar problem with MIN_INT64 as it is precisely
+ // representable as double.
+ const double maxInt64Plus1AsDouble = 9223372036854775808.0;
+ if (this >= maxInt64Plus1AsDouble) {
+ return GREATER;
+ }
+ }
+ return toInt().compareTo(other);
+ } else {
+ return EQUAL;
+ }
+ } else if (isNaN) {
+ return other.isNaN ? EQUAL : GREATER;
+ } else {
+ // Other is NaN.
+ return LESS;
+ }
+ }
+}
diff --git a/sdk_nnbd/lib/_internal/vm/lib/double_patch.dart b/sdk_nnbd/lib/_internal/vm/lib/double_patch.dart
new file mode 100644
index 0000000..bad7834
--- /dev/null
+++ b/sdk_nnbd/lib/_internal/vm/lib/double_patch.dart
@@ -0,0 +1,120 @@
+// 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.5
+
+// part of "core_patch.dart";
+
+// VM implementation of double.
+
+@patch
+class double {
+ static double _nativeParse(String str, int start, int end)
+ native "Double_parse";
+
+ static double _tryParseDouble(var str, var start, var end) {
+ assert(start < end);
+ const int _DOT = 0x2e; // '.'
+ const int _ZERO = 0x30; // '0'
+ const int _MINUS = 0x2d; // '-'
+ const int _N = 0x4e; // 'N'
+ const int _a = 0x61; // 'a'
+ const int _I = 0x49; // 'I'
+ const int _e = 0x65; // 'e'
+ int exponent = 0;
+ // Set to non-zero if a digit is seen. Avoids accepting ".".
+ bool digitsSeen = false;
+ // Added to exponent for each digit. Set to -1 when seeing '.'.
+ int exponentDelta = 0;
+ double doubleValue = 0.0;
+ double sign = 1.0;
+ int firstChar = str.codeUnitAt(start);
+ if (firstChar == _MINUS) {
+ sign = -1.0;
+ start++;
+ if (start == end) return null;
+ firstChar = str.codeUnitAt(start);
+ }
+ if (firstChar == _I) {
+ if (end == start + 8 && str.startsWith("nfinity", start + 1)) {
+ return sign * double.infinity;
+ }
+ return null;
+ }
+ if (firstChar == _N) {
+ if (end == start + 3 &&
+ str.codeUnitAt(start + 1) == _a &&
+ str.codeUnitAt(start + 2) == _N) {
+ return double.nan;
+ }
+ return null;
+ }
+
+ int firstDigit = firstChar ^ _ZERO;
+ if (firstDigit <= 9) {
+ start++;
+ doubleValue = firstDigit.toDouble();
+ digitsSeen = true;
+ }
+ for (int i = start; i < end; i++) {
+ int c = str.codeUnitAt(i);
+ int digit = c ^ _ZERO; // '0'-'9' characters are now 0-9 integers.
+ if (digit <= 9) {
+ doubleValue = 10.0 * doubleValue + digit;
+ // Doubles at or above this value (2**53) might have lost precission.
+ const double MAX_EXACT_DOUBLE = 9007199254740992.0;
+ if (doubleValue >= MAX_EXACT_DOUBLE) return null;
+ exponent += exponentDelta;
+ digitsSeen = true;
+ } else if (c == _DOT && exponentDelta == 0) {
+ exponentDelta = -1;
+ } else if ((c | 0x20) == _e) {
+ i++;
+ if (i == end) return null;
+ // int._tryParseSmi treats its end argument as inclusive.
+ int expPart = int._tryParseSmi(str, i, end - 1);
+ if (expPart == null) return null;
+ exponent += expPart;
+ break;
+ } else {
+ return null;
+ }
+ }
+ if (!digitsSeen) return null; // No digits.
+ if (exponent == 0) return sign * doubleValue;
+ const P10 = POWERS_OF_TEN; // From shared library
+ if (exponent < 0) {
+ int negExponent = -exponent;
+ if (negExponent >= P10.length) return null;
+ return sign * (doubleValue / P10[negExponent]);
+ }
+ if (exponent >= P10.length) return null;
+ return sign * (doubleValue * P10[exponent]);
+ }
+
+ static double _parse(var str) {
+ int len = str.length;
+ int start = str._firstNonWhitespace();
+ if (start == len) return null; // All whitespace.
+ int end = str._lastNonWhitespace() + 1;
+ assert(start < end);
+ var result = _tryParseDouble(str, start, end);
+ if (result != null) return result;
+ return _nativeParse(str, start, end);
+ }
+
+ @patch
+ static double parse(String source,
+ [@deprecated double onError(String source)]) {
+ var result = _parse(source);
+ if (result == null) {
+ if (onError == null) throw new FormatException("Invalid double", source);
+ return onError(source);
+ }
+ return result;
+ }
+
+ @patch
+ static double tryParse(String source) => _parse(source);
+}
diff --git a/sdk_nnbd/lib/_internal/vm/lib/empty_source.dart b/sdk_nnbd/lib/_internal/vm/lib/empty_source.dart
new file mode 100644
index 0000000..1521417
--- /dev/null
+++ b/sdk_nnbd/lib/_internal/vm/lib/empty_source.dart
@@ -0,0 +1,7 @@
+// 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.5
+
+// THIS FILE INTENTIONALLY LEFT BLANK.
diff --git a/sdk_nnbd/lib/_internal/vm/lib/errors_patch.dart b/sdk_nnbd/lib/_internal/vm/lib/errors_patch.dart
new file mode 100644
index 0000000..628419c
--- /dev/null
+++ b/sdk_nnbd/lib/_internal/vm/lib/errors_patch.dart
@@ -0,0 +1,592 @@
+// 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.5
+
+// part of "core_patch.dart";
+
+@patch
+class Error {
+ @patch
+ static String _objectToString(Object object) {
+ return Object._toString(object);
+ }
+
+ @patch
+ static String _stringToSafeString(String string) {
+ return json.encode(string);
+ }
+
+ @patch
+ StackTrace get stackTrace => _stackTrace;
+
+ @pragma("vm:entry-point")
+ StackTrace _stackTrace;
+}
+
+class _AssertionError extends Error implements AssertionError {
+ @pragma("vm:entry-point")
+ _AssertionError._create(
+ this._failedAssertion, this._url, this._line, this._column, this.message);
+
+ // AssertionError_throwNew in errors.cc fishes the assertion source code
+ // out of the script. It expects a Dart stack frame from class
+ // _AssertionError. Thus we need a Dart stub that calls the native code.
+ @pragma("vm:entry-point", "call")
+ static _throwNew(int assertionStart, int assertionEnd, Object message) {
+ _doThrowNew(assertionStart, assertionEnd, message);
+ }
+
+ static _doThrowNew(int assertionStart, int assertionEnd, Object message)
+ native "AssertionError_throwNew";
+
+ @pragma("vm:entry-point", "call")
+ static _evaluateAssertion(condition) {
+ if (identical(condition, true) || identical(condition, false)) {
+ return condition;
+ }
+ if (condition is _Closure) {
+ return (condition as dynamic)();
+ }
+ if (condition is Function) {
+ condition = condition();
+ }
+ return condition;
+ }
+
+ String get _messageString {
+ if (message == null) return "is not true.";
+ if (message is String) return message;
+ return Error.safeToString(message);
+ }
+
+ String toString() {
+ if (_url == null) {
+ if (message == null) return _failedAssertion?.trim();
+ return "'${_failedAssertion?.trim()}': $_messageString";
+ }
+ var columnInfo = "";
+ if (_column > 0) {
+ // Only add column information if it is valid.
+ columnInfo = " pos $_column";
+ }
+ return "'$_url': Failed assertion: line $_line$columnInfo: "
+ "'$_failedAssertion': $_messageString";
+ }
+
+ final String _failedAssertion;
+ final String _url;
+ final int _line;
+ final int _column;
+ final Object message;
+}
+
+class _TypeError extends _AssertionError implements TypeError {
+ @pragma("vm:entry-point")
+ _TypeError._create(String url, int line, int column, String errorMsg)
+ : super._create("is assignable", url, line, column, errorMsg);
+
+ static _throwNew(int location, Object src_value, _Type dst_type,
+ String dst_name) native "TypeError_throwNew";
+
+ String toString() => super.message;
+}
+
+class _CastError extends Error implements CastError {
+ @pragma("vm:entry-point")
+ _CastError._create(this._url, this._line, this._column, this._errorMsg);
+
+ // A CastError is allocated by TypeError._throwNew() when dst_name equals
+ // Symbols::InTypeCast().
+
+ String toString() => _errorMsg;
+
+ // Fields _url, _line, and _column are only used for debugging purposes.
+ final String _url;
+ final int _line;
+ final int _column;
+ final String _errorMsg;
+}
+
+@patch
+class FallThroughError {
+ @patch
+ @pragma("vm:entry-point")
+ FallThroughError._create(String url, int line)
+ : _url = url,
+ _line = line;
+
+ static _throwNew(int case_clause_pos) native "FallThroughError_throwNew";
+
+ @patch
+ String toString() {
+ return "'$_url': Switch case fall-through at line $_line.";
+ }
+
+ // These new fields cannot be declared final, because a constructor exists
+ // in the original version of this patched class.
+ String _url;
+ int _line;
+}
+
+class _InternalError {
+ @pragma("vm:entry-point")
+ const _InternalError(this._msg);
+ String toString() => "InternalError: '${_msg}'";
+ final String _msg;
+}
+
+@patch
+@pragma("vm:entry-point")
+class UnsupportedError {
+ static _throwNew(String msg) {
+ throw new UnsupportedError(msg);
+ }
+}
+
+@patch
+class CyclicInitializationError {
+ static _throwNew(String variableName) {
+ throw new CyclicInitializationError(variableName);
+ }
+}
+
+@patch
+class AbstractClassInstantiationError {
+ @pragma("vm:entry-point")
+ AbstractClassInstantiationError._create(
+ this._className, this._url, this._line);
+
+ static _throwNew(int case_clause_pos, String className)
+ native "AbstractClassInstantiationError_throwNew";
+
+ @patch
+ String toString() {
+ return "Cannot instantiate abstract class $_className: "
+ "_url '$_url' line $_line";
+ }
+
+ // These new fields cannot be declared final, because a constructor exists
+ // in the original version of this patched class.
+ String _url;
+ int _line;
+}
+
+@patch
+class NoSuchMethodError {
+ // Deprecated members to be removed.
+ Symbol _memberName;
+ List _arguments;
+ Map<Symbol, dynamic> _namedArguments;
+ List _existingArgumentNames;
+
+ final Object _receiver;
+ final _InvocationMirror _invocation;
+
+ @patch
+ NoSuchMethodError.withInvocation(Object receiver, Invocation invocation)
+ : _receiver = receiver,
+ _invocation = invocation as _InvocationMirror;
+
+ static void _throwNewInvocation(Object receiver, Invocation invocation) {
+ throw new NoSuchMethodError.withInvocation(receiver, invocation);
+ }
+
+ // The compiler emits a call to _throwNew when it cannot resolve a static
+ // method at compile time. The receiver is actually the literal class of the
+ // unresolved method.
+ @pragma("vm:entry-point", "call")
+ static void _throwNew(Object receiver, String memberName, int invocation_type,
+ Object typeArguments, List arguments, List argumentNames) {
+ throw new NoSuchMethodError._withType(receiver, memberName, invocation_type,
+ typeArguments, arguments, argumentNames);
+ }
+
+ static void _throwNewIfNotLoaded(
+ _LibraryPrefix prefix,
+ Object receiver,
+ String memberName,
+ int invocation_type,
+ Object typeArguments,
+ List arguments,
+ List argumentNames) {
+ if (!prefix.isLoaded()) {
+ _throwNew(receiver, memberName, invocation_type, typeArguments, arguments,
+ argumentNames);
+ }
+ }
+
+ // TODO(regis): Deprecated member still used by dart2js to be removed.
+ // Remember the type from the invocation mirror or static compilation
+ // analysis when thrown directly with _throwNew. A negative value means
+ // that no information is available.
+ int _invocation_type;
+
+ // TODO(regis): Deprecated constructor still used by dart2js to be removed.
+ @patch
+ NoSuchMethodError(Object receiver, Symbol memberName,
+ List positionalArguments, Map<Symbol, dynamic> namedArguments,
+ [List existingArgumentNames = null])
+ : _receiver = receiver,
+ _invocation = null,
+ _memberName = memberName,
+ _arguments = positionalArguments,
+ _namedArguments = namedArguments,
+ _existingArgumentNames = existingArgumentNames,
+ _invocation_type = -1;
+
+ // Helper to build a map of named arguments.
+ static Map<Symbol, dynamic> _NamedArgumentsMap(
+ List arguments, List argumentNames) {
+ Map<Symbol, dynamic> namedArguments = new Map<Symbol, dynamic>();
+ int numPositionalArguments = arguments.length - argumentNames.length;
+ for (int i = 0; i < argumentNames.length; i++) {
+ var arg_value = arguments[numPositionalArguments + i];
+ namedArguments[new Symbol(argumentNames[i])] = arg_value;
+ }
+ return namedArguments;
+ }
+
+ // Constructor called from Exceptions::ThrowByType(kNoSuchMethod) and from
+ // _throwNew above, taking a TypeArguments object rather than an unpacked list
+ // of types, as well as a list of all arguments and a list of names, rather
+ // than a separate list of positional arguments and a map of named arguments.
+ @pragma("vm:entry-point")
+ NoSuchMethodError._withType(
+ this._receiver,
+ String memberName,
+ int invocation_type,
+ Object typeArguments,
+ List arguments,
+ List argumentNames)
+ : this._invocation = new _InvocationMirror._withType(
+ new Symbol(memberName),
+ invocation_type,
+ typeArguments != null
+ // TODO(33073): Use actual count of type arguments in place of 0.
+ ? _InvocationMirror._unpackTypeArguments(typeArguments, 0)
+ : null,
+ argumentNames != null
+ ? arguments.sublist(0, arguments.length - argumentNames.length)
+ : arguments,
+ argumentNames != null
+ ? _NamedArgumentsMap(arguments, argumentNames)
+ : null);
+
+ static String _existingMethodSignature(Object receiver, String methodName,
+ int invocationType) native "NoSuchMethodError_existingMethodSignature";
+
+ @patch
+ String toString() {
+ // TODO(regis): Remove this null check once dart2js is updated.
+ if (_invocation == null) {
+ // Use deprecated version of toString.
+ return _toStringDeprecated();
+ }
+ String memberName =
+ internal.Symbol.computeUnmangledName(_invocation.memberName);
+ var level = (_invocation._type >> _InvocationMirror._LEVEL_SHIFT) &
+ _InvocationMirror._LEVEL_MASK;
+ var kind = _invocation._type & _InvocationMirror._KIND_MASK;
+ if (kind == _InvocationMirror._LOCAL_VAR) {
+ return "NoSuchMethodError: Cannot assign to final variable '$memberName'";
+ }
+
+ StringBuffer typeArgumentsBuf = null;
+ var typeArguments = _invocation.typeArguments;
+ if ((typeArguments != null) && (typeArguments.length > 0)) {
+ typeArgumentsBuf = new StringBuffer();
+ typeArgumentsBuf.write("<");
+ for (int i = 0; i < typeArguments.length; i++) {
+ if (i > 0) {
+ typeArgumentsBuf.write(", ");
+ }
+ typeArgumentsBuf.write(Error.safeToString(typeArguments[i]));
+ }
+ typeArgumentsBuf.write(">");
+ }
+ StringBuffer argumentsBuf = new StringBuffer();
+ var positionalArguments = _invocation.positionalArguments;
+ int argumentCount = 0;
+ if (positionalArguments != null) {
+ for (; argumentCount < positionalArguments.length; argumentCount++) {
+ if (argumentCount > 0) {
+ argumentsBuf.write(", ");
+ }
+ argumentsBuf
+ .write(Error.safeToString(positionalArguments[argumentCount]));
+ }
+ }
+ var namedArguments = _invocation.namedArguments;
+ if (namedArguments != null) {
+ namedArguments.forEach((Symbol key, var value) {
+ if (argumentCount > 0) {
+ argumentsBuf.write(", ");
+ }
+ argumentsBuf.write(internal.Symbol.computeUnmangledName(key));
+ argumentsBuf.write(": ");
+ argumentsBuf.write(Error.safeToString(value));
+ argumentCount++;
+ });
+ }
+ String existingSig =
+ _existingMethodSignature(_receiver, memberName, _invocation._type);
+ String argsMsg = existingSig != null ? " with matching arguments" : "";
+
+ String kindBuf;
+ if (kind >= 0 && kind < 5) {
+ kindBuf = (const [
+ "method",
+ "getter",
+ "setter",
+ "getter or setter",
+ "variable"
+ ])[kind];
+ }
+
+ StringBuffer msgBuf = new StringBuffer("NoSuchMethodError: ");
+ bool is_type_call = false;
+ switch (level) {
+ case _InvocationMirror._DYNAMIC:
+ {
+ if (_receiver == null) {
+ if (existingSig != null) {
+ msgBuf.writeln("The null object does not have a $kindBuf "
+ "'$memberName'$argsMsg.");
+ } else {
+ msgBuf.writeln("The $kindBuf '$memberName' was called on null.");
+ }
+ } else {
+ if (_receiver is _Closure) {
+ msgBuf.writeln("Closure call with mismatched arguments: "
+ "function '$memberName'");
+ } else if (_receiver is _Type && memberName == "call") {
+ is_type_call = true;
+ String name = _receiver.toString();
+ msgBuf.writeln("Attempted to use type '$name' as a function. "
+ "Since types do not define a method 'call', this is not "
+ "possible. Did you intend to call the $name constructor and "
+ "forget the 'new' operator?");
+ } else {
+ msgBuf.writeln("Class '${_receiver.runtimeType}' has no instance "
+ "$kindBuf '$memberName'$argsMsg.");
+ }
+ }
+ break;
+ }
+ case _InvocationMirror._SUPER:
+ {
+ msgBuf.writeln("Super class of class '${_receiver.runtimeType}' has "
+ "no instance $kindBuf '$memberName'$argsMsg.");
+ memberName = "super.$memberName";
+ break;
+ }
+ case _InvocationMirror._STATIC:
+ {
+ msgBuf.writeln("No static $kindBuf '$memberName'$argsMsg "
+ "declared in class '$_receiver'.");
+ break;
+ }
+ case _InvocationMirror._CONSTRUCTOR:
+ {
+ msgBuf.writeln("No constructor '$memberName'$argsMsg declared "
+ "in class '$_receiver'.");
+ memberName = "new $memberName";
+ break;
+ }
+ case _InvocationMirror._TOP_LEVEL:
+ {
+ msgBuf.writeln("No top-level $kindBuf '$memberName'$argsMsg "
+ "declared.");
+ break;
+ }
+ }
+
+ if (level == _InvocationMirror._TOP_LEVEL) {
+ msgBuf.writeln("Receiver: top-level");
+ } else {
+ msgBuf.writeln("Receiver: ${Error.safeToString(_receiver)}");
+ }
+
+ if (kind == _InvocationMirror._METHOD) {
+ String m = is_type_call ? "$_receiver" : "$memberName";
+ msgBuf.write("Tried calling: $m");
+ if (typeArgumentsBuf != null) {
+ msgBuf.write(typeArgumentsBuf);
+ }
+ msgBuf.write("($argumentsBuf)");
+ } else if (argumentCount == 0) {
+ msgBuf.write("Tried calling: $memberName");
+ } else if (kind == _InvocationMirror._SETTER) {
+ msgBuf.write("Tried calling: $memberName$argumentsBuf");
+ } else {
+ msgBuf.write("Tried calling: $memberName = $argumentsBuf");
+ }
+
+ if (existingSig != null) {
+ msgBuf.write("\nFound: $memberName$existingSig");
+ }
+
+ return msgBuf.toString();
+ }
+
+ // TODO(regis): Remove this function once dart2js is updated.
+ String _toStringDeprecated() {
+ var level = (_invocation_type >> _InvocationMirror._LEVEL_SHIFT) &
+ _InvocationMirror._LEVEL_MASK;
+ var type = _invocation_type & _InvocationMirror._KIND_MASK;
+ String memberName = (_memberName == null)
+ ? ""
+ : internal.Symbol.computeUnmangledName(_memberName);
+
+ if (type == _InvocationMirror._LOCAL_VAR) {
+ return "NoSuchMethodError: Cannot assign to final variable '$memberName'";
+ }
+
+ StringBuffer arguments = new StringBuffer();
+ int argumentCount = 0;
+ if (_arguments != null) {
+ for (; argumentCount < _arguments.length; argumentCount++) {
+ if (argumentCount > 0) {
+ arguments.write(", ");
+ }
+ arguments.write(Error.safeToString(_arguments[argumentCount]));
+ }
+ }
+ if (_namedArguments != null) {
+ _namedArguments.forEach((Symbol key, var value) {
+ if (argumentCount > 0) {
+ arguments.write(", ");
+ }
+ arguments.write(internal.Symbol.computeUnmangledName(key));
+ arguments.write(": ");
+ arguments.write(Error.safeToString(value));
+ argumentCount++;
+ });
+ }
+ bool args_mismatch = _existingArgumentNames != null;
+ String args_message = args_mismatch ? " with matching arguments" : "";
+
+ String type_str;
+ if (type >= 0 && type < 5) {
+ type_str = (const [
+ "method",
+ "getter",
+ "setter",
+ "getter or setter",
+ "variable"
+ ])[type];
+ }
+
+ StringBuffer msg_buf = new StringBuffer("NoSuchMethodError: ");
+ bool is_type_call = false;
+ switch (level) {
+ case _InvocationMirror._DYNAMIC:
+ {
+ if (_receiver == null) {
+ if (args_mismatch) {
+ msg_buf.writeln("The null object does not have a $type_str "
+ "'$memberName'$args_message.");
+ } else {
+ msg_buf
+ .writeln("The $type_str '$memberName' was called on null.");
+ }
+ } else {
+ if (_receiver is _Closure) {
+ msg_buf.writeln("Closure call with mismatched arguments: "
+ "function '$memberName'");
+ } else if (_receiver is _Type && memberName == "call") {
+ is_type_call = true;
+ String name = _receiver.toString();
+ msg_buf.writeln("Attempted to use type '$name' as a function. "
+ "Since types do not define a method 'call', this is not "
+ "possible. Did you intend to call the $name constructor and "
+ "forget the 'new' operator?");
+ } else {
+ msg_buf
+ .writeln("Class '${_receiver.runtimeType}' has no instance "
+ "$type_str '$memberName'$args_message.");
+ }
+ }
+ break;
+ }
+ case _InvocationMirror._SUPER:
+ {
+ msg_buf.writeln("Super class of class '${_receiver.runtimeType}' has "
+ "no instance $type_str '$memberName'$args_message.");
+ memberName = "super.$memberName";
+ break;
+ }
+ case _InvocationMirror._STATIC:
+ {
+ msg_buf.writeln("No static $type_str '$memberName'$args_message "
+ "declared in class '$_receiver'.");
+ break;
+ }
+ case _InvocationMirror._CONSTRUCTOR:
+ {
+ msg_buf.writeln("No constructor '$memberName'$args_message declared "
+ "in class '$_receiver'.");
+ memberName = "new $memberName";
+ break;
+ }
+ case _InvocationMirror._TOP_LEVEL:
+ {
+ msg_buf.writeln("No top-level $type_str '$memberName'$args_message "
+ "declared.");
+ break;
+ }
+ }
+
+ if (level == _InvocationMirror._TOP_LEVEL) {
+ msg_buf.writeln("Receiver: top-level");
+ } else {
+ msg_buf.writeln("Receiver: ${Error.safeToString(_receiver)}");
+ }
+
+ if (type == _InvocationMirror._METHOD) {
+ String m = is_type_call ? "$_receiver" : "$memberName";
+ msg_buf.write("Tried calling: $m($arguments)");
+ } else if (argumentCount == 0) {
+ msg_buf.write("Tried calling: $memberName");
+ } else if (type == _InvocationMirror._SETTER) {
+ msg_buf.write("Tried calling: $memberName$arguments");
+ } else {
+ msg_buf.write("Tried calling: $memberName = $arguments");
+ }
+
+ if (args_mismatch) {
+ StringBuffer formalParameters = new StringBuffer();
+ for (int i = 0; i < _existingArgumentNames.length; i++) {
+ if (i > 0) {
+ formalParameters.write(", ");
+ }
+ formalParameters.write(_existingArgumentNames[i]);
+ }
+ msg_buf.write("\nFound: $memberName($formalParameters)");
+ }
+
+ return msg_buf.toString();
+ }
+}
+
+@pragma("vm:entry-point")
+class _CompileTimeError extends Error {
+ final String _errorMsg;
+ _CompileTimeError(this._errorMsg);
+ String toString() => _errorMsg;
+}
+
+/// Used by Fasta to report a runtime error when a final field with an
+/// initializer is also initialized in a generative constructor.
+///
+/// Note: in strong mode, this is a compile-time error and this class becomes
+/// obsolete.
+class _DuplicatedFieldInitializerError extends Error {
+ final String _name;
+
+ _DuplicatedFieldInitializerError(this._name);
+
+ toString() => "Error: field '$_name' is already initialized.";
+}
diff --git a/sdk_nnbd/lib/_internal/vm/lib/expando_patch.dart b/sdk_nnbd/lib/_internal/vm/lib/expando_patch.dart
new file mode 100644
index 0000000..3601908
--- /dev/null
+++ b/sdk_nnbd/lib/_internal/vm/lib/expando_patch.dart
@@ -0,0 +1,153 @@
+// 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.5
+
+// part of "core_patch.dart";
+
+@patch
+class Expando<T> {
+ @patch
+ Expando([String name])
+ : name = name,
+ _data = new List(_minSize),
+ _used = 0;
+
+ static const _minSize = 8;
+ static final _deletedEntry = new _WeakProperty(null, null);
+
+ @patch
+ T operator [](Object object) {
+ _checkType(object);
+
+ var mask = _size - 1;
+ var idx = object._identityHashCode & mask;
+ var wp = _data[idx];
+
+ while (wp != null) {
+ if (identical(wp.key, object)) {
+ return wp.value;
+ } else if (wp.key == null) {
+ // This entry has been cleared by the GC.
+ _data[idx] = _deletedEntry;
+ }
+ idx = (idx + 1) & mask;
+ wp = _data[idx];
+ }
+
+ return null;
+ }
+
+ @patch
+ void operator []=(Object object, T value) {
+ _checkType(object);
+
+ var mask = _size - 1;
+ var idx = object._identityHashCode & mask;
+ var empty_idx = -1;
+ var wp = _data[idx];
+
+ while (wp != null) {
+ if (identical(wp.key, object)) {
+ if (value != null) {
+ // Update the associated value.
+ wp.value = value;
+ } else {
+ // Mark the entry as deleted.
+ _data[idx] = _deletedEntry;
+ }
+ return;
+ } else if ((empty_idx < 0) && identical(wp, _deletedEntry)) {
+ empty_idx = idx; // Insert at this location if not found.
+ } else if (wp.key == null) {
+ // This entry has been cleared by the GC.
+ _data[idx] = _deletedEntry;
+ if (empty_idx < 0) {
+ empty_idx = idx; // Insert at this location if not found.
+ }
+ }
+ idx = (idx + 1) & mask;
+ wp = _data[idx];
+ }
+
+ if (value == null) {
+ // Not entering a null value. We just needed to make sure to clear an
+ // existing value if it existed.
+ return;
+ }
+
+ if (empty_idx >= 0) {
+ // We will be reusing the empty slot below.
+ _used--;
+ idx = empty_idx;
+ }
+
+ if (_used < _limit) {
+ _data[idx] = new _WeakProperty(object, value);
+ _used++;
+ return;
+ }
+
+ // Grow/reallocate if too many slots have been used.
+ _rehash();
+ this[object] = value; // Recursively add the value.
+ }
+
+ _rehash() {
+ // Determine the population count of the map to allocate an appropriately
+ // sized map below.
+ var count = 0;
+ var old_data = _data;
+ var len = old_data.length;
+ for (var i = 0; i < len; i++) {
+ var entry = old_data[i];
+ if ((entry != null) && (entry.key != null)) {
+ // Only count non-cleared entries.
+ count++;
+ }
+ }
+
+ var new_size = _size;
+ if (count <= (new_size >> 2)) {
+ new_size = new_size >> 1;
+ } else if (count > (new_size >> 1)) {
+ new_size = new_size << 1;
+ }
+ new_size = (new_size < _minSize) ? _minSize : new_size;
+
+ // Reset the mappings to empty so that we can just add the existing
+ // valid entries.
+ _data = new List(new_size);
+ _used = 0;
+
+ for (var i = 0; i < old_data.length; i++) {
+ var entry = old_data[i];
+ if (entry != null) {
+ // Ensure that the entry.key is not cleared between checking for it and
+ // inserting it into the new table.
+ var val = entry.value;
+ var key = entry.key;
+ if (key != null) {
+ this[key] = val;
+ }
+ }
+ }
+ }
+
+ static _checkType(object) {
+ if ((object == null) ||
+ (object is bool) ||
+ (object is num) ||
+ (object is String)) {
+ throw new ArgumentError.value(object,
+ "Expandos are not allowed on strings, numbers, booleans or null");
+ }
+ }
+
+ get _size => _data.length;
+ get _limit => (3 * (_size ~/ 4));
+
+ List _data;
+ int _used; // Number of used (active and deleted) slots.
+}
diff --git a/sdk_nnbd/lib/_internal/vm/lib/ffi_dynamic_library_patch.dart b/sdk_nnbd/lib/_internal/vm/lib/ffi_dynamic_library_patch.dart
new file mode 100644
index 0000000..581582f
--- /dev/null
+++ b/sdk_nnbd/lib/_internal/vm/lib/ffi_dynamic_library_patch.dart
@@ -0,0 +1,60 @@
+// Copyright (c) 2019, 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.5
+
+// All imports must be in all FFI patch files to not depend on the order
+// the patches are applied.
+import "dart:_internal" show patch;
+import 'dart:typed_data' show TypedData;
+
+DynamicLibrary _open(String name) native "Ffi_dl_open";
+DynamicLibrary _processLibrary() native "Ffi_dl_processLibrary";
+DynamicLibrary _executableLibrary() native "Ffi_dl_executableLibrary";
+
+@patch
+@pragma("vm:entry-point")
+class DynamicLibrary {
+ @patch
+ factory DynamicLibrary.open(String name) {
+ return _open(name);
+ }
+
+ @patch
+ factory DynamicLibrary.process() => _processLibrary();
+
+ @patch
+ factory DynamicLibrary.executable() => _executableLibrary();
+
+ @patch
+ Pointer<T> lookup<T extends NativeType>(String symbolName)
+ native "Ffi_dl_lookup";
+
+ // The real implementation of this function lives in FfiUseSiteTransformer
+ // for interface calls. Only dynamic calls (which are illegal) reach this
+ // implementation.
+ @patch
+ F lookupFunction<T extends Function, F extends Function>(String symbolName) {
+ throw UnsupportedError(
+ "Dynamic invocation of lookupFunction is not supported.");
+ }
+
+ // TODO(dacoharkes): Expose this to users, or extend Pointer?
+ // https://github.com/dart-lang/sdk/issues/35881
+ int getHandle() native "Ffi_dl_getHandle";
+
+ @patch
+ bool operator ==(other) {
+ if (other == null) return false;
+ return getHandle() == other.getHandle();
+ }
+
+ @patch
+ int get hashCode {
+ return getHandle().hashCode;
+ }
+
+ @patch
+ Pointer<Void> get handle => Pointer.fromAddress(getHandle());
+}
diff --git a/sdk_nnbd/lib/_internal/vm/lib/ffi_native_type_patch.dart b/sdk_nnbd/lib/_internal/vm/lib/ffi_native_type_patch.dart
new file mode 100644
index 0000000..876184d
--- /dev/null
+++ b/sdk_nnbd/lib/_internal/vm/lib/ffi_native_type_patch.dart
@@ -0,0 +1,77 @@
+// Copyright (c) 2019, 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.5
+
+// All imports must be in all FFI patch files to not depend on the order
+// the patches are applied.
+import "dart:_internal" show patch;
+import 'dart:typed_data' show TypedData;
+
+// NativeType is not private, because it is used in type arguments.
+// NativeType is abstract because it not used with const constructors in
+// annotations directly, so it should never be instantiated at runtime.
+@patch
+@pragma("vm:entry-point")
+abstract class NativeType {}
+
+@patch
+@pragma("vm:entry-point")
+class _NativeInteger extends NativeType {}
+
+@patch
+@pragma("vm:entry-point")
+class _NativeDouble extends NativeType {}
+
+@patch
+@pragma("vm:entry-point")
+class Int8 extends _NativeInteger {}
+
+@patch
+@pragma("vm:entry-point")
+class Int16 extends _NativeInteger {}
+
+@patch
+@pragma("vm:entry-point")
+class Int32 extends _NativeInteger {}
+
+@patch
+@pragma("vm:entry-point")
+class Int64 extends _NativeInteger {}
+
+@patch
+@pragma("vm:entry-point")
+class Uint8 extends _NativeInteger {}
+
+@patch
+@pragma("vm:entry-point")
+class Uint16 extends _NativeInteger {}
+
+@patch
+@pragma("vm:entry-point")
+class Uint32 extends _NativeInteger {}
+
+@patch
+@pragma("vm:entry-point")
+class Uint64 extends _NativeInteger {}
+
+@patch
+@pragma("vm:entry-point")
+class IntPtr extends _NativeInteger {}
+
+@patch
+@pragma("vm:entry-point")
+class Float extends _NativeDouble {}
+
+@patch
+@pragma("vm:entry-point")
+class Double extends _NativeDouble {}
+
+@patch
+@pragma("vm:entry-point")
+abstract class Void extends NativeType {}
+
+@patch
+@pragma("vm:entry-point")
+abstract class NativeFunction<T extends Function> extends NativeType {}
diff --git a/sdk_nnbd/lib/_internal/vm/lib/ffi_patch.dart b/sdk_nnbd/lib/_internal/vm/lib/ffi_patch.dart
new file mode 100644
index 0000000..25c3f41
--- /dev/null
+++ b/sdk_nnbd/lib/_internal/vm/lib/ffi_patch.dart
@@ -0,0 +1,88 @@
+// Copyright (c) 2019, 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.5
+
+// All imports must be in all FFI patch files to not depend on the order
+// the patches are applied.
+import "dart:_internal" show patch;
+import 'dart:typed_data' show TypedData;
+
+@patch
+int sizeOf<T extends NativeType>() native "Ffi_sizeOf";
+
+Pointer<T> _allocate<T extends NativeType>(int count) native "Ffi_allocate";
+
+Pointer<T> _fromAddress<T extends NativeType>(int ptr) native "Ffi_fromAddress";
+
+// The real implementation of this function (for interface calls) lives in
+// BuildFfiAsFunctionCall in the Kernel frontend. No calls can actually reach
+// this function.
+DS _asFunctionInternal<DS extends Function, NS extends Function>(
+ Pointer<NativeFunction<NS>> ptr) native "Ffi_asFunctionInternal";
+
+dynamic _asExternalTypedData(Pointer ptr, int count)
+ native "Ffi_asExternalTypedData";
+
+@patch
+@pragma("vm:entry-point")
+class Pointer<T extends NativeType> {
+ @patch
+ factory Pointer.allocate({int count: 1}) => _allocate<T>(count);
+
+ @patch
+ factory Pointer.fromAddress(int ptr) => _fromAddress(ptr);
+
+ @patch
+ static Pointer<NativeFunction<T>> fromFunction<T extends Function>(
+ @DartRepresentationOf("T") Function f,
+ Object exceptionalReturn) native "Ffi_fromFunction";
+
+ // TODO(sjindel): When NNBD is available, we should change `value` to be
+ // non-null.
+ @patch
+ void store(Object value) native "Ffi_store";
+
+ @patch
+ R load<R>() native "Ffi_load";
+
+ @patch
+ int get address native "Ffi_address";
+
+ // Note this could also be implmented without an extra native as offsetBy
+ // (elementSize()*index). This would be 2 native calls rather than one. What
+ // would be better?
+ @patch
+ Pointer<T> elementAt(int index) native "Ffi_elementAt";
+
+ // Note this could also be implmented without an extra native as
+ // fromAddress(address). This would be 2 native calls rather than one.
+ // What would be better?
+ @patch
+ Pointer<T> offsetBy(int offsetInBytes) native "Ffi_offsetBy";
+
+ // Note this could also be implemented without an extra native as
+ // fromAddress(address). This would be 2 native calls rather than one.
+ // What would be better?
+ @patch
+ Pointer<U> cast<U extends NativeType>() native "Ffi_cast";
+
+ @patch
+ R asFunction<R extends Function>() {
+ throw UnsupportedError("Pointer.asFunction cannot be called dynamically.");
+ }
+
+ @patch
+ void free() native "Ffi_free";
+
+ @patch
+ TypedData asExternalTypedData({int count: 1}) =>
+ _asExternalTypedData(this, count);
+}
+
+// Returns the ABI used for size and alignment calculations.
+// See pkg/vm/lib/transformations/ffi.dart.
+@pragma('vm:prefer-inline')
+int _abi()
+ native "Recognized method: method is directly interpreted by the bytecode interpreter or IR graph is built in the flow graph builder.";
diff --git a/sdk_nnbd/lib/_internal/vm/lib/function.dart b/sdk_nnbd/lib/_internal/vm/lib/function.dart
new file mode 100644
index 0000000..b055327
--- /dev/null
+++ b/sdk_nnbd/lib/_internal/vm/lib/function.dart
@@ -0,0 +1,56 @@
+// 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
+// BSD-style license that can be found in the LICENSE file.
+
+// @dart = 2.5
+
+// part of "core_patch.dart";
+
+@pragma("vm:entry-point")
+class _Closure implements Function {
+ factory _Closure._uninstantiable() {
+ throw "Unreachable";
+ }
+
+ bool operator ==(Object other) native "Closure_equals";
+
+ int get hashCode {
+ _hash ??= _computeHash();
+ return _hash;
+ }
+
+ _Closure get call => this;
+
+ _Closure _clone() native "Closure_clone";
+
+ int _computeHash() native "Closure_computeHash";
+
+ // No instance fields should be declared before the following fields whose
+ // offsets must be identical in Dart and C++.
+
+ // The following fields are declared both in raw_object.h (for direct access
+ // from C++ code) and also here so that the offset-to-field map used by
+ // deferred objects is properly initialized.
+ // Caution: These fields are not Dart instances, but VM objects. Their Dart
+ // names do not need to match the C++ names, but they must be private.
+ @pragma("vm:entry-point")
+ var _instantiator_type_arguments;
+ @pragma("vm:entry-point")
+ var _function_type_arguments;
+ @pragma("vm:entry-point")
+ var _delayed_type_arguments;
+ @pragma("vm:entry-point")
+ var _function;
+ @pragma("vm:entry-point")
+ var _context;
+
+ // Note: _Closure objects are created by VM "magically", without invoking
+ // constructor. So, _Closure default constructor is never compiled and
+ // detection of default-initialized fields is not performed.
+ // As a consequence, VM incorrectly assumes that _hash field is not
+ // nullable and may incorrectly remove 'if (_hash == null)' in get:hashCode.
+ // This initializer makes _hash field nullable even without constructor
+ // compilation.
+ @pragma("vm:entry-point")
+ var _hash = null;
+}
diff --git a/sdk_nnbd/lib/_internal/vm/lib/function_patch.dart b/sdk_nnbd/lib/_internal/vm/lib/function_patch.dart
new file mode 100644
index 0000000..f5f73bd
--- /dev/null
+++ b/sdk_nnbd/lib/_internal/vm/lib/function_patch.dart
@@ -0,0 +1,35 @@
+// 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.5
+
+// part of "core_patch.dart";
+
+@patch
+class Function {
+ // TODO(regis): Pass type arguments to generic functions. Wait for API spec.
+ static _apply(List arguments, List names) native "Function_apply";
+
+ @patch
+ static apply(Function function, List positionalArguments,
+ [Map<Symbol, dynamic> namedArguments]) {
+ int numPositionalArguments = 1 + // Function is first implicit argument.
+ (positionalArguments != null ? positionalArguments.length : 0);
+ int numNamedArguments = namedArguments != null ? namedArguments.length : 0;
+ int numArguments = numPositionalArguments + numNamedArguments;
+ List arguments = new List(numArguments);
+ arguments[0] = function;
+ arguments.setRange(1, numPositionalArguments, positionalArguments);
+ List names = new List(numNamedArguments);
+ int argumentIndex = numPositionalArguments;
+ int nameIndex = 0;
+ if (numNamedArguments > 0) {
+ namedArguments.forEach((name, value) {
+ arguments[argumentIndex++] = value;
+ names[nameIndex++] = internal.Symbol.getName(name);
+ });
+ }
+ return _apply(arguments, names);
+ }
+}
diff --git a/sdk_nnbd/lib/_internal/vm/lib/growable_array.dart b/sdk_nnbd/lib/_internal/vm/lib/growable_array.dart
new file mode 100644
index 0000000..851225b
--- /dev/null
+++ b/sdk_nnbd/lib/_internal/vm/lib/growable_array.dart
@@ -0,0 +1,396 @@
+// 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.5
+
+// part of "core_patch.dart";
+
+@pragma("vm:entry-point")
+class _GrowableList<T> extends ListBase<T> {
+ void insert(int index, T element) {
+ if ((index < 0) || (index > length)) {
+ throw new RangeError.range(index, 0, length);
+ }
+ if (index == this.length) {
+ add(element);
+ return;
+ }
+ int oldLength = this.length;
+ // We are modifying the length just below the is-check. Without the check
+ // Array.copy could throw an exception, leaving the list in a bad state
+ // (with a length that has been increased, but without a new element).
+ if (index is! int) throw new ArgumentError(index);
+ this.length++;
+ Lists.copy(this, index, this, index + 1, oldLength - index);
+ this[index] = element;
+ }
+
+ T removeAt(int index) {
+ var result = this[index];
+ int newLength = this.length - 1;
+ if (index < newLength) {
+ Lists.copy(this, index + 1, this, index, newLength - index);
+ }
+ this.length = newLength;
+ return result;
+ }
+
+ bool remove(Object element) {
+ for (int i = 0; i < this.length; i++) {
+ if (this[i] == element) {
+ removeAt(i);
+ return true;
+ }
+ }
+ return false;
+ }
+
+ void insertAll(int index, Iterable<T> iterable) {
+ if (index < 0 || index > length) {
+ throw new RangeError.range(index, 0, length);
+ }
+ // TODO(floitsch): we can probably detect more cases.
+ if (iterable is! List && iterable is! Set && iterable is! SubListIterable) {
+ iterable = iterable.toList();
+ }
+ int insertionLength = iterable.length;
+ // There might be errors after the length change, in which case the list
+ // will end up being modified but the operation not complete. Unless we
+ // always go through a "toList" we can't really avoid that.
+ this.length += insertionLength;
+ setRange(index + insertionLength, this.length, this, index);
+ setAll(index, iterable);
+ }
+
+ void setAll(int index, Iterable<T> iterable) {
+ if (iterable is List) {
+ setRange(index, index + iterable.length, iterable);
+ } else {
+ for (T element in iterable) {
+ this[index++] = element;
+ }
+ }
+ }
+
+ void removeRange(int start, int end) {
+ RangeError.checkValidRange(start, end, this.length);
+ Lists.copy(this, end, this, start, this.length - end);
+ this.length = this.length - (end - start);
+ }
+
+ List<T> sublist(int start, [int end]) {
+ end = RangeError.checkValidRange(start, end, this.length);
+ int length = end - start;
+ if (length == 0) return <T>[];
+ List list = new _List(length);
+ for (int i = 0; i < length; i++) {
+ list[i] = this[start + i];
+ }
+ var result = new _GrowableList<T>._withData(list);
+ result._setLength(length);
+ return result;
+ }
+
+ factory _GrowableList(int length) {
+ var data = _allocateData(length);
+ var result = new _GrowableList<T>._withData(data);
+ if (length > 0) {
+ result._setLength(length);
+ }
+ return result;
+ }
+
+ factory _GrowableList.withCapacity(int capacity) {
+ var data = _allocateData(capacity);
+ return new _GrowableList<T>._withData(data);
+ }
+
+ @pragma("vm:exact-result-type", _GrowableList)
+ factory _GrowableList._withData(_List data) native "GrowableList_allocate";
+
+ @pragma("vm:exact-result-type", "dart:core#_Smi")
+ @pragma("vm:prefer-inline")
+ int get _capacity native "GrowableList_getCapacity";
+
+ @pragma("vm:exact-result-type", "dart:core#_Smi")
+ @pragma("vm:prefer-inline")
+ int get length native "GrowableList_getLength";
+
+ void set length(int new_length) {
+ int old_capacity = _capacity;
+ int new_capacity = new_length;
+ if (new_capacity > old_capacity) {
+ _grow(new_capacity);
+ _setLength(new_length);
+ return;
+ }
+ // We are shrinking. Pick the method which has fewer writes.
+ // In the shrink-to-fit path, we write |new_capacity + new_length| words
+ // (null init + copy).
+ // In the non-shrink-to-fit path, we write |length - new_length| words
+ // (null overwrite).
+ final bool shouldShrinkToFit =
+ (new_capacity + new_length) < (length - new_length);
+ if (shouldShrinkToFit) {
+ _shrink(new_capacity, new_length);
+ } else {
+ for (int i = new_length; i < length; i++) {
+ this[i] = null;
+ }
+ }
+ _setLength(new_length);
+ }
+
+ void _setLength(int new_length) native "GrowableList_setLength";
+
+ void _setData(_List array) native "GrowableList_setData";
+
+ T operator [](int index) native "GrowableList_getIndexed";
+
+ void operator []=(int index, T value) {
+ _setIndexed(index, value);
+ }
+
+ void _setIndexed(int index, T value) native "GrowableList_setIndexed";
+
+ @pragma("vm:entry-point", "call")
+ @pragma("vm:prefer-inline")
+ void add(T value) {
+ var len = length;
+ if (len == _capacity) {
+ _grow(_nextCapacity(len));
+ }
+ _setLength(len + 1);
+ this[len] = value;
+ }
+
+ void addAll(Iterable<T> iterable) {
+ var len = length;
+ final cid = ClassID.getID(iterable);
+ final isVMList = (cid == ClassID.cidArray) ||
+ (cid == ClassID.cidGrowableObjectArray) ||
+ (cid == ClassID.cidImmutableArray);
+ if (isVMList || (iterable is EfficientLengthIterable)) {
+ var cap = _capacity;
+ // Pregrow if we know iterable.length.
+ var iterLen = iterable.length;
+ var newLen = len + iterLen;
+ if (newLen > cap) {
+ do {
+ cap = _nextCapacity(cap);
+ } while (newLen > cap);
+ _grow(cap);
+ }
+ if (isVMList) {
+ if (identical(iterable, this)) {
+ throw new ConcurrentModificationError(this);
+ }
+ this._setLength(newLen);
+ final ListBase<T> iterableAsList = iterable;
+ for (int i = 0; i < iterLen; i++) {
+ this[len++] = iterableAsList[i];
+ }
+ return;
+ }
+ }
+ Iterator it = iterable.iterator;
+ if (!it.moveNext()) return;
+ do {
+ while (len < _capacity) {
+ int newLen = len + 1;
+ this._setLength(newLen);
+ this[len] = it.current;
+ if (!it.moveNext()) return;
+ if (this.length != newLen) throw new ConcurrentModificationError(this);
+ len = newLen;
+ }
+ _grow(_nextCapacity(_capacity));
+ } while (true);
+ }
+
+ @pragma("vm:prefer-inline")
+ T removeLast() {
+ var len = length - 1;
+ var elem = this[len];
+ this.length = len;
+ return elem;
+ }
+
+ T get first {
+ if (length > 0) return this[0];
+ throw IterableElementError.noElement();
+ }
+
+ T get last {
+ if (length > 0) return this[length - 1];
+ throw IterableElementError.noElement();
+ }
+
+ T get single {
+ if (length == 1) return this[0];
+ if (length == 0) throw IterableElementError.noElement();
+ throw IterableElementError.tooMany();
+ }
+
+ // Shared array used as backing for new empty growable arrays.
+ static final _List _emptyList = new _List(0);
+
+ static _List _allocateData(int capacity) {
+ if (capacity == 0) {
+ // Use shared empty list as backing.
+ return _emptyList;
+ }
+ // Round up size to the next odd number, since this is free
+ // because of alignment requirements of the GC.
+ return new _List(capacity | 1);
+ }
+
+ // Grow from 0 to 3, and then double + 1.
+ int _nextCapacity(int old_capacity) => (old_capacity * 2) | 3;
+
+ void _grow(int new_capacity) {
+ var newData = _allocateData(new_capacity);
+ // This is a work-around for dartbug.com/30090: array-bound-check
+ // generalization causes excessive deoptimizations because it
+ // hoists CheckArrayBound(i, ...) out of the loop below and turns it
+ // into CheckArrayBound(length - 1, ...). Which deoptimizes
+ // if length == 0. However the loop itself does not execute
+ // if length == 0.
+ if (length > 0) {
+ for (int i = 0; i < length; i++) {
+ newData[i] = this[i];
+ }
+ }
+ _setData(newData);
+ }
+
+ void _shrink(int new_capacity, int new_length) {
+ var newData = _allocateData(new_capacity);
+ // This is a work-around for dartbug.com/30090. See the comment in _grow.
+ if (new_length > 0) {
+ for (int i = 0; i < new_length; i++) {
+ newData[i] = this[i];
+ }
+ }
+ _setData(newData);
+ }
+
+ // Iterable interface.
+
+ @pragma("vm:prefer-inline")
+ void forEach(f(T element)) {
+ int initialLength = length;
+ for (int i = 0; i < length; i++) {
+ f(this[i]);
+ if (length != initialLength) throw new ConcurrentModificationError(this);
+ }
+ }
+
+ String join([String separator = ""]) {
+ final int length = this.length;
+ if (length == 0) return "";
+ if (length == 1) return "${this[0]}";
+ if (separator.isNotEmpty) return _joinWithSeparator(separator);
+ var i = 0;
+ var codeUnitCount = 0;
+ while (i < length) {
+ final element = this[i];
+ // While list contains one-byte strings.
+ if (element is _OneByteString) {
+ codeUnitCount += element.length;
+ i++;
+ // Loop back while strings are one-byte strings.
+ continue;
+ }
+ // Otherwise, never loop back to the outer loop, and
+ // handle the remaining strings below.
+
+ // Loop while elements are strings,
+ final int firstNonOneByteStringLimit = i;
+ var nextElement = element;
+ while (nextElement is String) {
+ i++;
+ if (i == length) {
+ return _StringBase._concatRangeNative(this, 0, length);
+ }
+ nextElement = this[i];
+ }
+
+ // Not all elements are strings, so allocate a new backing array.
+ final list = new _List(length);
+ for (int copyIndex = 0; copyIndex < i; copyIndex++) {
+ list[copyIndex] = this[copyIndex];
+ }
+ // Is non-zero if list contains a non-onebyte string.
+ var onebyteCanary = i - firstNonOneByteStringLimit;
+ while (true) {
+ final String elementString = "$nextElement";
+ onebyteCanary |=
+ (ClassID.getID(elementString) ^ ClassID.cidOneByteString);
+ list[i] = elementString;
+ codeUnitCount += elementString.length;
+ i++;
+ if (i == length) break;
+ nextElement = this[i];
+ }
+ if (onebyteCanary == 0) {
+ // All elements returned a one-byte string from toString.
+ return _OneByteString._concatAll(list, codeUnitCount);
+ }
+ return _StringBase._concatRangeNative(list, 0, length);
+ }
+ // All elements were one-byte strings.
+ return _OneByteString._concatAll(this, codeUnitCount);
+ }
+
+ String _joinWithSeparator(String separator) {
+ StringBuffer buffer = new StringBuffer();
+ buffer.write(this[0]);
+ for (int i = 1; i < this.length; i++) {
+ buffer.write(separator);
+ buffer.write(this[i]);
+ }
+ return buffer.toString();
+ }
+
+ T elementAt(int index) {
+ return this[index];
+ }
+
+ bool get isEmpty {
+ return this.length == 0;
+ }
+
+ bool get isNotEmpty => !isEmpty;
+
+ void clear() {
+ this.length = 0;
+ }
+
+ String toString() => ListBase.listToString(this);
+
+ @pragma("vm:prefer-inline")
+ Iterator<T> get iterator {
+ return new ListIterator<T>(this);
+ }
+
+ List<T> toList({bool growable: true}) {
+ var length = this.length;
+ if (length > 0) {
+ List list = growable ? new _List(length) : new _List<T>(length);
+ for (int i = 0; i < length; i++) {
+ list[i] = this[i];
+ }
+ if (!growable) return list;
+ var result = new _GrowableList<T>._withData(list);
+ result._setLength(length);
+ return result;
+ }
+ return growable ? <T>[] : new List<T>(0);
+ }
+
+ Set<T> toSet() {
+ return new Set<T>.from(this);
+ }
+}
diff --git a/sdk_nnbd/lib/_internal/vm/lib/identical_patch.dart b/sdk_nnbd/lib/_internal/vm/lib/identical_patch.dart
new file mode 100644
index 0000000..68dd8c8
--- /dev/null
+++ b/sdk_nnbd/lib/_internal/vm/lib/identical_patch.dart
@@ -0,0 +1,15 @@
+// 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.5
+
+// part of "core_patch.dart";
+
+@patch
+@pragma("vm:exact-result-type", bool)
+bool identical(Object a, Object b) native "Identical_comparison";
+
+@patch
+@pragma("vm:entry-point", "call")
+int identityHashCode(Object object) => object._identityHashCode;
diff --git a/sdk_nnbd/lib/_internal/vm/lib/immutable_map.dart b/sdk_nnbd/lib/_internal/vm/lib/immutable_map.dart
new file mode 100644
index 0000000..08de90d
--- /dev/null
+++ b/sdk_nnbd/lib/_internal/vm/lib/immutable_map.dart
@@ -0,0 +1,222 @@
+// 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.5
+
+// part of "core_patch.dart";
+
+/// Immutable map class for compiler generated map literals.
+// TODO(lrn): Extend MapBase with UnmodifiableMapMixin when mixins
+// support forwarding const constructors.
+@pragma("vm:entry-point")
+class _ImmutableMap<K, V> implements Map<K, V> {
+ final _ImmutableList _kvPairs;
+
+ @pragma("vm:entry-point")
+ const _ImmutableMap._create(_ImmutableList keyValuePairs)
+ : _kvPairs = keyValuePairs;
+
+ Map<K2, V2> cast<K2, V2>() => Map.castFrom<K, V, K2, V2>(this);
+ V operator [](Object key) {
+ // To preserve the key-value order of the map literal, the keys are
+ // not sorted. Need to do linear search or implement an additional
+ // lookup table.
+ for (int i = 0; i < _kvPairs.length - 1; i += 2) {
+ if (key == _kvPairs[i]) {
+ return _kvPairs[i + 1];
+ }
+ }
+ return null;
+ }
+
+ bool get isEmpty {
+ return _kvPairs.length == 0;
+ }
+
+ bool get isNotEmpty => !isEmpty;
+
+ int get length {
+ return _kvPairs.length ~/ 2;
+ }
+
+ void forEach(void f(K key, V value)) {
+ for (int i = 0; i < _kvPairs.length; i += 2) {
+ f(_kvPairs[i], _kvPairs[i + 1]);
+ }
+ }
+
+ Iterable<K> get keys {
+ return new _ImmutableMapKeyIterable<K>(this);
+ }
+
+ Iterable<V> get values {
+ return new _ImmutableMapValueIterable<V>(this);
+ }
+
+ bool containsKey(Object key) {
+ for (int i = 0; i < _kvPairs.length; i += 2) {
+ if (key == _kvPairs[i]) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ bool containsValue(Object value) {
+ for (int i = 1; i < _kvPairs.length; i += 2) {
+ if (value == _kvPairs[i]) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ void operator []=(K key, V value) {
+ throw new UnsupportedError("Cannot set value in unmodifiable Map");
+ }
+
+ void addAll(Map<K, V> other) {
+ throw new UnsupportedError("Cannot set value in unmodifiable Map");
+ }
+
+ V putIfAbsent(K key, V ifAbsent()) {
+ throw new UnsupportedError("Cannot set value in unmodifiable Map");
+ }
+
+ void clear() {
+ throw new UnsupportedError("Cannot clear unmodifiable Map");
+ }
+
+ V remove(Object key) {
+ throw new UnsupportedError("Cannot remove from unmodifiable Map");
+ }
+
+ Iterable<MapEntry<K, V>> get entries =>
+ new _ImmutableMapEntryIterable<K, V>(this);
+
+ Map<K2, V2> map<K2, V2>(MapEntry<K2, V2> f(K key, V value)) {
+ var result = <K2, V2>{};
+ for (int i = 0; i < _kvPairs.length; i += 2) {
+ var entry = f(_kvPairs[i], _kvPairs[i + 1]);
+ result[entry.key] = entry.value;
+ }
+ return result;
+ }
+
+ void addEntries(Iterable<MapEntry<K, V>> newEntries) {
+ throw new UnsupportedError("Cannot modify an unmodifiable Map");
+ }
+
+ V update(K key, V update(V value), {V ifAbsent()}) {
+ throw new UnsupportedError("Cannot modify an unmodifiable Map");
+ }
+
+ void updateAll(V update(K key, V value)) {
+ throw new UnsupportedError("Cannot modify an unmodifiable Map");
+ }
+
+ void removeWhere(bool predicate(K key, V value)) {
+ throw new UnsupportedError("Cannot modify an unmodifiable Map");
+ }
+
+ String toString() => MapBase.mapToString(this);
+}
+
+class _ImmutableMapKeyIterable<E> extends EfficientLengthIterable<E> {
+ final _ImmutableMap _map;
+ _ImmutableMapKeyIterable(this._map);
+
+ Iterator<E> get iterator {
+ return new _ImmutableMapKeyIterator<E>(_map);
+ }
+
+ int get length => _map.length;
+}
+
+class _ImmutableMapValueIterable<E> extends EfficientLengthIterable<E> {
+ final _ImmutableMap _map;
+ _ImmutableMapValueIterable(this._map);
+
+ Iterator<E> get iterator {
+ return new _ImmutableMapValueIterator<E>(_map);
+ }
+
+ int get length => _map.length;
+}
+
+class _ImmutableMapEntryIterable<K, V>
+ extends EfficientLengthIterable<MapEntry<K, V>> {
+ final _ImmutableMap _map;
+ _ImmutableMapEntryIterable(this._map);
+
+ Iterator<MapEntry<K, V>> get iterator {
+ return new _ImmutableMapEntryIterator<K, V>(_map);
+ }
+
+ int get length => _map.length;
+}
+
+class _ImmutableMapKeyIterator<E> implements Iterator<E> {
+ _ImmutableMap _map;
+ int _nextIndex = 0;
+ E _current;
+
+ _ImmutableMapKeyIterator(this._map);
+
+ bool moveNext() {
+ int newIndex = _nextIndex;
+ if (newIndex < _map.length) {
+ _nextIndex = newIndex + 1;
+ _current = _map._kvPairs[newIndex * 2];
+ return true;
+ }
+ _current = null;
+ return false;
+ }
+
+ E get current => _current;
+}
+
+class _ImmutableMapValueIterator<E> implements Iterator<E> {
+ _ImmutableMap _map;
+ int _nextIndex = 0;
+ E _current;
+
+ _ImmutableMapValueIterator(this._map);
+
+ bool moveNext() {
+ int newIndex = _nextIndex;
+ if (newIndex < _map.length) {
+ _nextIndex = newIndex + 1;
+ _current = _map._kvPairs[newIndex * 2 + 1];
+ return true;
+ }
+ _current = null;
+ return false;
+ }
+
+ E get current => _current;
+}
+
+class _ImmutableMapEntryIterator<K, V> implements Iterator<MapEntry<K, V>> {
+ _ImmutableMap _map;
+ int _nextIndex = 0;
+ MapEntry<K, V> _current;
+
+ _ImmutableMapEntryIterator(this._map);
+
+ bool moveNext() {
+ int newIndex = _nextIndex;
+ if (newIndex < _map.length) {
+ _nextIndex = newIndex + 1;
+ _current = new MapEntry<K, V>(
+ _map._kvPairs[newIndex * 2], _map._kvPairs[newIndex * 2 + 1]);
+ return true;
+ }
+ _current = null;
+ return false;
+ }
+
+ MapEntry<K, V> get current => _current;
+}
diff --git a/sdk_nnbd/lib/_internal/vm/lib/integers.dart b/sdk_nnbd/lib/_internal/vm/lib/integers.dart
new file mode 100644
index 0000000..fb2dd30
--- /dev/null
+++ b/sdk_nnbd/lib/_internal/vm/lib/integers.dart
@@ -0,0 +1,722 @@
+// 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.5
+
+// part of "core_patch.dart";
+
+abstract class _IntegerImplementation implements int {
+ @pragma("vm:non-nullable-result-type")
+ @pragma("vm:never-inline")
+ num operator +(num other) => other._addFromInteger(this);
+ @pragma("vm:non-nullable-result-type")
+ @pragma("vm:never-inline")
+ num operator -(num other) => other._subFromInteger(this);
+ @pragma("vm:non-nullable-result-type")
+ @pragma("vm:never-inline")
+ num operator *(num other) => other._mulFromInteger(this);
+
+ @pragma("vm:non-nullable-result-type")
+ @pragma("vm:never-inline")
+ int operator ~/(num other) {
+ if ((other is int) && (other == 0)) {
+ throw const IntegerDivisionByZeroException();
+ }
+ return other._truncDivFromInteger(this);
+ }
+
+ double operator /(num other) {
+ return this.toDouble() / other.toDouble();
+ }
+
+ @pragma("vm:non-nullable-result-type")
+ num operator %(num other) {
+ if ((other is int) && (other == 0)) {
+ throw const IntegerDivisionByZeroException();
+ }
+ return other._moduloFromInteger(this);
+ }
+
+ @pragma("vm:non-nullable-result-type")
+ @pragma("vm:never-inline")
+ int operator -() {
+ return 0 - this;
+ }
+
+ @pragma("vm:non-nullable-result-type")
+ @pragma("vm:never-inline")
+ int operator &(int other) => other._bitAndFromInteger(this);
+ @pragma("vm:non-nullable-result-type")
+ @pragma("vm:never-inline")
+ int operator |(int other) => other._bitOrFromInteger(this);
+ @pragma("vm:non-nullable-result-type")
+ @pragma("vm:never-inline")
+ int operator ^(int other) => other._bitXorFromInteger(this);
+
+ num remainder(num other) {
+ return other._remainderFromInteger(this);
+ }
+
+ @pragma("vm:non-nullable-result-type")
+ int _bitAndFromSmi(_Smi other) native "Integer_bitAndFromInteger";
+ @pragma("vm:non-nullable-result-type")
+ int _bitAndFromInteger(int other) native "Integer_bitAndFromInteger";
+ @pragma("vm:non-nullable-result-type")
+ int _bitOrFromInteger(int other) native "Integer_bitOrFromInteger";
+ @pragma("vm:non-nullable-result-type")
+ int _bitXorFromInteger(int other) native "Integer_bitXorFromInteger";
+ @pragma("vm:non-nullable-result-type")
+ int _shrFromInteger(int other) native "Integer_shrFromInteger";
+ @pragma("vm:non-nullable-result-type")
+ int _shlFromInteger(int other) native "Integer_shlFromInteger";
+ @pragma("vm:non-nullable-result-type")
+ int _addFromInteger(int other) native "Integer_addFromInteger";
+ @pragma("vm:non-nullable-result-type")
+ int _subFromInteger(int other) native "Integer_subFromInteger";
+ @pragma("vm:non-nullable-result-type")
+ int _mulFromInteger(int other) native "Integer_mulFromInteger";
+ @pragma("vm:non-nullable-result-type")
+ int _truncDivFromInteger(int other) native "Integer_truncDivFromInteger";
+ @pragma("vm:non-nullable-result-type")
+ int _moduloFromInteger(int other) native "Integer_moduloFromInteger";
+ int _remainderFromInteger(int other) {
+ return other - (other ~/ this) * this;
+ }
+
+ @pragma("vm:non-nullable-result-type")
+ @pragma("vm:never-inline")
+ int operator >>(int other) => other._shrFromInteger(this);
+ @pragma("vm:non-nullable-result-type")
+ @pragma("vm:never-inline")
+ int operator <<(int other) => other._shlFromInteger(this);
+
+ @pragma("vm:exact-result-type", bool)
+ @pragma("vm:never-inline")
+ bool operator <(num other) {
+ return other > this;
+ }
+
+ @pragma("vm:exact-result-type", bool)
+ @pragma("vm:never-inline")
+ bool operator >(num other) {
+ return other._greaterThanFromInteger(this);
+ }
+
+ @pragma("vm:exact-result-type", bool)
+ @pragma("vm:never-inline")
+ bool operator >=(num other) {
+ return (this == other) || (this > other);
+ }
+
+ @pragma("vm:exact-result-type", bool)
+ @pragma("vm:never-inline")
+ bool operator <=(num other) {
+ return (this == other) || (this < other);
+ }
+
+ @pragma("vm:exact-result-type", bool)
+ bool _greaterThanFromInteger(int other)
+ native "Integer_greaterThanFromInteger";
+
+ @pragma("vm:exact-result-type", bool)
+ @pragma("vm:never-inline")
+ bool operator ==(Object other) {
+ if (other is num) {
+ return other._equalToInteger(this);
+ }
+ return false;
+ }
+
+ @pragma("vm:exact-result-type", bool)
+ bool _equalToInteger(int other) native "Integer_equalToInteger";
+ int abs() {
+ return this < 0 ? -this : this;
+ }
+
+ int get sign {
+ return (this > 0) ? 1 : (this < 0) ? -1 : 0;
+ }
+
+ bool get isEven => ((this & 1) == 0);
+ bool get isOdd => !isEven;
+ bool get isNaN => false;
+ bool get isNegative => this < 0;
+ bool get isInfinite => false;
+ bool get isFinite => true;
+
+ int toUnsigned(int width) {
+ return this & ((1 << width) - 1);
+ }
+
+ int toSigned(int width) {
+ // The value of binary number weights each bit by a power of two. The
+ // twos-complement value weights the sign bit negatively. We compute the
+ // value of the negative weighting by isolating the sign bit with the
+ // correct power of two weighting and subtracting it from the value of the
+ // lower bits.
+ int signMask = 1 << (width - 1);
+ return (this & (signMask - 1)) - (this & signMask);
+ }
+
+ int compareTo(num other) {
+ const int EQUAL = 0, LESS = -1, GREATER = 1;
+ if (other is double) {
+ const int MAX_EXACT_INT_TO_DOUBLE = 9007199254740992; // 2^53.
+ const int MIN_EXACT_INT_TO_DOUBLE = -MAX_EXACT_INT_TO_DOUBLE;
+ const bool limitIntsTo64Bits = ((1 << 64) == 0);
+ if (limitIntsTo64Bits) {
+ // With integers limited to 64 bits, double.toInt() clamps
+ // double value to fit into the MIN_INT64..MAX_INT64 range.
+ // Check if the double value is outside of this range.
+ // This check handles +/-infinity as well.
+ const double minInt64AsDouble = -9223372036854775808.0;
+ // MAX_INT64 is not precisely representable in doubles, so
+ // check against (MAX_INT64 + 1).
+ const double maxInt64Plus1AsDouble = 9223372036854775808.0;
+ if (other < minInt64AsDouble) {
+ return GREATER;
+ } else if (other >= maxInt64Plus1AsDouble) {
+ return LESS;
+ }
+ } else {
+ if (other.isInfinite) {
+ return other.isNegative ? GREATER : LESS;
+ }
+ }
+ if (other.isNaN) {
+ return LESS;
+ }
+ if (MIN_EXACT_INT_TO_DOUBLE <= this && this <= MAX_EXACT_INT_TO_DOUBLE) {
+ // Let the double implementation deal with -0.0.
+ return -(other.compareTo(this.toDouble()));
+ } else {
+ // If abs(other) > MAX_EXACT_INT_TO_DOUBLE, then other has an integer
+ // value (no bits below the decimal point).
+ other = other.toInt();
+ }
+ }
+ if (this < other) {
+ return LESS;
+ } else if (this > other) {
+ return GREATER;
+ } else {
+ return EQUAL;
+ }
+ }
+
+ int round() {
+ return this;
+ }
+
+ int floor() {
+ return this;
+ }
+
+ int ceil() {
+ return this;
+ }
+
+ int truncate() {
+ return this;
+ }
+
+ double roundToDouble() {
+ return this.toDouble();
+ }
+
+ double floorToDouble() {
+ return this.toDouble();
+ }
+
+ double ceilToDouble() {
+ return this.toDouble();
+ }
+
+ double truncateToDouble() {
+ return this.toDouble();
+ }
+
+ num clamp(num lowerLimit, num upperLimit) {
+ if (lowerLimit is! num) {
+ throw new ArgumentError.value(lowerLimit, "lowerLimit", "not a number");
+ }
+ if (upperLimit is! num) {
+ throw new ArgumentError.value(upperLimit, "upperLimit", "not a number");
+ }
+
+ // Special case for integers.
+ if (lowerLimit is int && upperLimit is int && lowerLimit <= upperLimit) {
+ if (this < lowerLimit) return lowerLimit;
+ if (this > upperLimit) return upperLimit;
+ return this;
+ }
+ // Generic case involving doubles, and invalid integer ranges.
+ if (lowerLimit.compareTo(upperLimit) > 0) {
+ throw new ArgumentError(lowerLimit);
+ }
+ if (lowerLimit.isNaN) return lowerLimit;
+ // Note that we don't need to care for -0.0 for the lower limit.
+ if (this < lowerLimit) return lowerLimit;
+ if (this.compareTo(upperLimit) > 0) return upperLimit;
+ return this;
+ }
+
+ int toInt() {
+ return this;
+ }
+
+ @pragma("vm:exact-result-type", _Double)
+ double toDouble() {
+ return new _Double.fromInteger(this);
+ }
+
+ String toStringAsFixed(int fractionDigits) {
+ return this.toDouble().toStringAsFixed(fractionDigits);
+ }
+
+ String toStringAsExponential([int fractionDigits]) {
+ return this.toDouble().toStringAsExponential(fractionDigits);
+ }
+
+ String toStringAsPrecision(int precision) {
+ return this.toDouble().toStringAsPrecision(precision);
+ }
+
+ static const _digits = "0123456789abcdefghijklmnopqrstuvwxyz";
+
+ String toRadixString(int radix) {
+ if (radix < 2 || 36 < radix) {
+ throw new RangeError.range(radix, 2, 36, "radix");
+ }
+ if (radix & (radix - 1) == 0) {
+ return _toPow2String(radix);
+ }
+ if (radix == 10) return this.toString();
+ final bool isNegative = this < 0;
+ int value = isNegative ? -this : this;
+ if (value < 0) {
+ // With integers limited to 64 bits, the value
+ // MIN_INT64 = -0x8000000000000000 overflows at negation:
+ // -MIN_INT64 == MIN_INT64, so it requires special handling.
+ return _minInt64ToRadixString(radix);
+ }
+ List temp = new List();
+ do {
+ int digit = value % radix;
+ value ~/= radix;
+ temp.add(_digits.codeUnitAt(digit));
+ } while (value > 0);
+ if (isNegative) temp.add(0x2d); // '-'.
+
+ _OneByteString string = _OneByteString._allocate(temp.length);
+ for (int i = 0, j = temp.length; j > 0; i++) {
+ string._setAt(i, temp[--j]);
+ }
+ return string;
+ }
+
+ String _toPow2String(int radix) {
+ int value = this;
+ if (value == 0) return "0";
+ assert(radix & (radix - 1) == 0);
+ var negative = value < 0;
+ var bitsPerDigit = radix.bitLength - 1;
+ var length = 0;
+ if (negative) {
+ value = -value;
+ length = 1;
+ if (value < 0) {
+ // With integers limited to 64 bits, the value
+ // MIN_INT64 = -0x8000000000000000 overflows at negation:
+ // -MIN_INT64 == MIN_INT64, so it requires special handling.
+ return _minInt64ToRadixString(radix);
+ }
+ }
+ // Integer division, rounding up, to find number of _digits.
+ length += (value.bitLength + bitsPerDigit - 1) ~/ bitsPerDigit;
+ _OneByteString string = _OneByteString._allocate(length);
+ string._setAt(0, 0x2d); // '-'. Is overwritten if not negative.
+ var mask = radix - 1;
+ do {
+ string._setAt(--length, _digits.codeUnitAt(value & mask));
+ value >>= bitsPerDigit;
+ } while (value > 0);
+ return string;
+ }
+
+ /// Converts negative value to radix string.
+ /// This method is only used to handle corner case of
+ /// MIN_INT64 = -0x8000000000000000.
+ String _minInt64ToRadixString(int radix) {
+ List temp = new List();
+ int value = this;
+ assert(value < 0);
+ do {
+ int digit = -value.remainder(radix);
+ value ~/= radix;
+ temp.add(_digits.codeUnitAt(digit));
+ } while (value != 0);
+ temp.add(0x2d); // '-'.
+
+ _OneByteString string = _OneByteString._allocate(temp.length);
+ for (int i = 0, j = temp.length; j > 0; i++) {
+ string._setAt(i, temp[--j]);
+ }
+ return string;
+ }
+
+ // Returns pow(this, e) % m.
+ int modPow(int e, int m) {
+ if (e is! int) {
+ throw new ArgumentError.value(e, "exponent", "not an integer");
+ }
+ if (m is! int) {
+ throw new ArgumentError.value(m, "modulus", "not an integer");
+ }
+ if (e < 0) throw new RangeError.range(e, 0, null, "exponent");
+ if (m <= 0) throw new RangeError.range(m, 1, null, "modulus");
+ if (e == 0) return 1;
+
+ // This is floor(sqrt(2^63)).
+ const int maxValueThatCanBeSquaredWithoutTruncation = 3037000499;
+ if (m > maxValueThatCanBeSquaredWithoutTruncation) {
+ // Use BigInt version to avoid truncation in multiplications below.
+ return BigInt.from(this).modPow(BigInt.from(e), BigInt.from(m)).toInt();
+ }
+
+ int b = this;
+ if (b < 0 || b > m) {
+ b %= m;
+ }
+ int r = 1;
+ while (e > 0) {
+ if (e.isOdd) {
+ r = (r * b) % m;
+ }
+ e >>= 1;
+ b = (b * b) % m;
+ }
+ return r;
+ }
+
+ // If inv is false, returns gcd(x, y).
+ // If inv is true and gcd(x, y) = 1, returns d, so that c*x + d*y = 1.
+ // If inv is true and gcd(x, y) != 1, throws Exception("Not coprime").
+ static int _binaryGcd(int x, int y, bool inv) {
+ int s = 0;
+ if (!inv) {
+ while (x.isEven && y.isEven) {
+ x >>= 1;
+ y >>= 1;
+ s++;
+ }
+ if (y.isOdd) {
+ var t = x;
+ x = y;
+ y = t;
+ }
+ }
+ final bool ac = x.isEven;
+ int u = x;
+ int v = y;
+ int a = 1, b = 0, c = 0, d = 1;
+ do {
+ while (u.isEven) {
+ u >>= 1;
+ if (ac) {
+ if (!a.isEven || !b.isEven) {
+ a += y;
+ b -= x;
+ }
+ a >>= 1;
+ } else if (!b.isEven) {
+ b -= x;
+ }
+ b >>= 1;
+ }
+ while (v.isEven) {
+ v >>= 1;
+ if (ac) {
+ if (!c.isEven || !d.isEven) {
+ c += y;
+ d -= x;
+ }
+ c >>= 1;
+ } else if (!d.isEven) {
+ d -= x;
+ }
+ d >>= 1;
+ }
+ if (u >= v) {
+ u -= v;
+ if (ac) a -= c;
+ b -= d;
+ } else {
+ v -= u;
+ if (ac) c -= a;
+ d -= b;
+ }
+ } while (u != 0);
+ if (!inv) return v << s;
+ if (v != 1) {
+ throw new Exception("Not coprime");
+ }
+ if (d < 0) {
+ d += x;
+ if (d < 0) d += x;
+ } else if (d > x) {
+ d -= x;
+ if (d > x) d -= x;
+ }
+ return d;
+ }
+
+ // Returns 1/this % m, with m > 0.
+ int modInverse(int m) {
+ if (m is! int) {
+ throw new ArgumentError.value(m, "modulus", "not an integer");
+ }
+ if (m <= 0) throw new RangeError.range(m, 1, null, "modulus");
+ if (m == 1) return 0;
+ int t = this;
+ if ((t < 0) || (t >= m)) t %= m;
+ if (t == 1) return 1;
+ if ((t == 0) || (t.isEven && m.isEven)) {
+ throw new Exception("Not coprime");
+ }
+ return _binaryGcd(m, t, true);
+ }
+
+ // Returns gcd of abs(this) and abs(other).
+ int gcd(int other) {
+ if (other is! int) {
+ throw new ArgumentError.value(other, "other", "not an integer");
+ }
+ int x = this.abs();
+ int y = other.abs();
+ if (x == 0) return y;
+ if (y == 0) return x;
+ if ((x == 1) || (y == 1)) return 1;
+ return _binaryGcd(x, y, false);
+ }
+}
+
+@pragma("vm:entry-point")
+class _Smi extends _IntegerImplementation {
+ factory _Smi._uninstantiable() {
+ throw "Unreachable";
+ }
+
+ int get hashCode => this;
+ int get _identityHashCode => this;
+ @pragma("vm:exact-result-type", "dart:core#_Smi")
+ int operator ~() native "Smi_bitNegate";
+ @pragma("vm:exact-result-type", "dart:core#_Smi")
+ int get bitLength native "Smi_bitLength";
+
+ int operator &(int other) => other._bitAndFromSmi(this);
+
+ @pragma("vm:exact-result-type", "dart:core#_Smi")
+ int _bitAndFromSmi(_Smi other) native "Smi_bitAndFromSmi";
+
+ /**
+ * The digits of '00', '01', ... '99' as a single array.
+ *
+ * Get the digits of `n`, with `0 <= n < 100`, as
+ * `_digitTable[n * 2]` and `_digitTable[n * 2 + 1]`.
+ */
+ static const _digitTable = const [
+ 0x30, 0x30, 0x30, 0x31, 0x30, 0x32, 0x30, 0x33, //
+ 0x30, 0x34, 0x30, 0x35, 0x30, 0x36, 0x30, 0x37, //
+ 0x30, 0x38, 0x30, 0x39, 0x31, 0x30, 0x31, 0x31, //
+ 0x31, 0x32, 0x31, 0x33, 0x31, 0x34, 0x31, 0x35, //
+ 0x31, 0x36, 0x31, 0x37, 0x31, 0x38, 0x31, 0x39, //
+ 0x32, 0x30, 0x32, 0x31, 0x32, 0x32, 0x32, 0x33, //
+ 0x32, 0x34, 0x32, 0x35, 0x32, 0x36, 0x32, 0x37, //
+ 0x32, 0x38, 0x32, 0x39, 0x33, 0x30, 0x33, 0x31, //
+ 0x33, 0x32, 0x33, 0x33, 0x33, 0x34, 0x33, 0x35, //
+ 0x33, 0x36, 0x33, 0x37, 0x33, 0x38, 0x33, 0x39, //
+ 0x34, 0x30, 0x34, 0x31, 0x34, 0x32, 0x34, 0x33, //
+ 0x34, 0x34, 0x34, 0x35, 0x34, 0x36, 0x34, 0x37, //
+ 0x34, 0x38, 0x34, 0x39, 0x35, 0x30, 0x35, 0x31, //
+ 0x35, 0x32, 0x35, 0x33, 0x35, 0x34, 0x35, 0x35, //
+ 0x35, 0x36, 0x35, 0x37, 0x35, 0x38, 0x35, 0x39, //
+ 0x36, 0x30, 0x36, 0x31, 0x36, 0x32, 0x36, 0x33, //
+ 0x36, 0x34, 0x36, 0x35, 0x36, 0x36, 0x36, 0x37, //
+ 0x36, 0x38, 0x36, 0x39, 0x37, 0x30, 0x37, 0x31, //
+ 0x37, 0x32, 0x37, 0x33, 0x37, 0x34, 0x37, 0x35, //
+ 0x37, 0x36, 0x37, 0x37, 0x37, 0x38, 0x37, 0x39, //
+ 0x38, 0x30, 0x38, 0x31, 0x38, 0x32, 0x38, 0x33, //
+ 0x38, 0x34, 0x38, 0x35, 0x38, 0x36, 0x38, 0x37, //
+ 0x38, 0x38, 0x38, 0x39, 0x39, 0x30, 0x39, 0x31, //
+ 0x39, 0x32, 0x39, 0x33, 0x39, 0x34, 0x39, 0x35, //
+ 0x39, 0x36, 0x39, 0x37, 0x39, 0x38, 0x39, 0x39, //
+ ];
+
+ /**
+ * Result of int.toString for -99, -98, ..., 98, 99.
+ */
+ static const _smallLookupTable = const [
+ "-99", "-98", "-97", "-96", "-95", "-94", "-93", "-92", "-91", "-90", //
+ "-89", "-88", "-87", "-86", "-85", "-84", "-83", "-82", "-81", "-80", //
+ "-79", "-78", "-77", "-76", "-75", "-74", "-73", "-72", "-71", "-70", //
+ "-69", "-68", "-67", "-66", "-65", "-64", "-63", "-62", "-61", "-60", //
+ "-59", "-58", "-57", "-56", "-55", "-54", "-53", "-52", "-51", "-50", //
+ "-49", "-48", "-47", "-46", "-45", "-44", "-43", "-42", "-41", "-40", //
+ "-39", "-38", "-37", "-36", "-35", "-34", "-33", "-32", "-31", "-30", //
+ "-29", "-28", "-27", "-26", "-25", "-24", "-23", "-22", "-21", "-20", //
+ "-19", "-18", "-17", "-16", "-15", "-14", "-13", "-12", "-11", "-10", //
+ "-9", "-8", "-7", "-6", "-5", "-4", "-3", "-2", "-1", "0", //
+ "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", //
+ "11", "12", "13", "14", "15", "16", "17", "18", "19", "20", //
+ "21", "22", "23", "24", "25", "26", "27", "28", "29", "30", //
+ "31", "32", "33", "34", "35", "36", "37", "38", "39", "40", //
+ "41", "42", "43", "44", "45", "46", "47", "48", "49", "50", //
+ "51", "52", "53", "54", "55", "56", "57", "58", "59", "60", //
+ "61", "62", "63", "64", "65", "66", "67", "68", "69", "70", //
+ "71", "72", "73", "74", "75", "76", "77", "78", "79", "80", //
+ "81", "82", "83", "84", "85", "86", "87", "88", "89", "90", //
+ "91", "92", "93", "94", "95", "96", "97", "98", "99" //
+ ];
+
+ // Powers of 10 above 1000000 are indistinguishable by eye.
+ static const int _POW_10_7 = 10000000;
+ static const int _POW_10_8 = 100000000;
+ static const int _POW_10_9 = 1000000000;
+
+ // Find the number of decimal digits in a positive smi.
+ // Never called with numbers < 100. These are handled before calling.
+ static int _positiveBase10Length(var smi) {
+ // A positive smi has length <= 19 if 63-bit, <=10 if 31-bit.
+ // Avoid comparing a 31-bit smi to a non-smi.
+ if (smi < 1000) return 3;
+ if (smi < 10000) return 4;
+ if (smi < _POW_10_7) {
+ if (smi < 100000) return 5;
+ if (smi < 1000000) return 6;
+ return 7;
+ }
+ if (smi < _POW_10_8) return 8;
+ if (smi < _POW_10_9) return 9;
+ smi = smi ~/ _POW_10_9;
+ // Handle numbers < 100 before calling recursively.
+ if (smi < 10) return 10;
+ if (smi < 100) return 11;
+ return 9 + _positiveBase10Length(smi);
+ }
+
+ String toString() {
+ if (this < 100 && this > -100) return _smallLookupTable[this + 99];
+ if (this < 0) return _negativeToString(this);
+ // Inspired by Andrei Alexandrescu: "Three Optimization Tips for C++"
+ // Avoid expensive remainder operation by doing it on more than
+ // one digit at a time.
+ const int DIGIT_ZERO = 0x30;
+ int length = _positiveBase10Length(this);
+ _OneByteString result = _OneByteString._allocate(length);
+ int index = length - 1;
+ var smi = this;
+ do {
+ // Two digits at a time.
+ var twoDigits = smi.remainder(100);
+ smi = smi ~/ 100;
+ int digitIndex = twoDigits * 2;
+ result._setAt(index, _digitTable[digitIndex + 1]);
+ result._setAt(index - 1, _digitTable[digitIndex]);
+ index -= 2;
+ } while (smi >= 100);
+ if (smi < 10) {
+ // Character code for '0'.
+ result._setAt(index, DIGIT_ZERO + smi);
+ } else {
+ // No remainder for this case.
+ int digitIndex = smi * 2;
+ result._setAt(index, _digitTable[digitIndex + 1]);
+ result._setAt(index - 1, _digitTable[digitIndex]);
+ }
+ return result;
+ }
+
+ // Find the number of decimal digits in a negative smi.
+ // Never called with numbers > -100. These are handled before calling.
+ static int _negativeBase10Length(var negSmi) {
+ // A negative smi has length <= 19 if 63-bit, <=10 if 31-bit.
+ // Avoid comparing a 31-bit smi to a non-smi.
+ if (negSmi > -1000) return 3;
+ if (negSmi > -10000) return 4;
+ if (negSmi > -_POW_10_7) {
+ if (negSmi > -100000) return 5;
+ if (negSmi > -1000000) return 6;
+ return 7;
+ }
+ if (negSmi > -_POW_10_8) return 8;
+ if (negSmi > -_POW_10_9) return 9;
+ negSmi = negSmi ~/ _POW_10_9;
+ // Handle numbers > -100 before calling recursively.
+ if (negSmi > -10) return 10;
+ if (negSmi > -100) return 11;
+ return 9 + _negativeBase10Length(negSmi);
+ }
+
+ // Convert a negative smi to a string.
+ // Doesn't negate the smi to avoid negating the most negative smi, which
+ // would become a non-smi.
+ static String _negativeToString(int negSmi) {
+ // Character code for '-'
+ const int MINUS_SIGN = 0x2d;
+ // Character code for '0'.
+ const int DIGIT_ZERO = 0x30;
+ if (negSmi > -10) {
+ return _OneByteString._allocate(2)
+ .._setAt(0, MINUS_SIGN)
+ .._setAt(1, DIGIT_ZERO - negSmi);
+ }
+ if (negSmi > -100) {
+ int digitIndex = 2 * -negSmi;
+ return _OneByteString._allocate(3)
+ .._setAt(0, MINUS_SIGN)
+ .._setAt(1, _digitTable[digitIndex])
+ .._setAt(2, _digitTable[digitIndex + 1]);
+ }
+ // Number of digits, not including minus.
+ int digitCount = _negativeBase10Length(negSmi);
+ _OneByteString result = _OneByteString._allocate(digitCount + 1);
+ result._setAt(0, MINUS_SIGN); // '-'.
+ int index = digitCount;
+ do {
+ var twoDigits = negSmi.remainder(100);
+ negSmi = negSmi ~/ 100;
+ int digitIndex = -twoDigits * 2;
+ result._setAt(index, _digitTable[digitIndex + 1]);
+ result._setAt(index - 1, _digitTable[digitIndex]);
+ index -= 2;
+ } while (negSmi <= -100);
+ if (negSmi > -10) {
+ result._setAt(index, DIGIT_ZERO - negSmi);
+ } else {
+ // No remainder necessary for this case.
+ int digitIndex = -negSmi * 2;
+ result._setAt(index, _digitTable[digitIndex + 1]);
+ result._setAt(index - 1, _digitTable[digitIndex]);
+ }
+ return result;
+ }
+}
+
+// Represents integers that cannot be represented by Smi but fit into 64bits.
+@pragma("vm:entry-point")
+class _Mint extends _IntegerImplementation {
+ factory _Mint._uninstantiable() {
+ throw "Unreachable";
+ }
+
+ int get hashCode => this;
+ int get _identityHashCode => this;
+ @pragma("vm:non-nullable-result-type")
+ int operator ~() native "Mint_bitNegate";
+ @pragma("vm:exact-result-type", "dart:core#_Smi")
+ int get bitLength native "Mint_bitLength";
+
+ int _bitAndFromSmi(_Smi other) => _bitAndFromInteger(other);
+}
diff --git a/sdk_nnbd/lib/_internal/vm/lib/integers_patch.dart b/sdk_nnbd/lib/_internal/vm/lib/integers_patch.dart
new file mode 100644
index 0000000..48f528d6
--- /dev/null
+++ b/sdk_nnbd/lib/_internal/vm/lib/integers_patch.dart
@@ -0,0 +1,308 @@
+// 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.5
+
+// part of "core_patch.dart";
+
+/// VM implementation of int.
+@patch
+class int {
+ @patch
+ const factory int.fromEnvironment(String name, {int defaultValue})
+ native "Integer_fromEnvironment";
+
+ int _bitAndFromSmi(_Smi other);
+ int _bitAndFromInteger(int other);
+ int _bitOrFromInteger(int other);
+ int _bitXorFromInteger(int other);
+ int _shrFromInteger(int other);
+ int _shlFromInteger(int other);
+
+ static int _tryParseSmi(String str, int first, int last) {
+ assert(first <= last);
+ var ix = first;
+ var sign = 1;
+ var c = str.codeUnitAt(ix);
+ // Check for leading '+' or '-'.
+ if ((c == 0x2b) || (c == 0x2d)) {
+ ix++;
+ sign = 0x2c - c; // -1 for '-', +1 for '+'.
+ if (ix > last) {
+ return null; // Empty.
+ }
+ }
+ var smiLimit = is64Bit ? 18 : 9;
+ if ((last - ix) >= smiLimit) {
+ return null; // May not fit into a Smi.
+ }
+ var result = 0;
+ for (int i = ix; i <= last; i++) {
+ var c = 0x30 ^ str.codeUnitAt(i);
+ if (9 < c) {
+ return null;
+ }
+ result = 10 * result + c;
+ }
+ return sign * result;
+ }
+
+ @patch
+ static int parse(String source, {int radix, int onError(String source)}) {
+ if (source == null) throw new ArgumentError("The source must not be null");
+ if (source.isEmpty) {
+ return _throwFormatException(onError, source, 0, radix, null);
+ }
+ if (radix == null || radix == 10) {
+ // Try parsing immediately, without trimming whitespace.
+ int result = _tryParseSmi(source, 0, source.length - 1);
+ if (result != null) return result;
+ } else if (radix < 2 || radix > 36) {
+ throw new RangeError("Radix $radix not in range 2..36");
+ }
+ // Split here so improve odds of parse being inlined and the checks omitted.
+ return _parse(source, radix, onError);
+ }
+
+ static int _parse(_StringBase source, int radix, onError) {
+ int end = source._lastNonWhitespace() + 1;
+ if (end == 0) {
+ return _throwFormatException(onError, source, source.length, radix, null);
+ }
+ int start = source._firstNonWhitespace();
+
+ int first = source.codeUnitAt(start);
+ int sign = 1;
+ if (first == 0x2b /* + */ || first == 0x2d /* - */) {
+ sign = 0x2c - first; // -1 if '-', +1 if '+'.
+ start++;
+ if (start == end) {
+ return _throwFormatException(onError, source, end, radix, null);
+ }
+ first = source.codeUnitAt(start);
+ }
+ if (radix == null) {
+ // check for 0x prefix.
+ int index = start;
+ if (first == 0x30 /* 0 */) {
+ index++;
+ if (index == end) return 0;
+ first = source.codeUnitAt(index);
+ if ((first | 0x20) == 0x78 /* x */) {
+ index++;
+ if (index == end) {
+ return _throwFormatException(onError, source, index, null, null);
+ }
+ return _parseRadix(source, 16, index, end, sign, sign > 0, onError);
+ }
+ }
+ radix = 10;
+ }
+ return _parseRadix(source, radix, start, end, sign, false, onError);
+ }
+
+ @patch
+ static int tryParse(String source, {int radix}) {
+ if (source == null) throw new ArgumentError("The source must not be null");
+ if (source.isEmpty) return null;
+ if (radix == null || radix == 10) {
+ // Try parsing immediately, without trimming whitespace.
+ int result = _tryParseSmi(source, 0, source.length - 1);
+ if (result != null) return result;
+ } else if (radix < 2 || radix > 36) {
+ throw new RangeError("Radix $radix not in range 2..36");
+ }
+ try {
+ return _parse(source, radix, _kNull);
+ } catch (e) {
+ return null;
+ }
+ }
+
+ static Null _kNull(_) => null;
+
+ static int _throwFormatException(onError, source, index, radix, message) {
+ if (onError != null) return onError(source);
+ if (message != null) {
+ throw new FormatException(message, source, index);
+ }
+ if (radix == null) {
+ throw new FormatException("Invalid number", source, index);
+ }
+ throw new FormatException("Invalid radix-$radix number", source, index);
+ }
+
+ static int _parseRadix(String source, int radix, int start, int end, int sign,
+ bool allowU64, onError) {
+ int tableIndex = (radix - 2) * 4 + (is64Bit ? 2 : 0);
+ int blockSize = _PARSE_LIMITS[tableIndex];
+ int length = end - start;
+ if (length <= blockSize) {
+ _Smi smi = _parseBlock(source, radix, start, end);
+ if (smi == null) {
+ return _throwFormatException(onError, source, start, radix, null);
+ }
+ return sign * smi;
+ }
+
+ // Often cheaper than: int smallBlockSize = length % blockSize;
+ // because digit count generally tends towards smaller. rather
+ // than larger.
+ int smallBlockSize = length;
+ while (smallBlockSize >= blockSize) smallBlockSize -= blockSize;
+ int result = 0;
+ if (smallBlockSize > 0) {
+ int blockEnd = start + smallBlockSize;
+ _Smi smi = _parseBlock(source, radix, start, blockEnd);
+ if (smi == null) {
+ return _throwFormatException(onError, source, start, radix, null);
+ }
+ result = sign * smi;
+ start = blockEnd;
+ }
+ int multiplier = _PARSE_LIMITS[tableIndex + 1];
+ int positiveOverflowLimit = 0;
+ int negativeOverflowLimit = 0;
+ tableIndex = tableIndex << 1; // pre-multiply by 2 for simpler indexing
+ positiveOverflowLimit = _int64OverflowLimits[tableIndex];
+ if (positiveOverflowLimit == 0) {
+ positiveOverflowLimit = _initInt64OverflowLimits(tableIndex, multiplier);
+ }
+ negativeOverflowLimit = _int64OverflowLimits[tableIndex + 1];
+ int blockEnd = start + blockSize;
+ do {
+ _Smi smi = _parseBlock(source, radix, start, blockEnd);
+ if (smi == null) {
+ return _throwFormatException(onError, source, start, radix, null);
+ }
+ if (result >= positiveOverflowLimit) {
+ if ((result > positiveOverflowLimit) ||
+ (smi > _int64OverflowLimits[tableIndex + 2])) {
+ // Although the unsigned overflow limits do not depend on the
+ // platform, the multiplier and block size, which are used to
+ // compute it, do.
+ int X = is64Bit ? 1 : 0;
+ if (allowU64 &&
+ !(result >= _int64UnsignedOverflowLimits[X] &&
+ (result > _int64UnsignedOverflowLimits[X] ||
+ smi > _int64UnsignedSmiOverflowLimits[X])) &&
+ blockEnd + blockSize > end) {
+ return (result * multiplier) + smi;
+ }
+ return _throwFormatException(onError, source, null, radix,
+ "Positive input exceeds the limit of integer");
+ }
+ } else if (result <= negativeOverflowLimit) {
+ if ((result < negativeOverflowLimit) ||
+ (smi > _int64OverflowLimits[tableIndex + 3])) {
+ return _throwFormatException(onError, source, null, radix,
+ "Negative input exceeds the limit of integer");
+ }
+ }
+ result = (result * multiplier) + (sign * smi);
+ start = blockEnd;
+ blockEnd = start + blockSize;
+ } while (blockEnd <= end);
+ return result;
+ }
+
+ // Parse block of digits into a Smi.
+ static _Smi _parseBlock(String source, int radix, int start, int end) {
+ _Smi result = 0;
+ if (radix <= 10) {
+ for (int i = start; i < end; i++) {
+ int digit = source.codeUnitAt(i) ^ 0x30;
+ if (digit >= radix) return null;
+ result = radix * result + digit;
+ }
+ } else {
+ for (int i = start; i < end; i++) {
+ int char = source.codeUnitAt(i);
+ int digit = char ^ 0x30;
+ if (digit > 9) {
+ digit = (char | 0x20) - (0x61 - 10);
+ if (digit < 10 || digit >= radix) return null;
+ }
+ result = radix * result + digit;
+ }
+ }
+ return result;
+ }
+
+ // For each radix, 2-36, how many digits are guaranteed to fit in a smi,
+ // and magnitude of such a block (radix ** digit-count).
+ // 32-bit limit/multiplier at (radix - 2)*4, 64-bit limit at (radix-2)*4+2
+ static const _PARSE_LIMITS = const [
+ 30, 1073741824, 62, 4611686018427387904, // radix: 2
+ 18, 387420489, 39, 4052555153018976267,
+ 15, 1073741824, 30, 1152921504606846976,
+ 12, 244140625, 26, 1490116119384765625, // radix: 5
+ 11, 362797056, 23, 789730223053602816,
+ 10, 282475249, 22, 3909821048582988049,
+ 10, 1073741824, 20, 1152921504606846976,
+ 9, 387420489, 19, 1350851717672992089,
+ 9, 1000000000, 18, 1000000000000000000, // radix: 10
+ 8, 214358881, 17, 505447028499293771,
+ 8, 429981696, 17, 2218611106740436992,
+ 8, 815730721, 16, 665416609183179841,
+ 7, 105413504, 16, 2177953337809371136,
+ 7, 170859375, 15, 437893890380859375, // radix: 15
+ 7, 268435456, 15, 1152921504606846976,
+ 7, 410338673, 15, 2862423051509815793,
+ 7, 612220032, 14, 374813367582081024,
+ 7, 893871739, 14, 799006685782884121,
+ 6, 64000000, 14, 1638400000000000000, // radix: 20
+ 6, 85766121, 14, 3243919932521508681,
+ 6, 113379904, 13, 282810057883082752,
+ 6, 148035889, 13, 504036361936467383,
+ 6, 191102976, 13, 876488338465357824,
+ 6, 244140625, 13, 1490116119384765625, // radix: 25
+ 6, 308915776, 13, 2481152873203736576,
+ 6, 387420489, 13, 4052555153018976267,
+ 6, 481890304, 12, 232218265089212416,
+ 6, 594823321, 12, 353814783205469041,
+ 6, 729000000, 12, 531441000000000000, // radix: 30
+ 6, 887503681, 12, 787662783788549761,
+ 6, 1073741824, 12, 1152921504606846976,
+ 5, 39135393, 12, 1667889514952984961,
+ 5, 45435424, 12, 2386420683693101056,
+ 5, 52521875, 12, 3379220508056640625, // radix: 35
+ 5, 60466176, 11, 131621703842267136,
+ ];
+
+ static const _maxInt64 = 0x7fffffffffffffff;
+ static const _minInt64 = -0x8000000000000000;
+
+ static const _int64UnsignedOverflowLimits = const [0xfffffffff, 0xf];
+ static const _int64UnsignedSmiOverflowLimits = const [
+ 0xfffffff,
+ 0xfffffffffffffff
+ ];
+
+ /// Calculation of the expression
+ ///
+ /// result = (result * multiplier) + (sign * smi)
+ ///
+ /// in `_parseRadix()` may overflow 64-bit integers. In such case,
+ /// `int.parse()` should stop with an error.
+ ///
+ /// This table is lazily filled with int64 overflow limits for result and smi.
+ /// For each multiplier from `_PARSE_LIMITS[tableIndex + 1]` this table
+ /// contains
+ ///
+ /// * `[tableIndex*2]` = positive limit for result
+ /// * `[tableIndex*2 + 1]` = negative limit for result
+ /// * `[tableIndex*2 + 2]` = limit for smi if result is exactly at positive limit
+ /// * `[tableIndex*2 + 3]` = limit for smi if result is exactly at negative limit
+ static final Int64List _int64OverflowLimits =
+ new Int64List(_PARSE_LIMITS.length * 2);
+
+ static int _initInt64OverflowLimits(int tableIndex, int multiplier) {
+ _int64OverflowLimits[tableIndex] = _maxInt64 ~/ multiplier;
+ _int64OverflowLimits[tableIndex + 1] = _minInt64 ~/ multiplier;
+ _int64OverflowLimits[tableIndex + 2] = _maxInt64.remainder(multiplier);
+ _int64OverflowLimits[tableIndex + 3] = -(_minInt64.remainder(multiplier));
+ return _int64OverflowLimits[tableIndex];
+ }
+}
diff --git a/sdk_nnbd/lib/_internal/vm/lib/internal_patch.dart b/sdk_nnbd/lib/_internal/vm/lib/internal_patch.dart
new file mode 100644
index 0000000..6e6d5be
--- /dev/null
+++ b/sdk_nnbd/lib/_internal/vm/lib/internal_patch.dart
@@ -0,0 +1,126 @@
+// 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
+// BSD-style license that can be found in the LICENSE file.
+
+// @dart = 2.5
+
+/// Note: the VM concatenates all patch files into a single patch file. This
+/// file is the first patch in "dart:_internal" which contains all the imports
+/// used by patches of that library. We plan to change this when we have a
+/// shared front end and simply use parts.
+
+import "dart:core" hide Symbol;
+
+import "dart:typed_data" show Int32List;
+
+/// These are the additional parts of this patch library:
+// part "class_id_fasta.dart";
+// part "print_patch.dart";
+// part "symbol_patch.dart";
+
+@patch
+List<T> makeListFixedLength<T>(List<T> growableList)
+ native "Internal_makeListFixedLength";
+
+@patch
+List<T> makeFixedListUnmodifiable<T>(List<T> fixedLengthList)
+ native "Internal_makeFixedListUnmodifiable";
+
+@patch
+Object extractTypeArguments<T>(T instance, Function extract)
+ native "Internal_extractTypeArguments";
+
+class VMLibraryHooks {
+ // Example: "dart:isolate _Timer._factory"
+ static var timerFactory;
+
+ // Example: "dart:io _EventHandler._sendData"
+ static var eventHandlerSendData;
+
+ // A nullary closure that answers the current clock value in milliseconds.
+ // Example: "dart:io _EventHandler._timerMillisecondClock"
+ static var timerMillisecondClock;
+
+ // Implementation of Resource.readAsBytes.
+ static var resourceReadAsBytes;
+
+ // Implementation of package root/map provision.
+ static var packageRootString;
+ static var packageConfigString;
+ static var packageRootUriFuture;
+ static var packageConfigUriFuture;
+ static var resolvePackageUriFuture;
+
+ static var _computeScriptUri;
+ static var _cachedScript;
+ static set platformScript(var f) {
+ _computeScriptUri = f;
+ _cachedScript = null;
+ }
+
+ static get platformScript {
+ if (_cachedScript == null && _computeScriptUri != null) {
+ _cachedScript = _computeScriptUri();
+ }
+ return _cachedScript;
+ }
+}
+
+final bool is64Bit = _inquireIs64Bit();
+
+bool _inquireIs64Bit() native "Internal_inquireIs64Bit";
+
+@pragma("vm:entry-point", "call")
+@pragma("vm:exact-result-type", bool)
+@pragma("vm:prefer-inline")
+bool _classRangeCheck(int cid, int lowerLimit, int upperLimit) {
+ return cid >= lowerLimit && cid <= upperLimit;
+}
+
+// Utility class now only used by the VM.
+class Lists {
+ @pragma("vm:prefer-inline")
+ static void copy(List src, int srcStart, List dst, int dstStart, int count) {
+ if (srcStart < dstStart) {
+ for (int i = srcStart + count - 1, j = dstStart + count - 1;
+ i >= srcStart;
+ i--, j--) {
+ dst[j] = src[i];
+ }
+ } else {
+ for (int i = srcStart, j = dstStart; i < srcStart + count; i++, j++) {
+ dst[j] = src[i];
+ }
+ }
+ }
+}
+
+// Prepend the parent type arguments (maybe null) of length 'parentLen' to the
+// function type arguments (may be null). The result is null if both input
+// vectors are null or is a newly allocated and canonicalized vector of length
+// 'totalLen'.
+@pragma("vm:entry-point", "call")
+_prependTypeArguments(functionTypeArguments, parentTypeArguments, parentLen,
+ totalLen) native "Internal_prependTypeArguments";
+
+// Check that a set of type arguments satisfy the type parameter bounds on a
+// closure.
+@pragma("vm:entry-point", "call")
+_boundsCheckForPartialInstantiation(closure, typeArgs)
+ native "Internal_boundsCheckForPartialInstantiation";
+
+// Called by IRRegExpMacroAssembler::GrowStack.
+Int32List _growRegExpStack(Int32List stack) {
+ final newStack = new Int32List(stack.length * 2);
+ for (int i = 0; i < stack.length; i++) {
+ newStack[i] = stack[i];
+ }
+ return newStack;
+}
+
+// This function can be used to skip implicit or explicit checked down casts in
+// the parts of the core library implementation where we know by construction the
+// type of a value.
+//
+// Important: this is unsafe and must be used with care.
+T unsafeCast<T>(Object v) native "Internal_unsafeCast";
diff --git a/sdk_nnbd/lib/_internal/vm/lib/invocation_mirror_patch.dart b/sdk_nnbd/lib/_internal/vm/lib/invocation_mirror_patch.dart
new file mode 100644
index 0000000..4472d2c
--- /dev/null
+++ b/sdk_nnbd/lib/_internal/vm/lib/invocation_mirror_patch.dart
@@ -0,0 +1,204 @@
+// 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.5
+
+// part of "core_patch.dart";
+
+// NOTE: When making changes to this class, please also update
+// `VmTarget.instantiateInvocation` and `VmTarget._invocationType` in
+// `pkg/kernel/lib/target/vm.dart`.
+class _InvocationMirror implements Invocation {
+ // Constants describing the invocation kind.
+ // _FIELD cannot be generated by regular invocation mirrors.
+ static const int _METHOD = 0;
+ static const int _GETTER = 1;
+ static const int _SETTER = 2;
+ static const int _FIELD = 3;
+ static const int _LOCAL_VAR = 4;
+ static const int _KIND_SHIFT = 0;
+ static const int _KIND_BITS = 3;
+ static const int _KIND_MASK = (1 << _KIND_BITS) - 1;
+
+ // These values, except _DYNAMIC and _SUPER, are only used when throwing
+ // NoSuchMethodError for compile-time resolution failures.
+ static const int _DYNAMIC = 0;
+ static const int _SUPER = 1;
+ static const int _STATIC = 2;
+ static const int _CONSTRUCTOR = 3;
+ static const int _TOP_LEVEL = 4;
+ static const int _LEVEL_SHIFT = _KIND_BITS;
+ static const int _LEVEL_BITS = 3;
+ static const int _LEVEL_MASK = (1 << _LEVEL_BITS) - 1;
+
+ // ArgumentsDescriptor layout. Keep in sync with enum in dart_entry.h.
+ static const int _TYPE_ARGS_LEN = 0;
+ static const int _COUNT = 1;
+ static const int _POSITIONAL_COUNT = 2;
+ static const int _FIRST_NAMED_ENTRY = 3;
+
+ // Internal representation of the invocation mirror.
+ String _functionName;
+ List _argumentsDescriptor;
+ List _arguments;
+ bool _isSuperInvocation;
+ int _delayedTypeArgumentsLen;
+
+ // External representation of the invocation mirror; populated on demand.
+ Symbol _memberName;
+ int _type;
+ List<Type> _typeArguments;
+ List _positionalArguments;
+ Map<Symbol, dynamic> _namedArguments;
+
+ _InvocationMirror._withType(this._memberName, this._type, this._typeArguments,
+ this._positionalArguments, this._namedArguments) {
+ _typeArguments ??= const <Type>[];
+ _positionalArguments ??= const [];
+ _namedArguments ??= const {};
+ }
+
+ void _setMemberNameAndType() {
+ _type ??= 0;
+ if (_functionName.startsWith("get:")) {
+ _type |= _GETTER;
+ _memberName = new internal.Symbol.unvalidated(_functionName.substring(4));
+ } else if (_functionName.startsWith("set:")) {
+ _type |= _SETTER;
+ _memberName =
+ new internal.Symbol.unvalidated(_functionName.substring(4) + "=");
+ } else {
+ _type |=
+ _isSuperInvocation ? (_SUPER << _LEVEL_SHIFT) | _METHOD : _METHOD;
+ _memberName = new internal.Symbol.unvalidated(_functionName);
+ }
+ }
+
+ Symbol get memberName {
+ if (_memberName == null) {
+ _setMemberNameAndType();
+ }
+ return _memberName;
+ }
+
+ int get _typeArgsLen {
+ int typeArgsLen = _argumentsDescriptor[_TYPE_ARGS_LEN];
+ return typeArgsLen == 0 ? _delayedTypeArgumentsLen : typeArgsLen;
+ }
+
+ List<Type> get typeArguments {
+ if (_typeArguments == null) {
+ if (_typeArgsLen == 0) {
+ return _typeArguments = const <Type>[];
+ }
+ // A TypeArguments object does not have a corresponding Dart class and
+ // cannot be accessed as an array in Dart. Therefore, we need a native
+ // call to unpack the individual types into a list.
+ _typeArguments = _unpackTypeArguments(_arguments[0], _typeArgsLen);
+ }
+ return _typeArguments;
+ }
+
+ // Unpack the given TypeArguments object into a new list of individual types.
+ static List<Type> _unpackTypeArguments(typeArguments, int numTypeArguments)
+ native "InvocationMirror_unpackTypeArguments";
+
+ List get positionalArguments {
+ if (_positionalArguments == null) {
+ // The argument descriptor counts the receiver, but not the type arguments
+ // as positional arguments.
+ int numPositionalArguments = _argumentsDescriptor[_POSITIONAL_COUNT] - 1;
+ if (numPositionalArguments == 0) {
+ return _positionalArguments = const [];
+ }
+ // Exclude receiver and type args in the returned list.
+ int receiverIndex = _typeArgsLen > 0 ? 1 : 0;
+ _positionalArguments = new _ImmutableList._from(
+ _arguments, receiverIndex + 1, numPositionalArguments);
+ }
+ return _positionalArguments;
+ }
+
+ Map<Symbol, dynamic> get namedArguments {
+ if (_namedArguments == null) {
+ int numArguments = _argumentsDescriptor[_COUNT] - 1; // Exclude receiver.
+ int numPositionalArguments = _argumentsDescriptor[_POSITIONAL_COUNT] - 1;
+ int numNamedArguments = numArguments - numPositionalArguments;
+ if (numNamedArguments == 0) {
+ return _namedArguments = const {};
+ }
+ int receiverIndex = _typeArgsLen > 0 ? 1 : 0;
+ _namedArguments = new Map<Symbol, dynamic>();
+ for (int i = 0; i < numNamedArguments; i++) {
+ int namedEntryIndex = _FIRST_NAMED_ENTRY + 2 * i;
+ String arg_name = _argumentsDescriptor[namedEntryIndex];
+ var arg_value = _arguments[
+ receiverIndex + _argumentsDescriptor[namedEntryIndex + 1]];
+ _namedArguments[new internal.Symbol.unvalidated(arg_name)] = arg_value;
+ }
+ _namedArguments = new Map.unmodifiable(_namedArguments);
+ }
+ return _namedArguments;
+ }
+
+ bool get isMethod {
+ if (_type == null) {
+ _setMemberNameAndType();
+ }
+ return (_type & _KIND_MASK) == _METHOD;
+ }
+
+ bool get isAccessor {
+ if (_type == null) {
+ _setMemberNameAndType();
+ }
+ return (_type & _KIND_MASK) != _METHOD;
+ }
+
+ bool get isGetter {
+ if (_type == null) {
+ _setMemberNameAndType();
+ }
+ return (_type & _KIND_MASK) == _GETTER;
+ }
+
+ bool get isSetter {
+ if (_type == null) {
+ _setMemberNameAndType();
+ }
+ return (_type & _KIND_MASK) == _SETTER;
+ }
+
+ _InvocationMirror(this._functionName, this._argumentsDescriptor,
+ this._arguments, this._isSuperInvocation, this._type,
+ [this._delayedTypeArgumentsLen = 0]);
+
+ _InvocationMirror._withoutType(this._functionName, this._typeArguments,
+ this._positionalArguments, this._namedArguments, this._isSuperInvocation,
+ [this._delayedTypeArgumentsLen = 0]);
+
+ @pragma("vm:entry-point", "call")
+ static _allocateInvocationMirror(String functionName,
+ List argumentsDescriptor, List arguments, bool isSuperInvocation,
+ [int type = null]) {
+ return new _InvocationMirror(
+ functionName, argumentsDescriptor, arguments, isSuperInvocation, type);
+ }
+
+ // This factory is used when creating an `Invocation` for a closure call which
+ // may have delayed type arguments. In that case, the arguments descriptor will
+ // indicate 0 type arguments, but the actual number of type arguments are
+ // passed in `delayedTypeArgumentsLen`. If any type arguments are available,
+ // the type arguments vector will be the first entry in `arguments`.
+ @pragma("vm:entry-point", "call")
+ static _allocateInvocationMirrorForClosure(
+ String functionName,
+ List argumentsDescriptor,
+ List arguments,
+ int type,
+ int delayedTypeArgumentsLen) {
+ return new _InvocationMirror(functionName, argumentsDescriptor, arguments,
+ false, type, delayedTypeArgumentsLen);
+ }
+}
diff --git a/sdk_nnbd/lib/_internal/vm/lib/isolate_patch.dart b/sdk_nnbd/lib/_internal/vm/lib/isolate_patch.dart
new file mode 100644
index 0000000..ec4bcf1
--- /dev/null
+++ b/sdk_nnbd/lib/_internal/vm/lib/isolate_patch.dart
@@ -0,0 +1,710 @@
+// 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.5
+
+/// Note: the VM concatenates all patch files into a single patch file. This
+/// file is the first patch in "dart:isolate" which contains all the imports
+/// used by patches of that library. We plan to change this when we have a
+/// shared front end and simply use parts.
+
+import "dart:_internal" show ClassID, VMLibraryHooks, patch;
+
+import "dart:async"
+ show Completer, Future, Stream, StreamController, StreamSubscription, Timer;
+
+import "dart:collection" show HashMap;
+import "dart:typed_data" show ByteBuffer, TypedData, Uint8List;
+
+/// These are the additional parts of this patch library:
+// part "timer_impl.dart";
+
+@patch
+class ReceivePort {
+ @patch
+ factory ReceivePort() => new _ReceivePortImpl();
+
+ @patch
+ factory ReceivePort.fromRawReceivePort(RawReceivePort rawPort) {
+ return new _ReceivePortImpl.fromRawReceivePort(rawPort);
+ }
+}
+
+@patch
+class Capability {
+ @patch
+ factory Capability() => new _CapabilityImpl();
+}
+
+@pragma("vm:entry-point")
+class _CapabilityImpl implements Capability {
+ factory _CapabilityImpl() native "CapabilityImpl_factory";
+
+ bool operator ==(var other) {
+ return (other is _CapabilityImpl) && _equals(other);
+ }
+
+ int get hashCode {
+ return _get_hashcode();
+ }
+
+ _equals(other) native "CapabilityImpl_equals";
+ _get_hashcode() native "CapabilityImpl_get_hashcode";
+}
+
+@patch
+class RawReceivePort {
+ /**
+ * Opens a long-lived port for receiving messages.
+ *
+ * A [RawReceivePort] is low level and does not work with [Zone]s. It
+ * can not be paused. The data-handler must be set before the first
+ * event is received.
+ */
+ @patch
+ factory RawReceivePort([Function handler]) {
+ _RawReceivePortImpl result = new _RawReceivePortImpl();
+ result.handler = handler;
+ return result;
+ }
+}
+
+class _ReceivePortImpl extends Stream implements ReceivePort {
+ _ReceivePortImpl() : this.fromRawReceivePort(new RawReceivePort());
+
+ _ReceivePortImpl.fromRawReceivePort(this._rawPort) {
+ _controller = new StreamController(onCancel: close, sync: true);
+ _rawPort.handler = _controller.add;
+ }
+
+ SendPort get sendPort {
+ return _rawPort.sendPort;
+ }
+
+ StreamSubscription listen(void onData(var message),
+ {Function onError, void onDone(), bool cancelOnError}) {
+ return _controller.stream.listen(onData,
+ onError: onError, onDone: onDone, cancelOnError: cancelOnError);
+ }
+
+ close() {
+ _rawPort.close();
+ _controller.close();
+ }
+
+ final RawReceivePort _rawPort;
+ StreamController _controller;
+}
+
+typedef void _ImmediateCallback();
+
+/// The callback that has been registered through `scheduleImmediate`.
+_ImmediateCallback _pendingImmediateCallback;
+
+/// The closure that should be used as scheduleImmediateClosure, when the VM
+/// is responsible for the event loop.
+void _isolateScheduleImmediate(void callback()) {
+ assert((_pendingImmediateCallback == null) ||
+ (_pendingImmediateCallback == callback));
+ _pendingImmediateCallback = callback;
+}
+
+@pragma("vm:entry-point", "call")
+void _runPendingImmediateCallback() {
+ if (_pendingImmediateCallback != null) {
+ var callback = _pendingImmediateCallback;
+ _pendingImmediateCallback = null;
+ callback();
+ }
+}
+
+_ImmediateCallback _removePendingImmediateCallback() {
+ var callback = _pendingImmediateCallback;
+ _pendingImmediateCallback = null;
+ return callback;
+}
+
+/// The embedder can execute this function to get hold of
+/// [_isolateScheduleImmediate] above.
+@pragma("vm:entry-point", "call")
+Function _getIsolateScheduleImmediateClosure() {
+ return _isolateScheduleImmediate;
+}
+
+@pragma("vm:entry-point")
+class _RawReceivePortImpl implements RawReceivePort {
+ factory _RawReceivePortImpl() native "RawReceivePortImpl_factory";
+
+ close() {
+ // Close the port and remove it from the handler map.
+ _handlerMap.remove(this._closeInternal());
+ }
+
+ SendPort get sendPort {
+ return _get_sendport();
+ }
+
+ bool operator ==(var other) {
+ return (other is _RawReceivePortImpl) &&
+ (this._get_id() == other._get_id());
+ }
+
+ int get hashCode {
+ return sendPort.hashCode;
+ }
+
+ /**** Internal implementation details ****/
+ _get_id() native "RawReceivePortImpl_get_id";
+ _get_sendport() native "RawReceivePortImpl_get_sendport";
+
+ // Called from the VM to retrieve the handler for a message.
+ @pragma("vm:entry-point", "call")
+ static _lookupHandler(int id) {
+ var result = _handlerMap[id];
+ return result;
+ }
+
+ // Called from the VM to dispatch to the handler.
+ @pragma("vm:entry-point", "call")
+ static void _handleMessage(Function handler, var message) {
+ // TODO(floitsch): this relies on the fact that any exception aborts the
+ // VM. Once we have non-fatal global exceptions we need to catch errors
+ // so that we can run the immediate callbacks.
+ handler(message);
+ _runPendingImmediateCallback();
+ }
+
+ // Call into the VM to close the VM maintained mappings.
+ _closeInternal() native "RawReceivePortImpl_closeInternal";
+
+ void set handler(Function value) {
+ _handlerMap[this._get_id()] = value;
+ }
+
+ // TODO(iposva): Ideally keep this map in the VM.
+ // id to handler mapping.
+ static _initHandlerMap() {
+ // TODO(18511): Workaround bad CheckSmi hoisting.
+ var tempMap = new HashMap();
+ // Collect feedback that not all keys are Smis.
+ tempMap["."] = 1;
+ tempMap["."] = 2;
+
+ return new HashMap();
+ }
+
+ static final Map _handlerMap = _initHandlerMap();
+}
+
+@pragma("vm:entry-point")
+class _SendPortImpl implements SendPort {
+ factory _SendPortImpl._uninstantiable() {
+ throw "Unreachable";
+ }
+
+ /*--- public interface ---*/
+ @pragma("vm:entry-point", "call")
+ void send(var message) {
+ _sendInternal(message);
+ }
+
+ bool operator ==(var other) {
+ return (other is _SendPortImpl) && (this._get_id() == other._get_id());
+ }
+
+ int get hashCode {
+ return _get_hashcode();
+ }
+
+ /*--- private implementation ---*/
+ _get_id() native "SendPortImpl_get_id";
+ _get_hashcode() native "SendPortImpl_get_hashcode";
+
+ // Forward the implementation of sending messages to the VM.
+ void _sendInternal(var message) native "SendPortImpl_sendInternal_";
+}
+
+typedef _NullaryFunction();
+typedef _UnaryFunction(Null args);
+typedef _BinaryFunction(Null args, Null message);
+
+/**
+ * Takes the real entry point as argument and invokes it with the
+ * initial message. Defers execution of the entry point until the
+ * isolate is in the message loop.
+ */
+@pragma("vm:entry-point", "call")
+void _startMainIsolate(Function entryPoint, List<String> args) {
+ _startIsolate(
+ null, // no parent port
+ entryPoint,
+ args,
+ null, // no message
+ true, // isSpawnUri
+ null, // no control port
+ null); // no capabilities
+}
+
+/**
+ * Returns the _startMainIsolate function. This closurization allows embedders
+ * to setup trampolines to the main function. This workaround can be removed
+ * once support for @pragma("vm:entry_point", "get") as documented in
+ * https://github.com/dart-lang/sdk/issues/35720 lands.
+ */
+@pragma("vm:entry-point", "call")
+Function _getStartMainIsolateFunction() {
+ return _startMainIsolate;
+}
+
+/**
+ * Takes the real entry point as argument and invokes it with the initial
+ * message.
+ */
+@pragma("vm:entry-point", "call")
+void _startIsolate(
+ SendPort parentPort,
+ Function entryPoint,
+ List<String> args,
+ var message,
+ bool isSpawnUri,
+ RawReceivePort controlPort,
+ List capabilities) {
+ // The control port (aka the main isolate port) does not handle any messages.
+ if (controlPort != null) {
+ controlPort.handler = (_) {}; // Nobody home on the control port.
+ }
+
+ if (parentPort != null) {
+ // Build a message to our parent isolate providing access to the
+ // current isolate's control port and capabilities.
+ //
+ // TODO(floitsch): Send an error message if we can't find the entry point.
+ var readyMessage = new List(2);
+ readyMessage[0] = controlPort.sendPort;
+ readyMessage[1] = capabilities;
+
+ // Out of an excess of paranoia we clear the capabilities from the
+ // stack. Not really necessary.
+ capabilities = null;
+ parentPort.send(readyMessage);
+ }
+ assert(capabilities == null);
+
+ // Delay all user code handling to the next run of the message loop. This
+ // allows us to intercept certain conditions in the event dispatch, such as
+ // starting in paused state.
+ RawReceivePort port = new RawReceivePort();
+ port.handler = (_) {
+ port.close();
+
+ if (isSpawnUri) {
+ if (entryPoint is _BinaryFunction) {
+ (entryPoint as dynamic)(args, message);
+ } else if (entryPoint is _UnaryFunction) {
+ (entryPoint as dynamic)(args);
+ } else {
+ entryPoint();
+ }
+ } else {
+ entryPoint(message);
+ }
+ };
+ // Make sure the message handler is triggered.
+ port.sendPort.send(null);
+}
+
+@patch
+class Isolate {
+ static final _currentIsolate = _getCurrentIsolate();
+ static final _rootUri = _getCurrentRootUri();
+
+ @patch
+ static Isolate get current => _currentIsolate;
+
+ @patch
+ String get debugName => _getDebugName(controlPort);
+
+ @patch
+ static Future<Uri> get packageRoot {
+ var hook = VMLibraryHooks.packageRootUriFuture;
+ if (hook == null) {
+ throw new UnsupportedError("Isolate.packageRoot");
+ }
+ return hook();
+ }
+
+ @patch
+ static Future<Uri> get packageConfig {
+ var hook = VMLibraryHooks.packageConfigUriFuture;
+ if (hook == null) {
+ throw new UnsupportedError("Isolate.packageConfig");
+ }
+ return hook();
+ }
+
+ @patch
+ static Future<Uri> resolvePackageUri(Uri packageUri) {
+ var hook = VMLibraryHooks.resolvePackageUriFuture;
+ if (hook == null) {
+ throw new UnsupportedError("Isolate.resolvePackageUri");
+ }
+ return hook(packageUri);
+ }
+
+ static bool _packageSupported() =>
+ (VMLibraryHooks.packageRootUriFuture != null) &&
+ (VMLibraryHooks.packageConfigUriFuture != null) &&
+ (VMLibraryHooks.resolvePackageUriFuture != null);
+
+ @patch
+ static Future<Isolate> spawn<T>(void entryPoint(T message), T message,
+ {bool paused: false,
+ bool errorsAreFatal,
+ SendPort onExit,
+ SendPort onError,
+ String debugName}) async {
+ // `paused` isn't handled yet.
+ RawReceivePort readyPort;
+ try {
+ // Check for the type of `entryPoint` on the spawning isolate to make
+ // error-handling easier.
+ if (entryPoint is! _UnaryFunction) {
+ throw new ArgumentError(entryPoint);
+ }
+ // The VM will invoke [_startIsolate] with entryPoint as argument.
+ readyPort = new RawReceivePort();
+
+ // We do not inherit the package config settings from the parent isolate,
+ // instead we use the values that were set on the command line.
+ var packageConfig = VMLibraryHooks.packageConfigString;
+ var script = VMLibraryHooks.platformScript;
+ if (script == null) {
+ // We do not have enough information to support spawning the new
+ // isolate.
+ throw new UnsupportedError("Isolate.spawn");
+ }
+ if (script.scheme == "package") {
+ script = await Isolate.resolvePackageUri(script);
+ }
+
+ _spawnFunction(
+ readyPort.sendPort,
+ script.toString(),
+ entryPoint,
+ message,
+ paused,
+ errorsAreFatal,
+ onExit,
+ onError,
+ null,
+ packageConfig,
+ debugName);
+ return await _spawnCommon(readyPort);
+ } catch (e, st) {
+ if (readyPort != null) {
+ readyPort.close();
+ }
+ return await new Future<Isolate>.error(e, st);
+ }
+ }
+
+ @patch
+ static Future<Isolate> spawnUri(Uri uri, List<String> args, var message,
+ {bool paused: false,
+ SendPort onExit,
+ SendPort onError,
+ bool errorsAreFatal,
+ bool checked,
+ Map<String, String> environment,
+ Uri packageRoot,
+ Uri packageConfig,
+ bool automaticPackageResolution: false,
+ String debugName}) async {
+ RawReceivePort readyPort;
+ if (environment != null) {
+ throw new UnimplementedError("environment");
+ }
+
+ // Verify that no mutually exclusive arguments have been passed.
+ if (automaticPackageResolution) {
+ if (packageRoot != null) {
+ throw new ArgumentError("Cannot simultaneously request "
+ "automaticPackageResolution and specify a"
+ "packageRoot.");
+ }
+ if (packageConfig != null) {
+ throw new ArgumentError("Cannot simultaneously request "
+ "automaticPackageResolution and specify a"
+ "packageConfig.");
+ }
+ } else {
+ if ((packageRoot != null) && (packageConfig != null)) {
+ throw new ArgumentError("Cannot simultaneously specify a "
+ "packageRoot and a packageConfig.");
+ }
+ }
+ try {
+ // Resolve the uri against the current isolate's root Uri first.
+ var spawnedUri = _rootUri.resolveUri(uri);
+
+ // Inherit this isolate's package resolution setup if not overridden.
+ if (!automaticPackageResolution &&
+ (packageRoot == null) &&
+ (packageConfig == null)) {
+ if (Isolate._packageSupported()) {
+ packageRoot = await Isolate.packageRoot;
+ packageConfig = await Isolate.packageConfig;
+ }
+ }
+
+ // Ensure to resolve package: URIs being handed in as parameters.
+ if (packageRoot != null) {
+ // `packages/` directory is no longer supported. Force it null.
+ // TODO(mfairhurst) Should this throw an exception?
+ packageRoot = null;
+ } else if (packageConfig != null) {
+ // Avoid calling resolvePackageUri if not strictly necessary in case
+ // the API is not supported.
+ if (packageConfig.scheme == "package") {
+ packageConfig = await Isolate.resolvePackageUri(packageConfig);
+ }
+ }
+
+ // The VM will invoke [_startIsolate] and not `main`.
+ readyPort = new RawReceivePort();
+ var packageRootString = packageRoot?.toString();
+ var packageConfigString = packageConfig?.toString();
+
+ _spawnUri(
+ readyPort.sendPort,
+ spawnedUri.toString(),
+ args,
+ message,
+ paused,
+ onExit,
+ onError,
+ errorsAreFatal,
+ checked,
+ null,
+ /* environment */
+ packageRootString,
+ packageConfigString,
+ debugName);
+ return await _spawnCommon(readyPort);
+ } catch (e) {
+ if (readyPort != null) {
+ readyPort.close();
+ }
+ rethrow;
+ }
+ }
+
+ static Future<Isolate> _spawnCommon(RawReceivePort readyPort) {
+ Completer completer = new Completer<Isolate>.sync();
+ readyPort.handler = (readyMessage) {
+ readyPort.close();
+ if (readyMessage is List && readyMessage.length == 2) {
+ SendPort controlPort = readyMessage[0];
+ List capabilities = readyMessage[1];
+ completer.complete(new Isolate(controlPort,
+ pauseCapability: capabilities[0],
+ terminateCapability: capabilities[1]));
+ } else if (readyMessage is String) {
+ // We encountered an error while starting the new isolate.
+ completer.completeError(new IsolateSpawnException(
+ 'Unable to spawn isolate: ${readyMessage}'));
+ } else {
+ // This shouldn't happen.
+ completer.completeError(new IsolateSpawnException(
+ "Internal error: unexpected format for ready message: "
+ "'${readyMessage}'"));
+ }
+ };
+ return completer.future;
+ }
+
+ // TODO(iposva): Cleanup to have only one definition.
+ // These values need to be kept in sync with the class IsolateMessageHandler
+ // in vm/isolate.cc.
+ static const _PAUSE = 1;
+ static const _RESUME = 2;
+ static const _PING = 3;
+ static const _KILL = 4;
+ static const _ADD_EXIT = 5;
+ static const _DEL_EXIT = 6;
+ static const _ADD_ERROR = 7;
+ static const _DEL_ERROR = 8;
+ static const _ERROR_FATAL = 9;
+
+ static void _spawnFunction(
+ SendPort readyPort,
+ String uri,
+ Function topLevelFunction,
+ var message,
+ bool paused,
+ bool errorsAreFatal,
+ SendPort onExit,
+ SendPort onError,
+ String packageRoot,
+ String packageConfig,
+ String debugName) native "Isolate_spawnFunction";
+
+ static void _spawnUri(
+ SendPort readyPort,
+ String uri,
+ List<String> args,
+ var message,
+ bool paused,
+ SendPort onExit,
+ SendPort onError,
+ bool errorsAreFatal,
+ bool checked,
+ List environment,
+ String packageRoot,
+ String packageConfig,
+ String debugName) native "Isolate_spawnUri";
+
+ static void _sendOOB(port, msg) native "Isolate_sendOOB";
+
+ static String _getDebugName(SendPort controlPort)
+ native "Isolate_getDebugName";
+
+ @patch
+ void _pause(Capability resumeCapability) {
+ var msg = new List(4)
+ ..[0] = 0 // Make room for OOB message type.
+ ..[1] = _PAUSE
+ ..[2] = pauseCapability
+ ..[3] = resumeCapability;
+ _sendOOB(controlPort, msg);
+ }
+
+ @patch
+ void resume(Capability resumeCapability) {
+ var msg = new List(4)
+ ..[0] = 0 // Make room for OOB message type.
+ ..[1] = _RESUME
+ ..[2] = pauseCapability
+ ..[3] = resumeCapability;
+ _sendOOB(controlPort, msg);
+ }
+
+ @patch
+ void addOnExitListener(SendPort responsePort, {Object response}) {
+ var msg = new List(4)
+ ..[0] = 0 // Make room for OOB message type.
+ ..[1] = _ADD_EXIT
+ ..[2] = responsePort
+ ..[3] = response;
+ _sendOOB(controlPort, msg);
+ }
+
+ @patch
+ void removeOnExitListener(SendPort responsePort) {
+ var msg = new List(3)
+ ..[0] = 0 // Make room for OOB message type.
+ ..[1] = _DEL_EXIT
+ ..[2] = responsePort;
+ _sendOOB(controlPort, msg);
+ }
+
+ @patch
+ void setErrorsFatal(bool errorsAreFatal) {
+ var msg = new List(4)
+ ..[0] = 0 // Make room for OOB message type.
+ ..[1] = _ERROR_FATAL
+ ..[2] = terminateCapability
+ ..[3] = errorsAreFatal;
+ _sendOOB(controlPort, msg);
+ }
+
+ @patch
+ void kill({int priority: beforeNextEvent}) {
+ var msg = new List(4)
+ ..[0] = 0 // Make room for OOB message type.
+ ..[1] = _KILL
+ ..[2] = terminateCapability
+ ..[3] = priority;
+ _sendOOB(controlPort, msg);
+ }
+
+ @patch
+ void ping(SendPort responsePort, {Object response, int priority: immediate}) {
+ var msg = new List(5)
+ ..[0] = 0 // Make room for OOM message type.
+ ..[1] = _PING
+ ..[2] = responsePort
+ ..[3] = priority
+ ..[4] = response;
+ _sendOOB(controlPort, msg);
+ }
+
+ @patch
+ void addErrorListener(SendPort port) {
+ var msg = new List(3)
+ ..[0] = 0 // Make room for OOB message type.
+ ..[1] = _ADD_ERROR
+ ..[2] = port;
+ _sendOOB(controlPort, msg);
+ }
+
+ @patch
+ void removeErrorListener(SendPort port) {
+ var msg = new List(3)
+ ..[0] = 0 // Make room for OOB message type.
+ ..[1] = _DEL_ERROR
+ ..[2] = port;
+ _sendOOB(controlPort, msg);
+ }
+
+ static Isolate _getCurrentIsolate() {
+ List portAndCapabilities = _getPortAndCapabilitiesOfCurrentIsolate();
+ return new Isolate(portAndCapabilities[0],
+ pauseCapability: portAndCapabilities[1],
+ terminateCapability: portAndCapabilities[2]);
+ }
+
+ static List _getPortAndCapabilitiesOfCurrentIsolate()
+ native "Isolate_getPortAndCapabilitiesOfCurrentIsolate";
+
+ static Uri _getCurrentRootUri() {
+ try {
+ return Uri.parse(_getCurrentRootUriStr());
+ } catch (e) {
+ return null;
+ }
+ }
+
+ static String _getCurrentRootUriStr() native "Isolate_getCurrentRootUriStr";
+}
+
+@patch
+abstract class TransferableTypedData {
+ @patch
+ factory TransferableTypedData.fromList(List<TypedData> chunks) {
+ if (chunks == null) {
+ throw ArgumentError(chunks);
+ }
+ final int cid = ClassID.getID(chunks);
+ if (cid != ClassID.cidArray &&
+ cid != ClassID.cidGrowableObjectArray &&
+ cid != ClassID.cidImmutableArray) {
+ chunks = List.unmodifiable(chunks);
+ }
+ return _TransferableTypedDataImpl(chunks);
+ }
+}
+
+@pragma("vm:entry-point")
+class _TransferableTypedDataImpl implements TransferableTypedData {
+ factory _TransferableTypedDataImpl(List<TypedData> list)
+ native "TransferableTypedData_factory";
+
+ ByteBuffer materialize() {
+ return _materializeIntoUint8List().buffer;
+ }
+
+ Uint8List _materializeIntoUint8List()
+ native "TransferableTypedData_materialize";
+}
diff --git a/sdk_nnbd/lib/_internal/vm/lib/lib_prefix.dart b/sdk_nnbd/lib/_internal/vm/lib/lib_prefix.dart
new file mode 100644
index 0000000..895e5cc
--- /dev/null
+++ b/sdk_nnbd/lib/_internal/vm/lib/lib_prefix.dart
@@ -0,0 +1,19 @@
+// Copyright (c) 2014, 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.5
+
+// part of "core_patch.dart";
+
+// This type corresponds to the VM-internal class LibraryPrefix.
+@pragma("vm:entry-point")
+class _LibraryPrefix {
+ factory _LibraryPrefix._uninstantiable() {
+ throw "Unreachable";
+ }
+
+ bool isLoaded() => true;
+
+ loadLibrary() => new Future.value(true);
+}
diff --git a/sdk_nnbd/lib/_internal/vm/lib/map_patch.dart b/sdk_nnbd/lib/_internal/vm/lib/map_patch.dart
new file mode 100644
index 0000000..9a014c6
--- /dev/null
+++ b/sdk_nnbd/lib/_internal/vm/lib/map_patch.dart
@@ -0,0 +1,33 @@
+// 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.5
+
+// part of "core_patch.dart";
+
+@patch
+class Map<K, V> {
+ // Factory constructing a Map from a parser generated Map literal.
+ // [elements] contains n key-value pairs.
+ // The keys are at position 2*n and are already type checked by the parser
+ // in checked mode.
+ // The values are at position 2*n+1 and are not yet type checked.
+ @pragma("vm:entry-point", "call")
+ factory Map._fromLiteral(List elements) {
+ var map = new LinkedHashMap<K, V>();
+ var len = elements.length;
+ for (int i = 1; i < len; i += 2) {
+ map[elements[i - 1]] = elements[i];
+ }
+ return map;
+ }
+
+ @patch
+ factory Map.unmodifiable(Map other) {
+ return new UnmodifiableMapView<K, V>(new Map<K, V>.from(other));
+ }
+
+ @patch
+ factory Map() => new LinkedHashMap<K, V>();
+}
diff --git a/sdk_nnbd/lib/_internal/vm/lib/math_patch.dart b/sdk_nnbd/lib/_internal/vm/lib/math_patch.dart
new file mode 100644
index 0000000..341d5eb
--- /dev/null
+++ b/sdk_nnbd/lib/_internal/vm/lib/math_patch.dart
@@ -0,0 +1,315 @@
+// 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.5
+
+/// Note: the VM concatenates all patch files into a single patch file. This
+/// file is the first patch in "dart:math" which contains all the imports used
+/// by patches of that library. We plan to change this when we have a shared
+/// front end and simply use parts.
+
+import "dart:_internal" show patch;
+
+import "dart:typed_data" show Uint32List;
+
+/// There are no parts of this patch library.
+
+@patch
+@pragma("vm:prefer-inline")
+T min<T extends num>(T a, T b) {
+ // These partially redundant type checks improve code quality for dart2js.
+ // Most of the improvement is at call sites from the inferred non-null num
+ // return type.
+ if (a is! num) throw new ArgumentError(a);
+ if (b is! num) throw new ArgumentError(b);
+
+ if (a > b) return b;
+ if (a < b) return a;
+ if (b is double) {
+ // Special case for NaN and -0.0. If one argument is NaN return NaN.
+ // [min] must also distinguish between -0.0 and 0.0.
+ if (a is double) {
+ if (a == 0.0) {
+ // a is either 0.0 or -0.0. b is either 0.0, -0.0 or NaN.
+ // The following returns -0.0 if either a or b is -0.0, and it
+ // returns NaN if b is NaN.
+ num n = (a + b) * a * b;
+ return n;
+ }
+ }
+ // Check for NaN and b == -0.0.
+ if (a == 0 && b.isNegative || b.isNaN) return b;
+ return a;
+ }
+ return a;
+}
+
+@patch
+@pragma("vm:prefer-inline")
+T max<T extends num>(T a, T b) {
+ // These partially redundant type checks improve code quality for dart2js.
+ // Most of the improvement is at call sites from the inferred non-null num
+ // return type.
+ if (a is! num) throw new ArgumentError(a);
+ if (b is! num) throw new ArgumentError(b);
+
+ if (a > b) return a;
+ if (a < b) return b;
+ if (b is double) {
+ // Special case for NaN and -0.0. If one argument is NaN return NaN.
+ // [max] must also distinguish between -0.0 and 0.0.
+ if (a is double) {
+ if (a == 0.0) {
+ // a is either 0.0 or -0.0. b is either 0.0, -0.0, or NaN.
+ // The following returns 0.0 if either a or b is 0.0, and it
+ // returns NaN if b is NaN.
+ num n = a + b;
+ return n;
+ }
+ }
+ // Check for NaN.
+ if (b.isNaN) return b;
+ return a;
+ }
+ // max(-0.0, 0) must return 0.
+ if (b == 0 && a.isNegative) return b;
+ return a;
+}
+
+// If [x] is an [int] and [exponent] is a non-negative [int], the result is
+// an [int], otherwise the result is a [double].
+@patch
+@pragma("vm:prefer-inline")
+num pow(num x, num exponent) {
+ if ((x is int) && (exponent is int) && (exponent >= 0)) {
+ return _intPow(x, exponent);
+ }
+ return _doublePow(x.toDouble(), exponent.toDouble());
+}
+
+@pragma("vm:exact-result-type", "dart:core#_Double")
+double _doublePow(double base, double exponent) {
+ if (exponent == 0.0) {
+ return 1.0; // ECMA-262 15.8.2.13
+ }
+ // Speed up simple cases.
+ if (exponent == 1.0) return base;
+ if (exponent == 2.0) return base * base;
+ if (exponent == 3.0) return base * base * base;
+
+ if (base == 1.0) return 1.0;
+
+ if (base.isNaN || exponent.isNaN) {
+ return double.nan;
+ }
+ if ((base != -double.infinity) && (exponent == 0.5)) {
+ if (base == 0.0) {
+ return 0.0;
+ }
+ return sqrt(base);
+ }
+ return _pow(base.toDouble(), exponent.toDouble());
+}
+
+double _pow(double base, double exponent) native "Math_doublePow";
+
+int _intPow(int base, int exponent) {
+ // Exponentiation by squaring.
+ int result = 1;
+ while (exponent != 0) {
+ if ((exponent & 1) == 1) {
+ result *= base;
+ }
+ exponent >>= 1;
+ // Skip unnecessary operation (can overflow to Mint).
+ if (exponent != 0) {
+ base *= base;
+ }
+ }
+ return result;
+}
+
+@patch
+@pragma("vm:exact-result-type", "dart:core#_Double")
+@pragma("vm:never-inline")
+double atan2(num a, num b) => _atan2(a.toDouble(), b.toDouble());
+@patch
+@pragma("vm:exact-result-type", "dart:core#_Double")
+@pragma("vm:never-inline")
+double sin(num radians) => _sin(radians.toDouble());
+@patch
+@pragma("vm:exact-result-type", "dart:core#_Double")
+@pragma("vm:never-inline")
+double cos(num radians) => _cos(radians.toDouble());
+@patch
+@pragma("vm:exact-result-type", "dart:core#_Double")
+@pragma("vm:never-inline")
+double tan(num radians) => _tan(radians.toDouble());
+@patch
+@pragma("vm:exact-result-type", "dart:core#_Double")
+@pragma("vm:never-inline")
+double acos(num x) => _acos(x.toDouble());
+@patch
+@pragma("vm:exact-result-type", "dart:core#_Double")
+@pragma("vm:never-inline")
+double asin(num x) => _asin(x.toDouble());
+@patch
+@pragma("vm:exact-result-type", "dart:core#_Double")
+@pragma("vm:never-inline")
+double atan(num x) => _atan(x.toDouble());
+@patch
+@pragma("vm:exact-result-type", "dart:core#_Double")
+@pragma("vm:never-inline")
+double sqrt(num x) => _sqrt(x.toDouble());
+@patch
+@pragma("vm:prefer-inline")
+double exp(num x) => _exp(x.toDouble());
+@patch
+@pragma("vm:prefer-inline")
+double log(num x) => _log(x.toDouble());
+
+double _atan2(double a, double b) native "Math_atan2";
+double _sin(double x) native "Math_sin";
+double _cos(double x) native "Math_cos";
+double _tan(double x) native "Math_tan";
+double _acos(double x) native "Math_acos";
+double _asin(double x) native "Math_asin";
+double _atan(double x) native "Math_atan";
+double _sqrt(double x) native "Math_sqrt";
+double _exp(double x) native "Math_exp";
+double _log(double x) native "Math_log";
+
+// TODO(iposva): Handle patch methods within a patch class correctly.
+@patch
+class Random {
+ @patch
+ factory Random([int seed]) {
+ var state = _Random._setupSeed((seed == null) ? _Random._nextSeed() : seed);
+ // Crank a couple of times to distribute the seed bits a bit further.
+ return new _Random._withState(state)
+ .._nextState()
+ .._nextState()
+ .._nextState()
+ .._nextState();
+ }
+
+ @patch
+ factory Random.secure() {
+ return new _SecureRandom();
+ }
+}
+
+class _Random implements Random {
+ // Internal state of the random number generator.
+ @pragma("vm:entry-point")
+ final Uint32List _state;
+ static const _kSTATE_LO = 0;
+ static const _kSTATE_HI = 1; // Unused in Dart code.
+
+ _Random._withState(this._state);
+
+ // The algorithm used here is Multiply with Carry (MWC) with a Base b = 2^32.
+ // http://en.wikipedia.org/wiki/Multiply-with-carry
+ // The constant A is selected from "Numerical Recipes 3rd Edition" p.348 B1.
+
+ // Implements:
+ // const _A = 0xffffda61;
+ // var state =
+ // ((_A * (_state[_kSTATE_LO])) + _state[_kSTATE_HI]) & ((1 << 64) - 1);
+ // _state[_kSTATE_LO] = state & ((1 << 32) - 1);
+ // _state[_kSTATE_HI] = state >> 32;
+ // This is a native to prevent 64-bit operations in Dart, which
+ // fail with --throw_on_javascript_int_overflow.
+ // TODO(regis): Implement in Dart and remove Random_nextState in math.cc.
+ void _nextState() native "Random_nextState";
+
+ int nextInt(int max) {
+ const limit = 0x3FFFFFFF;
+ if ((max <= 0) || ((max > limit) && (max > _POW2_32))) {
+ throw new RangeError.range(
+ max, 1, _POW2_32, "max", "Must be positive and <= 2^32");
+ }
+ if ((max & -max) == max) {
+ // Fast case for powers of two.
+ _nextState();
+ return _state[_kSTATE_LO] & (max - 1);
+ }
+
+ var rnd32;
+ var result;
+ do {
+ _nextState();
+ rnd32 = _state[_kSTATE_LO];
+ result = rnd32 % max;
+ } while ((rnd32 - result + max) > _POW2_32);
+ return result;
+ }
+
+ double nextDouble() {
+ return ((nextInt(1 << 26) * _POW2_27_D) + nextInt(1 << 27)) / _POW2_53_D;
+ }
+
+ bool nextBool() {
+ return nextInt(2) == 0;
+ }
+
+ // Constants used by the algorithm.
+ static const _POW2_32 = 1 << 32;
+ static const _POW2_53_D = 1.0 * (1 << 53);
+ static const _POW2_27_D = 1.0 * (1 << 27);
+
+ // Use a singleton Random object to get a new seed if no seed was passed.
+ static final _prng = new _Random._withState(_initialSeed());
+
+ // This is a native to prevent 64-bit operations in Dart, which
+ // fail with --throw_on_javascript_int_overflow.
+ // TODO(regis): Implement here in Dart and remove native in math.cc.
+ static Uint32List _setupSeed(int seed) native "Random_setupSeed";
+ // Get a seed from the VM's random number provider.
+ static Uint32List _initialSeed() native "Random_initialSeed";
+
+ static int _nextSeed() {
+ // Trigger the PRNG once to change the internal state.
+ _prng._nextState();
+ return _prng._state[_kSTATE_LO];
+ }
+}
+
+class _SecureRandom implements Random {
+ _SecureRandom() {
+ // Throw early in constructor if entropy source is not hooked up.
+ _getBytes(1);
+ }
+
+ // Return count bytes of entropy as a positive integer; count <= 8.
+ static int _getBytes(int count) native "SecureRandom_getBytes";
+
+ int nextInt(int max) {
+ RangeError.checkValueInInterval(
+ max, 1, _POW2_32, "max", "Must be positive and <= 2^32");
+ final byteCount = ((max - 1).bitLength + 7) >> 3;
+ if (byteCount == 0) {
+ return 0; // Not random if max == 1.
+ }
+ var rnd;
+ var result;
+ do {
+ rnd = _getBytes(byteCount);
+ result = rnd % max;
+ } while ((rnd - result + max) > (1 << (byteCount << 3)));
+ return result;
+ }
+
+ double nextDouble() {
+ return (_getBytes(7) >> 3) / _POW2_53_D;
+ }
+
+ bool nextBool() {
+ return _getBytes(1).isEven;
+ }
+
+ // Constants used by the algorithm.
+ static const _POW2_32 = 1 << 32;
+ static const _POW2_53_D = 1.0 * (1 << 53);
+}
diff --git a/sdk_nnbd/lib/_internal/vm/lib/mirror_reference.dart b/sdk_nnbd/lib/_internal/vm/lib/mirror_reference.dart
new file mode 100644
index 0000000..a403f38
--- /dev/null
+++ b/sdk_nnbd/lib/_internal/vm/lib/mirror_reference.dart
@@ -0,0 +1,16 @@
+// 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
+// BSD-style license that can be found in the LICENSE file.
+
+// @dart = 2.5
+
+// part of "mirrors_patch.dart";
+
+@pragma("vm:entry-point")
+class _MirrorReference {
+ factory _MirrorReference._uninstantiable() {
+ throw "Unreachable";
+ }
+
+ bool operator ==(other) native "MirrorReference_equals";
+}
diff --git a/runtime/lib/mirrors_impl.dart b/sdk_nnbd/lib/_internal/vm/lib/mirrors_impl.dart
similarity index 90%
rename from runtime/lib/mirrors_impl.dart
rename to sdk_nnbd/lib/_internal/vm/lib/mirrors_impl.dart
index d6d07fd..f83fe33 100644
--- a/runtime/lib/mirrors_impl.dart
+++ b/sdk_nnbd/lib/_internal/vm/lib/mirrors_impl.dart
@@ -2,6 +2,8 @@
// 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.5
+
// part of "mirrors_patch.dart";
var _dirty = false; // Set to true by the VM when more libraries are loaded.
@@ -67,7 +69,7 @@
bool _subtypeTest(Type a, Type b) native 'TypeMirror_subtypeTest';
-class _LocalMirrorSystem extends MirrorSystem {
+class _MirrorSystem extends MirrorSystem {
final TypeMirror dynamicType = new _SpecialTypeMirror._('dynamic');
final TypeMirror voidType = new _SpecialTypeMirror._('void');
@@ -114,13 +116,11 @@
}
}
-abstract class _LocalMirror implements Mirror {}
-
-class _LocalIsolateMirror extends _LocalMirror implements IsolateMirror {
+class _IsolateMirror extends Mirror implements IsolateMirror {
final String debugName;
final LibraryMirror rootLibrary;
- _LocalIsolateMirror._(this.debugName, this.rootLibrary);
+ _IsolateMirror._(this.debugName, this.rootLibrary);
bool get isCurrent => true;
@@ -201,14 +201,14 @@
List<InstanceMirror> get metadata => const <InstanceMirror>[];
}
-abstract class _LocalObjectMirror extends _LocalMirror implements ObjectMirror {
+abstract class _ObjectMirror extends Mirror implements ObjectMirror {
_invoke(reflectee, functionName, arguments, argumentNames);
_invokeGetter(reflectee, getterName);
_invokeSetter(reflectee, setterName, value);
final _reflectee; // May be a MirrorReference or an ordinary object.
- _LocalObjectMirror._(this._reflectee);
+ _ObjectMirror._(this._reflectee);
InstanceMirror invoke(Symbol memberName, List positionalArguments,
[Map<Symbol, dynamic> namedArguments]) {
@@ -260,9 +260,8 @@
}
}
-class _LocalInstanceMirror extends _LocalObjectMirror
- implements InstanceMirror {
- _LocalInstanceMirror._(reflectee) : super._(reflectee);
+class _InstanceMirror extends _ObjectMirror implements InstanceMirror {
+ _InstanceMirror._(reflectee) : super._(reflectee);
ClassMirror _type;
ClassMirror get type {
@@ -282,8 +281,7 @@
String toString() => 'InstanceMirror on ${Error.safeToString(_reflectee)}';
bool operator ==(other) {
- return other is _LocalInstanceMirror &&
- identical(_reflectee, other._reflectee);
+ return other is _InstanceMirror && identical(_reflectee, other._reflectee);
}
int get hashCode {
@@ -334,9 +332,8 @@
static _computeType(reflectee) native 'InstanceMirror_computeType';
}
-class _LocalClosureMirror extends _LocalInstanceMirror
- implements ClosureMirror {
- _LocalClosureMirror._(reflectee) : super._(reflectee);
+class _ClosureMirror extends _InstanceMirror implements ClosureMirror {
+ _ClosureMirror._(reflectee) : super._(reflectee);
MethodMirror _function;
MethodMirror get function {
@@ -356,12 +353,11 @@
static _computeFunction(reflectee) native 'ClosureMirror_function';
}
-abstract class _LocalTypeMirror {
+abstract class _TypeMirror {
Type get _reflectedType;
}
-class _LocalClassMirror extends _LocalObjectMirror
- implements ClassMirror, _LocalTypeMirror {
+class _ClassMirror extends _ObjectMirror implements ClassMirror, _TypeMirror {
final Type _reflectedType;
Symbol _simpleName;
DeclarationMirror _owner;
@@ -377,7 +373,7 @@
final bool isEnum;
Type _instantiator;
- _LocalClassMirror._(
+ _ClassMirror._(
reflectee,
reflectedType,
String simpleName,
@@ -419,7 +415,7 @@
DeclarationMirror get owner {
if (_owner == null) {
- var uri = _LocalClassMirror._libraryUri(_reflectee);
+ var uri = _ClassMirror._libraryUri(_reflectee);
_owner = currentMirrorSystem().libraries[Uri.parse(uri)];
}
return _owner;
@@ -433,8 +429,8 @@
return _location(_reflectee);
}
- _LocalClassMirror _trueSuperclassField;
- _LocalClassMirror get _trueSuperclass {
+ _ClassMirror _trueSuperclassField;
+ _ClassMirror get _trueSuperclass {
if (_trueSuperclassField == null) {
Type supertype = isOriginalDeclaration
? _supertype(_reflectedType)
@@ -487,8 +483,7 @@
var _mixin;
ClassMirror get mixin {
if (_mixin == null) {
- Type mixinType =
- _nativeMixinInstantiated(_reflectedType, _instantiator);
+ Type mixinType = _nativeMixinInstantiated(_reflectedType, _instantiator);
if (mixinType == null) {
// The reflectee is not a mixin application.
_mixin = this;
@@ -599,7 +594,7 @@
ClassMirror owner = originalDeclaration;
var mirror;
for (var i = 0; i < params.length; i += 2) {
- mirror = new _LocalTypeVariableMirror._(params[i + 1], params[i], owner);
+ mirror = new _TypeVariableMirror._(params[i + 1], params[i], owner);
_typeVariables.add(mirror);
}
_typeVariables =
@@ -676,14 +671,13 @@
bool isSubtypeOf(TypeMirror other) {
if (other == currentMirrorSystem().dynamicType) return true;
if (other == currentMirrorSystem().voidType) return false;
- return _subtypeTest(
- _reflectedType, (other as _LocalTypeMirror)._reflectedType);
+ return _subtypeTest(_reflectedType, (other as _TypeMirror)._reflectedType);
}
bool isAssignableTo(TypeMirror other) {
if (other == currentMirrorSystem().dynamicType) return true;
if (other == currentMirrorSystem().voidType) return false;
- final otherReflectedType = (other as _LocalTypeMirror)._reflectedType;
+ final otherReflectedType = (other as _TypeMirror)._reflectedType;
return _subtypeTest(_reflectedType, otherReflectedType) ||
_subtypeTest(otherReflectedType, _reflectedType);
}
@@ -741,12 +735,11 @@
native "ClassMirror_type_arguments";
}
-class _LocalFunctionTypeMirror extends _LocalClassMirror
- implements FunctionTypeMirror {
+class _FunctionTypeMirror extends _ClassMirror implements FunctionTypeMirror {
final _functionReflectee;
- _LocalFunctionTypeMirror._(reflectee, this._functionReflectee, reflectedType)
- : super._(reflectee, reflectedType, null, null, false, false, false, false,
- false);
+ _FunctionTypeMirror._(reflectee, this._functionReflectee, reflectedType)
+ : super._(reflectee, reflectedType, null, null, false, false, false,
+ false, false);
bool get _isAnonymousMixinApplication => false;
@@ -805,12 +798,11 @@
native "FunctionTypeMirror_parameters";
}
-abstract class _LocalDeclarationMirror extends _LocalMirror
- implements DeclarationMirror {
+abstract class _DeclarationMirror extends Mirror implements DeclarationMirror {
final _reflectee;
Symbol _simpleName;
- _LocalDeclarationMirror._(this._reflectee, this._simpleName);
+ _DeclarationMirror._(this._reflectee, this._simpleName);
Symbol get simpleName => _simpleName;
@@ -843,9 +835,9 @@
int get hashCode => simpleName.hashCode;
}
-class _LocalTypeVariableMirror extends _LocalDeclarationMirror
- implements TypeVariableMirror, _LocalTypeMirror {
- _LocalTypeVariableMirror._(reflectee, String simpleName, this._owner)
+class _TypeVariableMirror extends _DeclarationMirror
+ implements TypeVariableMirror, _TypeMirror {
+ _TypeVariableMirror._(reflectee, String simpleName, this._owner)
: super._(reflectee, _s(simpleName));
DeclarationMirror _owner;
@@ -894,14 +886,13 @@
bool isSubtypeOf(TypeMirror other) {
if (other == currentMirrorSystem().dynamicType) return true;
if (other == currentMirrorSystem().voidType) return false;
- return _subtypeTest(
- _reflectedType, (other as _LocalTypeMirror)._reflectedType);
+ return _subtypeTest(_reflectedType, (other as _TypeMirror)._reflectedType);
}
bool isAssignableTo(TypeMirror other) {
if (other == currentMirrorSystem().dynamicType) return true;
if (other == currentMirrorSystem().voidType) return false;
- final otherReflectedType = (other as _LocalTypeMirror)._reflectedType;
+ final otherReflectedType = (other as _TypeMirror)._reflectedType;
return _subtypeTest(_reflectedType, otherReflectedType) ||
_subtypeTest(otherReflectedType, _reflectedType);
}
@@ -913,13 +904,13 @@
native "TypeVariableMirror_upper_bound";
}
-class _LocalTypedefMirror extends _LocalDeclarationMirror
- implements TypedefMirror, _LocalTypeMirror {
+class _TypedefMirror extends _DeclarationMirror
+ implements TypedefMirror, _TypeMirror {
final Type _reflectedType;
final bool _isGeneric;
final bool _isGenericDeclaration;
- _LocalTypedefMirror(reflectee, this._reflectedType, String simpleName,
+ _TypedefMirror(reflectee, this._reflectedType, String simpleName,
this._isGeneric, this._isGenericDeclaration, this._owner)
: super._(reflectee, _s(simpleName));
@@ -928,13 +919,13 @@
DeclarationMirror _owner;
DeclarationMirror get owner {
if (_owner == null) {
- var uri = _LocalClassMirror._libraryUri(_reflectee);
+ var uri = _ClassMirror._libraryUri(_reflectee);
_owner = currentMirrorSystem().libraries[Uri.parse(uri)];
}
return _owner;
}
- _LocalFunctionTypeMirror _referent;
+ _FunctionTypeMirror _referent;
FunctionTypeMirror get referent {
if (_referent == null) {
_referent = _nativeReferent(_reflectedType);
@@ -966,11 +957,11 @@
List<TypeVariableMirror> get typeVariables {
if (_typeVariables == null) {
_typeVariables = new List<TypeVariableMirror>();
- List params = _LocalClassMirror._ClassMirror_type_variables(_reflectee);
+ List params = _ClassMirror._ClassMirror_type_variables(_reflectee);
TypedefMirror owner = originalDeclaration;
var mirror;
for (var i = 0; i < params.length; i += 2) {
- mirror = new _LocalTypeVariableMirror._(params[i + 1], params[i], owner);
+ mirror = new _TypeVariableMirror._(params[i + 1], params[i], owner);
_typeVariables.add(mirror);
}
}
@@ -983,9 +974,9 @@
if (_isGenericDeclaration) {
_typeArguments = const <TypeMirror>[];
} else {
- _typeArguments = new UnmodifiableListView<TypeMirror>(_LocalClassMirror
- ._computeTypeArguments(_reflectedType)
- .cast<TypeMirror>());
+ _typeArguments = new UnmodifiableListView<TypeMirror>(
+ _ClassMirror._computeTypeArguments(_reflectedType)
+ .cast<TypeMirror>());
}
}
return _typeArguments;
@@ -996,14 +987,13 @@
bool isSubtypeOf(TypeMirror other) {
if (other == currentMirrorSystem().dynamicType) return true;
if (other == currentMirrorSystem().voidType) return false;
- return _subtypeTest(
- _reflectedType, (other as _LocalTypeMirror)._reflectedType);
+ return _subtypeTest(_reflectedType, (other as _TypeMirror)._reflectedType);
}
bool isAssignableTo(TypeMirror other) {
if (other == currentMirrorSystem().dynamicType) return true;
if (other == currentMirrorSystem().voidType) return false;
- final otherReflectedType = (other as _LocalTypeMirror)._reflectedType;
+ final otherReflectedType = (other as _TypeMirror)._reflectedType;
return _subtypeTest(_reflectedType, otherReflectedType) ||
_subtypeTest(otherReflectedType, _reflectedType);
}
@@ -1020,11 +1010,11 @@
return MirrorSystem.getSymbol('${unwrapped}=', library);
}
-class _LocalLibraryMirror extends _LocalObjectMirror implements LibraryMirror {
+class _LibraryMirror extends _ObjectMirror implements LibraryMirror {
final Symbol simpleName;
final Uri uri;
- _LocalLibraryMirror._(reflectee, String simpleName, String url)
+ _LibraryMirror._(reflectee, String simpleName, String url)
: this.simpleName = _s(simpleName),
this.uri = Uri.parse(url),
super._(reflectee);
@@ -1097,7 +1087,7 @@
List<dynamic> _computeMembers(reflectee) native "LibraryMirror_members";
}
-class _LocalLibraryDependencyMirror extends _LocalMirror
+class _LibraryDependencyMirror extends Mirror
implements LibraryDependencyMirror {
final LibraryMirror sourceLibrary;
var _targetMirrorOrPrefix;
@@ -1107,7 +1097,7 @@
final bool isDeferred;
final List<InstanceMirror> metadata;
- _LocalLibraryDependencyMirror._(
+ _LibraryDependencyMirror._(
this.sourceLibrary,
this._targetMirrorOrPrefix,
List<dynamic> mutableCombinators,
@@ -1124,7 +1114,7 @@
bool get isExport => !isImport;
LibraryMirror get targetLibrary {
- if (_targetMirrorOrPrefix is _LocalLibraryMirror) {
+ if (_targetMirrorOrPrefix is _LibraryMirror) {
return _targetMirrorOrPrefix;
}
var mirrorOrNull = _tryUpgradePrefix(_targetMirrorOrPrefix);
@@ -1135,7 +1125,7 @@
}
Future<LibraryMirror> loadLibrary() {
- if (_targetMirrorOrPrefix is _LocalLibraryMirror) {
+ if (_targetMirrorOrPrefix is _LibraryMirror) {
return new Future.value(_targetMirrorOrPrefix);
}
var savedPrefix = _targetMirrorOrPrefix;
@@ -1150,25 +1140,24 @@
SourceLocation get location => null;
}
-class _LocalCombinatorMirror extends _LocalMirror implements CombinatorMirror {
+class _CombinatorMirror extends Mirror implements CombinatorMirror {
final List<Symbol> identifiers;
final bool isShow;
- _LocalCombinatorMirror._(identifierString, this.isShow)
+ _CombinatorMirror._(identifierString, this.isShow)
: this.identifiers =
new UnmodifiableListView<Symbol>(<Symbol>[_s(identifierString)]);
bool get isHide => !isShow;
}
-class _LocalMethodMirror extends _LocalDeclarationMirror
- implements MethodMirror {
+class _MethodMirror extends _DeclarationMirror implements MethodMirror {
final Type _instantiator;
final bool isStatic;
final int _kindFlags;
- _LocalMethodMirror._(reflectee, String simpleName, this._owner,
- this._instantiator, this.isStatic, this._kindFlags)
+ _MethodMirror._(reflectee, String simpleName, this._owner, this._instantiator,
+ this.isStatic, this._kindFlags)
: super._(reflectee, _s(simpleName));
static const kAbstract = 0;
@@ -1289,14 +1278,13 @@
static String _MethodMirror_source(reflectee) native "MethodMirror_source";
}
-class _LocalVariableMirror extends _LocalDeclarationMirror
- implements VariableMirror {
+class _VariableMirror extends _DeclarationMirror implements VariableMirror {
final DeclarationMirror owner;
final bool isStatic;
final bool isFinal;
final bool isConst;
- _LocalVariableMirror._(reflectee, String simpleName, this.owner, this._type,
+ _VariableMirror._(reflectee, String simpleName, this.owner, this._type,
this.isStatic, this.isFinal, this.isConst)
: super._(reflectee, _s(simpleName));
@@ -1304,11 +1292,11 @@
Type get _instantiator {
final o = owner; // Note: need local variable for promotion to happen.
- if (o is _LocalClassMirror) {
+ if (o is _ClassMirror) {
return o._instantiator;
- } else if (o is _LocalMethodMirror) {
+ } else if (o is _MethodMirror) {
return o._instantiator;
- } else if (o is _LocalLibraryMirror) {
+ } else if (o is _LibraryMirror) {
return o._instantiator;
} else {
throw new UnsupportedError("unexpected owner ${owner}");
@@ -1330,14 +1318,13 @@
native "VariableMirror_type";
}
-class _LocalParameterMirror extends _LocalVariableMirror
- implements ParameterMirror {
+class _ParameterMirror extends _VariableMirror implements ParameterMirror {
final int _position;
final bool isOptional;
final bool isNamed;
final List _unmirroredMetadata;
- _LocalParameterMirror._(
+ _ParameterMirror._(
reflectee,
String simpleName,
DeclarationMirror owner,
@@ -1396,7 +1383,7 @@
native "ParameterMirror_type";
}
-class _SpecialTypeMirror extends _LocalMirror
+class _SpecialTypeMirror extends Mirror
implements TypeMirror, DeclarationMirror {
final Symbol simpleName;
@@ -1445,7 +1432,7 @@
}
class _Mirrors {
- static MirrorSystem _currentMirrorSystem = new _LocalMirrorSystem();
+ static MirrorSystem _currentMirrorSystem = new _MirrorSystem();
static MirrorSystem currentMirrorSystem() {
return _currentMirrorSystem;
}
@@ -1453,8 +1440,8 @@
// Creates a new local mirror for some Object.
static InstanceMirror reflect(Object reflectee) {
return reflectee is Function
- ? new _LocalClosureMirror._(reflectee)
- : new _LocalInstanceMirror._(reflectee);
+ ? new _ClosureMirror._(reflectee)
+ : new _InstanceMirror._(reflectee);
}
static ClassMirror _makeLocalClassMirror(Type key)
@@ -1464,8 +1451,7 @@
static Type _instantiateGenericType(Type key, typeArguments)
native "Mirrors_instantiateGenericType";
- static Expando<_LocalClassMirror> _declarationCache =
- new Expando("ClassMirror");
+ static Expando<_ClassMirror> _declarationCache = new Expando("ClassMirror");
static Expando<TypeMirror> _instantiationCache = new Expando("TypeMirror");
static ClassMirror reflectClass(Type key) {
@@ -1488,7 +1474,7 @@
if (typeMirror == null) {
typeMirror = _makeLocalTypeMirror(key);
_instantiationCache[key] = typeMirror;
- if (typeMirror is _LocalClassMirror && !typeMirror._isGeneric) {
+ if (typeMirror is _ClassMirror && !typeMirror._isGeneric) {
_declarationCache[key] = typeMirror;
}
}
diff --git a/runtime/lib/mirrors_patch.dart b/sdk_nnbd/lib/_internal/vm/lib/mirrors_patch.dart
similarity index 98%
rename from runtime/lib/mirrors_patch.dart
rename to sdk_nnbd/lib/_internal/vm/lib/mirrors_patch.dart
index 623fd65..4c8a2f8 100644
--- a/runtime/lib/mirrors_patch.dart
+++ b/sdk_nnbd/lib/_internal/vm/lib/mirrors_patch.dart
@@ -2,6 +2,8 @@
// 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.5
+
/// Note: the VM concatenates all patch files into a single patch file. This
/// file is the first patch in "dart:_internal" which contains all the imports
/// used by patches of that library. We plan to change this when we have a
diff --git a/sdk_nnbd/lib/_internal/vm/lib/null_patch.dart b/sdk_nnbd/lib/_internal/vm/lib/null_patch.dart
new file mode 100644
index 0000000..ba721ad
--- /dev/null
+++ b/sdk_nnbd/lib/_internal/vm/lib/null_patch.dart
@@ -0,0 +1,18 @@
+// 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
+// BSD-style license that can be found in the LICENSE file.
+
+// @dart = 2.5
+
+// part of "core_patch.dart";
+
+@patch
+@pragma("vm:entry-point")
+class Null {
+ static const _HASH_CODE = 2011; // The year Dart was announced and a prime.
+
+ @patch
+ int get hashCode => _HASH_CODE;
+
+ int get _identityHashCode => _HASH_CODE;
+}
diff --git a/sdk_nnbd/lib/_internal/vm/lib/object_patch.dart b/sdk_nnbd/lib/_internal/vm/lib/object_patch.dart
new file mode 100644
index 0000000..9930fe7
--- /dev/null
+++ b/sdk_nnbd/lib/_internal/vm/lib/object_patch.dart
@@ -0,0 +1,77 @@
+// 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.5
+
+// part of "core_patch.dart";
+
+@pragma("vm:exact-result-type", "dart:core#_Smi")
+int _getHash(obj) native "Object_getHash";
+void _setHash(obj, hash) native "Object_setHash";
+
+@patch
+@pragma("vm:entry-point")
+class Object {
+ // The VM has its own implementation of equals.
+ @patch
+ @pragma("vm:exact-result-type", bool)
+ @pragma("vm:prefer-inline")
+ bool operator ==(other) native "Object_equals";
+
+ // Helpers used to implement hashCode. If a hashCode is used, we remember it
+ // in a weak table in the VM (32 bit) or in the header of the object (64
+ // bit). A new hashCode value is calculated using a random number generator.
+ static final _hashCodeRnd = new Random();
+
+ static int _objectHashCode(obj) {
+ var result = _getHash(obj);
+ if (result == 0) {
+ // We want the hash to be a Smi value greater than 0.
+ result = _hashCodeRnd.nextInt(0x40000000);
+ do {
+ result = _hashCodeRnd.nextInt(0x40000000);
+ } while (result == 0);
+ _setHash(obj, result);
+ }
+ return result;
+ }
+
+ @patch
+ int get hashCode => _objectHashCode(this);
+ int get _identityHashCode => _objectHashCode(this);
+
+ @patch
+ String toString() native "Object_toString";
+ // A statically dispatched version of Object.toString.
+ static String _toString(obj) native "Object_toString";
+
+ @patch
+ @pragma("vm:entry-point", "call")
+ dynamic noSuchMethod(Invocation invocation) {
+ // TODO(regis): Remove temp constructor identifier 'withInvocation'.
+ throw new NoSuchMethodError.withInvocation(this, invocation);
+ }
+
+ @patch
+ @pragma("vm:exact-result-type", "dart:core#_Type")
+ Type get runtimeType native "Object_runtimeType";
+
+ @pragma("vm:entry-point", "call")
+ @pragma("vm:exact-result-type", bool)
+ static bool _haveSameRuntimeType(a, b) native "Object_haveSameRuntimeType";
+
+ // Call this function instead of inlining instanceof, thus collecting
+ // type feedback and reducing code size of unoptimized code.
+ @pragma("vm:entry-point", "call")
+ bool _instanceOf(instantiatorTypeArguments, functionTypeArguments, type)
+ native "Object_instanceOf";
+
+ // Group of functions for implementing fast simple instance of.
+ @pragma("vm:entry-point", "call")
+ bool _simpleInstanceOf(type) native "Object_simpleInstanceOf";
+ @pragma("vm:entry-point", "call")
+ bool _simpleInstanceOfTrue(type) => true;
+ @pragma("vm:entry-point", "call")
+ bool _simpleInstanceOfFalse(type) => false;
+}
diff --git a/sdk_nnbd/lib/_internal/vm/lib/print_patch.dart b/sdk_nnbd/lib/_internal/vm/lib/print_patch.dart
new file mode 100644
index 0000000..a8ecb6b
--- /dev/null
+++ b/sdk_nnbd/lib/_internal/vm/lib/print_patch.dart
@@ -0,0 +1,25 @@
+// 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.5
+
+// part of "internal_patch.dart";
+
+// A print-closure gets a String that should be printed. In general the
+// string is a line, but it may contain "\n" characters.
+typedef void _PrintClosure(String line);
+
+@patch
+void printToConsole(String line) {
+ _printClosure(line);
+}
+
+void _unsupportedPrint(String line) {
+ throw new UnsupportedError("'print' is not supported");
+}
+
+// _printClosure can be overwritten by the embedder to supply a different
+// print implementation.
+@pragma("vm:entry-point")
+_PrintClosure _printClosure = _unsupportedPrint;
diff --git a/sdk_nnbd/lib/_internal/vm/lib/profiler.dart b/sdk_nnbd/lib/_internal/vm/lib/profiler.dart
new file mode 100644
index 0000000..2ecd7e0
--- /dev/null
+++ b/sdk_nnbd/lib/_internal/vm/lib/profiler.dart
@@ -0,0 +1,30 @@
+// Copyright (c) 2014, 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.5
+
+// part of "developer.dart";
+
+@patch
+class UserTag {
+ @patch
+ factory UserTag(String label) {
+ return new _UserTag(label);
+ }
+ @patch
+ static UserTag get defaultTag => _getDefaultTag();
+}
+
+@pragma("vm:entry-point")
+class _UserTag implements UserTag {
+ factory _UserTag(String label) native "UserTag_new";
+ String get label native "UserTag_label";
+ UserTag makeCurrent() native "UserTag_makeCurrent";
+}
+
+@patch
+UserTag getCurrentTag() => _getCurrentTag();
+UserTag _getCurrentTag() native "Profiler_getCurrentTag";
+
+UserTag _getDefaultTag() native "UserTag_defaultTag";
diff --git a/sdk_nnbd/lib/_internal/vm/lib/regexp_patch.dart b/sdk_nnbd/lib/_internal/vm/lib/regexp_patch.dart
new file mode 100644
index 0000000..e97b977
--- /dev/null
+++ b/sdk_nnbd/lib/_internal/vm/lib/regexp_patch.dart
@@ -0,0 +1,405 @@
+// 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.5
+
+// part of "core_patch.dart";
+
+@patch
+class RegExp {
+ @patch
+ factory RegExp(String source,
+ {bool multiLine: false,
+ bool caseSensitive: true,
+ bool unicode: false,
+ bool dotAll: false}) {
+ _RegExpHashKey key =
+ new _RegExpHashKey(source, multiLine, caseSensitive, unicode, dotAll);
+ _RegExpHashValue value = _cache[key];
+
+ if (value == null) {
+ if (_cache.length > _MAX_CACHE_SIZE) {
+ _RegExpHashKey lastKey = _recentlyUsed.last;
+ _recentlyUsed.remove(lastKey);
+ _cache.remove(lastKey);
+ }
+
+ value = new _RegExpHashValue(
+ new _RegExp(source,
+ multiLine: multiLine,
+ caseSensitive: caseSensitive,
+ unicode: unicode,
+ dotAll: dotAll),
+ key);
+ _cache[key] = value;
+ } else {
+ value.key.unlink();
+ }
+
+ assert(value != null);
+
+ _recentlyUsed.addFirst(value.key);
+ assert(_recentlyUsed.length == _cache.length);
+
+ // TODO(zerny): We might not want to canonicalize regexp objects.
+ return value.regexp;
+ }
+
+ /**
+ * Finds the index of the first RegExp-significant char in [text].
+ *
+ * Starts looking from [start]. Returns `text.length` if no character
+ * is found that has special meaning in RegExp syntax.
+ */
+ static int _findEscapeChar(String text, int start) {
+ // Table where each character in the range U+0000 to U+007f is represented
+ // by whether it needs to be escaped in a regexp.
+ // The \x00 characters means escacped, and \x01 means non-escaped.
+ const escapes =
+ "\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01"
+ "\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01"
+ // $ ( ) * + .
+ "\x01\x01\x01\x01\x00\x01\x01\x01\x00\x00\x00\x00\x01\x01\x00\x01"
+ // ?
+ "\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x00"
+ "\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01"
+ // [ \ ] ^
+ "\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x00\x00\x00\x00\x01"
+ "\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01"
+ // { | }
+ "\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x00\x00\x00\x01\x01";
+ for (int i = start; i < text.length; i++) {
+ int char = text.codeUnitAt(i);
+ if (char <= 0x7f && escapes.codeUnitAt(char) == 0) return i;
+ }
+ return text.length;
+ }
+
+ @patch
+ static String escape(String text) {
+ int escapeCharIndex = _findEscapeChar(text, 0);
+ // If the text contains no characters needing escape, return it directly.
+ if (escapeCharIndex == text.length) return text;
+
+ var buffer = new StringBuffer();
+ int previousSliceEndIndex = 0;
+ do {
+ // Copy characters from previous escape to current escape into result.
+ // This includes the previously escaped character.
+ buffer.write(text.substring(previousSliceEndIndex, escapeCharIndex));
+ // Prepare the current character to be escaped by prefixing it with a '\'.
+ buffer.write(r"\");
+ previousSliceEndIndex = escapeCharIndex;
+ escapeCharIndex = _findEscapeChar(text, escapeCharIndex + 1);
+ } while (escapeCharIndex < text.length);
+ // Copy tail of string into result.
+ buffer.write(text.substring(previousSliceEndIndex, escapeCharIndex));
+ return buffer.toString();
+ }
+
+ // Regular expression objects are stored in a cache of up to _MAX_CACHE_SIZE
+ // elements using an LRU eviction strategy.
+ // TODO(zerny): Do not impose a fixed limit on the number of cached objects.
+ // Other possibilities could be limiting by the size of the regexp objects,
+ // or imposing a lower time bound for the most recent use under which a regexp
+ // may not be removed from the cache.
+ // TODO(zerny): Use self-sizing cache similar to _AccessorCache in
+ // mirrors_impl.dart.
+ static const int _MAX_CACHE_SIZE = 256;
+ static final Map<_RegExpHashKey, _RegExpHashValue> _cache =
+ new HashMap<_RegExpHashKey, _RegExpHashValue>();
+ static final LinkedList<_RegExpHashKey> _recentlyUsed =
+ new LinkedList<_RegExpHashKey>();
+
+ int get _groupCount;
+ Iterable<String> get _groupNames;
+ int _groupNameIndex(String name);
+}
+
+// Represents both a key in the regular expression cache as well as its
+// corresponding entry in the LRU list.
+class _RegExpHashKey extends LinkedListEntry<_RegExpHashKey> {
+ final String pattern;
+ final bool multiLine;
+ final bool caseSensitive;
+ final bool unicode;
+ final bool dotAll;
+
+ _RegExpHashKey(this.pattern, this.multiLine, this.caseSensitive, this.unicode,
+ this.dotAll);
+
+ int get hashCode => pattern.hashCode;
+ bool operator ==(that) {
+ return (that is _RegExpHashKey) &&
+ (this.pattern == that.pattern) &&
+ (this.multiLine == that.multiLine) &&
+ (this.caseSensitive == that.caseSensitive) &&
+ (this.unicode == that.unicode) &&
+ (this.dotAll == that.dotAll);
+ }
+}
+
+// Represents a value in the regular expression cache. Contains a pointer
+// back to the key in order to access the corresponding LRU entry.
+class _RegExpHashValue {
+ final _RegExp regexp;
+ final _RegExpHashKey key;
+
+ _RegExpHashValue(this.regexp, this.key);
+}
+
+class _RegExpMatch implements RegExpMatch {
+ _RegExpMatch._(this._regexp, this.input, this._match);
+
+ int get start => _start(0);
+ int get end => _end(0);
+
+ int _start(int groupIdx) {
+ return _match[(groupIdx * _MATCH_PAIR)];
+ }
+
+ int _end(int groupIdx) {
+ return _match[(groupIdx * _MATCH_PAIR) + 1];
+ }
+
+ String group(int groupIdx) {
+ if (groupIdx < 0 || groupIdx > _regexp._groupCount) {
+ throw new RangeError.value(groupIdx);
+ }
+ int startIndex = _start(groupIdx);
+ int endIndex = _end(groupIdx);
+ if (startIndex == -1) {
+ assert(endIndex == -1);
+ return null;
+ }
+ return input._substringUnchecked(startIndex, endIndex);
+ }
+
+ String operator [](int groupIdx) {
+ return this.group(groupIdx);
+ }
+
+ List<String> groups(List<int> groupsSpec) {
+ var groupsList = new List<String>(groupsSpec.length);
+ for (int i = 0; i < groupsSpec.length; i++) {
+ groupsList[i] = group(groupsSpec[i]);
+ }
+ return groupsList;
+ }
+
+ int get groupCount => _regexp._groupCount;
+
+ Pattern get pattern => _regexp;
+
+ String namedGroup(String name) {
+ var idx = _regexp._groupNameIndex(name);
+ if (idx < 0) {
+ throw ArgumentError("Not a capture group name: ${name}");
+ }
+ return group(idx);
+ }
+
+ Iterable<String> get groupNames {
+ return _regexp._groupNames;
+ }
+
+ final RegExp _regexp;
+ final String input;
+ final List<int> _match;
+ static const int _MATCH_PAIR = 2;
+}
+
+@pragma("vm:entry-point")
+class _RegExp implements RegExp {
+ factory _RegExp(String pattern,
+ {bool multiLine: false,
+ bool caseSensitive: true,
+ bool unicode: false,
+ bool dotAll: false}) native "RegExp_factory";
+
+ RegExpMatch firstMatch(String str) {
+ if (str is! String) throw new ArgumentError(str);
+ List match = _ExecuteMatch(str, 0);
+ if (match == null) {
+ return null;
+ }
+ return new _RegExpMatch._(this, str, match);
+ }
+
+ Iterable<RegExpMatch> allMatches(String string, [int start = 0]) {
+ if (string is! String) throw new ArgumentError(string);
+ if (start is! int) throw new ArgumentError(start);
+ if (0 > start || start > string.length) {
+ throw new RangeError.range(start, 0, string.length);
+ }
+ return new _AllMatchesIterable(this, string, start);
+ }
+
+ RegExpMatch matchAsPrefix(String string, [int start = 0]) {
+ if (string is! String) throw new ArgumentError(string);
+ if (start is! int) throw new ArgumentError(start);
+ if (start < 0 || start > string.length) {
+ throw new RangeError.range(start, 0, string.length);
+ }
+ List<int> list = _ExecuteMatchSticky(string, start);
+ if (list == null) return null;
+ return new _RegExpMatch._(this, string, list);
+ }
+
+ bool hasMatch(String str) {
+ if (str is! String) throw new ArgumentError(str);
+ List match = _ExecuteMatch(str, 0);
+ return (match == null) ? false : true;
+ }
+
+ String stringMatch(String str) {
+ if (str is! String) throw new ArgumentError(str);
+ List match = _ExecuteMatch(str, 0);
+ if (match == null) {
+ return null;
+ }
+ return str._substringUnchecked(match[0], match[1]);
+ }
+
+ String get pattern native "RegExp_getPattern";
+
+ bool get isMultiLine native "RegExp_getIsMultiLine";
+
+ bool get isCaseSensitive native "RegExp_getIsCaseSensitive";
+
+ bool get isUnicode native "RegExp_getIsUnicode";
+
+ bool get isDotAll native "RegExp_getIsDotAll";
+
+ int get _groupCount native "RegExp_getGroupCount";
+
+ // Returns a List [String, int, String, int, ...] where each
+ // String is the name of a capture group and the following
+ // int is that capture group's index.
+ List get _groupNameList native "RegExp_getGroupNameMap";
+
+ Iterable<String> get _groupNames sync* {
+ final nameList = _groupNameList;
+ for (var i = 0; i < nameList.length; i += 2) {
+ yield nameList[i] as String;
+ }
+ }
+
+ int _groupNameIndex(String name) {
+ var nameList = _groupNameList;
+ for (var i = 0; i < nameList.length; i += 2) {
+ if (name == nameList[i]) {
+ return nameList[i + 1];
+ }
+ }
+ return -1;
+ }
+
+ // Byte map of one byte characters with a 0xff if the character is a word
+ // character (digit, letter or underscore) and 0x00 otherwise.
+ // Used by generated RegExp code.
+ static const List<int> _wordCharacterMap = const <int>[
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, // '0' - '7'
+ 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // '8' - '9'
+
+ 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, // 'A' - 'G'
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, // 'H' - 'O'
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, // 'P' - 'W'
+ 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, // 'X' - 'Z', '_'
+
+ 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, // 'a' - 'g'
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, // 'h' - 'o'
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, // 'p' - 'w'
+ 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, // 'x' - 'z'
+ // Latin-1 range
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ ];
+
+ List _ExecuteMatch(String str, int start_index) native "RegExp_ExecuteMatch";
+
+ List _ExecuteMatchSticky(String str, int start_index)
+ native "RegExp_ExecuteMatchSticky";
+}
+
+class _AllMatchesIterable extends IterableBase<RegExpMatch> {
+ final _RegExp _re;
+ final String _str;
+ final int _start;
+
+ _AllMatchesIterable(this._re, this._str, this._start);
+
+ Iterator<RegExpMatch> get iterator =>
+ new _AllMatchesIterator(_re, _str, _start);
+}
+
+class _AllMatchesIterator implements Iterator<RegExpMatch> {
+ final String _str;
+ int _nextIndex;
+ _RegExp _re;
+ RegExpMatch _current;
+
+ _AllMatchesIterator(this._re, this._str, this._nextIndex);
+
+ RegExpMatch get current => _current;
+
+ static bool _isLeadSurrogate(int c) {
+ return c >= 0xd800 && c <= 0xdbff;
+ }
+
+ static bool _isTrailSurrogate(int c) {
+ return c >= 0xdc00 && c <= 0xdfff;
+ }
+
+ bool moveNext() {
+ if (_re == null) return false; // Cleared after a failed match.
+ if (_nextIndex <= _str.length) {
+ var match = _re._ExecuteMatch(_str, _nextIndex);
+ if (match != null) {
+ _current = new _RegExpMatch._(_re, _str, match);
+ _nextIndex = _current.end;
+ if (_nextIndex == _current.start) {
+ // Zero-width match. Advance by one more, unless the regexp
+ // is in unicode mode and it would put us within a surrogate
+ // pair. In that case, advance past the code point as a whole.
+ if (_re.isUnicode &&
+ _nextIndex + 1 < _str.length &&
+ _isLeadSurrogate(_str.codeUnitAt(_nextIndex)) &&
+ _isTrailSurrogate(_str.codeUnitAt(_nextIndex + 1))) {
+ _nextIndex++;
+ }
+ _nextIndex++;
+ }
+ return true;
+ }
+ }
+ _current = null;
+ _re = null;
+ return false;
+ }
+}
diff --git a/sdk_nnbd/lib/_internal/vm/lib/schedule_microtask_patch.dart b/sdk_nnbd/lib/_internal/vm/lib/schedule_microtask_patch.dart
new file mode 100644
index 0000000..7fc8317
--- /dev/null
+++ b/sdk_nnbd/lib/_internal/vm/lib/schedule_microtask_patch.dart
@@ -0,0 +1,34 @@
+// 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
+// BSD-style license that can be found in the LICENSE file.
+
+// @dart = 2.5
+
+// part of "async_patch.dart";
+
+@patch
+class _AsyncRun {
+ @patch
+ static void _scheduleImmediate(void callback()) {
+ if (_ScheduleImmediate._closure == null) {
+ throw new UnsupportedError("Microtasks are not supported");
+ }
+ _ScheduleImmediate._closure(callback);
+ }
+}
+
+typedef void _ScheduleImmediateClosure(void callback());
+
+class _ScheduleImmediate {
+ static _ScheduleImmediateClosure _closure;
+}
+
+@pragma("vm:entry-point", "call")
+void _setScheduleImmediateClosure(_ScheduleImmediateClosure closure) {
+ _ScheduleImmediate._closure = closure;
+}
+
+@pragma("vm:entry-point", "call")
+void _ensureScheduleImmediate() {
+ _AsyncRun._scheduleImmediate(_startMicrotaskLoop);
+}
diff --git a/sdk_nnbd/lib/_internal/vm/lib/stacktrace.dart b/sdk_nnbd/lib/_internal/vm/lib/stacktrace.dart
new file mode 100644
index 0000000..fc7c633
--- /dev/null
+++ b/sdk_nnbd/lib/_internal/vm/lib/stacktrace.dart
@@ -0,0 +1,13 @@
+// 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
+// BSD-style license that can be found in the LICENSE file.
+
+// @dart = 2.5
+
+// part of "core_patch.dart";
+
+/// VM internal StackTrace implementation.
+@pragma("vm:entry-point")
+class _StackTrace implements StackTrace {
+ // toString() is overridden on the C++ side.
+}
diff --git a/sdk_nnbd/lib/_internal/vm/lib/stopwatch_patch.dart b/sdk_nnbd/lib/_internal/vm/lib/stopwatch_patch.dart
new file mode 100644
index 0000000..1aad490
--- /dev/null
+++ b/sdk_nnbd/lib/_internal/vm/lib/stopwatch_patch.dart
@@ -0,0 +1,58 @@
+// 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.5
+
+// part of "core_patch.dart";
+
+@patch
+class Stopwatch {
+ static const _maxInt = 0x7FFFFFFFFFFFFFFF;
+
+ @patch
+ static void _initTicker() {
+ if (_frequency == null) {
+ _frequency = _computeFrequency();
+ }
+ }
+
+ // Returns the current clock tick.
+ @patch
+ static int _now() native "Stopwatch_now";
+
+ // Returns the frequency of clock ticks in Hz.
+ static int _computeFrequency() native "Stopwatch_frequency";
+
+ @patch
+ int get elapsedMicroseconds {
+ int ticks = elapsedTicks;
+ // Special case the more likely frequencies to avoid division,
+ // or divide by a known value.
+ if (_frequency == 1000000000) return ticks ~/ 1000;
+ if (_frequency == 1000000) return ticks;
+ if (_frequency == 1000) return ticks * 1000;
+ if (ticks <= (_maxInt ~/ 1000000)) {
+ return (ticks * 1000000) ~/ _frequency;
+ }
+ // Multiplication would have overflowed.
+ int ticksPerSecond = ticks ~/ _frequency;
+ int remainingTicks = ticks.remainder(_frequency);
+ return ticksPerSecond * 1000000 + (remainingTicks * 1000000) ~/ _frequency;
+ }
+
+ @patch
+ int get elapsedMilliseconds {
+ int ticks = elapsedTicks;
+ if (_frequency == 1000000000) return ticks ~/ 1000000;
+ if (_frequency == 1000000) return ticks ~/ 1000;
+ if (_frequency == 1000) return ticks;
+ if (ticks <= (_maxInt ~/ 1000)) {
+ return (ticks * 1000) ~/ _frequency;
+ }
+ // Multiplication would have overflowed.
+ int ticksPerSecond = ticks ~/ _frequency;
+ int remainingTicks = ticks.remainder(_frequency);
+ return ticksPerSecond * 1000 + (remainingTicks * 1000) ~/ _frequency;
+ }
+}
diff --git a/sdk_nnbd/lib/_internal/vm/lib/string_buffer_patch.dart b/sdk_nnbd/lib/_internal/vm/lib/string_buffer_patch.dart
new file mode 100644
index 0000000..1403da4
--- /dev/null
+++ b/sdk_nnbd/lib/_internal/vm/lib/string_buffer_patch.dart
@@ -0,0 +1,198 @@
+// 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.5
+
+// part of "core_patch.dart";
+
+@patch
+class StringBuffer {
+ static const int _BUFFER_SIZE = 64;
+ static const int _PARTS_TO_COMPACT = 128;
+ static const int _PARTS_TO_COMPACT_SIZE_LIMIT = _PARTS_TO_COMPACT * 8;
+
+ /**
+ * When strings are written to the string buffer, we add them to a
+ * list of string parts.
+ */
+ List<String> _parts;
+
+ /**
+ * Total number of code units in the string parts. Does not include
+ * the code units added to the buffer.
+ */
+ int _partsCodeUnits = 0;
+
+ /**
+ * To preserve memory, we sometimes compact the parts. This combines
+ * several smaller parts into a single larger part to cut down on the
+ * cost that comes from the per-object memory overhead. We keep track
+ * of the last index where we ended our compaction and the number of
+ * code units added since the last compaction.
+ */
+ int _partsCompactionIndex = 0;
+ int _partsCodeUnitsSinceCompaction = 0;
+
+ /**
+ * The buffer is used to build up a string from code units. It is
+ * used when writing short strings or individual char codes to the
+ * buffer. The buffer is allocated on demand.
+ */
+ Uint16List _buffer;
+ int _bufferPosition = 0;
+
+ /**
+ * Collects the approximate maximal magnitude of the code units added
+ * to the buffer.
+ *
+ * The value of each added code unit is or'ed with this variable, so the
+ * most significant bit set in any code unit is also set in this value.
+ * If below 256, the string in the buffer is a Latin-1 string.
+ */
+ int _bufferCodeUnitMagnitude = 0;
+
+ /// Creates the string buffer with an initial content.
+ @patch
+ StringBuffer([Object content = ""]) {
+ write(content);
+ }
+
+ @patch
+ int get length => _partsCodeUnits + _bufferPosition;
+
+ @patch
+ void write(Object obj) {
+ String str = '$obj';
+ if (str.isEmpty) return;
+ _consumeBuffer();
+ _addPart(str);
+ }
+
+ @patch
+ void writeCharCode(int charCode) {
+ if (charCode <= 0xFFFF) {
+ if (charCode < 0) {
+ throw new RangeError.range(charCode, 0, 0x10FFFF);
+ }
+ _ensureCapacity(1);
+ _buffer[_bufferPosition++] = charCode;
+ _bufferCodeUnitMagnitude |= charCode;
+ } else {
+ if (charCode > 0x10FFFF) {
+ throw new RangeError.range(charCode, 0, 0x10FFFF);
+ }
+ _ensureCapacity(2);
+ int bits = charCode - 0x10000;
+ _buffer[_bufferPosition++] = 0xD800 | (bits >> 10);
+ _buffer[_bufferPosition++] = 0xDC00 | (bits & 0x3FF);
+ _bufferCodeUnitMagnitude |= 0xFFFF;
+ }
+ }
+
+ @patch
+ void writeAll(Iterable objects, [String separator = ""]) {
+ Iterator iterator = objects.iterator;
+ if (!iterator.moveNext()) return;
+ if (separator.isEmpty) {
+ do {
+ write(iterator.current);
+ } while (iterator.moveNext());
+ } else {
+ write(iterator.current);
+ while (iterator.moveNext()) {
+ write(separator);
+ write(iterator.current);
+ }
+ }
+ }
+
+ @patch
+ void writeln([Object obj = ""]) {
+ write(obj);
+ write("\n");
+ }
+
+ /** Makes the buffer empty. */
+ @patch
+ void clear() {
+ _parts = null;
+ _partsCodeUnits = _bufferPosition = _bufferCodeUnitMagnitude = 0;
+ }
+
+ /** Returns the contents of buffer as a string. */
+ @patch
+ String toString() {
+ _consumeBuffer();
+ return (_partsCodeUnits == 0)
+ ? ""
+ : _StringBase._concatRange(_parts, 0, _parts.length);
+ }
+
+ /** Ensures that the buffer has enough capacity to add n code units. */
+ void _ensureCapacity(int n) {
+ if (_buffer == null) {
+ _buffer = new Uint16List(_BUFFER_SIZE);
+ } else if (_bufferPosition + n > _buffer.length) {
+ _consumeBuffer();
+ }
+ }
+
+ /**
+ * Consumes the content of the buffer by turning it into a string
+ * and adding it as a part. After calling this the buffer position
+ * will be reset to zero.
+ */
+ void _consumeBuffer() {
+ if (_bufferPosition == 0) return;
+ bool isLatin1 = _bufferCodeUnitMagnitude <= 0xFF;
+ String str = _create(_buffer, _bufferPosition, isLatin1);
+ _bufferPosition = _bufferCodeUnitMagnitude = 0;
+ _addPart(str);
+ }
+
+ /**
+ * Adds a new part to this string buffer and keeps track of how
+ * many code units are contained in the parts.
+ */
+ void _addPart(String str) {
+ int length = str.length;
+ _partsCodeUnits += length;
+ _partsCodeUnitsSinceCompaction += length;
+
+ if (_parts == null) {
+ // Empirically this is a good capacity to minimize total bytes allocated.
+ _parts = new _GrowableList.withCapacity(10)..add(str);
+ } else {
+ _parts.add(str);
+ int partsSinceCompaction = _parts.length - _partsCompactionIndex;
+ if (partsSinceCompaction == _PARTS_TO_COMPACT) {
+ _compact();
+ }
+ }
+ }
+
+ /**
+ * Compacts the last N parts if their average size allows us to save a
+ * lot of memory by turning them all into a single part.
+ */
+ void _compact() {
+ if (_partsCodeUnitsSinceCompaction < _PARTS_TO_COMPACT_SIZE_LIMIT) {
+ String compacted = _StringBase._concatRange(
+ _parts,
+ _partsCompactionIndex, // Start
+ _partsCompactionIndex + _PARTS_TO_COMPACT // End
+ );
+ _parts.length = _parts.length - _PARTS_TO_COMPACT;
+ _parts.add(compacted);
+ }
+ _partsCodeUnitsSinceCompaction = 0;
+ _partsCompactionIndex = _parts.length;
+ }
+
+ /**
+ * Create a [String] from the UFT-16 code units in buffer.
+ */
+ static String _create(Uint16List buffer, int length, bool isLatin1)
+ native "StringBuffer_createStringFromUint16Array";
+}
diff --git a/runtime/lib/string_patch.dart b/sdk_nnbd/lib/_internal/vm/lib/string_patch.dart
similarity index 98%
rename from runtime/lib/string_patch.dart
rename to sdk_nnbd/lib/_internal/vm/lib/string_patch.dart
index c08bd49..cc3dc07 100644
--- a/runtime/lib/string_patch.dart
+++ b/sdk_nnbd/lib/_internal/vm/lib/string_patch.dart
@@ -2,6 +2,8 @@
// 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.5
+
// part of "core_patch.dart";
const int _maxAscii = 0x7f;
@@ -948,7 +950,9 @@
@pragma("vm:entry-point")
class _OneByteString extends _StringBase {
- factory _OneByteString._uninstantiable() { throw "Unreachable"; }
+ factory _OneByteString._uninstantiable() {
+ throw "Unreachable";
+ }
@pragma("vm:exact-result-type", "dart:core#_Smi")
int get hashCode native "String_getHashCode";
@@ -1254,7 +1258,9 @@
@pragma("vm:entry-point")
class _TwoByteString extends _StringBase {
- factory _TwoByteString._uninstantiable() { throw "Unreachable"; }
+ factory _TwoByteString._uninstantiable() {
+ throw "Unreachable";
+ }
static String _allocateFromTwoByteList(List<int> list, int start, int end)
native "TwoByteString_allocateFromTwoByteList";
@@ -1274,7 +1280,9 @@
@pragma("vm:entry-point")
class _ExternalOneByteString extends _StringBase {
- factory _ExternalOneByteString._uninstantiable() { throw "Unreachable"; }
+ factory _ExternalOneByteString._uninstantiable() {
+ throw "Unreachable";
+ }
bool _isWhitespace(int codeUnit) {
return _StringBase._isOneByteWhitespace(codeUnit);
@@ -1290,7 +1298,9 @@
@pragma("vm:entry-point")
class _ExternalTwoByteString extends _StringBase {
- factory _ExternalTwoByteString._uninstantiable() { throw "Unreachable"; }
+ factory _ExternalTwoByteString._uninstantiable() {
+ throw "Unreachable";
+ }
bool _isWhitespace(int codeUnit) {
return _StringBase._isTwoByteWhitespace(codeUnit);
diff --git a/sdk_nnbd/lib/_internal/vm/lib/symbol_patch.dart b/sdk_nnbd/lib/_internal/vm/lib/symbol_patch.dart
new file mode 100644
index 0000000..eb7a0f8
--- /dev/null
+++ b/sdk_nnbd/lib/_internal/vm/lib/symbol_patch.dart
@@ -0,0 +1,62 @@
+// 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
+// BSD-style license that can be found in the LICENSE file.
+
+// @dart = 2.5
+
+// part of "internal_patch.dart";
+
+@patch
+class Symbol {
+ @patch
+ const Symbol(String name) : this._name = name;
+
+ @patch
+ toString() => 'Symbol("${computeUnmangledName(this)}")';
+
+ @patch
+ static String computeUnmangledName(Symbol symbol) {
+ String string = Symbol.getName(symbol);
+
+ // get:foo -> foo
+ // set:foo -> foo=
+ // get:_foo@xxx -> _foo
+ // set:_foo@xxx -> _foo=
+ // Class._constructor@xxx -> Class._constructor
+ // _Class@xxx._constructor@xxx -> _Class._constructor
+ // lib._S@xxx with lib._M1@xxx, lib._M2@xxx -> lib._S with lib._M1, lib._M2
+ StringBuffer result = new StringBuffer();
+ bool add_setter_suffix = false;
+ var pos = 0;
+ if (string.length >= 4 && string[3] == ':') {
+ // Drop 'get:' or 'set:' prefix.
+ pos = 4;
+ if (string[0] == 's') {
+ add_setter_suffix = true;
+ }
+ }
+ // Skip everything between AT and PERIOD, SPACE, COMMA or END
+ bool skip = false;
+ for (; pos < string.length; pos++) {
+ var char = string[pos];
+ if (char == '@') {
+ skip = true;
+ } else if (char == '.' || char == ' ' || char == ',') {
+ skip = false;
+ }
+ if (!skip) {
+ result.write(char);
+ }
+ }
+ if (add_setter_suffix) {
+ result.write('=');
+ }
+ return result.toString();
+ }
+
+ @patch
+ int get hashCode {
+ const arbitraryPrime = 664597;
+ return 0x1fffffff & (arbitraryPrime * _name.hashCode);
+ }
+}
diff --git a/sdk_nnbd/lib/_internal/vm/lib/timeline.dart b/sdk_nnbd/lib/_internal/vm/lib/timeline.dart
new file mode 100644
index 0000000..9b3ed42
--- /dev/null
+++ b/sdk_nnbd/lib/_internal/vm/lib/timeline.dart
@@ -0,0 +1,35 @@
+// Copyright (c) 2015, 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.5
+
+// part of "developer.dart";
+
+@patch
+bool _isDartStreamEnabled() native "Timeline_isDartStreamEnabled";
+
+@patch
+int _getTraceClock() native "Timeline_getTraceClock";
+
+@patch
+int _getThreadCpuClock() native "Timeline_getThreadCpuClock";
+
+@patch
+int _getNextAsyncId() native "Timeline_getNextAsyncId";
+
+@patch
+void _reportTaskEvent(int start, int taskId, String phase, String category,
+ String name, String argumentsAsJson) native "Timeline_reportTaskEvent";
+
+@patch
+void _reportCompleteEvent(int start, int startCpu, String category, String name,
+ String argumentsAsJson) native "Timeline_reportCompleteEvent";
+
+@patch
+void _reportFlowEvent(int start, int startCpu, String category, String name,
+ int type, int id, String argumentsAsJson) native "Timeline_reportFlowEvent";
+
+@patch
+void _reportInstantEvent(int start, String category, String name,
+ String argumentsAsJson) native "Timeline_reportInstantEvent";
diff --git a/sdk_nnbd/lib/_internal/vm/lib/timer_impl.dart b/sdk_nnbd/lib/_internal/vm/lib/timer_impl.dart
new file mode 100644
index 0000000..fe80645
--- /dev/null
+++ b/sdk_nnbd/lib/_internal/vm/lib/timer_impl.dart
@@ -0,0 +1,471 @@
+// 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
+// BSD-style license that can be found in the LICENSE file.
+
+// @dart = 2.5
+
+// part of "isolate_patch.dart";
+
+// Timer heap implemented as a array-based binary heap[0].
+// This allows for O(1) `first`, O(log(n)) `remove`/`removeFirst` and O(log(n))
+// `add`.
+//
+// To ensure the timers are ordered by insertion time, the _Timer class has a
+// `_id` field set when added to the heap.
+//
+// [0] http://en.wikipedia.org/wiki/Binary_heap
+class _TimerHeap {
+ List<_Timer> _list;
+ int _used = 0;
+
+ _TimerHeap([int initSize = 7]) : _list = new List<_Timer>(initSize);
+
+ bool get isEmpty => _used == 0;
+
+ _Timer get first => _list[0];
+
+ bool isFirst(_Timer timer) => timer._indexOrNext == 0;
+
+ void add(_Timer timer) {
+ if (_used == _list.length) {
+ _resize();
+ }
+ timer._indexOrNext = _used++;
+ _list[timer._indexOrNext] = timer;
+ _bubbleUp(timer);
+ }
+
+ _Timer removeFirst() {
+ var f = first;
+ remove(f);
+ return f;
+ }
+
+ void remove(_Timer timer) {
+ _used--;
+ if (isEmpty) {
+ _list[0] = null;
+ timer._indexOrNext = null;
+ return;
+ }
+ var last = _list[_used];
+ if (!identical(last, timer)) {
+ last._indexOrNext = timer._indexOrNext;
+ _list[last._indexOrNext] = last;
+ if (last._compareTo(timer) < 0) {
+ _bubbleUp(last);
+ } else {
+ _bubbleDown(last);
+ }
+ }
+ _list[_used] = null;
+ timer._indexOrNext = null;
+ }
+
+ void _resize() {
+ var newList = new List<_Timer>(_list.length * 2 + 1);
+ newList.setRange(0, _used, _list);
+ _list = newList;
+ }
+
+ void _bubbleUp(_Timer timer) {
+ while (!isFirst(timer)) {
+ Timer parent = _parent(timer);
+ if (timer._compareTo(parent) < 0) {
+ _swap(timer, parent);
+ } else {
+ break;
+ }
+ }
+ }
+
+ void _bubbleDown(_Timer timer) {
+ while (true) {
+ int leftIndex = _leftChildIndex(timer._indexOrNext);
+ int rightIndex = _rightChildIndex(timer._indexOrNext);
+ _Timer newest = timer;
+ if (leftIndex < _used && _list[leftIndex]._compareTo(newest) < 0) {
+ newest = _list[leftIndex];
+ }
+ if (rightIndex < _used && _list[rightIndex]._compareTo(newest) < 0) {
+ newest = _list[rightIndex];
+ }
+ if (identical(newest, timer)) {
+ // We are where we should be, break.
+ break;
+ }
+ _swap(newest, timer);
+ }
+ }
+
+ void _swap(_Timer first, _Timer second) {
+ int tmp = first._indexOrNext;
+ first._indexOrNext = second._indexOrNext;
+ second._indexOrNext = tmp;
+ _list[first._indexOrNext] = first;
+ _list[second._indexOrNext] = second;
+ }
+
+ Timer _parent(_Timer timer) => _list[_parentIndex(timer._indexOrNext)];
+ Timer _leftChild(_Timer timer) => _list[_leftChildIndex(timer._indexOrNext)];
+ Timer _rightChild(_Timer timer) =>
+ _list[_rightChildIndex(timer._indexOrNext)];
+
+ static int _parentIndex(int index) => (index - 1) ~/ 2;
+ static int _leftChildIndex(int index) => 2 * index + 1;
+ static int _rightChildIndex(int index) => 2 * index + 2;
+}
+
+class _Timer implements Timer {
+ // Cancels the timer in the event handler.
+ static const _NO_TIMER = -1;
+
+ // We distinguish what kind of message arrived based on the value being sent.
+ static const _ZERO_EVENT = 1;
+ static const _TIMEOUT_EVENT = null;
+
+ // Timers are ordered by wakeup time. Timers with a timeout value of > 0 do
+ // end up on the TimerHeap. Timers with a timeout of 0 are queued in a list.
+ static final _heap = new _TimerHeap();
+ static _Timer _firstZeroTimer;
+ static _Timer _lastZeroTimer;
+
+ // We use an id to be able to sort timers with the same expiration time.
+ // ids are recycled after ID_MASK enqueues or when the timer queue is empty.
+ static const _ID_MASK = 0x1fffffff;
+ static int _idCount = 0;
+
+ static RawReceivePort _receivePort;
+ static SendPort _sendPort;
+ static int _scheduledWakeupTime;
+
+ static bool _handlingCallbacks = false;
+
+ Function _callback; // Closure to call when timer fires. null if canceled.
+ int _wakeupTime; // Expiration time.
+ final int _milliSeconds; // Duration specified at creation.
+ final bool _repeating; // Indicates periodic timers.
+ var _indexOrNext; // Index if part of the TimerHeap, link otherwise.
+ int _id; // Incrementing id to enable sorting of timers with same expiry.
+
+ int _tick = 0; // Backing for [tick],
+
+ // Get the next available id. We accept collisions and reordering when the
+ // _idCount overflows and the timers expire at the same millisecond.
+ static int _nextId() {
+ var result = _idCount;
+ _idCount = (_idCount + 1) & _ID_MASK;
+ return result;
+ }
+
+ _Timer._internal(
+ this._callback, this._wakeupTime, this._milliSeconds, this._repeating)
+ : _id = _nextId();
+
+ static Timer _createTimer(
+ void callback(Timer timer), int milliSeconds, bool repeating) {
+ // Negative timeouts are treated as if 0 timeout.
+ if (milliSeconds < 0) {
+ milliSeconds = 0;
+ }
+ // Add one because DateTime.now() is assumed to round down
+ // to nearest millisecond, not up, so that time + duration is before
+ // duration milliseconds from now. Using microsecond timers like
+ // Stopwatch allows detecting that the timer fires early.
+ int now = VMLibraryHooks.timerMillisecondClock();
+ int wakeupTime = (milliSeconds == 0) ? now : (now + 1 + milliSeconds);
+
+ _Timer timer =
+ new _Timer._internal(callback, wakeupTime, milliSeconds, repeating);
+ // Enqueue this newly created timer in the appropriate structure and
+ // notify if necessary.
+ timer._enqueue();
+ return timer;
+ }
+
+ factory _Timer(int milliSeconds, void callback(Timer timer)) {
+ return _createTimer(callback, milliSeconds, false);
+ }
+
+ factory _Timer.periodic(int milliSeconds, void callback(Timer timer)) {
+ return _createTimer(callback, milliSeconds, true);
+ }
+
+ bool get _isInHeap => _indexOrNext is int;
+
+ int _compareTo(_Timer other) {
+ int c = _wakeupTime - other._wakeupTime;
+ if (c != 0) return c;
+ return _id - other._id;
+ }
+
+ bool get isActive => _callback != null;
+
+ int get tick => _tick;
+
+ // Cancels a set timer. The timer is removed from the timer heap if it is a
+ // non-zero timer. Zero timers are kept in the list as they need to consume
+ // the corresponding pending message.
+ void cancel() {
+ _callback = null;
+ // Only heap timers are really removed. Zero timers need to consume their
+ // corresponding wakeup message so they are left in the queue.
+ if (!_isInHeap) return;
+ bool update = _heap.isFirst(this);
+ _heap.remove(this);
+ if (update) {
+ _notifyEventHandler();
+ }
+ }
+
+ void _advanceWakeupTime() {
+ // Recalculate the next wakeup time. For repeating timers with a 0 timeout
+ // the next wakeup time is now.
+ _id = _nextId();
+ if (_milliSeconds > 0) {
+ _wakeupTime += _milliSeconds;
+ } else {
+ _wakeupTime = VMLibraryHooks.timerMillisecondClock();
+ }
+ }
+
+ // Adds a timer to the heap or timer list. Timers with the same wakeup time
+ // are enqueued in order and notified in FIFO order.
+ void _enqueue() {
+ if (_milliSeconds == 0) {
+ if (_firstZeroTimer == null) {
+ _lastZeroTimer = this;
+ _firstZeroTimer = this;
+ } else {
+ _lastZeroTimer._indexOrNext = this;
+ _lastZeroTimer = this;
+ }
+ // Every zero timer gets its own event.
+ _notifyZeroHandler();
+ } else {
+ _heap.add(this);
+ if (_heap.isFirst(this)) {
+ _notifyEventHandler();
+ }
+ }
+ }
+
+ // Enqueue one message for each zero timer. To be able to distinguish from
+ // EventHandler messages we send a _ZERO_EVENT instead of a _TIMEOUT_EVENT.
+ static void _notifyZeroHandler() {
+ if (_sendPort == null) {
+ _createTimerHandler();
+ }
+ _sendPort.send(_ZERO_EVENT);
+ }
+
+ // Handle the notification of a zero timer. Make sure to also execute non-zero
+ // timers with a lower expiration time.
+ static List _queueFromZeroEvent() {
+ var pendingTimers = new List();
+ assert(_firstZeroTimer != null);
+ // Collect pending timers from the timer heap that have an expiration prior
+ // to the currently notified zero timer.
+ var timer;
+ while (!_heap.isEmpty && (_heap.first._compareTo(_firstZeroTimer) < 0)) {
+ timer = _heap.removeFirst();
+ pendingTimers.add(timer);
+ }
+ // Append the first zero timer to the pending timers.
+ timer = _firstZeroTimer;
+ _firstZeroTimer = timer._indexOrNext;
+ timer._indexOrNext = null;
+ pendingTimers.add(timer);
+ return pendingTimers;
+ }
+
+ static void _notifyEventHandler() {
+ if (_handlingCallbacks) {
+ // While we are already handling callbacks we will not notify the event
+ // handler. _handleTimeout will call _notifyEventHandler once all pending
+ // timers are processed.
+ return;
+ }
+
+ // If there are no pending timers. Close down the receive port.
+ if ((_firstZeroTimer == null) && _heap.isEmpty) {
+ // No pending timers: Close the receive port and let the event handler
+ // know.
+ if (_sendPort != null) {
+ _cancelWakeup();
+ _shutdownTimerHandler();
+ }
+ return;
+ } else if (_heap.isEmpty) {
+ // Only zero timers are left. Cancel any scheduled wakeups.
+ _cancelWakeup();
+ return;
+ }
+
+ // Only send a message if the requested wakeup time differs from the
+ // already scheduled wakeup time.
+ var wakeupTime = _heap.first._wakeupTime;
+ if ((_scheduledWakeupTime == null) ||
+ (wakeupTime != _scheduledWakeupTime)) {
+ _scheduleWakeup(wakeupTime);
+ }
+ }
+
+ static List _queueFromTimeoutEvent() {
+ var pendingTimers = new List();
+ if (_firstZeroTimer != null) {
+ // Collect pending timers from the timer heap that have an expiration
+ // prior to the next zero timer.
+ // By definition the first zero timer has been scheduled before the
+ // current time, meaning all timers which are "less than" the first zero
+ // timer are expired. The first zero timer will be dispatched when its
+ // corresponding message is delivered.
+ var timer;
+ while (!_heap.isEmpty && (_heap.first._compareTo(_firstZeroTimer) < 0)) {
+ timer = _heap.removeFirst();
+ pendingTimers.add(timer);
+ }
+ } else {
+ // Collect pending timers from the timer heap which have expired at this
+ // time.
+ var currentTime = VMLibraryHooks.timerMillisecondClock();
+ var timer;
+ while (!_heap.isEmpty && (_heap.first._wakeupTime <= currentTime)) {
+ timer = _heap.removeFirst();
+ pendingTimers.add(timer);
+ }
+ }
+ return pendingTimers;
+ }
+
+ static void _runTimers(List pendingTimers) {
+ // If there are no pending timers currently reset the id space before we
+ // have a chance to enqueue new timers.
+ if (_heap.isEmpty && (_firstZeroTimer == null)) {
+ _idCount = 0;
+ }
+
+ // Fast exit if no pending timers.
+ if (pendingTimers.length == 0) {
+ return;
+ }
+
+ // Trigger all of the pending timers. New timers added as part of the
+ // callbacks will be enqueued now and notified in the next spin at the
+ // earliest.
+ _handlingCallbacks = true;
+ var i = 0;
+ try {
+ for (; i < pendingTimers.length; i++) {
+ // Next pending timer.
+ var timer = pendingTimers[i];
+ timer._indexOrNext = null;
+
+ // One of the timers in the pending_timers list can cancel
+ // one of the later timers which will set the callback to
+ // null. Or the pending zero timer has been canceled earlier.
+ if (timer._callback != null) {
+ var callback = timer._callback;
+ if (!timer._repeating) {
+ // Mark timer as inactive.
+ timer._callback = null;
+ } else if (timer._milliSeconds > 0) {
+ var ms = timer._milliSeconds;
+ int overdue =
+ VMLibraryHooks.timerMillisecondClock() - timer._wakeupTime;
+ if (overdue > ms) {
+ int missedTicks = overdue ~/ ms;
+ timer._wakeupTime += missedTicks * ms;
+ timer._tick += missedTicks;
+ }
+ }
+ timer._tick += 1;
+
+ callback(timer);
+ // Re-insert repeating timer if not canceled.
+ if (timer._repeating && (timer._callback != null)) {
+ timer._advanceWakeupTime();
+ timer._enqueue();
+ }
+ // Execute pending micro tasks.
+ var immediateCallback = _removePendingImmediateCallback();
+ if (immediateCallback != null) {
+ immediateCallback();
+ }
+ }
+ }
+ } finally {
+ _handlingCallbacks = false;
+ // Re-queue timers we didn't get to.
+ for (i++; i < pendingTimers.length; i++) {
+ var timer = pendingTimers[i];
+ timer._enqueue();
+ }
+ _notifyEventHandler();
+ }
+ }
+
+ static void _handleMessage(msg) {
+ var pendingTimers;
+ if (msg == _ZERO_EVENT) {
+ pendingTimers = _queueFromZeroEvent();
+ assert(pendingTimers.length > 0);
+ } else {
+ assert(msg == _TIMEOUT_EVENT);
+ _scheduledWakeupTime = null; // Consumed the last scheduled wakeup now.
+ pendingTimers = _queueFromTimeoutEvent();
+ }
+ _runTimers(pendingTimers);
+ // Notify the event handler or shutdown the port if no more pending
+ // timers are present.
+ _notifyEventHandler();
+ }
+
+ // Tell the event handler to wake this isolate at a specific time.
+ static void _scheduleWakeup(int wakeupTime) {
+ if (_sendPort == null) {
+ _createTimerHandler();
+ }
+ VMLibraryHooks.eventHandlerSendData(null, _sendPort, wakeupTime);
+ _scheduledWakeupTime = wakeupTime;
+ }
+
+ // Cancel pending wakeups in the event handler.
+ static void _cancelWakeup() {
+ if (_sendPort != null) {
+ VMLibraryHooks.eventHandlerSendData(null, _sendPort, _NO_TIMER);
+ _scheduledWakeupTime = null;
+ }
+ }
+
+ // Create a receive port and register a message handler for the timer
+ // events.
+ static void _createTimerHandler() {
+ assert(_receivePort == null);
+ assert(_sendPort == null);
+ _receivePort = new RawReceivePort(_handleMessage);
+ _sendPort = _receivePort.sendPort;
+ _scheduledWakeupTime = null;
+ }
+
+ static void _shutdownTimerHandler() {
+ _receivePort.close();
+ _receivePort = null;
+ _sendPort = null;
+ _scheduledWakeupTime = null;
+ }
+
+ // The Timer factory registered with the dart:async library by the embedder.
+ static Timer _factory(
+ int milliSeconds, void callback(Timer timer), bool repeating) {
+ if (repeating) {
+ return new _Timer.periodic(milliSeconds, callback);
+ }
+ return new _Timer(milliSeconds, callback);
+ }
+}
+
+@pragma("vm:entry-point", "call")
+_setupHooks() {
+ VMLibraryHooks.timerFactory = _Timer._factory;
+}
diff --git a/sdk_nnbd/lib/_internal/vm/lib/timer_patch.dart b/sdk_nnbd/lib/_internal/vm/lib/timer_patch.dart
new file mode 100644
index 0000000..96c9c78b
--- /dev/null
+++ b/sdk_nnbd/lib/_internal/vm/lib/timer_patch.dart
@@ -0,0 +1,46 @@
+// 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.5
+
+// part of "async_patch.dart";
+
+@patch
+class Timer {
+ @patch
+ static Timer _createTimer(Duration duration, void callback()) {
+ // TODO(iposva): Remove _TimerFactory and use VMLibraryHooks exclusively.
+ if (_TimerFactory._factory == null) {
+ _TimerFactory._factory = VMLibraryHooks.timerFactory;
+ }
+ if (_TimerFactory._factory == null) {
+ throw new UnsupportedError("Timer interface not supported.");
+ }
+ int milliseconds = duration.inMilliseconds;
+ if (milliseconds < 0) milliseconds = 0;
+ return _TimerFactory._factory(milliseconds, (_) {
+ callback();
+ }, false);
+ }
+
+ @patch
+ static Timer _createPeriodicTimer(
+ Duration duration, void callback(Timer timer)) {
+ // TODO(iposva): Remove _TimerFactory and use VMLibraryHooks exclusively.
+ _TimerFactory._factory ??= VMLibraryHooks.timerFactory;
+ if (_TimerFactory._factory == null) {
+ throw new UnsupportedError("Timer interface not supported.");
+ }
+ int milliseconds = duration.inMilliseconds;
+ if (milliseconds < 0) milliseconds = 0;
+ return _TimerFactory._factory(milliseconds, callback, true);
+ }
+}
+
+typedef Timer _TimerFactoryClosure(
+ int milliseconds, void callback(Timer timer), bool repeating);
+
+class _TimerFactory {
+ static _TimerFactoryClosure _factory;
+}
diff --git a/sdk_nnbd/lib/_internal/vm/lib/type_patch.dart b/sdk_nnbd/lib/_internal/vm/lib/type_patch.dart
new file mode 100644
index 0000000..a4af411
--- /dev/null
+++ b/sdk_nnbd/lib/_internal/vm/lib/type_patch.dart
@@ -0,0 +1,41 @@
+// 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.5
+
+// part of "core_patch.dart";
+
+// These Dart classes correspond to the VM internal implementation classes.
+
+// Equivalent of RawAbstractType.
+abstract class _AbstractType implements Type {
+ String toString() native "AbstractType_toString";
+}
+
+// Equivalent of RawType.
+@pragma("vm:entry-point")
+class _Type extends _AbstractType {
+ factory _Type._uninstantiable() {
+ throw "Unreachable";
+ }
+
+ @pragma("vm:exact-result-type", "dart:core#_Smi")
+ int get hashCode native "Type_getHashCode";
+}
+
+// Equivalent of RawTypeRef.
+@pragma("vm:entry-point")
+class _TypeRef extends _AbstractType {
+ factory _TypeRef._uninstantiable() {
+ throw "Unreachable";
+ }
+}
+
+// Equivalent of RawTypeParameter.
+@pragma("vm:entry-point")
+class _TypeParameter extends _AbstractType {
+ factory _TypeParameter._uninstantiable() {
+ throw "Unreachable";
+ }
+}
diff --git a/sdk_nnbd/lib/_internal/vm/lib/typed_data_patch.dart b/sdk_nnbd/lib/_internal/vm/lib/typed_data_patch.dart
new file mode 100644
index 0000000..8443c16
--- /dev/null
+++ b/sdk_nnbd/lib/_internal/vm/lib/typed_data_patch.dart
@@ -0,0 +1,4640 @@
+// 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
+// BSD-style license that can be found in the LICENSE file.
+
+// @dart = 2.5
+
+/// Note: the VM concatenates all patch files into a single patch file. This
+/// file is the first patch in "dart:typed_data" which contains all the imports
+/// used by patches of that library. We plan to change this when we have a
+/// shared front end and simply use parts.
+
+import "dart:_internal"
+ show
+ ClassID,
+ CodeUnits,
+ ExpandIterable,
+ FollowedByIterable,
+ IterableElementError,
+ ListMapView,
+ Lists,
+ MappedIterable,
+ MappedIterable,
+ ReversedListIterable,
+ SkipWhileIterable,
+ Sort,
+ SubListIterable,
+ TakeWhileIterable,
+ WhereIterable,
+ WhereTypeIterable,
+ patch;
+
+import "dart:collection" show ListBase;
+
+import 'dart:math' show Random;
+
+/// There are no parts in patch library:
+
+@patch
+class ByteData implements TypedData {
+ @patch
+ @pragma("vm:entry-point")
+ factory ByteData(int length) {
+ final list = new Uint8List(length) as _TypedList;
+ _rangeCheck(list.lengthInBytes, 0, length);
+ return new _ByteDataView._(list, 0, length);
+ }
+
+ // Called directly from C code.
+ @pragma("vm:entry-point")
+ factory ByteData._view(_TypedList typedData, int offsetInBytes, int length) {
+ _rangeCheck(typedData.lengthInBytes, offsetInBytes, length);
+ return new _ByteDataView._(typedData, offsetInBytes, length);
+ }
+}
+
+// Based class for _TypedList that provides common methods for implementing
+// the collection and list interfaces.
+// This class does not extend ListBase<T> since that would add type arguments
+// to instances of _TypeListBase. Instead the subclasses use type specific
+// mixins (like _IntListMixin, _DoubleListMixin) to implement ListBase<T>.
+abstract class _TypedListBase {
+ int get length;
+ int get elementSizeInBytes;
+ int get offsetInBytes;
+ _ByteBuffer get buffer;
+
+ // Method(s) implementing the Collection interface.
+ String join([String separator = ""]) {
+ StringBuffer buffer = new StringBuffer();
+ buffer.writeAll(this as Iterable, separator);
+ return buffer.toString();
+ }
+
+ bool get isEmpty {
+ return this.length == 0;
+ }
+
+ bool get isNotEmpty => !isEmpty;
+
+ // Method(s) implementing the List interface.
+
+ set length(newLength) {
+ throw new UnsupportedError("Cannot resize a fixed-length list");
+ }
+
+ void clear() {
+ throw new UnsupportedError("Cannot remove from a fixed-length list");
+ }
+
+ bool remove(Object element) {
+ throw new UnsupportedError("Cannot remove from a fixed-length list");
+ }
+
+ void removeRange(int start, int end) {
+ throw new UnsupportedError("Cannot remove from a fixed-length list");
+ }
+
+ void replaceRange(int start, int end, Iterable iterable) {
+ throw new UnsupportedError("Cannot remove from a fixed-length list");
+ }
+
+ // Method(s) implementing Object interface.
+ String toString() => ListBase.listToString(this as List);
+
+ // Internal utility methods.
+
+ // Returns true if operation succeeds.
+ // 'fromCid' and 'toCid' may be cid-s of the views and therefore may not
+ // match the cids of 'this' and 'from'.
+ // Uses toCid and fromCid to decide if clamping is necessary.
+ // Element size of toCid and fromCid must match (test at caller).
+ bool _setRange(int startInBytes, int lengthInBytes, _TypedListBase from,
+ int startFromInBytes, int toCid, int fromCid) native "TypedData_setRange";
+}
+
+mixin _IntListMixin implements List<int> {
+ int get elementSizeInBytes;
+ int get offsetInBytes;
+ _ByteBuffer get buffer;
+
+ Iterable<T> whereType<T>() => new WhereTypeIterable<T>(this);
+
+ Iterable<int> followedBy(Iterable<int> other) =>
+ new FollowedByIterable<int>.firstEfficient(this, other);
+
+ List<R> cast<R>() => List.castFrom<int, R>(this);
+ void set first(int value) {
+ if (this.length == 0) throw new RangeError.index(0, this);
+ this[0] = value;
+ }
+
+ void set last(int value) {
+ if (this.length == 0) throw new RangeError.index(0, this);
+ this[this.length - 1] = value;
+ }
+
+ int indexWhere(bool test(int element), [int start = 0]) {
+ if (start < 0) start = 0;
+ for (int i = start; i < length; i++) {
+ if (test(this[i])) return i;
+ }
+ return -1;
+ }
+
+ int lastIndexWhere(bool test(int element), [int start]) {
+ if (start == null || start >= this.length) start = this.length - 1;
+ for (int i = start; i >= 0; i--) {
+ if (test(this[i])) return i;
+ }
+ return -1;
+ }
+
+ List<int> operator +(List<int> other) {
+ int totalLength = this.length + other.length;
+ return <int>[]
+ ..length = totalLength
+ ..setRange(0, this.length, this)
+ ..setRange(this.length, totalLength, other);
+ }
+
+ bool contains(Object element) {
+ var len = this.length;
+ for (var i = 0; i < len; ++i) {
+ if (this[i] == element) return true;
+ }
+ return false;
+ }
+
+ void shuffle([Random random]) {
+ random ??= new Random();
+ var i = this.length;
+ while (i > 1) {
+ int pos = random.nextInt(i);
+ i -= 1;
+ var tmp = this[i];
+ this[i] = this[pos];
+ this[pos] = tmp;
+ }
+ }
+
+ Iterable<int> where(bool f(int element)) => new WhereIterable<int>(this, f);
+
+ Iterable<int> take(int n) => new SubListIterable<int>(this, 0, n);
+
+ Iterable<int> takeWhile(bool test(int element)) =>
+ new TakeWhileIterable<int>(this, test);
+
+ Iterable<int> skip(int n) => new SubListIterable<int>(this, n, null);
+
+ Iterable<int> skipWhile(bool test(int element)) =>
+ new SkipWhileIterable<int>(this, test);
+
+ Iterable<int> get reversed => new ReversedListIterable<int>(this);
+
+ Map<int, int> asMap() => new ListMapView<int>(this);
+
+ Iterable<int> getRange(int start, [int end]) {
+ RangeError.checkValidRange(start, end, this.length);
+ return new SubListIterable<int>(this, start, end);
+ }
+
+ Iterator<int> get iterator => new _TypedListIterator<int>(this);
+
+ List<int> toList({bool growable: true}) {
+ return new List<int>.from(this, growable: growable);
+ }
+
+ Set<int> toSet() {
+ return new Set<int>.from(this);
+ }
+
+ void forEach(void f(int element)) {
+ var len = this.length;
+ for (var i = 0; i < len; i++) {
+ f(this[i]);
+ }
+ }
+
+ int reduce(int combine(int value, int element)) {
+ var len = this.length;
+ if (len == 0) throw IterableElementError.noElement();
+ var value = this[0];
+ for (var i = 1; i < len; ++i) {
+ value = combine(value, this[i]);
+ }
+ return value;
+ }
+
+ T fold<T>(T initialValue, T combine(T initialValue, int element)) {
+ var len = this.length;
+ for (var i = 0; i < len; ++i) {
+ initialValue = combine(initialValue, this[i]);
+ }
+ return initialValue;
+ }
+
+ Iterable<T> map<T>(T f(int element)) => new MappedIterable<int, T>(this, f);
+
+ Iterable<T> expand<T>(Iterable<T> f(int element)) =>
+ new ExpandIterable<int, T>(this, f);
+
+ bool every(bool f(int element)) {
+ var len = this.length;
+ for (var i = 0; i < len; ++i) {
+ if (!f(this[i])) return false;
+ }
+ return true;
+ }
+
+ bool any(bool f(int element)) {
+ var len = this.length;
+ for (var i = 0; i < len; ++i) {
+ if (f(this[i])) return true;
+ }
+ return false;
+ }
+
+ int firstWhere(bool test(int element), {int orElse()}) {
+ var len = this.length;
+ for (var i = 0; i < len; ++i) {
+ var element = this[i];
+ if (test(element)) return element;
+ }
+ if (orElse != null) return orElse();
+ throw IterableElementError.noElement();
+ }
+
+ int lastWhere(bool test(int element), {int orElse()}) {
+ var len = this.length;
+ for (var i = len - 1; i >= 0; --i) {
+ var element = this[i];
+ if (test(element)) {
+ return element;
+ }
+ }
+ if (orElse != null) return orElse();
+ throw IterableElementError.noElement();
+ }
+
+ int singleWhere(bool test(int element), {int orElse()}) {
+ var result = null;
+ bool foundMatching = false;
+ var len = this.length;
+ for (var i = 0; i < len; ++i) {
+ var element = this[i];
+ if (test(element)) {
+ if (foundMatching) {
+ throw IterableElementError.tooMany();
+ }
+ result = element;
+ foundMatching = true;
+ }
+ }
+ if (foundMatching) return result;
+ if (orElse != null) return orElse();
+ throw IterableElementError.noElement();
+ }
+
+ int elementAt(int index) {
+ return this[index];
+ }
+
+ void add(int value) {
+ throw new UnsupportedError("Cannot add to a fixed-length list");
+ }
+
+ void addAll(Iterable<int> value) {
+ throw new UnsupportedError("Cannot add to a fixed-length list");
+ }
+
+ void insert(int index, int value) {
+ throw new UnsupportedError("Cannot insert into a fixed-length list");
+ }
+
+ void insertAll(int index, Iterable<int> values) {
+ throw new UnsupportedError("Cannot insert into a fixed-length list");
+ }
+
+ void sort([int compare(int a, int b)]) {
+ Sort.sort(this, compare ?? Comparable.compare);
+ }
+
+ int indexOf(int element, [int start = 0]) {
+ if (start >= this.length) {
+ return -1;
+ } else if (start < 0) {
+ start = 0;
+ }
+ for (int i = start; i < this.length; i++) {
+ if (this[i] == element) return i;
+ }
+ return -1;
+ }
+
+ int lastIndexOf(int element, [int start = null]) {
+ if (start == null || start >= this.length) {
+ start = this.length - 1;
+ } else if (start < 0) {
+ return -1;
+ }
+ for (int i = start; i >= 0; i--) {
+ if (this[i] == element) return i;
+ }
+ return -1;
+ }
+
+ int removeLast() {
+ throw new UnsupportedError("Cannot remove from a fixed-length list");
+ }
+
+ int removeAt(int index) {
+ throw new UnsupportedError("Cannot remove from a fixed-length list");
+ }
+
+ void removeWhere(bool test(int element)) {
+ throw new UnsupportedError("Cannot remove from a fixed-length list");
+ }
+
+ void retainWhere(bool test(int element)) {
+ throw new UnsupportedError("Cannot remove from a fixed-length list");
+ }
+
+ int get first {
+ if (length > 0) return this[0];
+ throw IterableElementError.noElement();
+ }
+
+ int get last {
+ if (length > 0) return this[length - 1];
+ throw IterableElementError.noElement();
+ }
+
+ int get single {
+ if (length == 1) return this[0];
+ if (length == 0) throw IterableElementError.noElement();
+ throw IterableElementError.tooMany();
+ }
+
+ void setAll(int index, Iterable<int> iterable) {
+ final end = iterable.length + index;
+ setRange(index, end, iterable);
+ }
+
+ void fillRange(int start, int end, [int fillValue]) {
+ RangeError.checkValidRange(start, end, this.length);
+ for (var i = start; i < end; ++i) {
+ this[i] = fillValue;
+ }
+ }
+}
+
+mixin _TypedIntListMixin<SpawnedType extends List<int>> on _IntListMixin
+ implements List<int> {
+ SpawnedType _createList(int length);
+
+ void setRange(int start, int end, Iterable<int> from, [int skipCount = 0]) {
+ // Check ranges.
+ if (0 > start || start > end || end > length) {
+ RangeError.checkValidRange(start, end, length); // Always throws.
+ assert(false);
+ }
+ if (skipCount < 0) {
+ throw RangeError.range(skipCount, 0, null, "skipCount");
+ }
+
+ final count = end - start;
+ if ((from.length - skipCount) < count) {
+ throw IterableElementError.tooFew();
+ }
+
+ if (count == 0) return;
+
+ if (from is _TypedListBase) {
+ // Note: _TypedListBase is not related to Iterable<int> so there is
+ // no promotion here.
+ final fromAsTypedList = from as _TypedListBase;
+ if (this.elementSizeInBytes == fromAsTypedList.elementSizeInBytes) {
+ if ((count < 10) && (fromAsTypedList.buffer != this.buffer)) {
+ Lists.copy(from as List<int>, skipCount, this, start, count);
+ return;
+ } else if (this.buffer._data._setRange(
+ start * elementSizeInBytes + this.offsetInBytes,
+ count * elementSizeInBytes,
+ fromAsTypedList.buffer._data,
+ skipCount * elementSizeInBytes + fromAsTypedList.offsetInBytes,
+ ClassID.getID(this),
+ ClassID.getID(from))) {
+ return;
+ }
+ } else if (fromAsTypedList.buffer == this.buffer) {
+ // Different element sizes, but same buffer means that we need
+ // an intermediate structure.
+ // TODO(srdjan): Optimize to skip copying if the range does not overlap.
+ final fromAsList = from as List<int>;
+ final tempBuffer = _createList(count);
+ for (var i = 0; i < count; i++) {
+ tempBuffer[i] = fromAsList[skipCount + i];
+ }
+ for (var i = start; i < end; i++) {
+ this[i] = tempBuffer[i - start];
+ }
+ return;
+ }
+ }
+
+ List otherList;
+ int otherStart;
+ if (from is List<int>) {
+ otherList = from;
+ otherStart = skipCount;
+ } else {
+ otherList = from.skip(skipCount).toList(growable: false);
+ otherStart = 0;
+ }
+ if (otherStart + count > otherList.length) {
+ throw IterableElementError.tooFew();
+ }
+ Lists.copy(otherList, otherStart, this, start, count);
+ }
+
+ SpawnedType sublist(int start, [int end]) {
+ end = RangeError.checkValidRange(start, end, this.length);
+ var length = end - start;
+ SpawnedType result = _createList(length);
+ result.setRange(0, length, this, start);
+ return result;
+ }
+}
+
+mixin _DoubleListMixin implements List<double> {
+ int get elementSizeInBytes;
+ int get offsetInBytes;
+ _ByteBuffer get buffer;
+
+ Iterable<T> whereType<T>() => new WhereTypeIterable<T>(this);
+
+ Iterable<double> followedBy(Iterable<double> other) =>
+ new FollowedByIterable<double>.firstEfficient(this, other);
+
+ List<R> cast<R>() => List.castFrom<double, R>(this);
+ void set first(double value) {
+ if (this.length == 0) throw new RangeError.index(0, this);
+ this[0] = value;
+ }
+
+ void set last(double value) {
+ if (this.length == 0) throw new RangeError.index(0, this);
+ this[this.length - 1] = value;
+ }
+
+ int indexWhere(bool test(double element), [int start = 0]) {
+ if (start < 0) start = 0;
+ for (int i = start; i < length; i++) {
+ if (test(this[i])) return i;
+ }
+ return -1;
+ }
+
+ int lastIndexWhere(bool test(double element), [int start]) {
+ if (start == null || start >= this.length) start = this.length - 1;
+ for (int i = start; i >= 0; i--) {
+ if (test(this[i])) return i;
+ }
+ return -1;
+ }
+
+ List<double> operator +(List<double> other) {
+ int totalLength = this.length + other.length;
+ return <double>[]
+ ..length = totalLength
+ ..setRange(0, this.length, this)
+ ..setRange(this.length, totalLength, other);
+ }
+
+ bool contains(Object element) {
+ var len = this.length;
+ for (var i = 0; i < len; ++i) {
+ if (this[i] == element) return true;
+ }
+ return false;
+ }
+
+ void shuffle([Random random]) {
+ random ??= new Random();
+ var i = this.length;
+ while (i > 1) {
+ int pos = random.nextInt(i);
+ i -= 1;
+ var tmp = this[i];
+ this[i] = this[pos];
+ this[pos] = tmp;
+ }
+ }
+
+ Iterable<double> where(bool f(double element)) =>
+ new WhereIterable<double>(this, f);
+
+ Iterable<double> take(int n) => new SubListIterable<double>(this, 0, n);
+
+ Iterable<double> takeWhile(bool test(double element)) =>
+ new TakeWhileIterable<double>(this, test);
+
+ Iterable<double> skip(int n) => new SubListIterable<double>(this, n, null);
+
+ Iterable<double> skipWhile(bool test(double element)) =>
+ new SkipWhileIterable<double>(this, test);
+
+ Iterable<double> get reversed => new ReversedListIterable<double>(this);
+
+ Map<int, double> asMap() => new ListMapView<double>(this);
+
+ Iterable<double> getRange(int start, [int end]) {
+ RangeError.checkValidRange(start, end, this.length);
+ return new SubListIterable<double>(this, start, end);
+ }
+
+ Iterator<double> get iterator => new _TypedListIterator<double>(this);
+
+ List<double> toList({bool growable: true}) {
+ return new List<double>.from(this, growable: growable);
+ }
+
+ Set<double> toSet() {
+ return new Set<double>.from(this);
+ }
+
+ void forEach(void f(double element)) {
+ var len = this.length;
+ for (var i = 0; i < len; i++) {
+ f(this[i]);
+ }
+ }
+
+ double reduce(double combine(double value, double element)) {
+ var len = this.length;
+ if (len == 0) throw IterableElementError.noElement();
+ var value = this[0];
+ for (var i = 1; i < len; ++i) {
+ value = combine(value, this[i]);
+ }
+ return value;
+ }
+
+ T fold<T>(T initialValue, T combine(T initialValue, double element)) {
+ var len = this.length;
+ for (var i = 0; i < len; ++i) {
+ initialValue = combine(initialValue, this[i]);
+ }
+ return initialValue;
+ }
+
+ Iterable<T> map<T>(T f(double element)) =>
+ new MappedIterable<double, T>(this, f);
+
+ Iterable<T> expand<T>(Iterable<T> f(double element)) =>
+ new ExpandIterable<double, T>(this, f);
+
+ bool every(bool f(double element)) {
+ var len = this.length;
+ for (var i = 0; i < len; ++i) {
+ if (!f(this[i])) return false;
+ }
+ return true;
+ }
+
+ bool any(bool f(double element)) {
+ var len = this.length;
+ for (var i = 0; i < len; ++i) {
+ if (f(this[i])) return true;
+ }
+ return false;
+ }
+
+ double firstWhere(bool test(double element), {double orElse()}) {
+ var len = this.length;
+ for (var i = 0; i < len; ++i) {
+ var element = this[i];
+ if (test(element)) return element;
+ }
+ if (orElse != null) return orElse();
+ throw IterableElementError.noElement();
+ }
+
+ double lastWhere(bool test(double element), {double orElse()}) {
+ var len = this.length;
+ for (var i = len - 1; i >= 0; --i) {
+ var element = this[i];
+ if (test(element)) {
+ return element;
+ }
+ }
+ if (orElse != null) return orElse();
+ throw IterableElementError.noElement();
+ }
+
+ double singleWhere(bool test(double element), {double orElse()}) {
+ var result = null;
+ bool foundMatching = false;
+ var len = this.length;
+ for (var i = 0; i < len; ++i) {
+ var element = this[i];
+ if (test(element)) {
+ if (foundMatching) {
+ throw IterableElementError.tooMany();
+ }
+ result = element;
+ foundMatching = true;
+ }
+ }
+ if (foundMatching) return result;
+ if (orElse != null) return orElse();
+ throw IterableElementError.noElement();
+ }
+
+ double elementAt(int index) {
+ return this[index];
+ }
+
+ void add(double value) {
+ throw new UnsupportedError("Cannot add to a fixed-length list");
+ }
+
+ void addAll(Iterable<double> value) {
+ throw new UnsupportedError("Cannot add to a fixed-length list");
+ }
+
+ void insert(int index, double value) {
+ throw new UnsupportedError("Cannot insert into a fixed-length list");
+ }
+
+ void insertAll(int index, Iterable<double> values) {
+ throw new UnsupportedError("Cannot insert into a fixed-length list");
+ }
+
+ void sort([int compare(double a, double b)]) {
+ Sort.sort(this, compare ?? Comparable.compare);
+ }
+
+ int indexOf(double element, [int start = 0]) {
+ if (start >= this.length) {
+ return -1;
+ } else if (start < 0) {
+ start = 0;
+ }
+ for (int i = start; i < this.length; i++) {
+ if (this[i] == element) return i;
+ }
+ return -1;
+ }
+
+ int lastIndexOf(double element, [int start = null]) {
+ if (start == null || start >= this.length) {
+ start = this.length - 1;
+ } else if (start < 0) {
+ return -1;
+ }
+ for (int i = start; i >= 0; i--) {
+ if (this[i] == element) return i;
+ }
+ return -1;
+ }
+
+ double removeLast() {
+ throw new UnsupportedError("Cannot remove from a fixed-length list");
+ }
+
+ double removeAt(int index) {
+ throw new UnsupportedError("Cannot remove from a fixed-length list");
+ }
+
+ void removeWhere(bool test(double element)) {
+ throw new UnsupportedError("Cannot remove from a fixed-length list");
+ }
+
+ void retainWhere(bool test(double element)) {
+ throw new UnsupportedError("Cannot remove from a fixed-length list");
+ }
+
+ double get first {
+ if (length > 0) return this[0];
+ throw IterableElementError.noElement();
+ }
+
+ double get last {
+ if (length > 0) return this[length - 1];
+ throw IterableElementError.noElement();
+ }
+
+ double get single {
+ if (length == 1) return this[0];
+ if (length == 0) throw IterableElementError.noElement();
+ throw IterableElementError.tooMany();
+ }
+
+ void setAll(int index, Iterable<double> iterable) {
+ final end = iterable.length + index;
+ setRange(index, end, iterable);
+ }
+
+ void fillRange(int start, int end, [double fillValue]) {
+ RangeError.checkValidRange(start, end, this.length);
+ for (var i = start; i < end; ++i) {
+ this[i] = fillValue;
+ }
+ }
+}
+
+mixin _TypedDoubleListMixin<SpawnedType extends List<double>>
+ on _DoubleListMixin implements List<double> {
+ SpawnedType _createList(int length);
+
+ void setRange(int start, int end, Iterable<double> from,
+ [int skipCount = 0]) {
+ // Check ranges.
+ if (0 > start || start > end || end > length) {
+ RangeError.checkValidRange(start, end, length); // Always throws.
+ assert(false);
+ }
+ if (skipCount < 0) {
+ throw RangeError.range(skipCount, 0, null, "skipCount");
+ }
+
+ final count = end - start;
+ if ((from.length - skipCount) < count) {
+ throw IterableElementError.tooFew();
+ }
+
+ if (count == 0) return;
+
+ if (from is _TypedListBase) {
+ // Note: _TypedListBase is not related to Iterable<double> so there is
+ // no promotion here.
+ final fromAsTypedList = from as _TypedListBase;
+ if (this.elementSizeInBytes == fromAsTypedList.elementSizeInBytes) {
+ if ((count < 10) && (fromAsTypedList.buffer != this.buffer)) {
+ Lists.copy(from as List<double>, skipCount, this, start, count);
+ return;
+ } else if (this.buffer._data._setRange(
+ start * elementSizeInBytes + this.offsetInBytes,
+ count * elementSizeInBytes,
+ fromAsTypedList.buffer._data,
+ skipCount * elementSizeInBytes + fromAsTypedList.offsetInBytes,
+ ClassID.getID(this),
+ ClassID.getID(from))) {
+ return;
+ }
+ } else if (fromAsTypedList.buffer == this.buffer) {
+ // Different element sizes, but same buffer means that we need
+ // an intermediate structure.
+ // TODO(srdjan): Optimize to skip copying if the range does not overlap.
+ final fromAsList = from as List<double>;
+ final tempBuffer = _createList(count);
+ for (var i = 0; i < count; i++) {
+ tempBuffer[i] = fromAsList[skipCount + i];
+ }
+ for (var i = start; i < end; i++) {
+ this[i] = tempBuffer[i - start];
+ }
+ return;
+ }
+ }
+
+ List otherList;
+ int otherStart;
+ if (from is List<double>) {
+ otherList = from;
+ otherStart = skipCount;
+ } else {
+ otherList = from.skip(skipCount).toList(growable: false);
+ otherStart = 0;
+ }
+ if (otherStart + count > otherList.length) {
+ throw IterableElementError.tooFew();
+ }
+ Lists.copy(otherList, otherStart, this, start, count);
+ }
+
+ SpawnedType sublist(int start, [int end]) {
+ end = RangeError.checkValidRange(start, end, this.length);
+ var length = end - start;
+ SpawnedType result = _createList(length);
+ result.setRange(0, length, this, start);
+ return result;
+ }
+}
+
+abstract class _Float32x4ListMixin implements List<Float32x4> {
+ int get elementSizeInBytes;
+ int get offsetInBytes;
+ _ByteBuffer get buffer;
+
+ Float32x4List _createList(int length);
+
+ Iterable<T> whereType<T>() => new WhereTypeIterable<T>(this);
+
+ Iterable<Float32x4> followedBy(Iterable<Float32x4> other) =>
+ new FollowedByIterable<Float32x4>.firstEfficient(this, other);
+
+ List<R> cast<R>() => List.castFrom<Float32x4, R>(this);
+ void set first(Float32x4 value) {
+ if (this.length == 0) throw new RangeError.index(0, this);
+ this[0] = value;
+ }
+
+ void set last(Float32x4 value) {
+ if (this.length == 0) throw new RangeError.index(0, this);
+ this[this.length - 1] = value;
+ }
+
+ int indexWhere(bool test(Float32x4 element), [int start = 0]) {
+ if (start < 0) start = 0;
+ for (int i = start; i < length; i++) {
+ if (test(this[i])) return i;
+ }
+ return -1;
+ }
+
+ int lastIndexWhere(bool test(Float32x4 element), [int start]) {
+ if (start == null || start >= this.length) start = this.length - 1;
+ for (int i = start; i >= 0; i--) {
+ if (test(this[i])) return i;
+ }
+ return -1;
+ }
+
+ List<Float32x4> operator +(List<Float32x4> other) {
+ int totalLength = this.length + other.length;
+ return <Float32x4>[]
+ ..length = totalLength
+ ..setRange(0, this.length, this)
+ ..setRange(this.length, totalLength, other);
+ }
+
+ bool contains(Object element) {
+ var len = this.length;
+ for (var i = 0; i < len; ++i) {
+ if (this[i] == element) return true;
+ }
+ return false;
+ }
+
+ void shuffle([Random random]) {
+ random ??= new Random();
+ var i = this.length;
+ while (i > 1) {
+ int pos = random.nextInt(i);
+ i -= 1;
+ var tmp = this[i];
+ this[i] = this[pos];
+ this[pos] = tmp;
+ }
+ }
+
+ void setRange(int start, int end, Iterable<Float32x4> from,
+ [int skipCount = 0]) {
+ // Check ranges.
+ if (0 > start || start > end || end > length) {
+ RangeError.checkValidRange(start, end, length); // Always throws.
+ assert(false);
+ }
+ if (skipCount < 0) {
+ throw RangeError.range(skipCount, 0, null, "skipCount");
+ }
+
+ final count = end - start;
+ if ((from.length - skipCount) < count) {
+ throw IterableElementError.tooFew();
+ }
+
+ if (count == 0) return;
+
+ if (from is _TypedListBase) {
+ // Note: _TypedListBase is not related to Iterable<Float32x4> so there is
+ // no promotion here.
+ final fromAsTypedList = from as _TypedListBase;
+ if (this.elementSizeInBytes == fromAsTypedList.elementSizeInBytes) {
+ if ((count < 10) && (fromAsTypedList.buffer != this.buffer)) {
+ Lists.copy(from as List<Float32x4>, skipCount, this, start, count);
+ return;
+ } else if (this.buffer._data._setRange(
+ start * elementSizeInBytes + this.offsetInBytes,
+ count * elementSizeInBytes,
+ fromAsTypedList.buffer._data,
+ skipCount * elementSizeInBytes + fromAsTypedList.offsetInBytes,
+ ClassID.getID(this),
+ ClassID.getID(from))) {
+ return;
+ }
+ } else if (fromAsTypedList.buffer == this.buffer) {
+ // Different element sizes, but same buffer means that we need
+ // an intermediate structure.
+ // TODO(srdjan): Optimize to skip copying if the range does not overlap.
+ final fromAsList = from as List<Float32x4>;
+ final tempBuffer = _createList(count);
+ for (var i = 0; i < count; i++) {
+ tempBuffer[i] = fromAsList[skipCount + i];
+ }
+ for (var i = start; i < end; i++) {
+ this[i] = tempBuffer[i - start];
+ }
+ return;
+ }
+ }
+
+ List otherList;
+ int otherStart;
+ if (from is List<Float32x4>) {
+ otherList = from;
+ otherStart = skipCount;
+ } else {
+ otherList = from.skip(skipCount).toList(growable: false);
+ otherStart = 0;
+ }
+ if (otherStart + count > otherList.length) {
+ throw IterableElementError.tooFew();
+ }
+ Lists.copy(otherList, otherStart, this, start, count);
+ }
+
+ Iterable<Float32x4> where(bool f(Float32x4 element)) =>
+ new WhereIterable<Float32x4>(this, f);
+
+ Iterable<Float32x4> take(int n) => new SubListIterable<Float32x4>(this, 0, n);
+
+ Iterable<Float32x4> takeWhile(bool test(Float32x4 element)) =>
+ new TakeWhileIterable<Float32x4>(this, test);
+
+ Iterable<Float32x4> skip(int n) =>
+ new SubListIterable<Float32x4>(this, n, null);
+
+ Iterable<Float32x4> skipWhile(bool test(Float32x4 element)) =>
+ new SkipWhileIterable<Float32x4>(this, test);
+
+ Iterable<Float32x4> get reversed => new ReversedListIterable<Float32x4>(this);
+
+ Map<int, Float32x4> asMap() => new ListMapView<Float32x4>(this);
+
+ Iterable<Float32x4> getRange(int start, [int end]) {
+ RangeError.checkValidRange(start, end, this.length);
+ return new SubListIterable<Float32x4>(this, start, end);
+ }
+
+ Iterator<Float32x4> get iterator => new _TypedListIterator<Float32x4>(this);
+
+ List<Float32x4> toList({bool growable: true}) {
+ return new List<Float32x4>.from(this, growable: growable);
+ }
+
+ Set<Float32x4> toSet() {
+ return new Set<Float32x4>.from(this);
+ }
+
+ void forEach(void f(Float32x4 element)) {
+ var len = this.length;
+ for (var i = 0; i < len; i++) {
+ f(this[i]);
+ }
+ }
+
+ Float32x4 reduce(Float32x4 combine(Float32x4 value, Float32x4 element)) {
+ var len = this.length;
+ if (len == 0) throw IterableElementError.noElement();
+ var value = this[0];
+ for (var i = 1; i < len; ++i) {
+ value = combine(value, this[i]);
+ }
+ return value;
+ }
+
+ T fold<T>(T initialValue, T combine(T initialValue, Float32x4 element)) {
+ var len = this.length;
+ for (var i = 0; i < len; ++i) {
+ initialValue = combine(initialValue, this[i]);
+ }
+ return initialValue;
+ }
+
+ Iterable<T> map<T>(T f(Float32x4 element)) =>
+ new MappedIterable<Float32x4, T>(this, f);
+
+ Iterable<T> expand<T>(Iterable<T> f(Float32x4 element)) =>
+ new ExpandIterable<Float32x4, T>(this, f);
+
+ bool every(bool f(Float32x4 element)) {
+ var len = this.length;
+ for (var i = 0; i < len; ++i) {
+ if (!f(this[i])) return false;
+ }
+ return true;
+ }
+
+ bool any(bool f(Float32x4 element)) {
+ var len = this.length;
+ for (var i = 0; i < len; ++i) {
+ if (f(this[i])) return true;
+ }
+ return false;
+ }
+
+ Float32x4 firstWhere(bool test(Float32x4 element), {Float32x4 orElse()}) {
+ var len = this.length;
+ for (var i = 0; i < len; ++i) {
+ var element = this[i];
+ if (test(element)) return element;
+ }
+ if (orElse != null) return orElse();
+ throw IterableElementError.noElement();
+ }
+
+ Float32x4 lastWhere(bool test(Float32x4 element), {Float32x4 orElse()}) {
+ var len = this.length;
+ for (var i = len - 1; i >= 0; --i) {
+ var element = this[i];
+ if (test(element)) {
+ return element;
+ }
+ }
+ if (orElse != null) return orElse();
+ throw IterableElementError.noElement();
+ }
+
+ Float32x4 singleWhere(bool test(Float32x4 element), {Float32x4 orElse()}) {
+ var result = null;
+ bool foundMatching = false;
+ var len = this.length;
+ for (var i = 0; i < len; ++i) {
+ var element = this[i];
+ if (test(element)) {
+ if (foundMatching) {
+ throw IterableElementError.tooMany();
+ }
+ result = element;
+ foundMatching = true;
+ }
+ }
+ if (foundMatching) return result;
+ if (orElse != null) return orElse();
+ throw IterableElementError.noElement();
+ }
+
+ Float32x4 elementAt(int index) {
+ return this[index];
+ }
+
+ void add(Float32x4 value) {
+ throw new UnsupportedError("Cannot add to a fixed-length list");
+ }
+
+ void addAll(Iterable<Float32x4> value) {
+ throw new UnsupportedError("Cannot add to a fixed-length list");
+ }
+
+ void insert(int index, Float32x4 value) {
+ throw new UnsupportedError("Cannot insert into a fixed-length list");
+ }
+
+ void insertAll(int index, Iterable<Float32x4> values) {
+ throw new UnsupportedError("Cannot insert into a fixed-length list");
+ }
+
+ void sort([int compare(Float32x4 a, Float32x4 b)]) {
+ if (compare == null) {
+ throw "SIMD don't have default compare.";
+ }
+ Sort.sort(this, compare);
+ }
+
+ int indexOf(Float32x4 element, [int start = 0]) {
+ if (start >= this.length) {
+ return -1;
+ } else if (start < 0) {
+ start = 0;
+ }
+ for (int i = start; i < this.length; i++) {
+ if (this[i] == element) return i;
+ }
+ return -1;
+ }
+
+ int lastIndexOf(Float32x4 element, [int start = null]) {
+ if (start == null || start >= this.length) {
+ start = this.length - 1;
+ } else if (start < 0) {
+ return -1;
+ }
+ for (int i = start; i >= 0; i--) {
+ if (this[i] == element) return i;
+ }
+ return -1;
+ }
+
+ Float32x4 removeLast() {
+ throw new UnsupportedError("Cannot remove from a fixed-length list");
+ }
+
+ Float32x4 removeAt(int index) {
+ throw new UnsupportedError("Cannot remove from a fixed-length list");
+ }
+
+ void removeWhere(bool test(Float32x4 element)) {
+ throw new UnsupportedError("Cannot remove from a fixed-length list");
+ }
+
+ void retainWhere(bool test(Float32x4 element)) {
+ throw new UnsupportedError("Cannot remove from a fixed-length list");
+ }
+
+ Float32x4 get first {
+ if (length > 0) return this[0];
+ throw IterableElementError.noElement();
+ }
+
+ Float32x4 get last {
+ if (length > 0) return this[length - 1];
+ throw IterableElementError.noElement();
+ }
+
+ Float32x4 get single {
+ if (length == 1) return this[0];
+ if (length == 0) throw IterableElementError.noElement();
+ throw IterableElementError.tooMany();
+ }
+
+ Float32x4List sublist(int start, [int end]) {
+ end = RangeError.checkValidRange(start, end, this.length);
+ var length = end - start;
+ Float32x4List result = _createList(length);
+ result.setRange(0, length, this, start);
+ return result;
+ }
+
+ void setAll(int index, Iterable<Float32x4> iterable) {
+ final end = iterable.length + index;
+ setRange(index, end, iterable);
+ }
+
+ void fillRange(int start, int end, [Float32x4 fillValue]) {
+ RangeError.checkValidRange(start, end, this.length);
+ for (var i = start; i < end; ++i) {
+ this[i] = fillValue;
+ }
+ }
+}
+
+abstract class _Int32x4ListMixin implements List<Int32x4> {
+ int get elementSizeInBytes;
+ int get offsetInBytes;
+ _ByteBuffer get buffer;
+
+ Int32x4List _createList(int length);
+
+ Iterable<T> whereType<T>() => new WhereTypeIterable<T>(this);
+
+ Iterable<Int32x4> followedBy(Iterable<Int32x4> other) =>
+ new FollowedByIterable<Int32x4>.firstEfficient(this, other);
+
+ List<R> cast<R>() => List.castFrom<Int32x4, R>(this);
+ void set first(Int32x4 value) {
+ if (this.length == 0) throw new RangeError.index(0, this);
+ this[0] = value;
+ }
+
+ void set last(Int32x4 value) {
+ if (this.length == 0) throw new RangeError.index(0, this);
+ this[this.length - 1] = value;
+ }
+
+ int indexWhere(bool test(Int32x4 element), [int start = 0]) {
+ if (start < 0) start = 0;
+ for (int i = start; i < length; i++) {
+ if (test(this[i])) return i;
+ }
+ return -1;
+ }
+
+ int lastIndexWhere(bool test(Int32x4 element), [int start]) {
+ if (start == null || start >= this.length) start = this.length - 1;
+ for (int i = start; i >= 0; i--) {
+ if (test(this[i])) return i;
+ }
+ return -1;
+ }
+
+ List<Int32x4> operator +(List<Int32x4> other) {
+ int totalLength = this.length + other.length;
+ return <Int32x4>[]
+ ..length = totalLength
+ ..setRange(0, this.length, this)
+ ..setRange(this.length, totalLength, other);
+ }
+
+ bool contains(Object element) {
+ var len = this.length;
+ for (var i = 0; i < len; ++i) {
+ if (this[i] == element) return true;
+ }
+ return false;
+ }
+
+ void shuffle([Random random]) {
+ random ??= new Random();
+ var i = this.length;
+ while (i > 1) {
+ int pos = random.nextInt(i);
+ i -= 1;
+ var tmp = this[i];
+ this[i] = this[pos];
+ this[pos] = tmp;
+ }
+ }
+
+ void setRange(int start, int end, Iterable<Int32x4> from,
+ [int skipCount = 0]) {
+ // Check ranges.
+ if (0 > start || start > end || end > length) {
+ RangeError.checkValidRange(start, end, length); // Always throws.
+ assert(false);
+ }
+ if (skipCount < 0) {
+ throw RangeError.range(skipCount, 0, null, "skipCount");
+ }
+
+ final count = end - start;
+ if ((from.length - skipCount) < count) {
+ throw IterableElementError.tooFew();
+ }
+
+ if (count == 0) return;
+
+ if (from is _TypedListBase) {
+ // Note: _TypedListBase is not related to Iterable<Int32x4> so there is
+ // no promotion here.
+ final fromAsTypedList = from as _TypedListBase;
+ if (this.elementSizeInBytes == fromAsTypedList.elementSizeInBytes) {
+ if ((count < 10) && (fromAsTypedList.buffer != this.buffer)) {
+ Lists.copy(from as List<Int32x4>, skipCount, this, start, count);
+ return;
+ } else if (this.buffer._data._setRange(
+ start * elementSizeInBytes + this.offsetInBytes,
+ count * elementSizeInBytes,
+ fromAsTypedList.buffer._data,
+ skipCount * elementSizeInBytes + fromAsTypedList.offsetInBytes,
+ ClassID.getID(this),
+ ClassID.getID(from))) {
+ return;
+ }
+ } else if (fromAsTypedList.buffer == this.buffer) {
+ // Different element sizes, but same buffer means that we need
+ // an intermediate structure.
+ // TODO(srdjan): Optimize to skip copying if the range does not overlap.
+ final fromAsList = from as List<Int32x4>;
+ final tempBuffer = _createList(count);
+ for (var i = 0; i < count; i++) {
+ tempBuffer[i] = fromAsList[skipCount + i];
+ }
+ for (var i = start; i < end; i++) {
+ this[i] = tempBuffer[i - start];
+ }
+ return;
+ }
+ }
+
+ List otherList;
+ int otherStart;
+ if (from is List<Int32x4>) {
+ otherList = from;
+ otherStart = skipCount;
+ } else {
+ otherList = from.skip(skipCount).toList(growable: false);
+ otherStart = 0;
+ }
+ if (otherStart + count > otherList.length) {
+ throw IterableElementError.tooFew();
+ }
+ Lists.copy(otherList, otherStart, this, start, count);
+ }
+
+ Iterable<Int32x4> where(bool f(Int32x4 element)) =>
+ new WhereIterable<Int32x4>(this, f);
+
+ Iterable<Int32x4> take(int n) => new SubListIterable<Int32x4>(this, 0, n);
+
+ Iterable<Int32x4> takeWhile(bool test(Int32x4 element)) =>
+ new TakeWhileIterable<Int32x4>(this, test);
+
+ Iterable<Int32x4> skip(int n) => new SubListIterable<Int32x4>(this, n, null);
+
+ Iterable<Int32x4> skipWhile(bool test(Int32x4 element)) =>
+ new SkipWhileIterable<Int32x4>(this, test);
+
+ Iterable<Int32x4> get reversed => new ReversedListIterable<Int32x4>(this);
+
+ Map<int, Int32x4> asMap() => new ListMapView<Int32x4>(this);
+
+ Iterable<Int32x4> getRange(int start, [int end]) {
+ RangeError.checkValidRange(start, end, this.length);
+ return new SubListIterable<Int32x4>(this, start, end);
+ }
+
+ Iterator<Int32x4> get iterator => new _TypedListIterator<Int32x4>(this);
+
+ List<Int32x4> toList({bool growable: true}) {
+ return new List<Int32x4>.from(this, growable: growable);
+ }
+
+ Set<Int32x4> toSet() {
+ return new Set<Int32x4>.from(this);
+ }
+
+ void forEach(void f(Int32x4 element)) {
+ var len = this.length;
+ for (var i = 0; i < len; i++) {
+ f(this[i]);
+ }
+ }
+
+ Int32x4 reduce(Int32x4 combine(Int32x4 value, Int32x4 element)) {
+ var len = this.length;
+ if (len == 0) throw IterableElementError.noElement();
+ var value = this[0];
+ for (var i = 1; i < len; ++i) {
+ value = combine(value, this[i]);
+ }
+ return value;
+ }
+
+ T fold<T>(T initialValue, T combine(T initialValue, Int32x4 element)) {
+ var len = this.length;
+ for (var i = 0; i < len; ++i) {
+ initialValue = combine(initialValue, this[i]);
+ }
+ return initialValue;
+ }
+
+ Iterable<T> map<T>(T f(Int32x4 element)) =>
+ new MappedIterable<Int32x4, T>(this, f);
+
+ Iterable<T> expand<T>(Iterable<T> f(Int32x4 element)) =>
+ new ExpandIterable<Int32x4, T>(this, f);
+
+ bool every(bool f(Int32x4 element)) {
+ var len = this.length;
+ for (var i = 0; i < len; ++i) {
+ if (!f(this[i])) return false;
+ }
+ return true;
+ }
+
+ bool any(bool f(Int32x4 element)) {
+ var len = this.length;
+ for (var i = 0; i < len; ++i) {
+ if (f(this[i])) return true;
+ }
+ return false;
+ }
+
+ Int32x4 firstWhere(bool test(Int32x4 element), {Int32x4 orElse()}) {
+ var len = this.length;
+ for (var i = 0; i < len; ++i) {
+ var element = this[i];
+ if (test(element)) return element;
+ }
+ if (orElse != null) return orElse();
+ throw IterableElementError.noElement();
+ }
+
+ Int32x4 lastWhere(bool test(Int32x4 element), {Int32x4 orElse()}) {
+ var len = this.length;
+ for (var i = len - 1; i >= 0; --i) {
+ var element = this[i];
+ if (test(element)) {
+ return element;
+ }
+ }
+ if (orElse != null) return orElse();
+ throw IterableElementError.noElement();
+ }
+
+ Int32x4 singleWhere(bool test(Int32x4 element), {Int32x4 orElse()}) {
+ var result = null;
+ bool foundMatching = false;
+ var len = this.length;
+ for (var i = 0; i < len; ++i) {
+ var element = this[i];
+ if (test(element)) {
+ if (foundMatching) {
+ throw IterableElementError.tooMany();
+ }
+ result = element;
+ foundMatching = true;
+ }
+ }
+ if (foundMatching) return result;
+ if (orElse != null) return orElse();
+ throw IterableElementError.noElement();
+ }
+
+ Int32x4 elementAt(int index) {
+ return this[index];
+ }
+
+ void add(Int32x4 value) {
+ throw new UnsupportedError("Cannot add to a fixed-length list");
+ }
+
+ void addAll(Iterable<Int32x4> value) {
+ throw new UnsupportedError("Cannot add to a fixed-length list");
+ }
+
+ void insert(int index, Int32x4 value) {
+ throw new UnsupportedError("Cannot insert into a fixed-length list");
+ }
+
+ void insertAll(int index, Iterable<Int32x4> values) {
+ throw new UnsupportedError("Cannot insert into a fixed-length list");
+ }
+
+ void sort([int compare(Int32x4 a, Int32x4 b)]) {
+ if (compare == null) {
+ throw "SIMD don't have default compare.";
+ }
+ Sort.sort(this, compare);
+ }
+
+ int indexOf(Int32x4 element, [int start = 0]) {
+ if (start >= this.length) {
+ return -1;
+ } else if (start < 0) {
+ start = 0;
+ }
+ for (int i = start; i < this.length; i++) {
+ if (this[i] == element) return i;
+ }
+ return -1;
+ }
+
+ int lastIndexOf(Int32x4 element, [int start = null]) {
+ if (start == null || start >= this.length) {
+ start = this.length - 1;
+ } else if (start < 0) {
+ return -1;
+ }
+ for (int i = start; i >= 0; i--) {
+ if (this[i] == element) return i;
+ }
+ return -1;
+ }
+
+ Int32x4 removeLast() {
+ throw new UnsupportedError("Cannot remove from a fixed-length list");
+ }
+
+ Int32x4 removeAt(int index) {
+ throw new UnsupportedError("Cannot remove from a fixed-length list");
+ }
+
+ void removeWhere(bool test(Int32x4 element)) {
+ throw new UnsupportedError("Cannot remove from a fixed-length list");
+ }
+
+ void retainWhere(bool test(Int32x4 element)) {
+ throw new UnsupportedError("Cannot remove from a fixed-length list");
+ }
+
+ Int32x4 get first {
+ if (length > 0) return this[0];
+ throw IterableElementError.noElement();
+ }
+
+ Int32x4 get last {
+ if (length > 0) return this[length - 1];
+ throw IterableElementError.noElement();
+ }
+
+ Int32x4 get single {
+ if (length == 1) return this[0];
+ if (length == 0) throw IterableElementError.noElement();
+ throw IterableElementError.tooMany();
+ }
+
+ Int32x4List sublist(int start, [int end]) {
+ end = RangeError.checkValidRange(start, end, this.length);
+ var length = end - start;
+ Int32x4List result = _createList(length);
+ result.setRange(0, length, this, start);
+ return result;
+ }
+
+ void setAll(int index, Iterable<Int32x4> iterable) {
+ final end = iterable.length + index;
+ setRange(index, end, iterable);
+ }
+
+ void fillRange(int start, int end, [Int32x4 fillValue]) {
+ RangeError.checkValidRange(start, end, this.length);
+ for (var i = start; i < end; ++i) {
+ this[i] = fillValue;
+ }
+ }
+}
+
+abstract class _Float64x2ListMixin implements List<Float64x2> {
+ int get elementSizeInBytes;
+ int get offsetInBytes;
+ _ByteBuffer get buffer;
+
+ Float64x2List _createList(int length);
+
+ Iterable<T> whereType<T>() => new WhereTypeIterable<T>(this);
+
+ Iterable<Float64x2> followedBy(Iterable<Float64x2> other) =>
+ new FollowedByIterable<Float64x2>.firstEfficient(this, other);
+
+ List<R> cast<R>() => List.castFrom<Float64x2, R>(this);
+ void set first(Float64x2 value) {
+ if (this.length == 0) throw new RangeError.index(0, this);
+ this[0] = value;
+ }
+
+ void set last(Float64x2 value) {
+ if (this.length == 0) throw new RangeError.index(0, this);
+ this[this.length - 1] = value;
+ }
+
+ int indexWhere(bool test(Float64x2 element), [int start = 0]) {
+ if (start < 0) start = 0;
+ for (int i = start; i < length; i++) {
+ if (test(this[i])) return i;
+ }
+ return -1;
+ }
+
+ int lastIndexWhere(bool test(Float64x2 element), [int start]) {
+ if (start == null || start >= this.length) start = this.length - 1;
+ for (int i = start; i >= 0; i--) {
+ if (test(this[i])) return i;
+ }
+ return -1;
+ }
+
+ List<Float64x2> operator +(List<Float64x2> other) {
+ int totalLength = this.length + other.length;
+ return <Float64x2>[]
+ ..length = totalLength
+ ..setRange(0, this.length, this)
+ ..setRange(this.length, totalLength, other);
+ }
+
+ bool contains(Object element) {
+ var len = this.length;
+ for (var i = 0; i < len; ++i) {
+ if (this[i] == element) return true;
+ }
+ return false;
+ }
+
+ void shuffle([Random random]) {
+ random ??= new Random();
+ var i = this.length;
+ while (i > 1) {
+ int pos = random.nextInt(i);
+ i -= 1;
+ var tmp = this[i];
+ this[i] = this[pos];
+ this[pos] = tmp;
+ }
+ }
+
+ void setRange(int start, int end, Iterable<Float64x2> from,
+ [int skipCount = 0]) {
+ // Check ranges.
+ if (0 > start || start > end || end > length) {
+ RangeError.checkValidRange(start, end, length); // Always throws.
+ assert(false);
+ }
+ if (skipCount < 0) {
+ throw RangeError.range(skipCount, 0, null, "skipCount");
+ }
+
+ final count = end - start;
+ if ((from.length - skipCount) < count) {
+ throw IterableElementError.tooFew();
+ }
+
+ if (count == 0) return;
+
+ if (from is _TypedListBase) {
+ // Note: _TypedListBase is not related to Iterable<Float64x2> so there is
+ // no promotion here.
+ final fromAsTypedList = from as _TypedListBase;
+ if (this.elementSizeInBytes == fromAsTypedList.elementSizeInBytes) {
+ if ((count < 10) && (fromAsTypedList.buffer != this.buffer)) {
+ Lists.copy(from as List<Float64x2>, skipCount, this, start, count);
+ return;
+ } else if (this.buffer._data._setRange(
+ start * elementSizeInBytes + this.offsetInBytes,
+ count * elementSizeInBytes,
+ fromAsTypedList.buffer._data,
+ skipCount * elementSizeInBytes + fromAsTypedList.offsetInBytes,
+ ClassID.getID(this),
+ ClassID.getID(from))) {
+ return;
+ }
+ } else if (fromAsTypedList.buffer == this.buffer) {
+ // Different element sizes, but same buffer means that we need
+ // an intermediate structure.
+ // TODO(srdjan): Optimize to skip copying if the range does not overlap.
+ final fromAsList = from as List<Float64x2>;
+ final tempBuffer = _createList(count);
+ for (var i = 0; i < count; i++) {
+ tempBuffer[i] = fromAsList[skipCount + i];
+ }
+ for (var i = start; i < end; i++) {
+ this[i] = tempBuffer[i - start];
+ }
+ return;
+ }
+ }
+
+ List otherList;
+ int otherStart;
+ if (from is List<Float64x2>) {
+ otherList = from;
+ otherStart = skipCount;
+ } else {
+ otherList = from.skip(skipCount).toList(growable: false);
+ otherStart = 0;
+ }
+ if (otherStart + count > otherList.length) {
+ throw IterableElementError.tooFew();
+ }
+ Lists.copy(otherList, otherStart, this, start, count);
+ }
+
+ Iterable<Float64x2> where(bool f(Float64x2 element)) =>
+ new WhereIterable<Float64x2>(this, f);
+
+ Iterable<Float64x2> take(int n) => new SubListIterable<Float64x2>(this, 0, n);
+
+ Iterable<Float64x2> takeWhile(bool test(Float64x2 element)) =>
+ new TakeWhileIterable<Float64x2>(this, test);
+
+ Iterable<Float64x2> skip(int n) =>
+ new SubListIterable<Float64x2>(this, n, null);
+
+ Iterable<Float64x2> skipWhile(bool test(Float64x2 element)) =>
+ new SkipWhileIterable<Float64x2>(this, test);
+
+ Iterable<Float64x2> get reversed => new ReversedListIterable<Float64x2>(this);
+
+ Map<int, Float64x2> asMap() => new ListMapView<Float64x2>(this);
+
+ Iterable<Float64x2> getRange(int start, [int end]) {
+ RangeError.checkValidRange(start, end, this.length);
+ return new SubListIterable<Float64x2>(this, start, end);
+ }
+
+ Iterator<Float64x2> get iterator => new _TypedListIterator<Float64x2>(this);
+
+ List<Float64x2> toList({bool growable: true}) {
+ return new List<Float64x2>.from(this, growable: growable);
+ }
+
+ Set<Float64x2> toSet() {
+ return new Set<Float64x2>.from(this);
+ }
+
+ void forEach(void f(Float64x2 element)) {
+ var len = this.length;
+ for (var i = 0; i < len; i++) {
+ f(this[i]);
+ }
+ }
+
+ Float64x2 reduce(Float64x2 combine(Float64x2 value, Float64x2 element)) {
+ var len = this.length;
+ if (len == 0) throw IterableElementError.noElement();
+ var value = this[0];
+ for (var i = 1; i < len; ++i) {
+ value = combine(value, this[i]);
+ }
+ return value;
+ }
+
+ T fold<T>(T initialValue, T combine(T initialValue, Float64x2 element)) {
+ var len = this.length;
+ for (var i = 0; i < len; ++i) {
+ initialValue = combine(initialValue, this[i]);
+ }
+ return initialValue;
+ }
+
+ Iterable<T> map<T>(T f(Float64x2 element)) =>
+ new MappedIterable<Float64x2, T>(this, f);
+
+ Iterable<T> expand<T>(Iterable<T> f(Float64x2 element)) =>
+ new ExpandIterable<Float64x2, T>(this, f);
+
+ bool every(bool f(Float64x2 element)) {
+ var len = this.length;
+ for (var i = 0; i < len; ++i) {
+ if (!f(this[i])) return false;
+ }
+ return true;
+ }
+
+ bool any(bool f(Float64x2 element)) {
+ var len = this.length;
+ for (var i = 0; i < len; ++i) {
+ if (f(this[i])) return true;
+ }
+ return false;
+ }
+
+ Float64x2 firstWhere(bool test(Float64x2 element), {Float64x2 orElse()}) {
+ var len = this.length;
+ for (var i = 0; i < len; ++i) {
+ var element = this[i];
+ if (test(element)) return element;
+ }
+ if (orElse != null) return orElse();
+ throw IterableElementError.noElement();
+ }
+
+ Float64x2 lastWhere(bool test(Float64x2 element), {Float64x2 orElse()}) {
+ var len = this.length;
+ for (var i = len - 1; i >= 0; --i) {
+ var element = this[i];
+ if (test(element)) {
+ return element;
+ }
+ }
+ if (orElse != null) return orElse();
+ throw IterableElementError.noElement();
+ }
+
+ Float64x2 singleWhere(bool test(Float64x2 element), {Float64x2 orElse()}) {
+ var result = null;
+ bool foundMatching = false;
+ var len = this.length;
+ for (var i = 0; i < len; ++i) {
+ var element = this[i];
+ if (test(element)) {
+ if (foundMatching) {
+ throw IterableElementError.tooMany();
+ }
+ result = element;
+ foundMatching = true;
+ }
+ }
+ if (foundMatching) return result;
+ if (orElse != null) return orElse();
+ throw IterableElementError.noElement();
+ }
+
+ Float64x2 elementAt(int index) {
+ return this[index];
+ }
+
+ void add(Float64x2 value) {
+ throw new UnsupportedError("Cannot add to a fixed-length list");
+ }
+
+ void addAll(Iterable<Float64x2> value) {
+ throw new UnsupportedError("Cannot add to a fixed-length list");
+ }
+
+ void insert(int index, Float64x2 value) {
+ throw new UnsupportedError("Cannot insert into a fixed-length list");
+ }
+
+ void insertAll(int index, Iterable<Float64x2> values) {
+ throw new UnsupportedError("Cannot insert into a fixed-length list");
+ }
+
+ void sort([int compare(Float64x2 a, Float64x2 b)]) {
+ if (compare == null) {
+ throw "SIMD don't have default compare.";
+ }
+ Sort.sort(this, compare);
+ }
+
+ int indexOf(Float64x2 element, [int start = 0]) {
+ if (start >= this.length) {
+ return -1;
+ } else if (start < 0) {
+ start = 0;
+ }
+ for (int i = start; i < this.length; i++) {
+ if (this[i] == element) return i;
+ }
+ return -1;
+ }
+
+ int lastIndexOf(Float64x2 element, [int start = null]) {
+ if (start == null || start >= this.length) {
+ start = this.length - 1;
+ } else if (start < 0) {
+ return -1;
+ }
+ for (int i = start; i >= 0; i--) {
+ if (this[i] == element) return i;
+ }
+ return -1;
+ }
+
+ Float64x2 removeLast() {
+ throw new UnsupportedError("Cannot remove from a fixed-length list");
+ }
+
+ Float64x2 removeAt(int index) {
+ throw new UnsupportedError("Cannot remove from a fixed-length list");
+ }
+
+ void removeWhere(bool test(Float64x2 element)) {
+ throw new UnsupportedError("Cannot remove from a fixed-length list");
+ }
+
+ void retainWhere(bool test(Float64x2 element)) {
+ throw new UnsupportedError("Cannot remove from a fixed-length list");
+ }
+
+ Float64x2 get first {
+ if (length > 0) return this[0];
+ throw IterableElementError.noElement();
+ }
+
+ Float64x2 get last {
+ if (length > 0) return this[length - 1];
+ throw IterableElementError.noElement();
+ }
+
+ Float64x2 get single {
+ if (length == 1) return this[0];
+ if (length == 0) throw IterableElementError.noElement();
+ throw IterableElementError.tooMany();
+ }
+
+ Float64x2List sublist(int start, [int end]) {
+ end = RangeError.checkValidRange(start, end, this.length);
+ var length = end - start;
+ Float64x2List result = _createList(length);
+ result.setRange(0, length, this, start);
+ return result;
+ }
+
+ void setAll(int index, Iterable<Float64x2> iterable) {
+ final end = iterable.length + index;
+ setRange(index, end, iterable);
+ }
+
+ void fillRange(int start, int end, [Float64x2 fillValue]) {
+ RangeError.checkValidRange(start, end, this.length);
+ for (var i = start; i < end; ++i) {
+ this[i] = fillValue;
+ }
+ }
+}
+
+@pragma("vm:entry-point")
+class _ByteBuffer implements ByteBuffer {
+ final _TypedList _data;
+
+ _ByteBuffer(this._data);
+
+ @pragma("vm:entry-point")
+ factory _ByteBuffer._New(data) => new _ByteBuffer(data);
+
+ // Forward calls to _data.
+ int get lengthInBytes => _data.lengthInBytes;
+ int get hashCode => _data.hashCode;
+ bool operator ==(Object other) =>
+ (other is _ByteBuffer) && identical(_data, other._data);
+
+ ByteData asByteData([int offsetInBytes = 0, int length]) {
+ length ??= this.lengthInBytes - offsetInBytes;
+ _rangeCheck(this._data.lengthInBytes, offsetInBytes, length);
+ return new _ByteDataView._(this._data, offsetInBytes, length);
+ }
+
+ Int8List asInt8List([int offsetInBytes = 0, int length]) {
+ length ??= (this.lengthInBytes - offsetInBytes) ~/ Int8List.bytesPerElement;
+ _rangeCheck(
+ this.lengthInBytes, offsetInBytes, length * Int8List.bytesPerElement);
+ return new _Int8ArrayView._(this._data, offsetInBytes, length);
+ }
+
+ Uint8List asUint8List([int offsetInBytes = 0, int length]) {
+ length ??=
+ (this.lengthInBytes - offsetInBytes) ~/ Uint8List.bytesPerElement;
+ _rangeCheck(
+ this.lengthInBytes, offsetInBytes, length * Uint8List.bytesPerElement);
+ return new _Uint8ArrayView._(this._data, offsetInBytes, length);
+ }
+
+ Uint8ClampedList asUint8ClampedList([int offsetInBytes = 0, int length]) {
+ length ??= (this.lengthInBytes - offsetInBytes) ~/
+ Uint8ClampedList.bytesPerElement;
+ _rangeCheck(this.lengthInBytes, offsetInBytes,
+ length * Uint8ClampedList.bytesPerElement);
+ return new _Uint8ClampedArrayView._(this._data, offsetInBytes, length);
+ }
+
+ Int16List asInt16List([int offsetInBytes = 0, int length]) {
+ length ??=
+ (this.lengthInBytes - offsetInBytes) ~/ Int16List.bytesPerElement;
+ _rangeCheck(
+ this.lengthInBytes, offsetInBytes, length * Int16List.bytesPerElement);
+ _offsetAlignmentCheck(offsetInBytes, Int16List.bytesPerElement);
+ return new _Int16ArrayView._(this._data, offsetInBytes, length);
+ }
+
+ Uint16List asUint16List([int offsetInBytes = 0, int length]) {
+ length ??=
+ (this.lengthInBytes - offsetInBytes) ~/ Uint16List.bytesPerElement;
+ _rangeCheck(
+ this.lengthInBytes, offsetInBytes, length * Uint16List.bytesPerElement);
+ _offsetAlignmentCheck(offsetInBytes, Uint16List.bytesPerElement);
+ return new _Uint16ArrayView._(this._data, offsetInBytes, length);
+ }
+
+ Int32List asInt32List([int offsetInBytes = 0, int length]) {
+ length ??=
+ (this.lengthInBytes - offsetInBytes) ~/ Int32List.bytesPerElement;
+ _rangeCheck(
+ this.lengthInBytes, offsetInBytes, length * Int32List.bytesPerElement);
+ _offsetAlignmentCheck(offsetInBytes, Int32List.bytesPerElement);
+ return new _Int32ArrayView._(this._data, offsetInBytes, length);
+ }
+
+ Uint32List asUint32List([int offsetInBytes = 0, int length]) {
+ length ??=
+ (this.lengthInBytes - offsetInBytes) ~/ Uint32List.bytesPerElement;
+ _rangeCheck(
+ this.lengthInBytes, offsetInBytes, length * Uint32List.bytesPerElement);
+ _offsetAlignmentCheck(offsetInBytes, Uint32List.bytesPerElement);
+ return new _Uint32ArrayView._(this._data, offsetInBytes, length);
+ }
+
+ Int64List asInt64List([int offsetInBytes = 0, int length]) {
+ length ??=
+ (this.lengthInBytes - offsetInBytes) ~/ Int64List.bytesPerElement;
+ _rangeCheck(
+ this.lengthInBytes, offsetInBytes, length * Int64List.bytesPerElement);
+ _offsetAlignmentCheck(offsetInBytes, Int64List.bytesPerElement);
+ return new _Int64ArrayView._(this._data, offsetInBytes, length);
+ }
+
+ Uint64List asUint64List([int offsetInBytes = 0, int length]) {
+ length ??=
+ (this.lengthInBytes - offsetInBytes) ~/ Uint64List.bytesPerElement;
+ _rangeCheck(
+ this.lengthInBytes, offsetInBytes, length * Uint64List.bytesPerElement);
+ _offsetAlignmentCheck(offsetInBytes, Uint64List.bytesPerElement);
+ return new _Uint64ArrayView._(this._data, offsetInBytes, length);
+ }
+
+ Float32List asFloat32List([int offsetInBytes = 0, int length]) {
+ length ??=
+ (this.lengthInBytes - offsetInBytes) ~/ Float32List.bytesPerElement;
+ _rangeCheck(this.lengthInBytes, offsetInBytes,
+ length * Float32List.bytesPerElement);
+ _offsetAlignmentCheck(offsetInBytes, Float32List.bytesPerElement);
+ return new _Float32ArrayView._(this._data, offsetInBytes, length);
+ }
+
+ Float64List asFloat64List([int offsetInBytes = 0, int length]) {
+ length ??=
+ (this.lengthInBytes - offsetInBytes) ~/ Float64List.bytesPerElement;
+ _rangeCheck(this.lengthInBytes, offsetInBytes,
+ length * Float64List.bytesPerElement);
+ _offsetAlignmentCheck(offsetInBytes, Float64List.bytesPerElement);
+ return new _Float64ArrayView._(this._data, offsetInBytes, length);
+ }
+
+ Float32x4List asFloat32x4List([int offsetInBytes = 0, int length]) {
+ length ??=
+ (this.lengthInBytes - offsetInBytes) ~/ Float32x4List.bytesPerElement;
+ _rangeCheck(this.lengthInBytes, offsetInBytes,
+ length * Float32x4List.bytesPerElement);
+ _offsetAlignmentCheck(offsetInBytes, Float32x4List.bytesPerElement);
+ return new _Float32x4ArrayView._(this._data, offsetInBytes, length);
+ }
+
+ Int32x4List asInt32x4List([int offsetInBytes = 0, int length]) {
+ length ??=
+ (this.lengthInBytes - offsetInBytes) ~/ Int32x4List.bytesPerElement;
+ _rangeCheck(this.lengthInBytes, offsetInBytes,
+ length * Int32x4List.bytesPerElement);
+ _offsetAlignmentCheck(offsetInBytes, Int32x4List.bytesPerElement);
+ return new _Int32x4ArrayView._(this._data, offsetInBytes, length);
+ }
+
+ Float64x2List asFloat64x2List([int offsetInBytes = 0, int length]) {
+ length ??=
+ (this.lengthInBytes - offsetInBytes) ~/ Float64x2List.bytesPerElement;
+ _rangeCheck(this.lengthInBytes, offsetInBytes,
+ length * Float64x2List.bytesPerElement);
+ _offsetAlignmentCheck(offsetInBytes, Float64x2List.bytesPerElement);
+ return new _Float64x2ArrayView._(this._data, offsetInBytes, length);
+ }
+}
+
+abstract class _TypedList extends _TypedListBase {
+ int get elementSizeInBytes;
+
+ // Default method implementing parts of the TypedData interface.
+ int get offsetInBytes {
+ return 0;
+ }
+
+ int get lengthInBytes {
+ return length * elementSizeInBytes;
+ }
+
+ _ByteBuffer get buffer => new _ByteBuffer(this);
+
+ // Methods implementing the collection interface.
+
+ @pragma("vm:exact-result-type", "dart:core#_Smi")
+ @pragma("vm:prefer-inline")
+ int get length native "TypedData_length";
+
+ // Internal utility methods.
+
+ @pragma("vm:exact-result-type", "dart:core#_Smi")
+ int _getInt8(int offsetInBytes) native "TypedData_GetInt8";
+ void _setInt8(int offsetInBytes, int value) native "TypedData_SetInt8";
+
+ @pragma("vm:exact-result-type", "dart:core#_Smi")
+ int _getUint8(int offsetInBytes) native "TypedData_GetUint8";
+ void _setUint8(int offsetInBytes, int value) native "TypedData_SetUint8";
+
+ @pragma("vm:exact-result-type", "dart:core#_Smi")
+ int _getInt16(int offsetInBytes) native "TypedData_GetInt16";
+ void _setInt16(int offsetInBytes, int value) native "TypedData_SetInt16";
+
+ @pragma("vm:exact-result-type", "dart:core#_Smi")
+ int _getUint16(int offsetInBytes) native "TypedData_GetUint16";
+ void _setUint16(int offsetInBytes, int value) native "TypedData_SetUint16";
+
+ int _getInt32(int offsetInBytes) native "TypedData_GetInt32";
+ void _setInt32(int offsetInBytes, int value) native "TypedData_SetInt32";
+
+ int _getUint32(int offsetInBytes) native "TypedData_GetUint32";
+ void _setUint32(int offsetInBytes, int value) native "TypedData_SetUint32";
+
+ int _getInt64(int offsetInBytes) native "TypedData_GetInt64";
+ void _setInt64(int offsetInBytes, int value) native "TypedData_SetInt64";
+
+ int _getUint64(int offsetInBytes) native "TypedData_GetUint64";
+ void _setUint64(int offsetInBytes, int value) native "TypedData_SetUint64";
+
+ @pragma("vm:exact-result-type", "dart:core#_Double")
+ double _getFloat32(int offsetInBytes) native "TypedData_GetFloat32";
+ void _setFloat32(int offsetInBytes, double value)
+ native "TypedData_SetFloat32";
+
+ @pragma("vm:exact-result-type", "dart:core#_Double")
+ double _getFloat64(int offsetInBytes) native "TypedData_GetFloat64";
+ void _setFloat64(int offsetInBytes, double value)
+ native "TypedData_SetFloat64";
+
+ @pragma("vm:exact-result-type", _Float32x4)
+ Float32x4 _getFloat32x4(int offsetInBytes) native "TypedData_GetFloat32x4";
+ void _setFloat32x4(int offsetInBytes, Float32x4 value)
+ native "TypedData_SetFloat32x4";
+
+ @pragma("vm:exact-result-type", _Int32x4)
+ Int32x4 _getInt32x4(int offsetInBytes) native "TypedData_GetInt32x4";
+ void _setInt32x4(int offsetInBytes, Int32x4 value)
+ native "TypedData_SetInt32x4";
+
+ Float64x2 _getFloat64x2(int offsetInBytes) native "TypedData_GetFloat64x2";
+ void _setFloat64x2(int offsetInBytes, Float64x2 value)
+ native "TypedData_SetFloat64x2";
+
+ /**
+ * Stores the [CodeUnits] as UTF-16 units into this TypedData at
+ * positions [start]..[end] (uint16 indices).
+ */
+ void _setCodeUnits(
+ CodeUnits units, int byteStart, int length, int skipCount) {
+ assert(byteStart + length * Uint16List.bytesPerElement <= lengthInBytes);
+ String string = CodeUnits.stringOf(units);
+ int sliceEnd = skipCount + length;
+ RangeError.checkValidRange(
+ skipCount, sliceEnd, string.length, "skipCount", "skipCount + length");
+ for (int i = 0; i < length; i++) {
+ _setUint16(byteStart + i * Uint16List.bytesPerElement,
+ string.codeUnitAt(skipCount + i));
+ }
+ }
+}
+
+@patch
+class Int8List {
+ @patch
+ @pragma("vm:exact-result-type", _Int8List)
+ factory Int8List(int length) native "TypedData_Int8Array_new";
+
+ @patch
+ factory Int8List.fromList(List<int> elements) {
+ return new Int8List(elements.length)
+ ..setRange(0, elements.length, elements);
+ }
+}
+
+@pragma("vm:entry-point")
+class _Int8List extends _TypedList
+ with _IntListMixin, _TypedIntListMixin<Int8List>
+ implements Int8List {
+ factory _Int8List._uninstantiable() {
+ throw "Unreachable";
+ }
+
+ // Method(s) implementing List interface.
+ @pragma("vm:exact-result-type", "dart:core#_Smi")
+ int operator [](int index) {
+ if (index < 0 || index >= length) {
+ throw new RangeError.index(index, this, "index");
+ }
+ return _getInt8(index);
+ }
+
+ void operator []=(int index, int value) {
+ if (index < 0 || index >= length) {
+ throw new RangeError.index(index, this, "index");
+ }
+ _setInt8(index, _toInt8(value));
+ }
+
+ // Method(s) implementing TypedData interface.
+ int get elementSizeInBytes {
+ return Int8List.bytesPerElement;
+ }
+
+ // Internal utility methods.
+ Int8List _createList(int length) {
+ return new Int8List(length);
+ }
+}
+
+@patch
+class Uint8List {
+ @patch
+ @pragma("vm:exact-result-type", _Uint8List)
+ factory Uint8List(int length) native "TypedData_Uint8Array_new";
+
+ @patch
+ factory Uint8List.fromList(List<int> elements) {
+ return new Uint8List(elements.length)
+ ..setRange(0, elements.length, elements);
+ }
+}
+
+@pragma("vm:entry-point")
+class _Uint8List extends _TypedList
+ with _IntListMixin, _TypedIntListMixin<Uint8List>
+ implements Uint8List {
+ factory _Uint8List._uninstantiable() {
+ throw "Unreachable";
+ }
+
+ // Methods implementing List interface.
+ @pragma("vm:exact-result-type", "dart:core#_Smi")
+ int operator [](int index) {
+ if (index < 0 || index >= length) {
+ throw new RangeError.index(index, this, "index");
+ }
+ return _getUint8(index);
+ }
+
+ void operator []=(int index, int value) {
+ if (index < 0 || index >= length) {
+ throw new RangeError.index(index, this, "index");
+ }
+ _setUint8(index, _toUint8(value));
+ }
+
+ // Methods implementing TypedData interface.
+ int get elementSizeInBytes {
+ return Uint8List.bytesPerElement;
+ }
+
+ // Internal utility methods.
+ Uint8List _createList(int length) {
+ return new Uint8List(length);
+ }
+}
+
+@patch
+class Uint8ClampedList {
+ @patch
+ @pragma("vm:exact-result-type", _Uint8ClampedList)
+ factory Uint8ClampedList(int length) native "TypedData_Uint8ClampedArray_new";
+
+ @patch
+ factory Uint8ClampedList.fromList(List<int> elements) {
+ return new Uint8ClampedList(elements.length)
+ ..setRange(0, elements.length, elements);
+ }
+}
+
+@pragma("vm:entry-point")
+class _Uint8ClampedList extends _TypedList
+ with _IntListMixin, _TypedIntListMixin<Uint8ClampedList>
+ implements Uint8ClampedList {
+ factory _Uint8ClampedList._uninstantiable() {
+ throw "Unreachable";
+ }
+
+ // Methods implementing List interface.
+ @pragma("vm:exact-result-type", "dart:core#_Smi")
+ int operator [](int index) {
+ if (index < 0 || index >= length) {
+ throw new RangeError.index(index, this, "index");
+ }
+ return _getUint8(index);
+ }
+
+ void operator []=(int index, int value) {
+ if (index < 0 || index >= length) {
+ throw new RangeError.index(index, this, "index");
+ }
+ _setUint8(index, _toClampedUint8(value));
+ }
+
+ // Methods implementing TypedData interface.
+ int get elementSizeInBytes {
+ return Uint8List.bytesPerElement;
+ }
+
+ // Internal utility methods.
+ Uint8ClampedList _createList(int length) {
+ return new Uint8ClampedList(length);
+ }
+}
+
+@patch
+class Int16List {
+ @patch
+ @pragma("vm:exact-result-type", _Int16List)
+ factory Int16List(int length) native "TypedData_Int16Array_new";
+
+ @patch
+ factory Int16List.fromList(List<int> elements) {
+ return new Int16List(elements.length)
+ ..setRange(0, elements.length, elements);
+ }
+}
+
+@pragma("vm:entry-point")
+class _Int16List extends _TypedList
+ with _IntListMixin, _TypedIntListMixin<Int16List>
+ implements Int16List {
+ factory _Int16List._uninstantiable() {
+ throw "Unreachable";
+ }
+
+ // Method(s) implementing List interface.
+ @pragma("vm:exact-result-type", "dart:core#_Smi")
+ int operator [](int index) {
+ if (index < 0 || index >= length) {
+ throw new RangeError.index(index, this, "index");
+ }
+ return _getIndexedInt16(index);
+ }
+
+ void operator []=(int index, int value) {
+ if (index < 0 || index >= length) {
+ throw new RangeError.index(index, this, "index");
+ }
+ _setIndexedInt16(index, _toInt16(value));
+ }
+
+ void setRange(int start, int end, Iterable iterable, [int skipCount = 0]) {
+ if (iterable is CodeUnits) {
+ end = RangeError.checkValidRange(start, end, this.length);
+ int length = end - start;
+ int byteStart = this.offsetInBytes + start * Int16List.bytesPerElement;
+ _setCodeUnits(iterable, byteStart, length, skipCount);
+ } else {
+ super.setRange(start, end, iterable, skipCount);
+ }
+ }
+
+ // Method(s) implementing TypedData interface.
+ int get elementSizeInBytes {
+ return Int16List.bytesPerElement;
+ }
+
+ // Internal utility methods.
+ Int16List _createList(int length) {
+ return new Int16List(length);
+ }
+
+ int _getIndexedInt16(int index) {
+ return _getInt16(index * Int16List.bytesPerElement);
+ }
+
+ void _setIndexedInt16(int index, int value) {
+ _setInt16(index * Int16List.bytesPerElement, value);
+ }
+}
+
+@patch
+class Uint16List {
+ @patch
+ @pragma("vm:exact-result-type", _Uint16List)
+ factory Uint16List(int length) native "TypedData_Uint16Array_new";
+
+ @patch
+ factory Uint16List.fromList(List<int> elements) {
+ return new Uint16List(elements.length)
+ ..setRange(0, elements.length, elements);
+ }
+}
+
+@pragma("vm:entry-point")
+class _Uint16List extends _TypedList
+ with _IntListMixin, _TypedIntListMixin<Uint16List>
+ implements Uint16List {
+ factory _Uint16List._uninstantiable() {
+ throw "Unreachable";
+ }
+
+ // Method(s) implementing the List interface.
+ @pragma("vm:exact-result-type", "dart:core#_Smi")
+ int operator [](int index) {
+ if (index < 0 || index >= length) {
+ throw new RangeError.index(index, this, "index");
+ }
+ return _getIndexedUint16(index);
+ }
+
+ void operator []=(int index, int value) {
+ if (index < 0 || index >= length) {
+ throw new RangeError.index(index, this, "index");
+ }
+ _setIndexedUint16(index, _toUint16(value));
+ }
+
+ void setRange(int start, int end, Iterable iterable, [int skipCount = 0]) {
+ if (iterable is CodeUnits) {
+ end = RangeError.checkValidRange(start, end, this.length);
+ int length = end - start;
+ int byteStart = this.offsetInBytes + start * Uint16List.bytesPerElement;
+ _setCodeUnits(iterable, byteStart, length, skipCount);
+ } else {
+ super.setRange(start, end, iterable, skipCount);
+ }
+ }
+
+ // Method(s) implementing the TypedData interface.
+ int get elementSizeInBytes {
+ return Uint16List.bytesPerElement;
+ }
+
+ // Internal utility methods.
+ Uint16List _createList(int length) {
+ return new Uint16List(length);
+ }
+
+ int _getIndexedUint16(int index) {
+ return _getUint16(index * Uint16List.bytesPerElement);
+ }
+
+ void _setIndexedUint16(int index, int value) {
+ _setUint16(index * Uint16List.bytesPerElement, value);
+ }
+}
+
+@patch
+class Int32List {
+ @patch
+ @pragma("vm:exact-result-type", _Int32List)
+ factory Int32List(int length) native "TypedData_Int32Array_new";
+
+ @patch
+ factory Int32List.fromList(List<int> elements) {
+ return new Int32List(elements.length)
+ ..setRange(0, elements.length, elements);
+ }
+}
+
+@pragma("vm:entry-point")
+class _Int32List extends _TypedList
+ with _IntListMixin, _TypedIntListMixin<Int32List>
+ implements Int32List {
+ factory _Int32List._uninstantiable() {
+ throw "Unreachable";
+ }
+
+ // Method(s) implementing the List interface.
+ int operator [](int index) {
+ if (index < 0 || index >= length) {
+ throw new RangeError.index(index, this, "index");
+ }
+ return _getIndexedInt32(index);
+ }
+
+ void operator []=(int index, int value) {
+ if (index < 0 || index >= length) {
+ throw new RangeError.index(index, this, "index");
+ }
+ _setIndexedInt32(index, _toInt32(value));
+ }
+
+ // Method(s) implementing TypedData interface.
+ int get elementSizeInBytes {
+ return Int32List.bytesPerElement;
+ }
+
+ // Internal utility methods.
+ Int32List _createList(int length) {
+ return new Int32List(length);
+ }
+
+ int _getIndexedInt32(int index) {
+ return _getInt32(index * Int32List.bytesPerElement);
+ }
+
+ void _setIndexedInt32(int index, int value) {
+ _setInt32(index * Int32List.bytesPerElement, value);
+ }
+}
+
+@patch
+class Uint32List {
+ @patch
+ @pragma("vm:exact-result-type", _Uint32List)
+ factory Uint32List(int length) native "TypedData_Uint32Array_new";
+
+ @patch
+ factory Uint32List.fromList(List<int> elements) {
+ return new Uint32List(elements.length)
+ ..setRange(0, elements.length, elements);
+ }
+}
+
+@pragma("vm:entry-point")
+class _Uint32List extends _TypedList
+ with _IntListMixin, _TypedIntListMixin<Uint32List>
+ implements Uint32List {
+ factory _Uint32List._uninstantiable() {
+ throw "Unreachable";
+ }
+
+ // Method(s) implementing the List interface.
+ int operator [](int index) {
+ if (index < 0 || index >= length) {
+ throw new RangeError.index(index, this, "index");
+ }
+ return _getIndexedUint32(index);
+ }
+
+ void operator []=(int index, int value) {
+ if (index < 0 || index >= length) {
+ throw new RangeError.index(index, this, "index");
+ }
+ _setIndexedUint32(index, _toUint32(value));
+ }
+
+ // Method(s) implementing the TypedData interface.
+ int get elementSizeInBytes {
+ return Uint32List.bytesPerElement;
+ }
+
+ // Internal utility methods.
+ Uint32List _createList(int length) {
+ return new Uint32List(length);
+ }
+
+ int _getIndexedUint32(int index) {
+ return _getUint32(index * Uint32List.bytesPerElement);
+ }
+
+ void _setIndexedUint32(int index, int value) {
+ _setUint32(index * Uint32List.bytesPerElement, value);
+ }
+}
+
+@patch
+class Int64List {
+ @patch
+ @pragma("vm:exact-result-type", _Int64List)
+ factory Int64List(int length) native "TypedData_Int64Array_new";
+
+ @patch
+ factory Int64List.fromList(List<int> elements) {
+ return new Int64List(elements.length)
+ ..setRange(0, elements.length, elements);
+ }
+}
+
+@pragma("vm:entry-point")
+class _Int64List extends _TypedList
+ with _IntListMixin, _TypedIntListMixin<Int64List>
+ implements Int64List {
+ factory _Int64List._uninstantiable() {
+ throw "Unreachable";
+ }
+
+ // Method(s) implementing the List interface.
+ int operator [](int index) {
+ if (index < 0 || index >= length) {
+ throw new RangeError.index(index, this, "index");
+ }
+ return _getIndexedInt64(index);
+ }
+
+ void operator []=(int index, int value) {
+ if (index < 0 || index >= length) {
+ throw new RangeError.index(index, this, "index");
+ }
+ _setIndexedInt64(index, value);
+ }
+
+ // Method(s) implementing the TypedData interface.
+ int get elementSizeInBytes {
+ return Int64List.bytesPerElement;
+ }
+
+ // Internal utility methods.
+ Int64List _createList(int length) {
+ return new Int64List(length);
+ }
+
+ int _getIndexedInt64(int index) {
+ return _getInt64(index * Int64List.bytesPerElement);
+ }
+
+ void _setIndexedInt64(int index, int value) {
+ _setInt64(index * Int64List.bytesPerElement, value);
+ }
+}
+
+@patch
+class Uint64List {
+ @patch
+ @pragma("vm:exact-result-type", _Uint64List)
+ factory Uint64List(int length) native "TypedData_Uint64Array_new";
+
+ @patch
+ factory Uint64List.fromList(List<int> elements) {
+ return new Uint64List(elements.length)
+ ..setRange(0, elements.length, elements);
+ }
+}
+
+@pragma("vm:entry-point")
+class _Uint64List extends _TypedList
+ with _IntListMixin, _TypedIntListMixin<Uint64List>
+ implements Uint64List {
+ factory _Uint64List._uninstantiable() {
+ throw "Unreachable";
+ }
+
+ // Method(s) implementing the List interface.
+ int operator [](int index) {
+ if (index < 0 || index >= length) {
+ throw new RangeError.index(index, this, "index");
+ }
+ return _getIndexedUint64(index);
+ }
+
+ void operator []=(int index, int value) {
+ if (index < 0 || index >= length) {
+ throw new RangeError.index(index, this, "index");
+ }
+ _setIndexedUint64(index, value);
+ }
+
+ // Method(s) implementing the TypedData interface.
+ int get elementSizeInBytes {
+ return Uint64List.bytesPerElement;
+ }
+
+ // Internal utility methods.
+ Uint64List _createList(int length) {
+ return new Uint64List(length);
+ }
+
+ int _getIndexedUint64(int index) {
+ return _getUint64(index * Uint64List.bytesPerElement);
+ }
+
+ void _setIndexedUint64(int index, int value) {
+ _setUint64(index * Uint64List.bytesPerElement, value);
+ }
+}
+
+@patch
+class Float32List {
+ @patch
+ @pragma("vm:exact-result-type", _Float32List)
+ factory Float32List(int length) native "TypedData_Float32Array_new";
+
+ @patch
+ factory Float32List.fromList(List<double> elements) {
+ return new Float32List(elements.length)
+ ..setRange(0, elements.length, elements);
+ }
+}
+
+@pragma("vm:entry-point")
+class _Float32List extends _TypedList
+ with _DoubleListMixin, _TypedDoubleListMixin<Float32List>
+ implements Float32List {
+ factory _Float32List._uninstantiable() {
+ throw "Unreachable";
+ }
+
+ // Method(s) implementing the List interface.
+ @pragma("vm:exact-result-type", "dart:core#_Double")
+ double operator [](int index) {
+ if (index < 0 || index >= length) {
+ throw new RangeError.index(index, this, "index");
+ }
+ return _getIndexedFloat32(index);
+ }
+
+ void operator []=(int index, double value) {
+ if (index < 0 || index >= length) {
+ throw new RangeError.index(index, this, "index");
+ }
+ _setIndexedFloat32(index, value);
+ }
+
+ // Method(s) implementing the TypedData interface.
+ int get elementSizeInBytes {
+ return Float32List.bytesPerElement;
+ }
+
+ // Internal utility methods.
+ Float32List _createList(int length) {
+ return new Float32List(length);
+ }
+
+ double _getIndexedFloat32(int index) {
+ return _getFloat32(index * Float32List.bytesPerElement);
+ }
+
+ void _setIndexedFloat32(int index, double value) {
+ _setFloat32(index * Float32List.bytesPerElement, value);
+ }
+}
+
+@patch
+class Float64List {
+ @patch
+ @pragma("vm:exact-result-type", _Float64List)
+ factory Float64List(int length) native "TypedData_Float64Array_new";
+
+ @patch
+ factory Float64List.fromList(List<double> elements) {
+ return new Float64List(elements.length)
+ ..setRange(0, elements.length, elements);
+ }
+}
+
+@pragma("vm:entry-point")
+class _Float64List extends _TypedList
+ with _DoubleListMixin, _TypedDoubleListMixin<Float64List>
+ implements Float64List {
+ factory _Float64List._uninstantiable() {
+ throw "Unreachable";
+ }
+
+ // Method(s) implementing the List interface.
+ @pragma("vm:exact-result-type", "dart:core#_Double")
+ double operator [](int index) {
+ if (index < 0 || index >= length) {
+ throw new RangeError.index(index, this, "index");
+ }
+ return _getIndexedFloat64(index);
+ }
+
+ void operator []=(int index, double value) {
+ if (index < 0 || index >= length) {
+ throw new RangeError.index(index, this, "index");
+ }
+ _setIndexedFloat64(index, value);
+ }
+
+ // Method(s) implementing the TypedData interface.
+ int get elementSizeInBytes {
+ return Float64List.bytesPerElement;
+ }
+
+ // Internal utility methods.
+ Float64List _createList(int length) {
+ return new Float64List(length);
+ }
+
+ double _getIndexedFloat64(int index) {
+ return _getFloat64(index * Float64List.bytesPerElement);
+ }
+
+ void _setIndexedFloat64(int index, double value) {
+ _setFloat64(index * Float64List.bytesPerElement, value);
+ }
+}
+
+@patch
+class Float32x4List {
+ @patch
+ @pragma("vm:exact-result-type", _Float32x4List)
+ factory Float32x4List(int length) native "TypedData_Float32x4Array_new";
+
+ @patch
+ factory Float32x4List.fromList(List<Float32x4> elements) {
+ return new Float32x4List(elements.length)
+ ..setRange(0, elements.length, elements);
+ }
+}
+
+@pragma("vm:entry-point")
+class _Float32x4List extends _TypedList
+ with _Float32x4ListMixin
+ implements Float32x4List {
+ factory _Float32x4List._uninstantiable() {
+ throw "Unreachable";
+ }
+
+ @pragma("vm:exact-result-type", _Float32x4)
+ Float32x4 operator [](int index) {
+ if (index < 0 || index >= length) {
+ throw new RangeError.index(index, this, "index");
+ }
+ return _getIndexedFloat32x4(index);
+ }
+
+ void operator []=(int index, Float32x4 value) {
+ if (index < 0 || index >= length) {
+ throw new RangeError.index(index, this, "index");
+ }
+ _setIndexedFloat32x4(index, value);
+ }
+
+ // Method(s) implementing the TypedData interface.
+ int get elementSizeInBytes {
+ return Float32x4List.bytesPerElement;
+ }
+
+ // Internal utility methods.
+ Float32x4List _createList(int length) {
+ return new Float32x4List(length);
+ }
+
+ Float32x4 _getIndexedFloat32x4(int index) {
+ return _getFloat32x4(index * Float32x4List.bytesPerElement);
+ }
+
+ void _setIndexedFloat32x4(int index, Float32x4 value) {
+ _setFloat32x4(index * Float32x4List.bytesPerElement, value);
+ }
+}
+
+@patch
+class Int32x4List {
+ @patch
+ @pragma("vm:exact-result-type", _Int32x4List)
+ factory Int32x4List(int length) native "TypedData_Int32x4Array_new";
+
+ @patch
+ factory Int32x4List.fromList(List<Int32x4> elements) {
+ return new Int32x4List(elements.length)
+ ..setRange(0, elements.length, elements);
+ }
+}
+
+@pragma("vm:entry-point")
+class _Int32x4List extends _TypedList
+ with _Int32x4ListMixin
+ implements Int32x4List {
+ factory _Int32x4List._uninstantiable() {
+ throw "Unreachable";
+ }
+
+ @pragma("vm:exact-result-type", _Int32x4)
+ Int32x4 operator [](int index) {
+ if (index < 0 || index >= length) {
+ throw new RangeError.index(index, this, "index");
+ }
+ return _getIndexedInt32x4(index);
+ }
+
+ void operator []=(int index, Int32x4 value) {
+ if (index < 0 || index >= length) {
+ throw new RangeError.index(index, this, "index");
+ }
+ _setIndexedInt32x4(index, value);
+ }
+
+ // Method(s) implementing the TypedData interface.
+ int get elementSizeInBytes {
+ return Int32x4List.bytesPerElement;
+ }
+
+ // Internal utility methods.
+ Int32x4List _createList(int length) {
+ return new Int32x4List(length);
+ }
+
+ Int32x4 _getIndexedInt32x4(int index) {
+ return _getInt32x4(index * Int32x4List.bytesPerElement);
+ }
+
+ void _setIndexedInt32x4(int index, Int32x4 value) {
+ _setInt32x4(index * Int32x4List.bytesPerElement, value);
+ }
+}
+
+@patch
+class Float64x2List {
+ @patch
+ @pragma("vm:exact-result-type", _Float64x2List)
+ factory Float64x2List(int length) native "TypedData_Float64x2Array_new";
+
+ @patch
+ factory Float64x2List.fromList(List<Float64x2> elements) {
+ return new Float64x2List(elements.length)
+ ..setRange(0, elements.length, elements);
+ }
+}
+
+@pragma("vm:entry-point")
+class _Float64x2List extends _TypedList
+ with _Float64x2ListMixin
+ implements Float64x2List {
+ factory _Float64x2List._uninstantiable() {
+ throw "Unreachable";
+ }
+
+ @pragma("vm:exact-result-type", _Float64x2)
+ Float64x2 operator [](int index) {
+ if (index < 0 || index >= length) {
+ throw new RangeError.index(index, this, "index");
+ }
+ return _getIndexedFloat64x2(index);
+ }
+
+ void operator []=(int index, Float64x2 value) {
+ if (index < 0 || index >= length) {
+ throw new RangeError.index(index, this, "index");
+ }
+ _setIndexedFloat64x2(index, value);
+ }
+
+ // Method(s) implementing the TypedData interface.
+ int get elementSizeInBytes {
+ return Float64x2List.bytesPerElement;
+ }
+
+ // Internal utility methods.
+ Float64x2List _createList(int length) {
+ return new Float64x2List(length);
+ }
+
+ Float64x2 _getIndexedFloat64x2(int index) {
+ return _getFloat64x2(index * Float64x2List.bytesPerElement);
+ }
+
+ void _setIndexedFloat64x2(int index, Float64x2 value) {
+ _setFloat64x2(index * Float64x2List.bytesPerElement, value);
+ }
+}
+
+@pragma("vm:entry-point")
+class _ExternalInt8Array extends _TypedList
+ with _IntListMixin, _TypedIntListMixin<Int8List>
+ implements Int8List {
+ factory _ExternalInt8Array._uninstantiable() {
+ throw "Unreachable";
+ }
+
+ // Method(s) implementing the List interface.
+ int operator [](int index) {
+ if (index < 0 || index >= length) {
+ throw new RangeError.index(index, this, "index");
+ }
+ return _getInt8(index);
+ }
+
+ void operator []=(int index, int value) {
+ if (index < 0 || index >= length) {
+ throw new RangeError.index(index, this, "index");
+ }
+ _setInt8(index, value);
+ }
+
+ // Method(s) implementing the TypedData interface.
+ int get elementSizeInBytes {
+ return Int8List.bytesPerElement;
+ }
+
+ // Internal utility methods.
+ Int8List _createList(int length) {
+ return new Int8List(length);
+ }
+}
+
+@pragma("vm:entry-point")
+class _ExternalUint8Array extends _TypedList
+ with _IntListMixin, _TypedIntListMixin<Uint8List>
+ implements Uint8List {
+ factory _ExternalUint8Array._uninstantiable() {
+ throw "Unreachable";
+ }
+
+ // Method(s) implementing the List interface.
+ @pragma("vm:exact-result-type", "dart:core#_Smi")
+ int operator [](int index) {
+ if (index < 0 || index >= length) {
+ throw new RangeError.index(index, this, "index");
+ }
+ return _getUint8(index);
+ }
+
+ void operator []=(int index, int value) {
+ if (index < 0 || index >= length) {
+ throw new RangeError.index(index, this, "index");
+ }
+ _setUint8(index, _toUint8(value));
+ }
+
+ // Method(s) implementing the TypedData interface.
+ int get elementSizeInBytes {
+ return Uint8List.bytesPerElement;
+ }
+
+ // Internal utility methods.
+ Uint8List _createList(int length) {
+ return new Uint8List(length);
+ }
+}
+
+@pragma("vm:entry-point")
+class _ExternalUint8ClampedArray extends _TypedList
+ with _IntListMixin, _TypedIntListMixin<Uint8ClampedList>
+ implements Uint8ClampedList {
+ factory _ExternalUint8ClampedArray._uninstantiable() {
+ throw "Unreachable";
+ }
+
+ // Method(s) implementing the List interface.
+ @pragma("vm:exact-result-type", "dart:core#_Smi")
+ int operator [](int index) {
+ if (index < 0 || index >= length) {
+ throw new RangeError.index(index, this, "index");
+ }
+ return _getUint8(index);
+ }
+
+ void operator []=(int index, int value) {
+ if (index < 0 || index >= length) {
+ throw new RangeError.index(index, this, "index");
+ }
+ _setUint8(index, _toClampedUint8(value));
+ }
+
+ // Method(s) implementing the TypedData interface.
+ int get elementSizeInBytes {
+ return Uint8List.bytesPerElement;
+ }
+
+ // Internal utility methods.
+ Uint8ClampedList _createList(int length) {
+ return new Uint8ClampedList(length);
+ }
+}
+
+@pragma("vm:entry-point")
+class _ExternalInt16Array extends _TypedList
+ with _IntListMixin, _TypedIntListMixin<Int16List>
+ implements Int16List {
+ factory _ExternalInt16Array._uninstantiable() {
+ throw "Unreachable";
+ }
+
+ // Method(s) implementing the List interface.
+ int operator [](int index) {
+ if (index < 0 || index >= length) {
+ throw new RangeError.index(index, this, "index");
+ }
+ return _getIndexedInt16(index);
+ }
+
+ void operator []=(int index, int value) {
+ if (index < 0 || index >= length) {
+ throw new RangeError.index(index, this, "index");
+ }
+ _setIndexedInt16(index, _toInt16(value));
+ }
+
+ // Method(s) implementing the TypedData interface.
+ int get elementSizeInBytes {
+ return Int16List.bytesPerElement;
+ }
+
+ // Internal utility methods.
+ Int16List _createList(int length) {
+ return new Int16List(length);
+ }
+
+ int _getIndexedInt16(int index) {
+ return _getInt16(index * Int16List.bytesPerElement);
+ }
+
+ void _setIndexedInt16(int index, int value) {
+ _setInt16(index * Int16List.bytesPerElement, value);
+ }
+}
+
+@pragma("vm:entry-point")
+class _ExternalUint16Array extends _TypedList
+ with _IntListMixin, _TypedIntListMixin<Uint16List>
+ implements Uint16List {
+ factory _ExternalUint16Array._uninstantiable() {
+ throw "Unreachable";
+ }
+
+ // Method(s) implementing the List interface.
+ int operator [](int index) {
+ if (index < 0 || index >= length) {
+ throw new RangeError.index(index, this, "index");
+ }
+ return _getIndexedUint16(index);
+ }
+
+ void operator []=(int index, int value) {
+ if (index < 0 || index >= length) {
+ throw new RangeError.index(index, this, "index");
+ }
+ _setIndexedUint16(index, _toUint16(value));
+ }
+
+ // Method(s) implementing the TypedData interface.
+ int get elementSizeInBytes {
+ return Uint16List.bytesPerElement;
+ }
+
+ // Internal utility methods.
+ Uint16List _createList(int length) {
+ return new Uint16List(length);
+ }
+
+ int _getIndexedUint16(int index) {
+ return _getUint16(index * Uint16List.bytesPerElement);
+ }
+
+ void _setIndexedUint16(int index, int value) {
+ _setUint16(index * Uint16List.bytesPerElement, value);
+ }
+}
+
+@pragma("vm:entry-point")
+class _ExternalInt32Array extends _TypedList
+ with _IntListMixin, _TypedIntListMixin<Int32List>
+ implements Int32List {
+ factory _ExternalInt32Array._uninstantiable() {
+ throw "Unreachable";
+ }
+
+ // Method(s) implementing the List interface.
+ int operator [](int index) {
+ if (index < 0 || index >= length) {
+ throw new RangeError.index(index, this, "index");
+ }
+ return _getIndexedInt32(index);
+ }
+
+ void operator []=(int index, int value) {
+ if (index < 0 || index >= length) {
+ throw new RangeError.index(index, this, "index");
+ }
+ _setIndexedInt32(index, _toInt32(value));
+ }
+
+ // Method(s) implementing the TypedData interface.
+ int get elementSizeInBytes {
+ return Int32List.bytesPerElement;
+ }
+
+ // Internal utility methods.
+ Int32List _createList(int length) {
+ return new Int32List(length);
+ }
+
+ int _getIndexedInt32(int index) {
+ return _getInt32(index * Int32List.bytesPerElement);
+ }
+
+ void _setIndexedInt32(int index, int value) {
+ _setInt32(index * Int32List.bytesPerElement, value);
+ }
+}
+
+@pragma("vm:entry-point")
+class _ExternalUint32Array extends _TypedList
+ with _IntListMixin, _TypedIntListMixin<Uint32List>
+ implements Uint32List {
+ factory _ExternalUint32Array._uninstantiable() {
+ throw "Unreachable";
+ }
+
+ // Method(s) implementing the List interface.
+ int operator [](int index) {
+ if (index < 0 || index >= length) {
+ throw new RangeError.index(index, this, "index");
+ }
+ return _getIndexedUint32(index);
+ }
+
+ void operator []=(int index, int value) {
+ if (index < 0 || index >= length) {
+ throw new RangeError.index(index, this, "index");
+ }
+ _setIndexedUint32(index, _toUint32(value));
+ }
+
+ // Method(s) implementing the TypedData interface.
+ int get elementSizeInBytes {
+ return Uint32List.bytesPerElement;
+ }
+
+ // Internal utility methods.
+ Uint32List _createList(int length) {
+ return new Uint32List(length);
+ }
+
+ int _getIndexedUint32(int index) {
+ return _getUint32(index * Uint32List.bytesPerElement);
+ }
+
+ void _setIndexedUint32(int index, int value) {
+ _setUint32(index * Uint32List.bytesPerElement, value);
+ }
+}
+
+@pragma("vm:entry-point")
+class _ExternalInt64Array extends _TypedList
+ with _IntListMixin, _TypedIntListMixin<Int64List>
+ implements Int64List {
+ factory _ExternalInt64Array._uninstantiable() {
+ throw "Unreachable";
+ }
+
+ // Method(s) implementing the List interface.
+ int operator [](int index) {
+ if (index < 0 || index >= length) {
+ throw new RangeError.index(index, this, "index");
+ }
+ return _getIndexedInt64(index);
+ }
+
+ void operator []=(int index, int value) {
+ if (index < 0 || index >= length) {
+ throw new RangeError.index(index, this, "index");
+ }
+ _setIndexedInt64(index, value);
+ }
+
+ // Method(s) implementing the TypedData interface.
+ int get elementSizeInBytes {
+ return Int64List.bytesPerElement;
+ }
+
+ // Internal utility methods.
+ Int64List _createList(int length) {
+ return new Int64List(length);
+ }
+
+ int _getIndexedInt64(int index) {
+ return _getInt64(index * Int64List.bytesPerElement);
+ }
+
+ void _setIndexedInt64(int index, int value) {
+ _setInt64(index * Int64List.bytesPerElement, value);
+ }
+}
+
+@pragma("vm:entry-point")
+class _ExternalUint64Array extends _TypedList
+ with _IntListMixin, _TypedIntListMixin<Uint64List>
+ implements Uint64List {
+ factory _ExternalUint64Array._uninstantiable() {
+ throw "Unreachable";
+ }
+
+ // Method(s) implementing the List interface.
+ int operator [](int index) {
+ if (index < 0 || index >= length) {
+ throw new RangeError.index(index, this, "index");
+ }
+ return _getIndexedUint64(index);
+ }
+
+ void operator []=(int index, int value) {
+ if (index < 0 || index >= length) {
+ throw new RangeError.index(index, this, "index");
+ }
+ _setIndexedUint64(index, value);
+ }
+
+ // Method(s) implementing the TypedData interface.
+ int get elementSizeInBytes {
+ return Uint64List.bytesPerElement;
+ }
+
+ // Internal utility methods.
+ Uint64List _createList(int length) {
+ return new Uint64List(length);
+ }
+
+ int _getIndexedUint64(int index) {
+ return _getUint64(index * Uint64List.bytesPerElement);
+ }
+
+ void _setIndexedUint64(int index, int value) {
+ _setUint64(index * Uint64List.bytesPerElement, value);
+ }
+}
+
+@pragma("vm:entry-point")
+class _ExternalFloat32Array extends _TypedList
+ with _DoubleListMixin, _TypedDoubleListMixin<Float32List>
+ implements Float32List {
+ factory _ExternalFloat32Array._uninstantiable() {
+ throw "Unreachable";
+ }
+
+ // Method(s) implementing the List interface.
+ double operator [](int index) {
+ if (index < 0 || index >= length) {
+ throw new RangeError.index(index, this, "index");
+ }
+ return _getIndexedFloat32(index);
+ }
+
+ void operator []=(int index, double value) {
+ if (index < 0 || index >= length) {
+ throw new RangeError.index(index, this, "index");
+ }
+ _setIndexedFloat32(index, value);
+ }
+
+ // Method(s) implementing the TypedData interface.
+ int get elementSizeInBytes {
+ return Float32List.bytesPerElement;
+ }
+
+ // Internal utility methods.
+ Float32List _createList(int length) {
+ return new Float32List(length);
+ }
+
+ double _getIndexedFloat32(int index) {
+ return _getFloat32(index * Float32List.bytesPerElement);
+ }
+
+ void _setIndexedFloat32(int index, double value) {
+ _setFloat32(index * Float32List.bytesPerElement, value);
+ }
+}
+
+@pragma("vm:entry-point")
+class _ExternalFloat64Array extends _TypedList
+ with _DoubleListMixin, _TypedDoubleListMixin<Float64List>
+ implements Float64List {
+ factory _ExternalFloat64Array._uninstantiable() {
+ throw "Unreachable";
+ }
+
+ // Method(s) implementing the List interface.
+ double operator [](int index) {
+ if (index < 0 || index >= length) {
+ throw new RangeError.index(index, this, "index");
+ }
+ return _getIndexedFloat64(index);
+ }
+
+ void operator []=(int index, double value) {
+ if (index < 0 || index >= length) {
+ throw new RangeError.index(index, this, "index");
+ }
+ _setIndexedFloat64(index, value);
+ }
+
+ // Method(s) implementing the TypedData interface.
+ int get elementSizeInBytes {
+ return Float64List.bytesPerElement;
+ }
+
+ // Internal utility methods.
+ Float64List _createList(int length) {
+ return new Float64List(length);
+ }
+
+ double _getIndexedFloat64(int index) {
+ return _getFloat64(index * Float64List.bytesPerElement);
+ }
+
+ void _setIndexedFloat64(int index, double value) {
+ _setFloat64(index * Float64List.bytesPerElement, value);
+ }
+}
+
+@pragma("vm:entry-point")
+class _ExternalFloat32x4Array extends _TypedList
+ with _Float32x4ListMixin
+ implements Float32x4List {
+ factory _ExternalFloat32x4Array._uninstantiable() {
+ throw "Unreachable";
+ }
+
+ // Method(s) implementing the List interface.
+ Float32x4 operator [](int index) {
+ if (index < 0 || index >= length) {
+ throw new RangeError.index(index, this, "index");
+ }
+ return _getIndexedFloat32x4(index);
+ }
+
+ void operator []=(int index, Float32x4 value) {
+ if (index < 0 || index >= length) {
+ throw new RangeError.index(index, this, "index");
+ }
+ _setIndexedFloat32x4(index, value);
+ }
+
+ // Method(s) implementing the TypedData interface.
+ int get elementSizeInBytes {
+ return Float32x4List.bytesPerElement;
+ }
+
+ // Internal utility methods.
+ Float32x4List _createList(int length) {
+ return new Float32x4List(length);
+ }
+
+ Float32x4 _getIndexedFloat32x4(int index) {
+ return _getFloat32x4(index * Float32x4List.bytesPerElement);
+ }
+
+ void _setIndexedFloat32x4(int index, Float32x4 value) {
+ _setFloat32x4(index * Float32x4List.bytesPerElement, value);
+ }
+}
+
+@pragma("vm:entry-point")
+class _ExternalInt32x4Array extends _TypedList
+ with _Int32x4ListMixin
+ implements Int32x4List {
+ factory _ExternalInt32x4Array._uninstantiable() {
+ throw "Unreachable";
+ }
+
+ // Method(s) implementing the List interface.
+ Int32x4 operator [](int index) {
+ if (index < 0 || index >= length) {
+ throw new RangeError.index(index, this, "index");
+ }
+ return _getIndexedInt32x4(index);
+ }
+
+ void operator []=(int index, Int32x4 value) {
+ if (index < 0 || index >= length) {
+ throw new RangeError.index(index, this, "index");
+ }
+ _setIndexedInt32x4(index, value);
+ }
+
+ // Method(s) implementing the TypedData interface.
+ int get elementSizeInBytes {
+ return Int32x4List.bytesPerElement;
+ }
+
+ // Internal utility methods.
+ Int32x4List _createList(int length) {
+ return new Int32x4List(length);
+ }
+
+ Int32x4 _getIndexedInt32x4(int index) {
+ return _getInt32x4(index * Int32x4List.bytesPerElement);
+ }
+
+ void _setIndexedInt32x4(int index, Int32x4 value) {
+ _setInt32x4(index * Int32x4List.bytesPerElement, value);
+ }
+}
+
+@pragma("vm:entry-point")
+class _ExternalFloat64x2Array extends _TypedList
+ with _Float64x2ListMixin
+ implements Float64x2List {
+ factory _ExternalFloat64x2Array._uninstantiable() {
+ throw "Unreachable";
+ }
+
+ // Method(s) implementing the List interface.
+ Float64x2 operator [](int index) {
+ if (index < 0 || index >= length) {
+ throw new RangeError.index(index, this, "index");
+ }
+ return _getIndexedFloat64x2(index);
+ }
+
+ void operator []=(int index, Float64x2 value) {
+ if (index < 0 || index >= length) {
+ throw new RangeError.index(index, this, "index");
+ }
+ _setIndexedFloat64x2(index, value);
+ }
+
+ // Method(s) implementing the TypedData interface.
+ int get elementSizeInBytes {
+ return Float64x2List.bytesPerElement;
+ }
+
+ // Internal utility methods.
+ Float64x2List _createList(int length) {
+ return new Float64x2List(length);
+ }
+
+ Float64x2 _getIndexedFloat64x2(int index) {
+ return _getFloat64x2(index * Float64x2List.bytesPerElement);
+ }
+
+ void _setIndexedFloat64x2(int index, Float64x2 value) {
+ _setFloat64x2(index * Float64x2List.bytesPerElement, value);
+ }
+}
+
+@patch
+class Float32x4 {
+ @patch
+ @pragma("vm:exact-result-type", _Float32x4)
+ factory Float32x4(double x, double y, double z, double w)
+ native "Float32x4_fromDoubles";
+
+ @patch
+ @pragma("vm:exact-result-type", _Float32x4)
+ factory Float32x4.splat(double v) native "Float32x4_splat";
+
+ @patch
+ @pragma("vm:exact-result-type", _Float32x4)
+ factory Float32x4.zero() native "Float32x4_zero";
+
+ @patch
+ @pragma("vm:exact-result-type", _Float32x4)
+ factory Float32x4.fromInt32x4Bits(Int32x4 x)
+ native "Float32x4_fromInt32x4Bits";
+
+ @patch
+ @pragma("vm:exact-result-type", _Float32x4)
+ factory Float32x4.fromFloat64x2(Float64x2 v) native "Float32x4_fromFloat64x2";
+}
+
+@pragma("vm:entry-point")
+class _Float32x4 implements Float32x4 {
+ @pragma("vm:exact-result-type", _Float32x4)
+ Float32x4 operator +(Float32x4 other) native "Float32x4_add";
+ @pragma("vm:exact-result-type", _Float32x4)
+ Float32x4 operator -() native "Float32x4_negate";
+ @pragma("vm:exact-result-type", _Float32x4)
+ Float32x4 operator -(Float32x4 other) native "Float32x4_sub";
+ @pragma("vm:exact-result-type", _Float32x4)
+ Float32x4 operator *(Float32x4 other) native "Float32x4_mul";
+ Float32x4 operator /(Float32x4 other) native "Float32x4_div";
+ @pragma("vm:exact-result-type", _Int32x4)
+ Int32x4 lessThan(Float32x4 other) native "Float32x4_cmplt";
+ @pragma("vm:exact-result-type", _Int32x4)
+ Int32x4 lessThanOrEqual(Float32x4 other) native "Float32x4_cmplte";
+ @pragma("vm:exact-result-type", _Int32x4)
+ Int32x4 greaterThan(Float32x4 other) native "Float32x4_cmpgt";
+ @pragma("vm:exact-result-type", _Int32x4)
+ Int32x4 greaterThanOrEqual(Float32x4 other) native "Float32x4_cmpgte";
+ @pragma("vm:exact-result-type", _Int32x4)
+ Int32x4 equal(Float32x4 other) native "Float32x4_cmpequal";
+ @pragma("vm:exact-result-type", _Int32x4)
+ Int32x4 notEqual(Float32x4 other) native "Float32x4_cmpnequal";
+ @pragma("vm:exact-result-type", _Float32x4)
+ Float32x4 scale(double s) native "Float32x4_scale";
+ @pragma("vm:exact-result-type", _Float32x4)
+ Float32x4 abs() native "Float32x4_abs";
+ @pragma("vm:exact-result-type", _Float32x4)
+ Float32x4 clamp(Float32x4 lowerLimit, Float32x4 upperLimit)
+ native "Float32x4_clamp";
+ @pragma("vm:exact-result-type", "dart:core#_Double")
+ double get x native "Float32x4_getX";
+ @pragma("vm:exact-result-type", "dart:core#_Double")
+ double get y native "Float32x4_getY";
+ @pragma("vm:exact-result-type", "dart:core#_Double")
+ double get z native "Float32x4_getZ";
+ @pragma("vm:exact-result-type", "dart:core#_Double")
+ double get w native "Float32x4_getW";
+ int get signMask native "Float32x4_getSignMask";
+
+ @pragma("vm:exact-result-type", _Float32x4)
+ Float32x4 shuffle(int mask) native "Float32x4_shuffle";
+ @pragma("vm:exact-result-type", _Float32x4)
+ Float32x4 shuffleMix(Float32x4 zw, int mask) native "Float32x4_shuffleMix";
+
+ @pragma("vm:exact-result-type", _Float32x4)
+ Float32x4 withX(double x) native "Float32x4_setX";
+ @pragma("vm:exact-result-type", _Float32x4)
+ Float32x4 withY(double y) native "Float32x4_setY";
+ @pragma("vm:exact-result-type", _Float32x4)
+ Float32x4 withZ(double z) native "Float32x4_setZ";
+ @pragma("vm:exact-result-type", _Float32x4)
+ Float32x4 withW(double w) native "Float32x4_setW";
+ @pragma("vm:exact-result-type", _Float32x4)
+ Float32x4 min(Float32x4 other) native "Float32x4_min";
+ @pragma("vm:exact-result-type", _Float32x4)
+ Float32x4 max(Float32x4 other) native "Float32x4_max";
+ @pragma("vm:exact-result-type", _Float32x4)
+ Float32x4 sqrt() native "Float32x4_sqrt";
+ @pragma("vm:exact-result-type", _Float32x4)
+ Float32x4 reciprocal() native "Float32x4_reciprocal";
+ @pragma("vm:exact-result-type", _Float32x4)
+ Float32x4 reciprocalSqrt() native "Float32x4_reciprocalSqrt";
+}
+
+@patch
+class Int32x4 {
+ @patch
+ @pragma("vm:exact-result-type", _Int32x4)
+ factory Int32x4(int x, int y, int z, int w) native "Int32x4_fromInts";
+
+ @patch
+ @pragma("vm:exact-result-type", _Int32x4)
+ factory Int32x4.bool(bool x, bool y, bool z, bool w)
+ native "Int32x4_fromBools";
+
+ @patch
+ @pragma("vm:exact-result-type", _Int32x4)
+ factory Int32x4.fromFloat32x4Bits(Float32x4 x)
+ native "Int32x4_fromFloat32x4Bits";
+}
+
+@pragma("vm:entry-point")
+class _Int32x4 implements Int32x4 {
+ Int32x4 operator |(Int32x4 other) native "Int32x4_or";
+ Int32x4 operator &(Int32x4 other) native "Int32x4_and";
+ Int32x4 operator ^(Int32x4 other) native "Int32x4_xor";
+ Int32x4 operator +(Int32x4 other) native "Int32x4_add";
+ Int32x4 operator -(Int32x4 other) native "Int32x4_sub";
+ int get x native "Int32x4_getX";
+ int get y native "Int32x4_getY";
+ int get z native "Int32x4_getZ";
+ int get w native "Int32x4_getW";
+ int get signMask native "Int32x4_getSignMask";
+ @pragma("vm:exact-result-type", _Int32x4)
+ Int32x4 shuffle(int mask) native "Int32x4_shuffle";
+ @pragma("vm:exact-result-type", _Int32x4)
+ Int32x4 shuffleMix(Int32x4 zw, int mask) native "Int32x4_shuffleMix";
+ Int32x4 withX(int x) native "Int32x4_setX";
+ Int32x4 withY(int y) native "Int32x4_setY";
+ Int32x4 withZ(int z) native "Int32x4_setZ";
+ Int32x4 withW(int w) native "Int32x4_setW";
+ @pragma("vm:exact-result-type", bool)
+ bool get flagX native "Int32x4_getFlagX";
+ @pragma("vm:exact-result-type", bool)
+ bool get flagY native "Int32x4_getFlagY";
+ @pragma("vm:exact-result-type", bool)
+ bool get flagZ native "Int32x4_getFlagZ";
+ @pragma("vm:exact-result-type", bool)
+ bool get flagW native "Int32x4_getFlagW";
+ @pragma("vm:exact-result-type", _Int32x4)
+ Int32x4 withFlagX(bool x) native "Int32x4_setFlagX";
+ @pragma("vm:exact-result-type", _Int32x4)
+ Int32x4 withFlagY(bool y) native "Int32x4_setFlagY";
+ @pragma("vm:exact-result-type", _Int32x4)
+ Int32x4 withFlagZ(bool z) native "Int32x4_setFlagZ";
+ @pragma("vm:exact-result-type", _Int32x4)
+ Int32x4 withFlagW(bool w) native "Int32x4_setFlagW";
+ @pragma("vm:exact-result-type", _Float32x4)
+ Float32x4 select(Float32x4 trueValue, Float32x4 falseValue)
+ native "Int32x4_select";
+}
+
+@patch
+class Float64x2 {
+ @patch
+ @pragma("vm:exact-result-type", _Float64x2)
+ factory Float64x2(double x, double y) native "Float64x2_fromDoubles";
+
+ @patch
+ @pragma("vm:exact-result-type", _Float64x2)
+ factory Float64x2.splat(double v) native "Float64x2_splat";
+
+ @patch
+ @pragma("vm:exact-result-type", _Float64x2)
+ factory Float64x2.zero() native "Float64x2_zero";
+
+ @patch
+ @pragma("vm:exact-result-type", _Float64x2)
+ factory Float64x2.fromFloat32x4(Float32x4 v) native "Float64x2_fromFloat32x4";
+}
+
+@pragma("vm:entry-point")
+class _Float64x2 implements Float64x2 {
+ Float64x2 operator +(Float64x2 other) native "Float64x2_add";
+ @pragma("vm:exact-result-type", _Float64x2)
+ Float64x2 operator -() native "Float64x2_negate";
+ Float64x2 operator -(Float64x2 other) native "Float64x2_sub";
+ Float64x2 operator *(Float64x2 other) native "Float64x2_mul";
+ Float64x2 operator /(Float64x2 other) native "Float64x2_div";
+ @pragma("vm:exact-result-type", _Float64x2)
+ Float64x2 scale(double s) native "Float64x2_scale";
+ @pragma("vm:exact-result-type", _Float64x2)
+ Float64x2 abs() native "Float64x2_abs";
+ Float64x2 clamp(Float64x2 lowerLimit, Float64x2 upperLimit)
+ native "Float64x2_clamp";
+ @pragma("vm:exact-result-type", "dart:core#_Double")
+ double get x native "Float64x2_getX";
+ @pragma("vm:exact-result-type", "dart:core#_Double")
+ double get y native "Float64x2_getY";
+ int get signMask native "Float64x2_getSignMask";
+ @pragma("vm:exact-result-type", _Float64x2)
+ Float64x2 withX(double x) native "Float64x2_setX";
+ @pragma("vm:exact-result-type", _Float64x2)
+ Float64x2 withY(double y) native "Float64x2_setY";
+ @pragma("vm:exact-result-type", _Float64x2)
+ Float64x2 min(Float64x2 other) native "Float64x2_min";
+ @pragma("vm:exact-result-type", _Float64x2)
+ Float64x2 max(Float64x2 other) native "Float64x2_max";
+ @pragma("vm:exact-result-type", _Float64x2)
+ Float64x2 sqrt() native "Float64x2_sqrt";
+}
+
+class _TypedListIterator<E> implements Iterator<E> {
+ final List<E> _array;
+ final int _length;
+ int _position;
+ E _current;
+
+ _TypedListIterator(List array)
+ : _array = array,
+ _length = array.length,
+ _position = -1 {
+ assert(array is _TypedList || array is _TypedListView);
+ }
+
+ bool moveNext() {
+ int nextPosition = _position + 1;
+ if (nextPosition < _length) {
+ _current = _array[nextPosition];
+ _position = nextPosition;
+ return true;
+ }
+ _position = _length;
+ _current = null;
+ return false;
+ }
+
+ E get current => _current;
+}
+
+abstract class _TypedListView extends _TypedListBase implements TypedData {
+ // Method(s) implementing the TypedData interface.
+
+ int get lengthInBytes {
+ return length * elementSizeInBytes;
+ }
+
+ _ByteBuffer get buffer {
+ return _typedData.buffer;
+ }
+
+ @pragma("vm:non-nullable-result-type")
+ @pragma("vm:prefer-inline")
+ _TypedList get _typedData native "TypedDataView_typedData";
+
+ @pragma("vm:exact-result-type", "dart:core#_Smi")
+ @pragma("vm:prefer-inline")
+ int get offsetInBytes native "TypedDataView_offsetInBytes";
+
+ @pragma("vm:exact-result-type", "dart:core#_Smi")
+ @pragma("vm:prefer-inline")
+ int get length native "TypedDataView_length";
+}
+
+@pragma("vm:entry-point")
+class _Int8ArrayView extends _TypedListView
+ with _IntListMixin, _TypedIntListMixin<Int8List>
+ implements Int8List {
+ // Constructor.
+ @pragma("vm:exact-result-type", _Int8ArrayView)
+ factory _Int8ArrayView._(_TypedList buffer, int offsetInBytes, int length)
+ native "TypedDataView_Int8ArrayView_new";
+
+ // Method(s) implementing List interface.
+ @pragma("vm:prefer-inline")
+ int operator [](int index) {
+ if (index < 0 || index >= length) {
+ throw new RangeError.index(index, this, "index");
+ }
+ return _typedData
+ ._getInt8(offsetInBytes + (index * Int8List.bytesPerElement));
+ }
+
+ @pragma("vm:prefer-inline")
+ void operator []=(int index, int value) {
+ if (index < 0 || index >= length) {
+ throw new RangeError.index(index, this, "index");
+ }
+ _typedData._setInt8(
+ offsetInBytes + (index * Int8List.bytesPerElement), _toInt8(value));
+ }
+
+ // Method(s) implementing TypedData interface.
+ int get elementSizeInBytes {
+ return Int8List.bytesPerElement;
+ }
+
+ // Internal utility methods.
+ Int8List _createList(int length) {
+ return new Int8List(length);
+ }
+}
+
+@pragma("vm:entry-point")
+class _Uint8ArrayView extends _TypedListView
+ with _IntListMixin, _TypedIntListMixin<Uint8List>
+ implements Uint8List {
+ // Constructor.
+ @pragma("vm:exact-result-type", _Uint8ArrayView)
+ factory _Uint8ArrayView._(_TypedList buffer, int offsetInBytes, int length)
+ native "TypedDataView_Uint8ArrayView_new";
+
+ // Method(s) implementing List interface.
+ @pragma("vm:prefer-inline")
+ int operator [](int index) {
+ if (index < 0 || index >= length) {
+ throw new RangeError.index(index, this, "index");
+ }
+ return _typedData
+ ._getUint8(offsetInBytes + (index * Uint8List.bytesPerElement));
+ }
+
+ @pragma("vm:prefer-inline")
+ void operator []=(int index, int value) {
+ if (index < 0 || index >= length) {
+ throw new RangeError.index(index, this, "index");
+ }
+ _typedData._setUint8(
+ offsetInBytes + (index * Uint8List.bytesPerElement), _toUint8(value));
+ }
+
+ // Method(s) implementing TypedData interface.
+ int get elementSizeInBytes {
+ return Uint8List.bytesPerElement;
+ }
+
+ // Internal utility methods.
+ Uint8List _createList(int length) {
+ return new Uint8List(length);
+ }
+}
+
+@pragma("vm:entry-point")
+class _Uint8ClampedArrayView extends _TypedListView
+ with _IntListMixin, _TypedIntListMixin<Uint8ClampedList>
+ implements Uint8ClampedList {
+ // Constructor.
+ @pragma("vm:exact-result-type", _Uint8ClampedArrayView)
+ factory _Uint8ClampedArrayView._(_TypedList buffer, int offsetInBytes,
+ int length) native "TypedDataView_Uint8ClampedArrayView_new";
+
+ // Method(s) implementing List interface.
+ @pragma("vm:prefer-inline")
+ int operator [](int index) {
+ if (index < 0 || index >= length) {
+ throw new RangeError.index(index, this, "index");
+ }
+ return _typedData
+ ._getUint8(offsetInBytes + (index * Uint8List.bytesPerElement));
+ }
+
+ @pragma("vm:prefer-inline")
+ void operator []=(int index, int value) {
+ if (index < 0 || index >= length) {
+ throw new RangeError.index(index, this, "index");
+ }
+ _typedData._setUint8(offsetInBytes + (index * Uint8List.bytesPerElement),
+ _toClampedUint8(value));
+ }
+
+ // Method(s) implementing TypedData interface.
+ int get elementSizeInBytes {
+ return Uint8List.bytesPerElement;
+ }
+
+ // Internal utility methods.
+ Uint8ClampedList _createList(int length) {
+ return new Uint8ClampedList(length);
+ }
+}
+
+@pragma("vm:entry-point")
+class _Int16ArrayView extends _TypedListView
+ with _IntListMixin, _TypedIntListMixin<Int16List>
+ implements Int16List {
+ // Constructor.
+ @pragma("vm:exact-result-type", _Int16ArrayView)
+ factory _Int16ArrayView._(_TypedList buffer, int offsetInBytes, int length)
+ native "TypedDataView_Int16ArrayView_new";
+
+ // Method(s) implementing List interface.
+ @pragma("vm:prefer-inline")
+ int operator [](int index) {
+ if (index < 0 || index >= length) {
+ throw new RangeError.index(index, this, "index");
+ }
+ return _typedData
+ ._getInt16(offsetInBytes + (index * Int16List.bytesPerElement));
+ }
+
+ @pragma("vm:prefer-inline")
+ void operator []=(int index, int value) {
+ if (index < 0 || index >= length) {
+ throw new RangeError.index(index, this, "index");
+ }
+ _typedData._setInt16(
+ offsetInBytes + (index * Int16List.bytesPerElement), _toInt16(value));
+ }
+
+ void setRange(int start, int end, Iterable iterable, [int skipCount = 0]) {
+ if (iterable is CodeUnits) {
+ end = RangeError.checkValidRange(start, end, this.length);
+ int length = end - start;
+ int byteStart = this.offsetInBytes + start * Int16List.bytesPerElement;
+ _typedData._setCodeUnits(iterable, byteStart, length, skipCount);
+ } else {
+ super.setRange(start, end, iterable, skipCount);
+ }
+ }
+
+ // Method(s) implementing TypedData interface.
+
+ int get elementSizeInBytes {
+ return Int16List.bytesPerElement;
+ }
+
+ // Internal utility methods.
+ Int16List _createList(int length) {
+ return new Int16List(length);
+ }
+}
+
+@pragma("vm:entry-point")
+class _Uint16ArrayView extends _TypedListView
+ with _IntListMixin, _TypedIntListMixin<Uint16List>
+ implements Uint16List {
+ // Constructor.
+ @pragma("vm:exact-result-type", _Uint16ArrayView)
+ factory _Uint16ArrayView._(_TypedList buffer, int offsetInBytes, int length)
+ native "TypedDataView_Uint16ArrayView_new";
+
+ // Method(s) implementing List interface.
+ @pragma("vm:prefer-inline")
+ int operator [](int index) {
+ if (index < 0 || index >= length) {
+ throw new RangeError.index(index, this, "index");
+ }
+ return _typedData
+ ._getUint16(offsetInBytes + (index * Uint16List.bytesPerElement));
+ }
+
+ @pragma("vm:prefer-inline")
+ void operator []=(int index, int value) {
+ if (index < 0 || index >= length) {
+ throw new RangeError.index(index, this, "index");
+ }
+ _typedData._setUint16(
+ offsetInBytes + (index * Uint16List.bytesPerElement), _toUint16(value));
+ }
+
+ void setRange(int start, int end, Iterable iterable, [int skipCount = 0]) {
+ if (iterable is CodeUnits) {
+ end = RangeError.checkValidRange(start, end, this.length);
+ int length = end - start;
+ int byteStart = this.offsetInBytes + start * Uint16List.bytesPerElement;
+ _typedData._setCodeUnits(iterable, byteStart, length, skipCount);
+ } else {
+ super.setRange(start, end, iterable, skipCount);
+ }
+ }
+
+ // Method(s) implementing TypedData interface.
+
+ int get elementSizeInBytes {
+ return Uint16List.bytesPerElement;
+ }
+
+ // Internal utility methods.
+
+ Uint16List _createList(int length) {
+ return new Uint16List(length);
+ }
+}
+
+@pragma("vm:entry-point")
+class _Int32ArrayView extends _TypedListView
+ with _IntListMixin, _TypedIntListMixin<Int32List>
+ implements Int32List {
+ // Constructor.
+ @pragma("vm:exact-result-type", _Int32ArrayView)
+ factory _Int32ArrayView._(_TypedList buffer, int offsetInBytes, int length)
+ native "TypedDataView_Int32ArrayView_new";
+
+ // Method(s) implementing List interface.
+ @pragma("vm:prefer-inline")
+ int operator [](int index) {
+ if (index < 0 || index >= length) {
+ throw new RangeError.index(index, this, "index");
+ }
+ return _typedData
+ ._getInt32(offsetInBytes + (index * Int32List.bytesPerElement));
+ }
+
+ @pragma("vm:prefer-inline")
+ void operator []=(int index, int value) {
+ if (index < 0 || index >= length) {
+ throw new RangeError.index(index, this, "index");
+ }
+ _typedData._setInt32(
+ offsetInBytes + (index * Int32List.bytesPerElement), _toInt32(value));
+ }
+
+ // Method(s) implementing TypedData interface.
+ int get elementSizeInBytes {
+ return Int32List.bytesPerElement;
+ }
+
+ // Internal utility methods.
+ Int32List _createList(int length) {
+ return new Int32List(length);
+ }
+}
+
+@pragma("vm:entry-point")
+class _Uint32ArrayView extends _TypedListView
+ with _IntListMixin, _TypedIntListMixin<Uint32List>
+ implements Uint32List {
+ // Constructor.
+ @pragma("vm:exact-result-type", _Uint32ArrayView)
+ factory _Uint32ArrayView._(_TypedList buffer, int offsetInBytes, int length)
+ native "TypedDataView_Uint32ArrayView_new";
+
+ // Method(s) implementing List interface.
+ @pragma("vm:prefer-inline")
+ int operator [](int index) {
+ if (index < 0 || index >= length) {
+ throw new RangeError.index(index, this, "index");
+ }
+ return _typedData
+ ._getUint32(offsetInBytes + (index * Uint32List.bytesPerElement));
+ }
+
+ @pragma("vm:prefer-inline")
+ void operator []=(int index, int value) {
+ if (index < 0 || index >= length) {
+ throw new RangeError.index(index, this, "index");
+ }
+ _typedData._setUint32(
+ offsetInBytes + (index * Uint32List.bytesPerElement), _toUint32(value));
+ }
+
+ // Method(s) implementing TypedData interface.
+ int get elementSizeInBytes {
+ return Uint32List.bytesPerElement;
+ }
+
+ // Internal utility methods.
+ Uint32List _createList(int length) {
+ return new Uint32List(length);
+ }
+}
+
+@pragma("vm:entry-point")
+class _Int64ArrayView extends _TypedListView
+ with _IntListMixin, _TypedIntListMixin<Int64List>
+ implements Int64List {
+ // Constructor.
+ @pragma("vm:exact-result-type", _Int64ArrayView)
+ factory _Int64ArrayView._(_TypedList buffer, int offsetInBytes, int length)
+ native "TypedDataView_Int64ArrayView_new";
+
+ // Method(s) implementing List interface.
+ @pragma("vm:prefer-inline")
+ int operator [](int index) {
+ if (index < 0 || index >= length) {
+ throw new RangeError.index(index, this, "index");
+ }
+ return _typedData
+ ._getInt64(offsetInBytes + (index * Int64List.bytesPerElement));
+ }
+
+ @pragma("vm:prefer-inline")
+ void operator []=(int index, int value) {
+ if (index < 0 || index >= length) {
+ throw new RangeError.index(index, this, "index");
+ }
+ _typedData._setInt64(
+ offsetInBytes + (index * Int64List.bytesPerElement), value);
+ }
+
+ // Method(s) implementing TypedData interface.
+ int get elementSizeInBytes {
+ return Int64List.bytesPerElement;
+ }
+
+ // Internal utility methods.
+ Int64List _createList(int length) {
+ return new Int64List(length);
+ }
+}
+
+@pragma("vm:entry-point")
+class _Uint64ArrayView extends _TypedListView
+ with _IntListMixin, _TypedIntListMixin<Uint64List>
+ implements Uint64List {
+ // Constructor.
+ @pragma("vm:exact-result-type", _Uint64ArrayView)
+ factory _Uint64ArrayView._(_TypedList buffer, int offsetInBytes, int length)
+ native "TypedDataView_Uint64ArrayView_new";
+
+ // Method(s) implementing List interface.
+ @pragma("vm:prefer-inline")
+ int operator [](int index) {
+ if (index < 0 || index >= length) {
+ throw new RangeError.index(index, this, "index");
+ }
+ return _typedData
+ ._getUint64(offsetInBytes + (index * Uint64List.bytesPerElement));
+ }
+
+ @pragma("vm:prefer-inline")
+ void operator []=(int index, int value) {
+ if (index < 0 || index >= length) {
+ throw new RangeError.index(index, this, "index");
+ }
+ _typedData._setUint64(
+ offsetInBytes + (index * Uint64List.bytesPerElement), value);
+ }
+
+ // Method(s) implementing TypedData interface.
+ int get elementSizeInBytes {
+ return Uint64List.bytesPerElement;
+ }
+
+ // Internal utility methods.
+ Uint64List _createList(int length) {
+ return new Uint64List(length);
+ }
+}
+
+@pragma("vm:entry-point")
+class _Float32ArrayView extends _TypedListView
+ with _DoubleListMixin, _TypedDoubleListMixin<Float32List>
+ implements Float32List {
+ // Constructor.
+ @pragma("vm:exact-result-type", _Float32ArrayView)
+ factory _Float32ArrayView._(_TypedList buffer, int offsetInBytes, int length)
+ native "TypedDataView_Float32ArrayView_new";
+
+ // Method(s) implementing List interface.
+ @pragma("vm:prefer-inline")
+ double operator [](int index) {
+ if (index < 0 || index >= length) {
+ throw new RangeError.index(index, this, "index");
+ }
+ return _typedData
+ ._getFloat32(offsetInBytes + (index * Float32List.bytesPerElement));
+ }
+
+ @pragma("vm:prefer-inline")
+ void operator []=(int index, double value) {
+ if (index < 0 || index >= length) {
+ throw new RangeError.index(index, this, "index");
+ }
+ _typedData._setFloat32(
+ offsetInBytes + (index * Float32List.bytesPerElement), value);
+ }
+
+ // Method(s) implementing TypedData interface.
+ int get elementSizeInBytes {
+ return Float32List.bytesPerElement;
+ }
+
+ // Internal utility methods.
+ Float32List _createList(int length) {
+ return new Float32List(length);
+ }
+}
+
+@pragma("vm:entry-point")
+class _Float64ArrayView extends _TypedListView
+ with _DoubleListMixin, _TypedDoubleListMixin<Float64List>
+ implements Float64List {
+ // Constructor.
+ @pragma("vm:exact-result-type", _Float64ArrayView)
+ factory _Float64ArrayView._(_TypedList buffer, int offsetInBytes, int length)
+ native "TypedDataView_Float64ArrayView_new";
+
+ // Method(s) implementing List interface.
+ @pragma("vm:prefer-inline")
+ double operator [](int index) {
+ if (index < 0 || index >= length) {
+ throw new RangeError.index(index, this, "index");
+ }
+ return _typedData
+ ._getFloat64(offsetInBytes + (index * Float64List.bytesPerElement));
+ }
+
+ @pragma("vm:prefer-inline")
+ void operator []=(int index, double value) {
+ if (index < 0 || index >= length) {
+ throw new RangeError.index(index, this, "index");
+ }
+ _typedData._setFloat64(
+ offsetInBytes + (index * Float64List.bytesPerElement), value);
+ }
+
+ // Method(s) implementing TypedData interface.
+ int get elementSizeInBytes {
+ return Float64List.bytesPerElement;
+ }
+
+ // Internal utility methods.
+ Float64List _createList(int length) {
+ return new Float64List(length);
+ }
+}
+
+@pragma("vm:entry-point")
+class _Float32x4ArrayView extends _TypedListView
+ with _Float32x4ListMixin
+ implements Float32x4List {
+ // Constructor.
+ @pragma("vm:exact-result-type", _Float32x4ArrayView)
+ factory _Float32x4ArrayView._(_TypedList buffer, int offsetInBytes,
+ int length) native "TypedDataView_Float32x4ArrayView_new";
+
+ // Method(s) implementing List interface.
+ Float32x4 operator [](int index) {
+ if (index < 0 || index >= length) {
+ throw new RangeError.index(index, this, "index");
+ }
+ return _typedData
+ ._getFloat32x4(offsetInBytes + (index * Float32x4List.bytesPerElement));
+ }
+
+ void operator []=(int index, Float32x4 value) {
+ if (index < 0 || index >= length) {
+ throw new RangeError.index(index, this, "index");
+ }
+ _typedData._setFloat32x4(
+ offsetInBytes + (index * Float32x4List.bytesPerElement), value);
+ }
+
+ // Method(s) implementing TypedData interface.
+ int get elementSizeInBytes {
+ return Float32x4List.bytesPerElement;
+ }
+
+ // Internal utility methods.
+ Float32x4List _createList(int length) {
+ return new Float32x4List(length);
+ }
+}
+
+@pragma("vm:entry-point")
+class _Int32x4ArrayView extends _TypedListView
+ with _Int32x4ListMixin
+ implements Int32x4List {
+ // Constructor.
+ @pragma("vm:exact-result-type", _Int32x4ArrayView)
+ factory _Int32x4ArrayView._(_TypedList buffer, int offsetInBytes, int length)
+ native "TypedDataView_Int32x4ArrayView_new";
+
+ // Method(s) implementing List interface.
+ Int32x4 operator [](int index) {
+ if (index < 0 || index >= length) {
+ throw new RangeError.index(index, this, "index");
+ }
+ return _typedData
+ ._getInt32x4(offsetInBytes + (index * Int32x4List.bytesPerElement));
+ }
+
+ void operator []=(int index, Int32x4 value) {
+ if (index < 0 || index >= length) {
+ throw new RangeError.index(index, this, "index");
+ }
+ _typedData._setInt32x4(
+ offsetInBytes + (index * Int32x4List.bytesPerElement), value);
+ }
+
+ // Method(s) implementing TypedData interface.
+ int get elementSizeInBytes {
+ return Int32x4List.bytesPerElement;
+ }
+
+ // Internal utility methods.
+ Int32x4List _createList(int length) {
+ return new Int32x4List(length);
+ }
+}
+
+@pragma("vm:entry-point")
+class _Float64x2ArrayView extends _TypedListView
+ with _Float64x2ListMixin
+ implements Float64x2List {
+ // Constructor.
+ @pragma("vm:exact-result-type", _Float64x2ArrayView)
+ factory _Float64x2ArrayView._(_TypedList buffer, int offsetInBytes,
+ int length) native "TypedDataView_Float64x2ArrayView_new";
+
+ // Method(s) implementing List interface.
+ Float64x2 operator [](int index) {
+ if (index < 0 || index >= length) {
+ throw new RangeError.index(index, this, "index");
+ }
+ return _typedData
+ ._getFloat64x2(offsetInBytes + (index * Float64x2List.bytesPerElement));
+ }
+
+ void operator []=(int index, Float64x2 value) {
+ if (index < 0 || index >= length) {
+ throw new RangeError.index(index, this, "index");
+ }
+ _typedData._setFloat64x2(
+ offsetInBytes + (index * Float64x2List.bytesPerElement), value);
+ }
+
+ // Method(s) implementing TypedData interface.
+ int get elementSizeInBytes {
+ return Float64x2List.bytesPerElement;
+ }
+
+ // Internal utility methods.
+ Float64x2List _createList(int length) {
+ return new Float64x2List(length);
+ }
+}
+
+@pragma("vm:entry-point")
+class _ByteDataView implements ByteData {
+ @pragma("vm:exact-result-type", _ByteDataView)
+ factory _ByteDataView._(_TypedList buffer, int offsetInBytes, int length)
+ native "TypedDataView_ByteDataView_new";
+
+ // Method(s) implementing TypedData interface.
+ _ByteBuffer get buffer {
+ return _typedData.buffer;
+ }
+
+ int get lengthInBytes {
+ return length;
+ }
+
+ int get elementSizeInBytes {
+ return 1;
+ }
+
+ // Method(s) implementing ByteData interface.
+
+ @pragma("vm:prefer-inline")
+ int getInt8(int byteOffset) {
+ if (byteOffset < 0 || byteOffset >= length) {
+ throw new RangeError.index(byteOffset, this, "byteOffset");
+ }
+ return _typedData._getInt8(offsetInBytes + byteOffset);
+ }
+
+ @pragma("vm:prefer-inline")
+ void setInt8(int byteOffset, int value) {
+ if (byteOffset < 0 || byteOffset >= length) {
+ throw new RangeError.index(byteOffset, this, "byteOffset");
+ }
+ _typedData._setInt8(offsetInBytes + byteOffset, value);
+ }
+
+ @pragma("vm:prefer-inline")
+ int getUint8(int byteOffset) {
+ if (byteOffset < 0 || byteOffset >= length) {
+ throw new RangeError.index(byteOffset, this, "byteOffset");
+ }
+ return _typedData._getUint8(offsetInBytes + byteOffset);
+ }
+
+ @pragma("vm:prefer-inline")
+ void setUint8(int byteOffset, int value) {
+ if (byteOffset < 0 || byteOffset >= length) {
+ throw new RangeError.index(byteOffset, this, "byteOffset");
+ }
+ _typedData._setUint8(offsetInBytes + byteOffset, value);
+ }
+
+ @pragma("vm:prefer-inline")
+ int getInt16(int byteOffset, [Endian endian = Endian.big]) {
+ if (byteOffset < 0 || byteOffset + 1 >= length) {
+ throw new RangeError.range(byteOffset, 0, length - 2, "byteOffset");
+ }
+ var result = _typedData._getInt16(offsetInBytes + byteOffset);
+ if (identical(endian, Endian.host)) {
+ return result;
+ }
+ return _byteSwap16(result).toSigned(16);
+ }
+
+ @pragma("vm:prefer-inline")
+ void setInt16(int byteOffset, int value, [Endian endian = Endian.big]) {
+ if (byteOffset < 0 || byteOffset + 1 >= length) {
+ throw new RangeError.range(byteOffset, 0, length - 2, "byteOffset");
+ }
+ _typedData._setInt16(offsetInBytes + byteOffset,
+ identical(endian, Endian.host) ? value : _byteSwap16(value));
+ }
+
+ @pragma("vm:prefer-inline")
+ int getUint16(int byteOffset, [Endian endian = Endian.big]) {
+ if (byteOffset < 0 || byteOffset + 1 >= length) {
+ throw new RangeError.range(byteOffset, 0, length - 2, "byteOffset");
+ }
+ var result = _typedData._getUint16(offsetInBytes + byteOffset);
+ if (identical(endian, Endian.host)) {
+ return result;
+ }
+ return _byteSwap16(result);
+ }
+
+ @pragma("vm:prefer-inline")
+ void setUint16(int byteOffset, int value, [Endian endian = Endian.big]) {
+ if (byteOffset < 0 || byteOffset + 1 >= length) {
+ throw new RangeError.range(byteOffset, 0, length - 2, "byteOffset");
+ }
+ _typedData._setUint16(offsetInBytes + byteOffset,
+ identical(endian, Endian.host) ? value : _byteSwap16(value));
+ }
+
+ @pragma("vm:prefer-inline")
+ int getInt32(int byteOffset, [Endian endian = Endian.big]) {
+ if (byteOffset < 0 || byteOffset + 3 >= length) {
+ throw new RangeError.range(byteOffset, 0, length - 4, "byteOffset");
+ }
+ var result = _typedData._getInt32(offsetInBytes + byteOffset);
+ if (identical(endian, Endian.host)) {
+ return result;
+ }
+ return _byteSwap32(result).toSigned(32);
+ }
+
+ @pragma("vm:prefer-inline")
+ void setInt32(int byteOffset, int value, [Endian endian = Endian.big]) {
+ if (byteOffset < 0 || byteOffset + 3 >= length) {
+ throw new RangeError.range(byteOffset, 0, length - 4, "byteOffset");
+ }
+ _typedData._setInt32(offsetInBytes + byteOffset,
+ identical(endian, Endian.host) ? value : _byteSwap32(value));
+ }
+
+ @pragma("vm:prefer-inline")
+ int getUint32(int byteOffset, [Endian endian = Endian.big]) {
+ if (byteOffset < 0 || byteOffset + 3 >= length) {
+ throw new RangeError.range(byteOffset, 0, length - 4, "byteOffset");
+ }
+ var result = _typedData._getUint32(offsetInBytes + byteOffset);
+ if (identical(endian, Endian.host)) {
+ return result;
+ }
+ return _byteSwap32(result);
+ }
+
+ @pragma("vm:prefer-inline")
+ void setUint32(int byteOffset, int value, [Endian endian = Endian.big]) {
+ if (byteOffset < 0 || byteOffset + 3 >= length) {
+ throw new RangeError.range(byteOffset, 0, length - 4, "byteOffset");
+ }
+ _typedData._setUint32(offsetInBytes + byteOffset,
+ identical(endian, Endian.host) ? value : _byteSwap32(value));
+ }
+
+ @pragma("vm:prefer-inline")
+ int getInt64(int byteOffset, [Endian endian = Endian.big]) {
+ if (byteOffset < 0 || byteOffset + 7 >= length) {
+ throw new RangeError.range(byteOffset, 0, length - 8, "byteOffset");
+ }
+ var result = _typedData._getInt64(offsetInBytes + byteOffset);
+ if (identical(endian, Endian.host)) {
+ return result;
+ }
+ return _byteSwap64(result).toSigned(64);
+ }
+
+ @pragma("vm:prefer-inline")
+ void setInt64(int byteOffset, int value, [Endian endian = Endian.big]) {
+ if (byteOffset < 0 || byteOffset + 7 >= length) {
+ throw new RangeError.range(byteOffset, 0, length - 8, "byteOffset");
+ }
+ _typedData._setInt64(offsetInBytes + byteOffset,
+ identical(endian, Endian.host) ? value : _byteSwap64(value));
+ }
+
+ @pragma("vm:prefer-inline")
+ int getUint64(int byteOffset, [Endian endian = Endian.big]) {
+ if (byteOffset < 0 || byteOffset + 7 >= length) {
+ throw new RangeError.range(byteOffset, 0, length - 8, "byteOffset");
+ }
+ var result = _typedData._getUint64(offsetInBytes + byteOffset);
+ if (identical(endian, Endian.host)) {
+ return result;
+ }
+ return _byteSwap64(result);
+ }
+
+ @pragma("vm:prefer-inline")
+ void setUint64(int byteOffset, int value, [Endian endian = Endian.big]) {
+ if (byteOffset < 0 || byteOffset + 7 >= length) {
+ throw new RangeError.range(byteOffset, 0, length - 8, "byteOffset");
+ }
+ _typedData._setUint64(offsetInBytes + byteOffset,
+ identical(endian, Endian.host) ? value : _byteSwap64(value));
+ }
+
+ @pragma("vm:prefer-inline")
+ double getFloat32(int byteOffset, [Endian endian = Endian.big]) {
+ if (byteOffset < 0 || byteOffset + 3 >= length) {
+ throw new RangeError.range(byteOffset, 0, length - 4, "byteOffset");
+ }
+ if (identical(endian, Endian.host)) {
+ return _typedData._getFloat32(offsetInBytes + byteOffset);
+ }
+ _convU32[0] =
+ _byteSwap32(_typedData._getUint32(offsetInBytes + byteOffset));
+ return _convF32[0];
+ }
+
+ @pragma("vm:prefer-inline")
+ void setFloat32(int byteOffset, double value, [Endian endian = Endian.big]) {
+ if (byteOffset < 0 || byteOffset + 3 >= length) {
+ throw new RangeError.range(byteOffset, 0, length - 4, "byteOffset");
+ }
+ if (identical(endian, Endian.host)) {
+ _typedData._setFloat32(offsetInBytes + byteOffset, value);
+ return;
+ }
+ _convF32[0] = value;
+ _typedData._setUint32(offsetInBytes + byteOffset, _byteSwap32(_convU32[0]));
+ }
+
+ @pragma("vm:prefer-inline")
+ double getFloat64(int byteOffset, [Endian endian = Endian.big]) {
+ if (byteOffset < 0 || byteOffset + 7 >= length) {
+ throw new RangeError.range(byteOffset, 0, length - 8, "byteOffset");
+ }
+ if (identical(endian, Endian.host)) {
+ return _typedData._getFloat64(offsetInBytes + byteOffset);
+ }
+ _convU64[0] =
+ _byteSwap64(_typedData._getUint64(offsetInBytes + byteOffset));
+ return _convF64[0];
+ }
+
+ @pragma("vm:prefer-inline")
+ void setFloat64(int byteOffset, double value, [Endian endian = Endian.big]) {
+ if (byteOffset < 0 || byteOffset + 7 >= length) {
+ throw new RangeError.range(byteOffset, 0, length - 8, "byteOffset");
+ }
+ if (identical(endian, Endian.host)) {
+ _typedData._setFloat64(offsetInBytes + byteOffset, value);
+ return;
+ }
+ _convF64[0] = value;
+ _typedData._setUint64(offsetInBytes + byteOffset, _byteSwap64(_convU64[0]));
+ }
+
+ Float32x4 getFloat32x4(int byteOffset, [Endian endian = Endian.big]) {
+ if (byteOffset < 0 || byteOffset + 3 >= length) {
+ throw new RangeError.range(byteOffset, 0, length - 4, "byteOffset");
+ }
+ // TODO(johnmccutchan) : Need to resolve this for endianity.
+ return _typedData._getFloat32x4(offsetInBytes + byteOffset);
+ }
+
+ void setFloat32x4(int byteOffset, Float32x4 value,
+ [Endian endian = Endian.big]) {
+ if (byteOffset < 0 || byteOffset + 3 >= length) {
+ throw new RangeError.range(byteOffset, 0, length - 4, "byteOffset");
+ }
+ // TODO(johnmccutchan) : Need to resolve this for endianity.
+ _typedData._setFloat32x4(offsetInBytes + byteOffset, value);
+ }
+
+ @pragma("vm:non-nullable-result-type")
+ @pragma("vm:prefer-inline")
+ _TypedList get _typedData native "TypedDataView_typedData";
+
+ @pragma("vm:exact-result-type", "dart:core#_Smi")
+ @pragma("vm:prefer-inline")
+ int get offsetInBytes native "TypedDataView_offsetInBytes";
+
+ @pragma("vm:exact-result-type", "dart:core#_Smi")
+ @pragma("vm:prefer-inline")
+ int get length native "TypedDataView_length";
+}
+
+@pragma("vm:prefer-inline")
+int _byteSwap16(int value) {
+ return ((value & 0xFF00) >> 8) | ((value & 0x00FF) << 8);
+}
+
+@pragma("vm:prefer-inline")
+int _byteSwap32(int value) {
+ value = ((value & 0xFF00FF00) >> 8) | ((value & 0x00FF00FF) << 8);
+ value = ((value & 0xFFFF0000) >> 16) | ((value & 0x0000FFFF) << 16);
+ return value;
+}
+
+@pragma("vm:prefer-inline")
+int _byteSwap64(int value) {
+ return (_byteSwap32(value) << 32) | _byteSwap32(value >> 32);
+}
+
+final _convU32 = new Uint32List(2);
+final _convU64 = new Uint64List.view(_convU32.buffer);
+final _convF32 = new Float32List.view(_convU32.buffer);
+final _convF64 = new Float64List.view(_convU32.buffer);
+
+// Top level utility methods.
+@pragma("vm:prefer-inline")
+int _toInt(int value, int mask) {
+ value &= mask;
+ if (value > (mask >> 1)) value -= mask + 1;
+ return value;
+}
+
+@pragma("vm:prefer-inline")
+int _toInt8(int value) {
+ return _toInt(value, 0xFF);
+}
+
+@pragma("vm:prefer-inline")
+int _toUint8(int value) {
+ return value & 0xFF;
+}
+
+@pragma("vm:exact-result-type", "dart:core#_Smi")
+int _toClampedUint8(int value) {
+ if (value < 0) return 0;
+ if (value > 0xFF) return 0xFF;
+ return value;
+}
+
+@pragma("vm:prefer-inline")
+int _toInt16(int value) {
+ return _toInt(value, 0xFFFF);
+}
+
+@pragma("vm:prefer-inline")
+int _toUint16(int value) {
+ return value & 0xFFFF;
+}
+
+@pragma("vm:prefer-inline")
+int _toInt32(int value) {
+ return _toInt(value, 0xFFFFFFFF);
+}
+
+@pragma("vm:prefer-inline")
+int _toUint32(int value) {
+ return value & 0xFFFFFFFF;
+}
+
+// In addition to explicitly checking the range, this method implicitly ensures
+// that all arguments are non-null (a no such method error gets thrown
+// otherwise).
+void _rangeCheck(int listLength, int start, int length) {
+ if (length < 0) {
+ throw new RangeError.value(length);
+ }
+ if (start < 0) {
+ throw new RangeError.value(start);
+ }
+ if (start + length > listLength) {
+ throw new RangeError.value(start + length);
+ }
+}
+
+void _offsetAlignmentCheck(int offset, int alignment) {
+ if ((offset % alignment) != 0) {
+ throw new RangeError('Offset ($offset) must be a multiple of '
+ 'BYTES_PER_ELEMENT ($alignment)');
+ }
+}
diff --git a/sdk_nnbd/lib/_internal/vm/lib/uri_patch.dart b/sdk_nnbd/lib/_internal/vm/lib/uri_patch.dart
new file mode 100644
index 0000000..57fe914
--- /dev/null
+++ b/sdk_nnbd/lib/_internal/vm/lib/uri_patch.dart
@@ -0,0 +1,82 @@
+// 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
+// BSD-style license that can be found in the LICENSE file.
+
+// @dart = 2.5
+
+// part of "core_patch.dart";
+
+typedef Uri _UriBaseClosure();
+
+Uri _unsupportedUriBase() {
+ throw new UnsupportedError("'Uri.base' is not supported");
+}
+
+// _uriBaseClosure can be overwritten by the embedder to supply a different
+// value for Uri.base.
+@pragma("vm:entry-point")
+_UriBaseClosure _uriBaseClosure = _unsupportedUriBase;
+
+@patch
+class Uri {
+ @patch
+ static Uri get base => _uriBaseClosure();
+}
+
+/// VM implementation of Uri.
+@patch
+class _Uri {
+ static final bool _isWindowsCached = _isWindowsPlatform;
+
+ static bool get _isWindowsPlatform native "Uri_isWindowsPlatform";
+
+ @patch
+ static bool get _isWindows => _isWindowsCached;
+
+ @patch
+ static String _uriEncode(List<int> canonicalTable, String text,
+ Encoding encoding, bool spaceToPlus) {
+ // First check if the text will be changed by encoding.
+ int i = 0;
+ if (identical(encoding, utf8) ||
+ identical(encoding, latin1) ||
+ identical(encoding, ascii)) {
+ // Encoding is compatible with the original string.
+ // Find first character that needs encoding.
+ for (; i < text.length; i++) {
+ var char = text.codeUnitAt(i);
+ if (char >= 128 ||
+ canonicalTable[char >> 4] & (1 << (char & 0x0f)) == 0) {
+ break;
+ }
+ }
+ }
+ if (i == text.length) return text;
+
+ // Encode the string into bytes then generate an ASCII only string
+ // by percent encoding selected bytes.
+ StringBuffer result = new StringBuffer();
+ for (int j = 0; j < i; j++) {
+ result.writeCharCode(text.codeUnitAt(j));
+ }
+
+ // TODO(lrn): Is there a way to only encode from index i and forwards.
+ var bytes = encoding.encode(text);
+ for (; i < bytes.length; i++) {
+ int byte = bytes[i];
+ if (byte < 128 &&
+ ((canonicalTable[byte >> 4] & (1 << (byte & 0x0f))) != 0)) {
+ result.writeCharCode(byte);
+ } else if (spaceToPlus && byte == _SPACE) {
+ result.writeCharCode(_PLUS);
+ } else {
+ const String hexDigits = '0123456789ABCDEF';
+ result
+ ..writeCharCode(_PERCENT)
+ ..writeCharCode(hexDigits.codeUnitAt(byte >> 4))
+ ..writeCharCode(hexDigits.codeUnitAt(byte & 0x0f));
+ }
+ }
+ return result.toString();
+ }
+}
diff --git a/sdk_nnbd/lib/_internal/vm/lib/wasm_patch.dart b/sdk_nnbd/lib/_internal/vm/lib/wasm_patch.dart
new file mode 100644
index 0000000..fc33afa
--- /dev/null
+++ b/sdk_nnbd/lib/_internal/vm/lib/wasm_patch.dart
@@ -0,0 +1,151 @@
+// Copyright (c) 2019, 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.5
+
+import 'dart:_internal' show patch;
+import "dart:nativewrappers" show NativeFieldWrapperClass1;
+import 'dart:typed_data';
+
+@patch
+@pragma("vm:entry-point")
+class Int32 {}
+
+@patch
+@pragma("vm:entry-point")
+class Int64 {}
+
+@patch
+@pragma("vm:entry-point")
+class Float {}
+
+@patch
+@pragma("vm:entry-point")
+class Double {}
+
+@patch
+@pragma("vm:entry-point")
+class Void {}
+
+@patch
+class WasmModule {
+ @patch
+ factory WasmModule(Uint8List data) {
+ return _NativeWasmModule(data);
+ }
+}
+
+@patch
+class WasmMemory {
+ @patch
+ factory WasmMemory(int initialPages, [int maxPages]) {
+ return _NativeWasmMemory(initialPages, maxPages);
+ }
+}
+
+@patch
+class WasmImports {
+ @patch
+ factory WasmImports(String moduleName) {
+ return _NativeWasmImports(moduleName);
+ }
+}
+
+class _NativeWasmModule extends NativeFieldWrapperClass1 implements WasmModule {
+ _NativeWasmModule(Uint8List data) {
+ _init(data);
+ }
+
+ WasmInstance instantiate(covariant _NativeWasmImports imports) {
+ return _NativeWasmInstance(this, imports);
+ }
+
+ void _init(Uint8List data) native 'Wasm_initModule';
+}
+
+class _NativeWasmImports extends NativeFieldWrapperClass1
+ implements WasmImports {
+ List<WasmMemory> _memories;
+
+ _NativeWasmImports(String moduleName) : _memories = [] {
+ _init(moduleName);
+ }
+
+ void addMemory(String name, WasmMemory memory) {
+ _memories.add(memory);
+ _addMemory(name, memory);
+ }
+
+ void addGlobal<T>(String name, num value, bool mutable) {
+ _addGlobal(name, value, T, mutable);
+ }
+
+ void _init(String moduleName) native 'Wasm_initImports';
+ void _addMemory(String name, WasmMemory memory) native 'Wasm_addMemoryImport';
+ void _addGlobal(String name, num value, Type type, bool mutable)
+ native 'Wasm_addGlobalImport';
+}
+
+class _NativeWasmMemory extends NativeFieldWrapperClass1 implements WasmMemory {
+ int _pages;
+ Uint8List _buffer;
+
+ _NativeWasmMemory(int initialPages, int maxPages) : _pages = initialPages {
+ _buffer = _init(initialPages, maxPages);
+ }
+
+ int get lengthInPages => _pages;
+ int get lengthInBytes => _buffer.lengthInBytes;
+ int operator [](int index) => _buffer[index];
+ void operator []=(int index, int value) {
+ _buffer[index] = value;
+ }
+
+ int grow(int deltaPages) {
+ int oldPages = _pages;
+ _buffer = _grow(deltaPages);
+ _pages += deltaPages;
+ return oldPages;
+ }
+
+ Uint8List _init(int initialPages, int maxPages) native 'Wasm_initMemory';
+ Uint8List _grow(int deltaPages) native 'Wasm_growMemory';
+}
+
+class _NativeWasmInstance extends NativeFieldWrapperClass1
+ implements WasmInstance {
+ _NativeWasmModule _module;
+ _NativeWasmImports _imports;
+
+ _NativeWasmInstance(_NativeWasmModule module, _NativeWasmImports imports)
+ : _module = module,
+ _imports = imports {
+ _init(module, imports);
+ }
+
+ WasmFunction<T> lookupFunction<T extends Function>(String name) {
+ return _NativeWasmFunction<T>(this, name);
+ }
+
+ void _init(_NativeWasmModule module, _NativeWasmImports imports)
+ native 'Wasm_initInstance';
+}
+
+class _NativeWasmFunction<T extends Function> extends NativeFieldWrapperClass1
+ implements WasmFunction<T> {
+ _NativeWasmInstance _inst;
+
+ _NativeWasmFunction(_NativeWasmInstance inst, String name) : _inst = inst {
+ _init(inst, name, T);
+ }
+
+ num call(List<num> args) {
+ var arg_copy = List<num>.from(args, growable: false);
+ return _call(arg_copy);
+ }
+
+ void _init(_NativeWasmInstance inst, String name, Type fnType)
+ native 'Wasm_initFunction';
+ num _call(List<num> args) native 'Wasm_callFunction';
+}
diff --git a/sdk_nnbd/lib/_internal/vm/lib/weak_property.dart b/sdk_nnbd/lib/_internal/vm/lib/weak_property.dart
new file mode 100644
index 0000000..9f689d1
--- /dev/null
+++ b/sdk_nnbd/lib/_internal/vm/lib/weak_property.dart
@@ -0,0 +1,22 @@
+// 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.5
+
+// part of "core_patch.dart";
+
+@pragma("vm:entry-point")
+class _WeakProperty {
+ factory _WeakProperty(key, value) => _new(key, value);
+
+ get key => _getKey();
+ get value => _getValue();
+ set value(value) => _setValue(value);
+
+ static _WeakProperty _new(key, value) native "WeakProperty_new";
+
+ _getKey() native "WeakProperty_getKey";
+ _getValue() native "WeakProperty_getValue";
+ _setValue(value) native "WeakProperty_setValue";
+}
diff --git a/sdk_nnbd/lib/async/async.dart b/sdk_nnbd/lib/async/async.dart
index b3a5dbd..b4bec24 100644
--- a/sdk_nnbd/lib/async/async.dart
+++ b/sdk_nnbd/lib/async/async.dart
@@ -2,6 +2,8 @@
// 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.5
+
/**
* Support for asynchronous programming,
* with classes such as Future and Stream.
diff --git a/sdk_nnbd/lib/async/async_error.dart b/sdk_nnbd/lib/async/async_error.dart
index 1520c54..5edac63 100644
--- a/sdk_nnbd/lib/async/async_error.dart
+++ b/sdk_nnbd/lib/async/async_error.dart
@@ -2,6 +2,8 @@
// 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.5
+
part of dart.async;
_invokeErrorHandler(
diff --git a/sdk_nnbd/lib/async/broadcast_stream_controller.dart b/sdk_nnbd/lib/async/broadcast_stream_controller.dart
index 32e4582..c5358f2 100644
--- a/sdk_nnbd/lib/async/broadcast_stream_controller.dart
+++ b/sdk_nnbd/lib/async/broadcast_stream_controller.dart
@@ -2,6 +2,8 @@
// 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.5
+
part of dart.async;
class _BroadcastStream<T> extends _ControllerStream<T> {
diff --git a/sdk_nnbd/lib/async/deferred_load.dart b/sdk_nnbd/lib/async/deferred_load.dart
index f83d4b8..1e2be92 100644
--- a/sdk_nnbd/lib/async/deferred_load.dart
+++ b/sdk_nnbd/lib/async/deferred_load.dart
@@ -2,6 +2,8 @@
// 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.5
+
part of dart.async;
/**
diff --git a/sdk_nnbd/lib/async/future.dart b/sdk_nnbd/lib/async/future.dart
index b9d22c1..2f9c24d 100644
--- a/sdk_nnbd/lib/async/future.dart
+++ b/sdk_nnbd/lib/async/future.dart
@@ -2,6 +2,8 @@
// 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.5
+
part of dart.async;
/// A type representing values that are either `Future<T>` or `T`.
diff --git a/sdk_nnbd/lib/async/future_impl.dart b/sdk_nnbd/lib/async/future_impl.dart
index 1ec0791..c9685ff 100644
--- a/sdk_nnbd/lib/async/future_impl.dart
+++ b/sdk_nnbd/lib/async/future_impl.dart
@@ -2,6 +2,8 @@
// 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.5
+
part of dart.async;
/** The onValue and onError handlers return either a value or a future */
diff --git a/sdk_nnbd/lib/async/schedule_microtask.dart b/sdk_nnbd/lib/async/schedule_microtask.dart
index 801490a..41b9d31 100644
--- a/sdk_nnbd/lib/async/schedule_microtask.dart
+++ b/sdk_nnbd/lib/async/schedule_microtask.dart
@@ -2,6 +2,8 @@
// 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.5
+
part of dart.async;
typedef void _AsyncCallback();
diff --git a/sdk_nnbd/lib/async/stream.dart b/sdk_nnbd/lib/async/stream.dart
index 95a8b97..ba3dad6 100644
--- a/sdk_nnbd/lib/async/stream.dart
+++ b/sdk_nnbd/lib/async/stream.dart
@@ -2,6 +2,8 @@
// 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.5
+
part of dart.async;
// -------------------------------------------------------------------
diff --git a/sdk_nnbd/lib/async/stream_controller.dart b/sdk_nnbd/lib/async/stream_controller.dart
index 34c6adf..f8f2d6d 100644
--- a/sdk_nnbd/lib/async/stream_controller.dart
+++ b/sdk_nnbd/lib/async/stream_controller.dart
@@ -2,6 +2,8 @@
// 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.5
+
part of dart.async;
// -------------------------------------------------------------------
diff --git a/sdk_nnbd/lib/async/stream_impl.dart b/sdk_nnbd/lib/async/stream_impl.dart
index 14c84a5..fac736c 100644
--- a/sdk_nnbd/lib/async/stream_impl.dart
+++ b/sdk_nnbd/lib/async/stream_impl.dart
@@ -2,6 +2,8 @@
// 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.5
+
part of dart.async;
/** Abstract and private interface for a place to put events. */
diff --git a/sdk_nnbd/lib/async/stream_pipe.dart b/sdk_nnbd/lib/async/stream_pipe.dart
index e526179..1549ad5 100644
--- a/sdk_nnbd/lib/async/stream_pipe.dart
+++ b/sdk_nnbd/lib/async/stream_pipe.dart
@@ -2,6 +2,8 @@
// 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.5
+
part of dart.async;
/** Runs user code and takes actions depending on success or failure. */
diff --git a/sdk_nnbd/lib/async/stream_transformers.dart b/sdk_nnbd/lib/async/stream_transformers.dart
index 9ec13bd..5c788fe 100644
--- a/sdk_nnbd/lib/async/stream_transformers.dart
+++ b/sdk_nnbd/lib/async/stream_transformers.dart
@@ -2,6 +2,8 @@
// 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.5
+
part of dart.async;
/**
diff --git a/sdk_nnbd/lib/async/timer.dart b/sdk_nnbd/lib/async/timer.dart
index aa2f088..e3f7edb 100644
--- a/sdk_nnbd/lib/async/timer.dart
+++ b/sdk_nnbd/lib/async/timer.dart
@@ -2,6 +2,8 @@
// 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.5
+
part of dart.async;
/**
diff --git a/sdk_nnbd/lib/async/zone.dart b/sdk_nnbd/lib/async/zone.dart
index 911ecff..6a2d015 100644
--- a/sdk_nnbd/lib/async/zone.dart
+++ b/sdk_nnbd/lib/async/zone.dart
@@ -2,6 +2,8 @@
// 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.5
+
part of dart.async;
typedef R ZoneCallback<R>();
diff --git a/sdk_nnbd/lib/cli/cli.dart b/sdk_nnbd/lib/cli/cli.dart
index 9c19c3a..4748181 100644
--- a/sdk_nnbd/lib/cli/cli.dart
+++ b/sdk_nnbd/lib/cli/cli.dart
@@ -2,6 +2,8 @@
// 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.5
+
/// {@category VM}
library dart.cli;
diff --git a/sdk_nnbd/lib/cli/wait_for.dart b/sdk_nnbd/lib/cli/wait_for.dart
index 1886ff1..d4dd71e 100644
--- a/sdk_nnbd/lib/cli/wait_for.dart
+++ b/sdk_nnbd/lib/cli/wait_for.dart
@@ -2,6 +2,8 @@
// 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.5
+
part of dart.cli;
/**
diff --git a/sdk_nnbd/lib/collection/collection.dart b/sdk_nnbd/lib/collection/collection.dart
index b050a48..644bcff 100644
--- a/sdk_nnbd/lib/collection/collection.dart
+++ b/sdk_nnbd/lib/collection/collection.dart
@@ -2,6 +2,8 @@
// 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.5
+
/// Classes and utilities that supplement the collection support in dart:core.
///
/// To use this library in your code:
diff --git a/sdk_nnbd/lib/collection/collections.dart b/sdk_nnbd/lib/collection/collections.dart
index 9b43996..f836d8e 100644
--- a/sdk_nnbd/lib/collection/collections.dart
+++ b/sdk_nnbd/lib/collection/collections.dart
@@ -2,6 +2,8 @@
// 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.5
+
part of dart.collection;
/// An unmodifiable [List] view of another List.
diff --git a/sdk_nnbd/lib/collection/hash_map.dart b/sdk_nnbd/lib/collection/hash_map.dart
index 525f43a..18ea1b6 100644
--- a/sdk_nnbd/lib/collection/hash_map.dart
+++ b/sdk_nnbd/lib/collection/hash_map.dart
@@ -2,6 +2,8 @@
// 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.5
+
part of dart.collection;
/// Default function for equality comparison in customized HashMaps
diff --git a/sdk_nnbd/lib/collection/hash_set.dart b/sdk_nnbd/lib/collection/hash_set.dart
index 3fd00fe..61f1f6c 100644
--- a/sdk_nnbd/lib/collection/hash_set.dart
+++ b/sdk_nnbd/lib/collection/hash_set.dart
@@ -2,6 +2,8 @@
// 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.5
+
part of dart.collection;
/// An unordered hash-table based [Set] implementation.
diff --git a/sdk_nnbd/lib/collection/iterable.dart b/sdk_nnbd/lib/collection/iterable.dart
index 14e7226..8ac38b2 100644
--- a/sdk_nnbd/lib/collection/iterable.dart
+++ b/sdk_nnbd/lib/collection/iterable.dart
@@ -2,6 +2,8 @@
// 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.5
+
part of dart.collection;
/// This [Iterable] mixin implements all [Iterable] members except `iterator`.
diff --git a/sdk_nnbd/lib/collection/iterator.dart b/sdk_nnbd/lib/collection/iterator.dart
index 671f0ee..e7e0c3b 100644
--- a/sdk_nnbd/lib/collection/iterator.dart
+++ b/sdk_nnbd/lib/collection/iterator.dart
@@ -2,6 +2,8 @@
// 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.5
+
part of dart.collection;
/// The [HasNextIterator] class wraps an [Iterator] and provides methods to
diff --git a/sdk_nnbd/lib/collection/linked_hash_map.dart b/sdk_nnbd/lib/collection/linked_hash_map.dart
index e3a650d..de94009 100644
--- a/sdk_nnbd/lib/collection/linked_hash_map.dart
+++ b/sdk_nnbd/lib/collection/linked_hash_map.dart
@@ -2,6 +2,8 @@
// 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.5
+
part of dart.collection;
/// A hash-table based implementation of [Map].
diff --git a/sdk_nnbd/lib/collection/linked_hash_set.dart b/sdk_nnbd/lib/collection/linked_hash_set.dart
index a058b5e..195b5fb 100644
--- a/sdk_nnbd/lib/collection/linked_hash_set.dart
+++ b/sdk_nnbd/lib/collection/linked_hash_set.dart
@@ -2,6 +2,8 @@
// 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.5
+
part of dart.collection;
/// A [LinkedHashSet] is a hash-table based [Set] implementation.
diff --git a/sdk_nnbd/lib/collection/linked_list.dart b/sdk_nnbd/lib/collection/linked_list.dart
index 91461cb..9ef7a56 100644
--- a/sdk_nnbd/lib/collection/linked_list.dart
+++ b/sdk_nnbd/lib/collection/linked_list.dart
@@ -2,6 +2,8 @@
// 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.5
+
part of dart.collection;
/// A specialized double-linked list of elements that extends [LinkedListEntry].
diff --git a/sdk_nnbd/lib/collection/list.dart b/sdk_nnbd/lib/collection/list.dart
index 1d83aa4..911820b 100644
--- a/sdk_nnbd/lib/collection/list.dart
+++ b/sdk_nnbd/lib/collection/list.dart
@@ -2,6 +2,8 @@
// 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.5
+
part of dart.collection;
/// Abstract implementation of a list.
diff --git a/sdk_nnbd/lib/collection/maps.dart b/sdk_nnbd/lib/collection/maps.dart
index 8159342..7fb2551 100644
--- a/sdk_nnbd/lib/collection/maps.dart
+++ b/sdk_nnbd/lib/collection/maps.dart
@@ -2,6 +2,8 @@
// 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.5
+
part of dart.collection;
/// Base class for implementing a [Map].
diff --git a/sdk_nnbd/lib/collection/queue.dart b/sdk_nnbd/lib/collection/queue.dart
index 62994b9..77b27b1 100644
--- a/sdk_nnbd/lib/collection/queue.dart
+++ b/sdk_nnbd/lib/collection/queue.dart
@@ -2,6 +2,8 @@
// 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.5
+
part of dart.collection;
/// A [Queue] is a collection that can be manipulated at both ends. One
diff --git a/sdk_nnbd/lib/collection/set.dart b/sdk_nnbd/lib/collection/set.dart
index 7508b23..b6b9efc 100644
--- a/sdk_nnbd/lib/collection/set.dart
+++ b/sdk_nnbd/lib/collection/set.dart
@@ -2,6 +2,8 @@
// 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.5
+
/// Base implementations of [Set].
part of dart.collection;
diff --git a/sdk_nnbd/lib/collection/splay_tree.dart b/sdk_nnbd/lib/collection/splay_tree.dart
index 5f71934..ef3e51f 100644
--- a/sdk_nnbd/lib/collection/splay_tree.dart
+++ b/sdk_nnbd/lib/collection/splay_tree.dart
@@ -2,6 +2,8 @@
// 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.5
+
part of dart.collection;
typedef _Predicate<T> = bool Function(T value);
diff --git a/sdk_nnbd/lib/convert/ascii.dart b/sdk_nnbd/lib/convert/ascii.dart
index 35105ac..307ac08 100644
--- a/sdk_nnbd/lib/convert/ascii.dart
+++ b/sdk_nnbd/lib/convert/ascii.dart
@@ -2,6 +2,8 @@
// 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.5
+
part of dart.convert;
/// An instance of the default implementation of the [AsciiCodec].
diff --git a/sdk_nnbd/lib/convert/base64.dart b/sdk_nnbd/lib/convert/base64.dart
index ce522be..4187658 100644
--- a/sdk_nnbd/lib/convert/base64.dart
+++ b/sdk_nnbd/lib/convert/base64.dart
@@ -2,6 +2,8 @@
// 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.5
+
part of dart.convert;
/// A [base64](https://tools.ietf.org/html/rfc4648) encoder and decoder.
diff --git a/sdk_nnbd/lib/convert/byte_conversion.dart b/sdk_nnbd/lib/convert/byte_conversion.dart
index 3d52d78..9e66ecd 100644
--- a/sdk_nnbd/lib/convert/byte_conversion.dart
+++ b/sdk_nnbd/lib/convert/byte_conversion.dart
@@ -2,6 +2,8 @@
// 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.5
+
part of dart.convert;
/// The [ByteConversionSink] provides an interface for converters to
diff --git a/sdk_nnbd/lib/convert/chunked_conversion.dart b/sdk_nnbd/lib/convert/chunked_conversion.dart
index e946f97..d2f1a7c 100644
--- a/sdk_nnbd/lib/convert/chunked_conversion.dart
+++ b/sdk_nnbd/lib/convert/chunked_conversion.dart
@@ -2,6 +2,8 @@
// 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.5
+
part of dart.convert;
/// A [ChunkedConversionSink] is used to transmit data more efficiently between
diff --git a/sdk_nnbd/lib/convert/codec.dart b/sdk_nnbd/lib/convert/codec.dart
index 38e4a3c..7c9fb07 100644
--- a/sdk_nnbd/lib/convert/codec.dart
+++ b/sdk_nnbd/lib/convert/codec.dart
@@ -2,6 +2,8 @@
// 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.5
+
part of dart.convert;
/// A [Codec] encodes and (if supported) decodes data.
diff --git a/sdk_nnbd/lib/convert/convert.dart b/sdk_nnbd/lib/convert/convert.dart
index 6173782..727a8c8 100644
--- a/sdk_nnbd/lib/convert/convert.dart
+++ b/sdk_nnbd/lib/convert/convert.dart
@@ -2,6 +2,8 @@
// 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.5
+
///
/// Encoders and decoders for converting between different data representations,
/// including JSON and UTF-8.
diff --git a/sdk_nnbd/lib/convert/converter.dart b/sdk_nnbd/lib/convert/converter.dart
index 2167933..0205771 100644
--- a/sdk_nnbd/lib/convert/converter.dart
+++ b/sdk_nnbd/lib/convert/converter.dart
@@ -2,6 +2,8 @@
// 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.5
+
part of dart.convert;
/// A [Converter] converts data from one representation into another.
diff --git a/sdk_nnbd/lib/convert/encoding.dart b/sdk_nnbd/lib/convert/encoding.dart
index 7ce8ec3..d6d36ee 100644
--- a/sdk_nnbd/lib/convert/encoding.dart
+++ b/sdk_nnbd/lib/convert/encoding.dart
@@ -2,6 +2,8 @@
// 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.5
+
part of dart.convert;
/// Open-ended Encoding enum.
diff --git a/sdk_nnbd/lib/convert/html_escape.dart b/sdk_nnbd/lib/convert/html_escape.dart
index a0a7119..98f24df 100644
--- a/sdk_nnbd/lib/convert/html_escape.dart
+++ b/sdk_nnbd/lib/convert/html_escape.dart
@@ -2,6 +2,8 @@
// 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.5
+
part of dart.convert;
/// A `String` converter that converts characters to HTML entities.
diff --git a/sdk_nnbd/lib/convert/json.dart b/sdk_nnbd/lib/convert/json.dart
index 5746e52..6ac392a 100644
--- a/sdk_nnbd/lib/convert/json.dart
+++ b/sdk_nnbd/lib/convert/json.dart
@@ -2,6 +2,8 @@
// 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.5
+
part of dart.convert;
/// Error thrown by JSON serialization if an object cannot be serialized.
diff --git a/sdk_nnbd/lib/convert/latin1.dart b/sdk_nnbd/lib/convert/latin1.dart
index c22010c..305017f 100644
--- a/sdk_nnbd/lib/convert/latin1.dart
+++ b/sdk_nnbd/lib/convert/latin1.dart
@@ -2,6 +2,8 @@
// 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.5
+
part of dart.convert;
/// An instance of the default implementation of the [Latin1Codec].
diff --git a/sdk_nnbd/lib/convert/line_splitter.dart b/sdk_nnbd/lib/convert/line_splitter.dart
index 71be2c0..6980e88 100644
--- a/sdk_nnbd/lib/convert/line_splitter.dart
+++ b/sdk_nnbd/lib/convert/line_splitter.dart
@@ -2,6 +2,8 @@
// 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.5
+
part of dart.convert;
// Character constants.
diff --git a/sdk_nnbd/lib/convert/string_conversion.dart b/sdk_nnbd/lib/convert/string_conversion.dart
index 81e5621..94d129c 100644
--- a/sdk_nnbd/lib/convert/string_conversion.dart
+++ b/sdk_nnbd/lib/convert/string_conversion.dart
@@ -2,6 +2,8 @@
// 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.5
+
part of dart.convert;
/// This class provides an interface for converters to
diff --git a/sdk_nnbd/lib/convert/utf.dart b/sdk_nnbd/lib/convert/utf.dart
index 39eb135..692a01c 100644
--- a/sdk_nnbd/lib/convert/utf.dart
+++ b/sdk_nnbd/lib/convert/utf.dart
@@ -2,6 +2,8 @@
// 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.5
+
part of dart.convert;
/// The Unicode Replacement character `U+FFFD` (�).
diff --git a/sdk_nnbd/lib/core/annotations.dart b/sdk_nnbd/lib/core/annotations.dart
index 2d30f1c..4592eb0 100644
--- a/sdk_nnbd/lib/core/annotations.dart
+++ b/sdk_nnbd/lib/core/annotations.dart
@@ -2,6 +2,8 @@
// 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.5
+
part of dart.core;
/**
diff --git a/sdk_nnbd/lib/core/bigint.dart b/sdk_nnbd/lib/core/bigint.dart
index b495a9e..e6f3ba0 100644
--- a/sdk_nnbd/lib/core/bigint.dart
+++ b/sdk_nnbd/lib/core/bigint.dart
@@ -2,6 +2,8 @@
// 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.5
+
part of dart.core;
/**
diff --git a/sdk_nnbd/lib/core/bool.dart b/sdk_nnbd/lib/core/bool.dart
index 5ed1065..692186f 100644
--- a/sdk_nnbd/lib/core/bool.dart
+++ b/sdk_nnbd/lib/core/bool.dart
@@ -2,6 +2,8 @@
// 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.5
+
part of dart.core;
/**
diff --git a/sdk_nnbd/lib/core/comparable.dart b/sdk_nnbd/lib/core/comparable.dart
index 835aa34..4416dc0 100644
--- a/sdk_nnbd/lib/core/comparable.dart
+++ b/sdk_nnbd/lib/core/comparable.dart
@@ -2,6 +2,8 @@
// 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.5
+
part of dart.core;
/**
diff --git a/sdk_nnbd/lib/core/core.dart b/sdk_nnbd/lib/core/core.dart
index 9ab8ed4..d9137cd 100644
--- a/sdk_nnbd/lib/core/core.dart
+++ b/sdk_nnbd/lib/core/core.dart
@@ -2,6 +2,8 @@
// 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.5
+
/**
*
* Built-in types, collections,
diff --git a/sdk_nnbd/lib/core/date_time.dart b/sdk_nnbd/lib/core/date_time.dart
index dd242de..1dd01bb 100644
--- a/sdk_nnbd/lib/core/date_time.dart
+++ b/sdk_nnbd/lib/core/date_time.dart
@@ -2,6 +2,8 @@
// 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.5
+
part of dart.core;
/**
diff --git a/sdk_nnbd/lib/core/double.dart b/sdk_nnbd/lib/core/double.dart
index 61191ec..f8d109c 100644
--- a/sdk_nnbd/lib/core/double.dart
+++ b/sdk_nnbd/lib/core/double.dart
@@ -2,6 +2,8 @@
// 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.5
+
part of dart.core;
// TODO: Convert this abstract class into a concrete class double
diff --git a/sdk_nnbd/lib/core/duration.dart b/sdk_nnbd/lib/core/duration.dart
index 914f05a..f68609f 100644
--- a/sdk_nnbd/lib/core/duration.dart
+++ b/sdk_nnbd/lib/core/duration.dart
@@ -2,6 +2,8 @@
// 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.5
+
part of dart.core;
/**
diff --git a/sdk_nnbd/lib/core/errors.dart b/sdk_nnbd/lib/core/errors.dart
index 53f3d35..b2454f8 100644
--- a/sdk_nnbd/lib/core/errors.dart
+++ b/sdk_nnbd/lib/core/errors.dart
@@ -2,6 +2,8 @@
// 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.5
+
part of dart.core;
/**
diff --git a/sdk_nnbd/lib/core/exceptions.dart b/sdk_nnbd/lib/core/exceptions.dart
index 2e137e5..4ac5ace 100644
--- a/sdk_nnbd/lib/core/exceptions.dart
+++ b/sdk_nnbd/lib/core/exceptions.dart
@@ -2,6 +2,8 @@
// 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.5
+
part of dart.core;
// Exceptions are thrown either by the VM or from Dart code.
diff --git a/sdk_nnbd/lib/core/expando.dart b/sdk_nnbd/lib/core/expando.dart
index 92cf90c..132d38a 100644
--- a/sdk_nnbd/lib/core/expando.dart
+++ b/sdk_nnbd/lib/core/expando.dart
@@ -2,6 +2,8 @@
// 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.5
+
part of dart.core;
/**
diff --git a/sdk_nnbd/lib/core/function.dart b/sdk_nnbd/lib/core/function.dart
index 7ff40e9..6c0462b 100644
--- a/sdk_nnbd/lib/core/function.dart
+++ b/sdk_nnbd/lib/core/function.dart
@@ -2,6 +2,8 @@
// 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.5
+
part of dart.core;
/**
diff --git a/sdk_nnbd/lib/core/identical.dart b/sdk_nnbd/lib/core/identical.dart
index 68da9f3..8789642 100644
--- a/sdk_nnbd/lib/core/identical.dart
+++ b/sdk_nnbd/lib/core/identical.dart
@@ -2,6 +2,8 @@
// 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.5
+
part of dart.core;
/**
diff --git a/sdk_nnbd/lib/core/int.dart b/sdk_nnbd/lib/core/int.dart
index bc493fb..a55641c 100644
--- a/sdk_nnbd/lib/core/int.dart
+++ b/sdk_nnbd/lib/core/int.dart
@@ -2,6 +2,8 @@
// 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.5
+
part of dart.core;
/**
diff --git a/sdk_nnbd/lib/core/invocation.dart b/sdk_nnbd/lib/core/invocation.dart
index e9ea57e..6644a84 100644
--- a/sdk_nnbd/lib/core/invocation.dart
+++ b/sdk_nnbd/lib/core/invocation.dart
@@ -2,6 +2,8 @@
// 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.5
+
part of dart.core;
/**
diff --git a/sdk_nnbd/lib/core/iterable.dart b/sdk_nnbd/lib/core/iterable.dart
index 0744937..32225b0 100644
--- a/sdk_nnbd/lib/core/iterable.dart
+++ b/sdk_nnbd/lib/core/iterable.dart
@@ -2,6 +2,8 @@
// 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.5
+
part of dart.core;
/**
diff --git a/sdk_nnbd/lib/core/iterator.dart b/sdk_nnbd/lib/core/iterator.dart
index cd0ad32..d69e937 100644
--- a/sdk_nnbd/lib/core/iterator.dart
+++ b/sdk_nnbd/lib/core/iterator.dart
@@ -2,6 +2,8 @@
// 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.5
+
part of dart.core;
/**
diff --git a/sdk_nnbd/lib/core/list.dart b/sdk_nnbd/lib/core/list.dart
index 27e1653..b096bfa 100644
--- a/sdk_nnbd/lib/core/list.dart
+++ b/sdk_nnbd/lib/core/list.dart
@@ -2,6 +2,8 @@
// 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.5
+
part of dart.core;
/**
diff --git a/sdk_nnbd/lib/core/map.dart b/sdk_nnbd/lib/core/map.dart
index f914fe1..fa1573a 100644
--- a/sdk_nnbd/lib/core/map.dart
+++ b/sdk_nnbd/lib/core/map.dart
@@ -2,6 +2,8 @@
// 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.5
+
part of dart.core;
/**
diff --git a/sdk_nnbd/lib/core/null.dart b/sdk_nnbd/lib/core/null.dart
index af7d86d..0e8dec5 100644
--- a/sdk_nnbd/lib/core/null.dart
+++ b/sdk_nnbd/lib/core/null.dart
@@ -2,6 +2,8 @@
// 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.5
+
part of dart.core;
/**
diff --git a/sdk_nnbd/lib/core/num.dart b/sdk_nnbd/lib/core/num.dart
index e04112c..e7afd77 100644
--- a/sdk_nnbd/lib/core/num.dart
+++ b/sdk_nnbd/lib/core/num.dart
@@ -2,6 +2,8 @@
// 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.5
+
part of dart.core;
/**
diff --git a/sdk_nnbd/lib/core/object.dart b/sdk_nnbd/lib/core/object.dart
index 505efdf..6490430 100644
--- a/sdk_nnbd/lib/core/object.dart
+++ b/sdk_nnbd/lib/core/object.dart
@@ -2,6 +2,8 @@
// 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.5
+
part of dart.core;
/**
diff --git a/sdk_nnbd/lib/core/pattern.dart b/sdk_nnbd/lib/core/pattern.dart
index 6749340..42607e1 100644
--- a/sdk_nnbd/lib/core/pattern.dart
+++ b/sdk_nnbd/lib/core/pattern.dart
@@ -2,6 +2,8 @@
// 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.5
+
part of dart.core;
/**
diff --git a/sdk_nnbd/lib/core/print.dart b/sdk_nnbd/lib/core/print.dart
index 42c7d1c..6b33db5 100644
--- a/sdk_nnbd/lib/core/print.dart
+++ b/sdk_nnbd/lib/core/print.dart
@@ -2,6 +2,8 @@
// 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.5
+
part of dart.core;
/// Prints a string representation of the object to the console.
diff --git a/sdk_nnbd/lib/core/regexp.dart b/sdk_nnbd/lib/core/regexp.dart
index b3046cc..4d1228c 100644
--- a/sdk_nnbd/lib/core/regexp.dart
+++ b/sdk_nnbd/lib/core/regexp.dart
@@ -2,6 +2,8 @@
// 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.5
+
part of dart.core;
/**
diff --git a/sdk_nnbd/lib/core/set.dart b/sdk_nnbd/lib/core/set.dart
index e57d974..d0be04c 100644
--- a/sdk_nnbd/lib/core/set.dart
+++ b/sdk_nnbd/lib/core/set.dart
@@ -2,6 +2,8 @@
// 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.5
+
part of dart.core;
/**
diff --git a/sdk_nnbd/lib/core/sink.dart b/sdk_nnbd/lib/core/sink.dart
index c79214b..ed921b1 100644
--- a/sdk_nnbd/lib/core/sink.dart
+++ b/sdk_nnbd/lib/core/sink.dart
@@ -2,6 +2,8 @@
// 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.5
+
part of dart.core;
/**
diff --git a/sdk_nnbd/lib/core/stacktrace.dart b/sdk_nnbd/lib/core/stacktrace.dart
index 2eb1493..434be96 100644
--- a/sdk_nnbd/lib/core/stacktrace.dart
+++ b/sdk_nnbd/lib/core/stacktrace.dart
@@ -2,6 +2,8 @@
// 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.5
+
part of dart.core;
/**
diff --git a/sdk_nnbd/lib/core/stopwatch.dart b/sdk_nnbd/lib/core/stopwatch.dart
index 45d71ca..0db02c9 100644
--- a/sdk_nnbd/lib/core/stopwatch.dart
+++ b/sdk_nnbd/lib/core/stopwatch.dart
@@ -2,6 +2,8 @@
// 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.5
+
part of dart.core;
/**
diff --git a/sdk_nnbd/lib/core/string.dart b/sdk_nnbd/lib/core/string.dart
index c611bd5..7559f9c 100644
--- a/sdk_nnbd/lib/core/string.dart
+++ b/sdk_nnbd/lib/core/string.dart
@@ -2,6 +2,8 @@
// 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.5
+
part of dart.core;
/**
diff --git a/sdk_nnbd/lib/core/string_buffer.dart b/sdk_nnbd/lib/core/string_buffer.dart
index 8fe17f5..417676a 100644
--- a/sdk_nnbd/lib/core/string_buffer.dart
+++ b/sdk_nnbd/lib/core/string_buffer.dart
@@ -2,6 +2,8 @@
// 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.5
+
part of dart.core;
/**
diff --git a/sdk_nnbd/lib/core/string_sink.dart b/sdk_nnbd/lib/core/string_sink.dart
index e7d950c..8c19b9b 100644
--- a/sdk_nnbd/lib/core/string_sink.dart
+++ b/sdk_nnbd/lib/core/string_sink.dart
@@ -2,6 +2,8 @@
// 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.5
+
part of dart.core;
abstract class StringSink {
diff --git a/sdk_nnbd/lib/core/symbol.dart b/sdk_nnbd/lib/core/symbol.dart
index a46ec97..2904b9f 100644
--- a/sdk_nnbd/lib/core/symbol.dart
+++ b/sdk_nnbd/lib/core/symbol.dart
@@ -2,6 +2,8 @@
// 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.5
+
part of dart.core;
/// Opaque name used by mirrors, invocations and [Function.apply].
diff --git a/sdk_nnbd/lib/core/type.dart b/sdk_nnbd/lib/core/type.dart
index d2e107b..8657cd4 100644
--- a/sdk_nnbd/lib/core/type.dart
+++ b/sdk_nnbd/lib/core/type.dart
@@ -2,6 +2,8 @@
// 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.5
+
part of dart.core;
/**
diff --git a/sdk_nnbd/lib/core/uri.dart b/sdk_nnbd/lib/core/uri.dart
index 2ca94a1..478e9d7 100644
--- a/sdk_nnbd/lib/core/uri.dart
+++ b/sdk_nnbd/lib/core/uri.dart
@@ -2,6 +2,8 @@
// 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.5
+
part of dart.core;
// Frequently used character codes.
diff --git a/sdk_nnbd/lib/developer/developer.dart b/sdk_nnbd/lib/developer/developer.dart
index c446fdf..732e1d9 100644
--- a/sdk_nnbd/lib/developer/developer.dart
+++ b/sdk_nnbd/lib/developer/developer.dart
@@ -2,6 +2,8 @@
// 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.5
+
/// Interact with developer tools such as the debugger and inspector.
///
/// This library is platform dependent and has separate implementations for
diff --git a/sdk_nnbd/lib/developer/extension.dart b/sdk_nnbd/lib/developer/extension.dart
index 3cc4ede..d292857 100644
--- a/sdk_nnbd/lib/developer/extension.dart
+++ b/sdk_nnbd/lib/developer/extension.dart
@@ -2,6 +2,8 @@
// 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.5
+
part of dart.developer;
/// A response to a service protocol extension RPC.
diff --git a/sdk_nnbd/lib/developer/profiler.dart b/sdk_nnbd/lib/developer/profiler.dart
index 05a9211..f08df89 100644
--- a/sdk_nnbd/lib/developer/profiler.dart
+++ b/sdk_nnbd/lib/developer/profiler.dart
@@ -2,6 +2,8 @@
// 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.5
+
part of dart.developer;
/// A UserTag can be used to group samples in the Observatory profiler.
diff --git a/sdk_nnbd/lib/developer/service.dart b/sdk_nnbd/lib/developer/service.dart
index a4d92b9..2678da7 100644
--- a/sdk_nnbd/lib/developer/service.dart
+++ b/sdk_nnbd/lib/developer/service.dart
@@ -2,6 +2,8 @@
// 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.5
+
part of dart.developer;
/// Service protocol is the protocol that a client like the Observatory
diff --git a/sdk_nnbd/lib/developer/timeline.dart b/sdk_nnbd/lib/developer/timeline.dart
index 02f9c98..2e5f4ec 100644
--- a/sdk_nnbd/lib/developer/timeline.dart
+++ b/sdk_nnbd/lib/developer/timeline.dart
@@ -2,6 +2,8 @@
// 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.5
+
part of dart.developer;
const bool _hasTimeline =
diff --git a/sdk_nnbd/lib/ffi/annotations.dart b/sdk_nnbd/lib/ffi/annotations.dart
index d246b56..c4e9b7f 100644
--- a/sdk_nnbd/lib/ffi/annotations.dart
+++ b/sdk_nnbd/lib/ffi/annotations.dart
@@ -2,6 +2,8 @@
// 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.5
+
part of dart.ffi;
class DartRepresentationOf {
diff --git a/sdk_nnbd/lib/ffi/dynamic_library.dart b/sdk_nnbd/lib/ffi/dynamic_library.dart
index ec68eeb..86cd117 100644
--- a/sdk_nnbd/lib/ffi/dynamic_library.dart
+++ b/sdk_nnbd/lib/ffi/dynamic_library.dart
@@ -2,6 +2,8 @@
// 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.5
+
part of dart.ffi;
/// Represents a dynamically loaded C library.
diff --git a/sdk_nnbd/lib/ffi/ffi.dart b/sdk_nnbd/lib/ffi/ffi.dart
index a975a13..eb1bdcd 100644
--- a/sdk_nnbd/lib/ffi/ffi.dart
+++ b/sdk_nnbd/lib/ffi/ffi.dart
@@ -2,6 +2,8 @@
// 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.5
+
/**
* Foreign Function Interface for interoperability with the C programming language.
*
diff --git a/sdk_nnbd/lib/ffi/native_type.dart b/sdk_nnbd/lib/ffi/native_type.dart
index aa30e63..1498ecc 100644
--- a/sdk_nnbd/lib/ffi/native_type.dart
+++ b/sdk_nnbd/lib/ffi/native_type.dart
@@ -2,6 +2,8 @@
// 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.5
+
part of dart.ffi;
/// [NativeType]'s subtypes represent a native type in C.
diff --git a/sdk_nnbd/lib/ffi/struct.dart b/sdk_nnbd/lib/ffi/struct.dart
index 23124eb..33872f3 100644
--- a/sdk_nnbd/lib/ffi/struct.dart
+++ b/sdk_nnbd/lib/ffi/struct.dart
@@ -2,6 +2,8 @@
// 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.5
+
part of dart.ffi;
/// This class is extended to define structs.
diff --git a/sdk_nnbd/lib/html/dart2js/html_dart2js.dart b/sdk_nnbd/lib/html/dart2js/html_dart2js.dart
index 303ec9e..b5afe53 100644
--- a/sdk_nnbd/lib/html/dart2js/html_dart2js.dart
+++ b/sdk_nnbd/lib/html/dart2js/html_dart2js.dart
@@ -1,3 +1,5 @@
+// @dart = 2.5
+
/**
* HTML elements and other resources for web-based applications that need to
* interact with the browser and the DOM (Document Object Model).
diff --git a/sdk_nnbd/lib/html/dartium/nativewrappers.dart b/sdk_nnbd/lib/html/dartium/nativewrappers.dart
index b6d2dc4..03fea72 100644
--- a/sdk_nnbd/lib/html/dartium/nativewrappers.dart
+++ b/sdk_nnbd/lib/html/dartium/nativewrappers.dart
@@ -2,6 +2,8 @@
// 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.5
+
library nativewrappers;
class NativeFieldWrapperClass1 {}
diff --git a/sdk_nnbd/lib/html/html_common/conversions.dart b/sdk_nnbd/lib/html/html_common/conversions.dart
index 4c31efb..ca118a9 100644
--- a/sdk_nnbd/lib/html/html_common/conversions.dart
+++ b/sdk_nnbd/lib/html/html_common/conversions.dart
@@ -2,6 +2,8 @@
// 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.5
+
// Conversions for IDBKey.
//
// Per http://www.w3.org/TR/IndexedDB/#key-construct
diff --git a/sdk_nnbd/lib/html/html_common/conversions_dart2js.dart b/sdk_nnbd/lib/html/html_common/conversions_dart2js.dart
index 36153cf..08ce947 100644
--- a/sdk_nnbd/lib/html/html_common/conversions_dart2js.dart
+++ b/sdk_nnbd/lib/html/html_common/conversions_dart2js.dart
@@ -1,3 +1,5 @@
+// @dart = 2.5
+
part of html_common;
/// Converts a JavaScript object with properties into a Dart Map.
diff --git a/sdk_nnbd/lib/html/html_common/css_class_set.dart b/sdk_nnbd/lib/html/html_common/css_class_set.dart
index 2286057..bda757e 100644
--- a/sdk_nnbd/lib/html/html_common/css_class_set.dart
+++ b/sdk_nnbd/lib/html/html_common/css_class_set.dart
@@ -2,6 +2,8 @@
// 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.5
+
part of html_common;
abstract class CssClassSetImpl extends SetBase<String> implements CssClassSet {
diff --git a/sdk_nnbd/lib/html/html_common/device.dart b/sdk_nnbd/lib/html/html_common/device.dart
index 123a5db..1062bb6 100644
--- a/sdk_nnbd/lib/html/html_common/device.dart
+++ b/sdk_nnbd/lib/html/html_common/device.dart
@@ -2,6 +2,8 @@
// 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.5
+
part of html_common;
/**
diff --git a/sdk_nnbd/lib/html/html_common/filtered_element_list.dart b/sdk_nnbd/lib/html/html_common/filtered_element_list.dart
index fba6ad7..e3b0a3e 100644
--- a/sdk_nnbd/lib/html/html_common/filtered_element_list.dart
+++ b/sdk_nnbd/lib/html/html_common/filtered_element_list.dart
@@ -2,6 +2,8 @@
// 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.5
+
part of html_common;
/**
diff --git a/sdk_nnbd/lib/html/html_common/html_common.dart b/sdk_nnbd/lib/html/html_common/html_common.dart
index e689c9a..2dfec89 100644
--- a/sdk_nnbd/lib/html/html_common/html_common.dart
+++ b/sdk_nnbd/lib/html/html_common/html_common.dart
@@ -1,6 +1,8 @@
// 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.5
+
library html_common;
import 'dart:async';
diff --git a/sdk_nnbd/lib/html/html_common/html_common_dart2js.dart b/sdk_nnbd/lib/html/html_common/html_common_dart2js.dart
index f162ad8..3a91281 100644
--- a/sdk_nnbd/lib/html/html_common/html_common_dart2js.dart
+++ b/sdk_nnbd/lib/html/html_common/html_common_dart2js.dart
@@ -2,6 +2,8 @@
// 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.5
+
library html_common;
import 'dart:async';
diff --git a/sdk_nnbd/lib/html/html_common/lists.dart b/sdk_nnbd/lib/html/html_common/lists.dart
index c7abc41..5f9d86c 100644
--- a/sdk_nnbd/lib/html/html_common/lists.dart
+++ b/sdk_nnbd/lib/html/html_common/lists.dart
@@ -2,6 +2,8 @@
// 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.5
+
part of html_common;
class Lists {
diff --git a/sdk_nnbd/lib/html/html_common/metadata.dart b/sdk_nnbd/lib/html/html_common/metadata.dart
index b5542dc..f21f495 100644
--- a/sdk_nnbd/lib/html/html_common/metadata.dart
+++ b/sdk_nnbd/lib/html/html_common/metadata.dart
@@ -2,6 +2,8 @@
// 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.5
+
library metadata;
/**
diff --git a/sdk_nnbd/lib/indexed_db/dart2js/indexed_db_dart2js.dart b/sdk_nnbd/lib/indexed_db/dart2js/indexed_db_dart2js.dart
index b664b7d..baefa2a 100644
--- a/sdk_nnbd/lib/indexed_db/dart2js/indexed_db_dart2js.dart
+++ b/sdk_nnbd/lib/indexed_db/dart2js/indexed_db_dart2js.dart
@@ -1,3 +1,5 @@
+// @dart = 2.5
+
/**
* A client-side key-value store with support for indexes.
*
diff --git a/sdk_nnbd/lib/internal/async_cast.dart b/sdk_nnbd/lib/internal/async_cast.dart
index e041ff3..9f4448d 100644
--- a/sdk_nnbd/lib/internal/async_cast.dart
+++ b/sdk_nnbd/lib/internal/async_cast.dart
@@ -2,6 +2,8 @@
// 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.5
+
part of dart._internal;
// Casting wrappers for asynchronous classes.
diff --git a/sdk_nnbd/lib/internal/cast.dart b/sdk_nnbd/lib/internal/cast.dart
index b3620f5..ae20c66 100644
--- a/sdk_nnbd/lib/internal/cast.dart
+++ b/sdk_nnbd/lib/internal/cast.dart
@@ -2,6 +2,8 @@
// 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.5
+
part of dart._internal;
// Casting wrappers for collection classes.
diff --git a/sdk_nnbd/lib/internal/internal.dart b/sdk_nnbd/lib/internal/internal.dart
index 11ee996..94fb13e 100644
--- a/sdk_nnbd/lib/internal/internal.dart
+++ b/sdk_nnbd/lib/internal/internal.dart
@@ -2,6 +2,8 @@
// 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.5
+
library dart._internal;
import 'dart:collection';
diff --git a/sdk_nnbd/lib/internal/iterable.dart b/sdk_nnbd/lib/internal/iterable.dart
index b3e8e4e..55cf780 100644
--- a/sdk_nnbd/lib/internal/iterable.dart
+++ b/sdk_nnbd/lib/internal/iterable.dart
@@ -2,6 +2,8 @@
// 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.5
+
part of dart._internal;
/**
diff --git a/sdk_nnbd/lib/internal/linked_list.dart b/sdk_nnbd/lib/internal/linked_list.dart
index 31a6c01..5c2e79a 100644
--- a/sdk_nnbd/lib/internal/linked_list.dart
+++ b/sdk_nnbd/lib/internal/linked_list.dart
@@ -2,6 +2,8 @@
// 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.5
+
part of dart._internal;
/// A rudimentary linked list.
diff --git a/sdk_nnbd/lib/internal/list.dart b/sdk_nnbd/lib/internal/list.dart
index e0ddd70..be15f36 100644
--- a/sdk_nnbd/lib/internal/list.dart
+++ b/sdk_nnbd/lib/internal/list.dart
@@ -2,6 +2,8 @@
// 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.5
+
part of dart._internal;
/**
diff --git a/sdk_nnbd/lib/internal/patch.dart b/sdk_nnbd/lib/internal/patch.dart
index 3fc9733..1d05fda 100644
--- a/sdk_nnbd/lib/internal/patch.dart
+++ b/sdk_nnbd/lib/internal/patch.dart
@@ -2,6 +2,8 @@
// 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.5
+
part of "dart:_internal";
class _Patch {
diff --git a/sdk_nnbd/lib/internal/print.dart b/sdk_nnbd/lib/internal/print.dart
index 417003b..ce5bb2a 100644
--- a/sdk_nnbd/lib/internal/print.dart
+++ b/sdk_nnbd/lib/internal/print.dart
@@ -2,6 +2,8 @@
// 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.5
+
part of dart._internal;
/**
diff --git a/sdk_nnbd/lib/internal/sort.dart b/sdk_nnbd/lib/internal/sort.dart
index d6cca2e..ad79811 100644
--- a/sdk_nnbd/lib/internal/sort.dart
+++ b/sdk_nnbd/lib/internal/sort.dart
@@ -2,6 +2,8 @@
// 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.5
+
part of dart._internal;
/**
diff --git a/sdk_nnbd/lib/internal/symbol.dart b/sdk_nnbd/lib/internal/symbol.dart
index 54d235c..d6f05d7 100644
--- a/sdk_nnbd/lib/internal/symbol.dart
+++ b/sdk_nnbd/lib/internal/symbol.dart
@@ -2,6 +2,8 @@
// 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.5
+
part of dart._internal;
/**
diff --git a/sdk_nnbd/lib/io/bytes_builder.dart b/sdk_nnbd/lib/io/bytes_builder.dart
index 9113d44..719b85a 100644
--- a/sdk_nnbd/lib/io/bytes_builder.dart
+++ b/sdk_nnbd/lib/io/bytes_builder.dart
@@ -2,6 +2,8 @@
// 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.5
+
part of dart.io;
/**
diff --git a/sdk_nnbd/lib/io/common.dart b/sdk_nnbd/lib/io/common.dart
index 77b7587..1635f56 100644
--- a/sdk_nnbd/lib/io/common.dart
+++ b/sdk_nnbd/lib/io/common.dart
@@ -2,6 +2,8 @@
// 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.5
+
part of dart.io;
// Constants used when working with native ports.
diff --git a/sdk_nnbd/lib/io/data_transformer.dart b/sdk_nnbd/lib/io/data_transformer.dart
index 33c615d..0df0b62 100644
--- a/sdk_nnbd/lib/io/data_transformer.dart
+++ b/sdk_nnbd/lib/io/data_transformer.dart
@@ -2,6 +2,8 @@
// 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.5
+
part of dart.io;
/**
diff --git a/sdk_nnbd/lib/io/directory.dart b/sdk_nnbd/lib/io/directory.dart
index 2f141cb..b655779 100644
--- a/sdk_nnbd/lib/io/directory.dart
+++ b/sdk_nnbd/lib/io/directory.dart
@@ -2,6 +2,8 @@
// 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.5
+
part of dart.io;
/**
diff --git a/sdk_nnbd/lib/io/directory_impl.dart b/sdk_nnbd/lib/io/directory_impl.dart
index faed892..9f6b907 100644
--- a/sdk_nnbd/lib/io/directory_impl.dart
+++ b/sdk_nnbd/lib/io/directory_impl.dart
@@ -2,6 +2,8 @@
// 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.5
+
part of dart.io;
class _Directory extends FileSystemEntity implements Directory {
diff --git a/sdk_nnbd/lib/io/embedder_config.dart b/sdk_nnbd/lib/io/embedder_config.dart
index cbc94f7..2248d1b 100644
--- a/sdk_nnbd/lib/io/embedder_config.dart
+++ b/sdk_nnbd/lib/io/embedder_config.dart
@@ -2,6 +2,8 @@
// 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.5
+
part of dart.io;
/// Embedder-specific, fine-grained dart:io configuration.
diff --git a/sdk_nnbd/lib/io/eventhandler.dart b/sdk_nnbd/lib/io/eventhandler.dart
index 36f54e6..90f22a6 100644
--- a/sdk_nnbd/lib/io/eventhandler.dart
+++ b/sdk_nnbd/lib/io/eventhandler.dart
@@ -2,6 +2,8 @@
// 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.5
+
part of dart.io;
class _EventHandler {
diff --git a/sdk_nnbd/lib/io/file.dart b/sdk_nnbd/lib/io/file.dart
index 861ce47..6e515ea 100644
--- a/sdk_nnbd/lib/io/file.dart
+++ b/sdk_nnbd/lib/io/file.dart
@@ -2,6 +2,8 @@
// 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.5
+
part of dart.io;
/**
diff --git a/sdk_nnbd/lib/io/file_impl.dart b/sdk_nnbd/lib/io/file_impl.dart
index 410182c..3d302cc 100644
--- a/sdk_nnbd/lib/io/file_impl.dart
+++ b/sdk_nnbd/lib/io/file_impl.dart
@@ -2,6 +2,8 @@
// 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.5
+
part of dart.io;
// Read the file in blocks of size 64k.
diff --git a/sdk_nnbd/lib/io/file_system_entity.dart b/sdk_nnbd/lib/io/file_system_entity.dart
index 16e99e6..871cfd9 100644
--- a/sdk_nnbd/lib/io/file_system_entity.dart
+++ b/sdk_nnbd/lib/io/file_system_entity.dart
@@ -2,6 +2,8 @@
// 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.5
+
part of dart.io;
/**
diff --git a/sdk_nnbd/lib/io/io.dart b/sdk_nnbd/lib/io/io.dart
index c640c5b..05df370 100644
--- a/sdk_nnbd/lib/io/io.dart
+++ b/sdk_nnbd/lib/io/io.dart
@@ -2,6 +2,8 @@
// 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.5
+
/**
* File, socket, HTTP, and other I/O support for non-web applications.
*
diff --git a/sdk_nnbd/lib/io/io_resource_info.dart b/sdk_nnbd/lib/io/io_resource_info.dart
index 3e29221..8426483 100644
--- a/sdk_nnbd/lib/io/io_resource_info.dart
+++ b/sdk_nnbd/lib/io/io_resource_info.dart
@@ -2,6 +2,8 @@
// 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.5
+
part of dart.io;
abstract class _IOResourceInfo {
diff --git a/sdk_nnbd/lib/io/io_service.dart b/sdk_nnbd/lib/io/io_service.dart
index 7af382c..b572def 100644
--- a/sdk_nnbd/lib/io/io_service.dart
+++ b/sdk_nnbd/lib/io/io_service.dart
@@ -2,6 +2,8 @@
// 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.5
+
part of dart.io;
class _IOService {
diff --git a/sdk_nnbd/lib/io/io_sink.dart b/sdk_nnbd/lib/io/io_sink.dart
index 5481265..8331dd0 100644
--- a/sdk_nnbd/lib/io/io_sink.dart
+++ b/sdk_nnbd/lib/io/io_sink.dart
@@ -2,6 +2,8 @@
// 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.5
+
part of dart.io;
/**
diff --git a/sdk_nnbd/lib/io/link.dart b/sdk_nnbd/lib/io/link.dart
index 79f8656..0ff9e9d 100644
--- a/sdk_nnbd/lib/io/link.dart
+++ b/sdk_nnbd/lib/io/link.dart
@@ -2,6 +2,8 @@
// 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.5
+
part of dart.io;
/**
diff --git a/sdk_nnbd/lib/io/namespace_impl.dart b/sdk_nnbd/lib/io/namespace_impl.dart
index 88987b6..1bac5a2 100644
--- a/sdk_nnbd/lib/io/namespace_impl.dart
+++ b/sdk_nnbd/lib/io/namespace_impl.dart
@@ -2,6 +2,8 @@
// 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.5
+
part of dart.io;
// Each Isolate may run in a different "namespace", which provides the scope in
diff --git a/sdk_nnbd/lib/io/overrides.dart b/sdk_nnbd/lib/io/overrides.dart
index 1a71881..6786ae4 100644
--- a/sdk_nnbd/lib/io/overrides.dart
+++ b/sdk_nnbd/lib/io/overrides.dart
@@ -2,6 +2,8 @@
// 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.5
+
part of dart.io;
final _ioOverridesToken = new Object();
diff --git a/sdk_nnbd/lib/io/platform.dart b/sdk_nnbd/lib/io/platform.dart
index f7c9053..c08b937 100644
--- a/sdk_nnbd/lib/io/platform.dart
+++ b/sdk_nnbd/lib/io/platform.dart
@@ -2,6 +2,8 @@
// 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.5
+
part of dart.io;
/**
diff --git a/sdk_nnbd/lib/io/platform_impl.dart b/sdk_nnbd/lib/io/platform_impl.dart
index a350119..c7b23a9 100644
--- a/sdk_nnbd/lib/io/platform_impl.dart
+++ b/sdk_nnbd/lib/io/platform_impl.dart
@@ -2,6 +2,8 @@
// 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.5
+
part of dart.io;
class _Platform {
diff --git a/sdk_nnbd/lib/io/process.dart b/sdk_nnbd/lib/io/process.dart
index 4cf78b9..b503e9e 100644
--- a/sdk_nnbd/lib/io/process.dart
+++ b/sdk_nnbd/lib/io/process.dart
@@ -2,6 +2,8 @@
// 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.5
+
part of dart.io;
// TODO(ager): The only reason for this class is that we
diff --git a/sdk_nnbd/lib/io/secure_server_socket.dart b/sdk_nnbd/lib/io/secure_server_socket.dart
index b4ca32e..4b84859 100644
--- a/sdk_nnbd/lib/io/secure_server_socket.dart
+++ b/sdk_nnbd/lib/io/secure_server_socket.dart
@@ -2,6 +2,8 @@
// 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.5
+
part of dart.io;
/**
diff --git a/sdk_nnbd/lib/io/secure_socket.dart b/sdk_nnbd/lib/io/secure_socket.dart
index a4751ef..e9b5759 100644
--- a/sdk_nnbd/lib/io/secure_socket.dart
+++ b/sdk_nnbd/lib/io/secure_socket.dart
@@ -2,6 +2,8 @@
// 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.5
+
part of dart.io;
/**
diff --git a/sdk_nnbd/lib/io/security_context.dart b/sdk_nnbd/lib/io/security_context.dart
index 96da93b..78a4569 100644
--- a/sdk_nnbd/lib/io/security_context.dart
+++ b/sdk_nnbd/lib/io/security_context.dart
@@ -2,6 +2,8 @@
// 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.5
+
part of dart.io;
/**
diff --git a/sdk_nnbd/lib/io/service_object.dart b/sdk_nnbd/lib/io/service_object.dart
index e6b1851..54db0ea 100644
--- a/sdk_nnbd/lib/io/service_object.dart
+++ b/sdk_nnbd/lib/io/service_object.dart
@@ -2,6 +2,8 @@
// 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.5
+
part of dart.io;
int _nextServiceId = 1;
diff --git a/sdk_nnbd/lib/io/socket.dart b/sdk_nnbd/lib/io/socket.dart
index df60490..c3583de 100644
--- a/sdk_nnbd/lib/io/socket.dart
+++ b/sdk_nnbd/lib/io/socket.dart
@@ -2,6 +2,8 @@
// 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.5
+
part of dart.io;
/**
diff --git a/sdk_nnbd/lib/io/stdio.dart b/sdk_nnbd/lib/io/stdio.dart
index 4086f08..c1aacba 100644
--- a/sdk_nnbd/lib/io/stdio.dart
+++ b/sdk_nnbd/lib/io/stdio.dart
@@ -2,6 +2,8 @@
// 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.5
+
part of dart.io;
const int _stdioHandleTypeTerminal = 0;
diff --git a/sdk_nnbd/lib/io/string_transformer.dart b/sdk_nnbd/lib/io/string_transformer.dart
index f31c41e..e8548d1 100644
--- a/sdk_nnbd/lib/io/string_transformer.dart
+++ b/sdk_nnbd/lib/io/string_transformer.dart
@@ -2,6 +2,8 @@
// 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.5
+
part of dart.io;
/// The current system encoding.
diff --git a/sdk_nnbd/lib/io/sync_socket.dart b/sdk_nnbd/lib/io/sync_socket.dart
index fee259d..0b7d5b1 100644
--- a/sdk_nnbd/lib/io/sync_socket.dart
+++ b/sdk_nnbd/lib/io/sync_socket.dart
@@ -2,6 +2,8 @@
// 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.5
+
part of dart.io;
/**
diff --git a/sdk_nnbd/lib/isolate/capability.dart b/sdk_nnbd/lib/isolate/capability.dart
index a51eec2..7f1daa6 100644
--- a/sdk_nnbd/lib/isolate/capability.dart
+++ b/sdk_nnbd/lib/isolate/capability.dart
@@ -2,6 +2,8 @@
// 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.5
+
part of dart.isolate;
/**
diff --git a/sdk_nnbd/lib/isolate/isolate.dart b/sdk_nnbd/lib/isolate/isolate.dart
index a697db4..11240ad 100644
--- a/sdk_nnbd/lib/isolate/isolate.dart
+++ b/sdk_nnbd/lib/isolate/isolate.dart
@@ -2,6 +2,8 @@
// 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.5
+
/**
* Concurrent programming using _isolates_:
* independent workers that are similar to threads
diff --git a/sdk_nnbd/lib/js/_js.dart b/sdk_nnbd/lib/js/_js.dart
index aef7ef9..d0d51f6 100644
--- a/sdk_nnbd/lib/js/_js.dart
+++ b/sdk_nnbd/lib/js/_js.dart
@@ -2,6 +2,8 @@
// 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.5
+
/// Helper library used by `dart:js`.
///
/// This library hides any logic that is specific to the web, and allows us to
diff --git a/sdk_nnbd/lib/js/_js_client.dart b/sdk_nnbd/lib/js/_js_client.dart
index de25540..e81821a 100644
--- a/sdk_nnbd/lib/js/_js_client.dart
+++ b/sdk_nnbd/lib/js/_js_client.dart
@@ -2,6 +2,8 @@
// 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.5
+
import 'dart:html' show Blob, Event, ImageData, Node, Window, WorkerGlobalScope;
import 'dart:indexed_db' show KeyRange;
import 'dart:_js_helper' show patch;
diff --git a/sdk_nnbd/lib/js/_js_server.dart b/sdk_nnbd/lib/js/_js_server.dart
index b941d77..8ca6a02 100644
--- a/sdk_nnbd/lib/js/_js_server.dart
+++ b/sdk_nnbd/lib/js/_js_server.dart
@@ -2,6 +2,8 @@
// 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.5
+
import 'dart:_js_helper' show patch;
@patch
diff --git a/sdk_nnbd/lib/js/dart2js/js_dart2js.dart b/sdk_nnbd/lib/js/dart2js/js_dart2js.dart
index 535227b..4155113 100644
--- a/sdk_nnbd/lib/js/dart2js/js_dart2js.dart
+++ b/sdk_nnbd/lib/js/dart2js/js_dart2js.dart
@@ -2,85 +2,88 @@
// 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.
-/**
- * Support for interoperating with JavaScript.
- *
- * This library provides access to JavaScript objects from Dart, allowing
- * Dart code to get and set properties, and call methods of JavaScript objects
- * and invoke JavaScript functions. The library takes care of converting
- * between Dart and JavaScript objects where possible, or providing proxies if
- * conversion isn't possible.
- *
- * This library does not yet make Dart objects usable from JavaScript, their
- * methods and proeprties are not accessible, though it does allow Dart
- * functions to be passed into and called from JavaScript.
- *
- * [JsObject] is the core type and represents a proxy of a JavaScript object.
- * JsObject gives access to the underlying JavaScript objects properties and
- * methods. `JsObject`s can be acquired by calls to JavaScript, or they can be
- * created from proxies to JavaScript constructors.
- *
- * The top-level getter [context] provides a [JsObject] that represents the
- * global object in JavaScript, usually `window`.
- *
- * The following example shows an alert dialog via a JavaScript call to the
- * global function `alert()`:
- *
- * import 'dart:js';
- *
- * main() => context.callMethod('alert', ['Hello from Dart!']);
- *
- * This example shows how to create a [JsObject] from a JavaScript constructor
- * and access its properties:
- *
- * import 'dart:js';
- *
- * main() {
- * var object = new JsObject(context['Object']);
- * object['greeting'] = 'Hello';
- * object['greet'] = (name) => "${object['greeting']} $name";
- * var message = object.callMethod('greet', ['JavaScript']);
- * context['console'].callMethod('log', [message]);
- * }
- *
- * ## Proxying and automatic conversion
- *
- * When setting properties on a JsObject or passing arguments to a Javascript
- * method or function, Dart objects are automatically converted or proxied to
- * JavaScript objects. When accessing JavaScript properties, or when a Dart
- * closure is invoked from JavaScript, the JavaScript objects are also
- * converted to Dart.
- *
- * Functions and closures are proxied in such a way that they are callable. A
- * Dart closure assigned to a JavaScript property is proxied by a function in
- * JavaScript. A JavaScript function accessed from Dart is proxied by a
- * [JsFunction], which has a [apply] method to invoke it.
- *
- * The following types are transferred directly and not proxied:
- *
- * * Basic types: `null`, `bool`, `num`, `String`, `DateTime`
- * * `TypedData`, including its subclasses like `Int32List`, but _not_
- * `ByteBuffer`
- * * When compiling for the web, also: `Blob`, `Event`, `ImageData`,
- * `KeyRange`, `Node`, and `Window`.
- *
- * ## Converting collections with JsObject.jsify()
- *
- * To create a JavaScript collection from a Dart collection use the
- * [JsObject.jsify] constructor, which converts Dart [Map]s and [Iterable]s
- * into JavaScript Objects and Arrays.
- *
- * The following expression creates a new JavaScript object with the properties
- * `a` and `b` defined:
- *
- * var jsMap = new JsObject.jsify({'a': 1, 'b': 2});
- *
- * This expression creates a JavaScript array:
- *
- * var jsArray = new JsObject.jsify([1, 2, 3]);
- *
- * {@category Web}
- */
+// @dart = 2.5
+
+/// Low-level support for interoperating with JavaScript.
+///
+/// You should usually use `package:js` instead of this library. For more
+/// information, see the [JS interop page](https://dart.dev/web/js-interop).
+///
+/// This library provides access to JavaScript objects from Dart, allowing
+/// Dart code to get and set properties, and call methods of JavaScript objects
+/// and invoke JavaScript functions. The library takes care of converting
+/// between Dart and JavaScript objects where possible, or providing proxies if
+/// conversion isn't possible.
+///
+/// This library does not make Dart objects usable from JavaScript, their
+/// methods and properties are not accessible, though it does allow Dart
+/// functions to be passed into and called from JavaScript.
+///
+/// [JsObject] is the core type and represents a proxy of a JavaScript object.
+/// JsObject gives access to the underlying JavaScript objects properties and
+/// methods. `JsObject`s can be acquired by calls to JavaScript, or they can be
+/// created from proxies to JavaScript constructors.
+///
+/// The top-level getter [context] provides a [JsObject] that represents the
+/// global object in JavaScript, usually `window`.
+///
+/// The following example shows an alert dialog via a JavaScript call to the
+/// global function `alert()`:
+///
+/// import 'dart:js';
+///
+/// main() => context.callMethod('alert', ['Hello from Dart!']);
+///
+/// This example shows how to create a [JsObject] from a JavaScript constructor
+/// and access its properties:
+///
+/// import 'dart:js';
+///
+/// main() {
+/// var object = JsObject(context['Object']);
+/// object['greeting'] = 'Hello';
+/// object['greet'] = (name) => "${object['greeting']} $name";
+/// var message = object.callMethod('greet', ['JavaScript']);
+/// context['console'].callMethod('log', [message]);
+/// }
+///
+/// ## Proxying and automatic conversion
+///
+/// When setting properties on a JsObject or passing arguments to a Javascript
+/// method or function, Dart objects are automatically converted or proxied to
+/// JavaScript objects. When accessing JavaScript properties, or when a Dart
+/// closure is invoked from JavaScript, the JavaScript objects are also
+/// converted to Dart.
+///
+/// Functions and closures are proxied in such a way that they are callable. A
+/// Dart closure assigned to a JavaScript property is proxied by a function in
+/// JavaScript. A JavaScript function accessed from Dart is proxied by a
+/// [JsFunction], which has a [apply] method to invoke it.
+///
+/// The following types are transferred directly and not proxied:
+///
+/// * Basic types: `null`, `bool`, `num`, `String`, `DateTime`
+/// * `TypedData`, including its subclasses like `Int32List`, but _not_
+/// `ByteBuffer`
+/// * When compiling for the web, also: `Blob`, `Event`, `ImageData`,
+/// `KeyRange`, `Node`, and `Window`.
+///
+/// ## Converting collections with JsObject.jsify()
+///
+/// To create a JavaScript collection from a Dart collection use the
+/// [JsObject.jsify] constructor, which converts Dart [Map]s and [Iterable]s
+/// into JavaScript Objects and Arrays.
+///
+/// The following expression creates a new JavaScript object with the properties
+/// `a` and `b` defined:
+///
+/// var jsMap = JsObject.jsify({'a': 1, 'b': 2});
+///
+/// This expression creates a JavaScript array:
+///
+/// var jsArray = JsObject.jsify([1, 2, 3]);
+///
+/// {@category Web}
library dart.js;
import 'dart:collection' show HashMap, ListMixin;
@@ -99,6 +102,7 @@
export 'dart:_interceptors' show JavaScriptObject;
+/// The JavaScript global object, usually `window`.
final JsObject context = _wrapToDart(JS('', 'self'));
_convertDartFunction(Function f, {bool captureThis: false}) {
@@ -121,56 +125,51 @@
if (captureThis) {
arguments = [self]..addAll(arguments);
}
- var dartArgs = new List.from(arguments.map(_convertToDart));
+ var dartArgs = List.from(arguments.map(_convertToDart));
return _convertToJS(Function.apply(callback, dartArgs));
}
-/**
- * Proxies a JavaScript object to Dart.
- *
- * The properties of the JavaScript object are accessible via the `[]` and
- * `[]=` operators. Methods are callable via [callMethod].
- */
+/// A proxy on a JavaScript object.
+///
+/// The properties of the JavaScript object are accessible via the `[]` and
+/// `[]=` operators. Methods are callable via [callMethod].
class JsObject {
// The wrapped JS object.
final dynamic _jsObject;
- // This shoud only be called from _wrapToDart
+ // This should only be called from _wrapToDart
JsObject._fromJs(this._jsObject) {
assert(_jsObject != null);
}
- /**
- * Constructs a new JavaScript object from [constructor] and returns a proxy
- * to it.
- */
+ /// Constructs a JavaScript object from its native [constructor] and returns
+ /// a proxy to it.
factory JsObject(JsFunction constructor, [List arguments]) {
- var constr = _convertToJS(constructor);
+ var ctor = _convertToJS(constructor);
if (arguments == null) {
- return _wrapToDart(JS('', 'new #()', constr));
+ return _wrapToDart(JS('', 'new #()', ctor));
}
if (JS('bool', '# instanceof Array', arguments)) {
int argumentCount = JS('int', '#.length', arguments);
switch (argumentCount) {
case 0:
- return _wrapToDart(JS('', 'new #()', constr));
+ return _wrapToDart(JS('', 'new #()', ctor));
case 1:
var arg0 = _convertToJS(JS('', '#[0]', arguments));
- return _wrapToDart(JS('', 'new #(#)', constr, arg0));
+ return _wrapToDart(JS('', 'new #(#)', ctor, arg0));
case 2:
var arg0 = _convertToJS(JS('', '#[0]', arguments));
var arg1 = _convertToJS(JS('', '#[1]', arguments));
- return _wrapToDart(JS('', 'new #(#, #)', constr, arg0, arg1));
+ return _wrapToDart(JS('', 'new #(#, #)', ctor, arg0, arg1));
case 3:
var arg0 = _convertToJS(JS('', '#[0]', arguments));
var arg1 = _convertToJS(JS('', '#[1]', arguments));
var arg2 = _convertToJS(JS('', '#[2]', arguments));
- return _wrapToDart(
- JS('', 'new #(#, #, #)', constr, arg0, arg1, arg2));
+ return _wrapToDart(JS('', 'new #(#, #, #)', ctor, arg0, arg1, arg2));
case 4:
var arg0 = _convertToJS(JS('', '#[0]', arguments));
@@ -178,7 +177,7 @@
var arg2 = _convertToJS(JS('', '#[2]', arguments));
var arg3 = _convertToJS(JS('', '#[3]', arguments));
return _wrapToDart(
- JS('', 'new #(#, #, #, #)', constr, arg0, arg1, arg2, arg3));
+ JS('', 'new #(#, #, #, #)', ctor, arg0, arg1, arg2, arg3));
}
}
@@ -190,7 +189,7 @@
// After that, use the JavaScript 'new' operator which overrides any binding
// of 'this' with the new instance.
var args = <dynamic>[null]..addAll(arguments.map(_convertToJS));
- var factoryFunction = JS('', '#.bind.apply(#, #)', constr, constr, args);
+ var factoryFunction = JS('', '#.bind.apply(#, #)', ctor, ctor, args);
// Without this line, calling factoryFunction as a constructor throws
JS('String', 'String(#)', factoryFunction);
// This could return an UnknownJavaScriptObject, or a native
@@ -201,48 +200,44 @@
// TODO(sra): Investigate:
//
- // var jsObj = JS('', 'Object.create(#.prototype)', constr);
- // JS('', '#.apply(#, #)', constr, jsObj,
+ // var jsObj = JS('', 'Object.create(#.prototype)', ctor);
+ // JS('', '#.apply(#, #)', ctor, jsObj,
// []..addAll(arguments.map(_convertToJS)));
// return _wrapToDart(jsObj);
}
- /**
- * Constructs a [JsObject] that proxies a native Dart object; _for expert use
- * only_.
- *
- * Use this constructor only if you wish to get access to JavaScript
- * properties attached to a browser host object, such as a Node or Blob, that
- * is normally automatically converted into a native Dart object.
- *
- * An exception will be thrown if [object] either is `null` or has the type
- * `bool`, `num`, or `String`.
- */
+ /// Constructs a [JsObject] that proxies a native Dart object; _for expert use
+ /// only_.
+ ///
+ /// Use this constructor only if you wish to get access to JavaScript
+ /// properties attached to a browser host object, such as a Node or Blob, that
+ /// is normally automatically converted into a native Dart object.
+ ///
+ /// An exception will be thrown if [object] either is `null` or has the type
+ /// `bool`, `num`, or `String`.
factory JsObject.fromBrowserObject(object) {
if (object is num || object is String || object is bool || object == null) {
- throw new 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));
}
- /**
- * Recursively converts a JSON-like collection of Dart objects to a
- * collection of JavaScript objects and returns a [JsObject] proxy to it.
- *
- * [object] must be a [Map] or [Iterable], the contents of which are also
- * converted. Maps and Iterables are copied to a new JavaScript object.
- * Primitives and other transferrable values are directly converted to their
- * JavaScript type, and all other objects are proxied.
- */
+ /// Recursively converts a JSON-like collection of Dart objects to a
+ /// collection of JavaScript objects and returns a [JsObject] proxy to it.
+ ///
+ /// [object] must be a [Map] or [Iterable], the contents of which are also
+ /// converted. Maps and Iterables are copied to a new JavaScript object.
+ /// Primitives and other transferable values are directly converted to their
+ /// JavaScript type, and all other objects are proxied.
factory JsObject.jsify(object) {
if ((object is! Map) && (object is! Iterable)) {
- throw new ArgumentError("object must be a Map or Iterable");
+ throw ArgumentError("object must be a Map or Iterable");
}
return _wrapToDart(_convertDataTree(object));
}
static _convertDataTree(data) {
- var _convertedObjects = new HashMap.identity();
+ var _convertedObjects = HashMap.identity();
_convert(o) {
if (_convertedObjects.containsKey(o)) {
@@ -252,7 +247,7 @@
final convertedMap = JS('=Object', '{}');
_convertedObjects[o] = convertedMap;
for (var key in o.keys) {
- JS('=Object', '#[#]=#', convertedMap, key, _convert(o[key]));
+ JS('=Object', '#[#] = #', convertedMap, key, _convert(o[key]));
}
return convertedMap;
} else if (o is Iterable) {
@@ -268,30 +263,26 @@
return _convert(data);
}
- /**
- * Returns the value associated with [property] from the proxied JavaScript
- * object.
- *
- * The type of [property] must be either [String] or [num].
- */
+ /// Returns the value associated with [property] from the proxied JavaScript
+ /// object.
+ ///
+ /// The type of [property] must be either [String] or [num].
dynamic operator [](property) {
if (property is! String && property is! num) {
- throw new ArgumentError("property is not a String or num");
+ throw ArgumentError("property is not a String or num");
}
return _convertToDart(JS('', '#[#]', _jsObject, property));
}
- /**
- * Sets the value associated with [property] on the proxied JavaScript
- * object.
- *
- * The type of [property] must be either [String] or [num].
- */
- operator []=(property, value) {
+ // Sets the value associated with [property] on the proxied JavaScript
+ // object.
+ //
+ // The type of [property] must be either [String] or [num].
+ void operator []=(property, value) {
if (property is! String && property is! num) {
- throw new ArgumentError("property is not a String or num");
+ throw ArgumentError("property is not a String or num");
}
- JS('', '#[#]=#', _jsObject, property, _convertToJS(value));
+ JS('', '#[#] = #', _jsObject, property, _convertToJS(value));
}
int get hashCode => 0;
@@ -299,43 +290,35 @@
bool operator ==(other) =>
other is JsObject && JS('bool', '# === #', _jsObject, other._jsObject);
- /**
- * Returns `true` if the JavaScript object contains the specified property
- * either directly or though its prototype chain.
- *
- * This is the equivalent of the `in` operator in JavaScript.
- */
+ /// Returns `true` if the JavaScript object contains the specified property
+ /// either directly or though its prototype chain.
+ ///
+ /// This is the equivalent of the `in` operator in JavaScript.
bool hasProperty(property) {
if (property is! String && property is! num) {
- throw new ArgumentError("property is not a String or num");
+ throw ArgumentError("property is not a String or num");
}
return JS('bool', '# in #', property, _jsObject);
}
- /**
- * Removes [property] from the JavaScript object.
- *
- * This is the equivalent of the `delete` operator in JavaScript.
- */
+ /// Removes [property] from the JavaScript object.
+ ///
+ /// This is the equivalent of the `delete` operator in JavaScript.
void deleteProperty(property) {
if (property is! String && property is! num) {
- throw new ArgumentError("property is not a String or num");
+ throw ArgumentError("property is not a String or num");
}
JS('bool', 'delete #[#]', _jsObject, property);
}
- /**
- * Returns `true` if the JavaScript object has [type] in its prototype chain.
- *
- * This is the equivalent of the `instanceof` operator in JavaScript.
- */
+ /// Returns `true` if the JavaScript object has [type] in its prototype chain.
+ ///
+ /// This is the equivalent of the `instanceof` operator in JavaScript.
bool instanceof(JsFunction type) {
return JS('bool', '# instanceof #', _jsObject, _convertToJS(type));
}
- /**
- * Returns the result of the JavaScript objects `toString` method.
- */
+ /// Returns the result of the JavaScript objects `toString` method.
String toString() {
try {
return JS('String', 'String(#)', _jsObject);
@@ -344,66 +327,47 @@
}
}
- /**
- * Calls [method] on the JavaScript object with the arguments [args] and
- * returns the result.
- *
- * The type of [method] must be either [String] or [num].
- */
+ /// Calls [method] on the JavaScript object with the arguments [args] and
+ /// returns the result.
+ ///
+ /// The type of [method] must be either [String] or [num].
dynamic callMethod(method, [List args]) {
if (method is! String && method is! num) {
- throw new ArgumentError("method is not a String or num");
+ throw ArgumentError("method is not a String or num");
}
- return _convertToDart(JS(
- '',
- '#[#].apply(#, #)',
- _jsObject,
- method,
- _jsObject,
- args == null ? null : new List.from(args.map(_convertToJS))));
+ return _convertToDart(JS('', '#[#].apply(#, #)', _jsObject, method,
+ _jsObject, args == null ? null : List.from(args.map(_convertToJS))));
}
}
-/**
- * Proxies a JavaScript Function object.
- */
+/// A proxy on a JavaScript Function object.
class JsFunction extends JsObject {
- /**
- * Returns a [JsFunction] that captures its 'this' binding and calls [f]
- * with the value of this passed as the first argument.
- */
+ /// Returns a [JsFunction] that captures its 'this' binding and calls [f]
+ /// with the value of JavaScript `this` passed as the first argument.
factory JsFunction.withThis(Function f) {
var jsFunc = _convertDartFunction(f, captureThis: true);
- return new JsFunction._fromJs(jsFunc);
+ return JsFunction._fromJs(jsFunc);
}
JsFunction._fromJs(jsObject) : super._fromJs(jsObject);
- /**
- * Invokes the JavaScript function with arguments [args]. If [thisArg] is
- * supplied it is the value of `this` for the invocation.
- */
+ /// Invokes the JavaScript function with arguments [args]. If [thisArg] is
+ /// supplied it is the value of `this` for the invocation.
dynamic apply(List args, {thisArg}) => _convertToDart(JS(
'',
'#.apply(#, #)',
_jsObject,
_convertToJS(thisArg),
- args == null ? null : new List.from(args.map(_convertToJS))));
+ args == null ? null : List.from(args.map(_convertToJS))));
}
-/**
- * A [List] that proxies a JavaScript array.
- */
+/// A [List] that proxies a JavaScript array.
class JsArray<E> extends JsObject with ListMixin<E> {
- /**
- * Creates a new JavaScript array.
- */
+ /// Creates an empty JavaScript array.
JsArray() : super._fromJs([]);
- /**
- * Creates a new JavaScript array and initializes it to the contents of
- * [other].
- */
+ /// Creates a new JavaScript array and initializes it to the contents of
+ /// [other].
JsArray.from(Iterable<E> other)
: super._fromJs([]..addAll(other.map(_convertToJS)));
@@ -411,22 +375,22 @@
_checkIndex(int index) {
if (index is int && (index < 0 || index >= length)) {
- throw new RangeError.range(index, 0, length);
+ throw RangeError.range(index, 0, length);
}
}
_checkInsertIndex(int index) {
if (index is int && (index < 0 || index >= length + 1)) {
- throw new RangeError.range(index, 0, length);
+ throw RangeError.range(index, 0, length);
}
}
static _checkRange(int start, int end, int length) {
if (start < 0 || start > length) {
- throw new RangeError.range(start, 0, length);
+ throw RangeError.range(start, 0, length);
}
if (end < start || end > length) {
- throw new RangeError.range(end, start, length);
+ throw RangeError.range(end, start, length);
}
}
@@ -457,7 +421,7 @@
if (JS('bool', 'typeof # === "number" && (# >>> 0) === #', len, len, len)) {
return JS('int', '#', len);
}
- throw new StateError('Bad JsArray length');
+ throw StateError('Bad JsArray length');
}
void set length(int length) {
@@ -473,7 +437,7 @@
void addAll(Iterable<E> iterable) {
var list = (JS('bool', '# instanceof Array', iterable))
? iterable
- : new List.from(iterable);
+ : List.from(iterable);
callMethod('push', list);
}
@@ -488,7 +452,7 @@
}
E removeLast() {
- if (length == 0) throw new RangeError(-1);
+ if (length == 0) throw RangeError(-1);
return callMethod('pop');
}
@@ -501,7 +465,7 @@
_checkRange(start, end, this.length);
int length = end - start;
if (length == 0) return;
- if (skipCount < 0) throw new ArgumentError(skipCount);
+ if (skipCount < 0) throw ArgumentError(skipCount);
var args = <dynamic>[start, length]
..addAll(iterable.skip(skipCount).take(length));
callMethod('splice', args);
@@ -612,7 +576,7 @@
return JS('TypedData', '#', o);
} else if (JS('bool', '# instanceof Date', o)) {
var ms = JS('num', '#.getTime()', o);
- return new DateTime.fromMillisecondsSinceEpoch(ms);
+ return DateTime.fromMillisecondsSinceEpoch(ms);
} else if (JS('bool', '#.constructor === #', o, _dartProxyCtor)) {
return JS('', '#.o', o);
} else {
@@ -623,14 +587,14 @@
Object _wrapToDart(o) {
if (JS('bool', 'typeof # == "function"', o)) {
return _getDartProxy(
- o, DART_CLOSURE_PROPERTY_NAME, (o) => new JsFunction._fromJs(o));
+ o, DART_CLOSURE_PROPERTY_NAME, (o) => JsFunction._fromJs(o));
}
if (JS('bool', '# instanceof Array', o)) {
return _getDartProxy(
- o, _DART_OBJECT_PROPERTY_NAME, (o) => new JsArray._fromJs(o));
+ o, _DART_OBJECT_PROPERTY_NAME, (o) => JsArray._fromJs(o));
}
return _getDartProxy(
- o, _DART_OBJECT_PROPERTY_NAME, (o) => new JsObject._fromJs(o));
+ o, _DART_OBJECT_PROPERTY_NAME, (o) => JsObject._fromJs(o));
}
Object _getDartProxy(o, String propertyName, createProxy(o)) {
@@ -649,9 +613,6 @@
return dartProxy;
}
-// ---------------------------------------------------------------------------
-// Start of methods for new style Dart-JS interop.
-
_convertDartFunctionFast(Function f) {
var existing = JS('', '#.#', f, _JS_FUNCTION_PROPERTY_NAME);
if (existing != null) return existing;
@@ -698,6 +659,17 @@
return Function.apply(callback, [self]..addAll(arguments));
}
+/// Returns a wrapper around function [f] that can be called from JavaScript
+/// using `package:js` JavaScript interop.
+///
+/// The calling conventions in Dart2Js differ from JavaScript and so, by
+/// default, it is not possible to call a Dart function directly. Wrapping with
+/// `allowInterop` creates a function that can be called from JavaScript or
+/// Dart. The semantics of the wrapped function are still more strict than
+/// JavaScript, and the function will throw if called with too many or too few
+/// arguments.
+///
+/// Calling this method repeatedly on a function will return the same result.
F allowInterop<F extends Function>(F f) {
if (JS('bool', 'typeof(#) == "function"', f)) {
// Already supports interop, just use the existing function.
@@ -707,10 +679,17 @@
}
}
+/// Returns a wrapper around function [f] that can be called from JavaScript
+/// using `package:js` JavaScript interop, passing JavaScript `this` as the first
+/// argument.
+///
+/// See [allowInterop].
+///
+/// When called from Dart, [null] will be passed as the first argument.
Function allowInteropCaptureThis(Function f) {
if (JS('bool', 'typeof(#) == "function"', f)) {
// Behavior when the function is already a JS function is unspecified.
- throw new ArgumentError(
+ throw ArgumentError(
"Function is already a JS function so cannot capture this.");
return f;
} else {
diff --git a/sdk_nnbd/lib/js_util/dart2js/js_util_dart2js.dart b/sdk_nnbd/lib/js_util/dart2js/js_util_dart2js.dart
index 6b605fb..558bdaa 100644
--- a/sdk_nnbd/lib/js_util/dart2js/js_util_dart2js.dart
+++ b/sdk_nnbd/lib/js_util/dart2js/js_util_dart2js.dart
@@ -2,6 +2,8 @@
// 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.5
+
/// Utility methods to efficiently manipulate typed JSInterop objects in cases
/// where the name to call is not known at runtime. You should only use these
/// methods when the same effect cannot be achieved with @JS annotations.
diff --git a/sdk_nnbd/lib/libraries.json b/sdk_nnbd/lib/libraries.json
index 663991f..a9276e2 100644
--- a/sdk_nnbd/lib/libraries.json
+++ b/sdk_nnbd/lib/libraries.json
@@ -1,153 +1,153 @@
{
"comment:0": "NOTE: THIS FILE IS GENERATED. DO NOT EDIT.",
- "comment:1": "Instead modify 'sdk/lib/libraries.yaml' and follow the instructions therein.",
+ "comment:1": "Instead modify 'sdk_nnbd/lib/libraries.yaml' and follow the instructions therein.",
"vm": {
"libraries": {
"_builtin": {
- "uri": "../../runtime/bin/builtin.dart"
+ "uri": "_internal/vm/bin/builtin.dart"
},
"cli": {
"patches": [
- "../../runtime/bin/cli_patch.dart"
+ "_internal/vm/bin/cli_patch.dart"
],
"uri": "cli/cli.dart"
},
"core": {
"patches": [
- "../../runtime/lib/core_patch.dart",
- "../../runtime/lib/array.dart",
- "../../runtime/lib/array_patch.dart",
- "../../runtime/lib/bigint_patch.dart",
- "../../runtime/lib/bool_patch.dart",
- "../../runtime/lib/date_patch.dart",
- "../../runtime/lib/double.dart",
- "../../runtime/lib/double_patch.dart",
- "../../runtime/lib/errors_patch.dart",
- "../../runtime/lib/expando_patch.dart",
- "../../runtime/lib/function.dart",
- "../../runtime/lib/function_patch.dart",
- "../../runtime/lib/growable_array.dart",
- "../../runtime/lib/identical_patch.dart",
- "../../runtime/lib/immutable_map.dart",
- "../../runtime/lib/integers.dart",
- "../../runtime/lib/integers_patch.dart",
- "../../runtime/lib/invocation_mirror_patch.dart",
- "../../runtime/lib/lib_prefix.dart",
- "../../runtime/lib/map_patch.dart",
- "../../runtime/lib/null_patch.dart",
- "../../runtime/lib/object_patch.dart",
- "../../runtime/lib/regexp_patch.dart",
- "../../runtime/lib/stacktrace.dart",
- "../../runtime/lib/stopwatch_patch.dart",
- "../../runtime/lib/string_buffer_patch.dart",
- "../../runtime/lib/string_patch.dart",
- "../../runtime/lib/type_patch.dart",
- "../../runtime/lib/uri_patch.dart",
- "../../runtime/lib/weak_property.dart"
+ "_internal/vm/lib/core_patch.dart",
+ "_internal/vm/lib/array.dart",
+ "_internal/vm/lib/array_patch.dart",
+ "_internal/vm/lib/bigint_patch.dart",
+ "_internal/vm/lib/bool_patch.dart",
+ "_internal/vm/lib/date_patch.dart",
+ "_internal/vm/lib/double.dart",
+ "_internal/vm/lib/double_patch.dart",
+ "_internal/vm/lib/errors_patch.dart",
+ "_internal/vm/lib/expando_patch.dart",
+ "_internal/vm/lib/function.dart",
+ "_internal/vm/lib/function_patch.dart",
+ "_internal/vm/lib/growable_array.dart",
+ "_internal/vm/lib/identical_patch.dart",
+ "_internal/vm/lib/immutable_map.dart",
+ "_internal/vm/lib/integers.dart",
+ "_internal/vm/lib/integers_patch.dart",
+ "_internal/vm/lib/invocation_mirror_patch.dart",
+ "_internal/vm/lib/lib_prefix.dart",
+ "_internal/vm/lib/map_patch.dart",
+ "_internal/vm/lib/null_patch.dart",
+ "_internal/vm/lib/object_patch.dart",
+ "_internal/vm/lib/regexp_patch.dart",
+ "_internal/vm/lib/stacktrace.dart",
+ "_internal/vm/lib/stopwatch_patch.dart",
+ "_internal/vm/lib/string_buffer_patch.dart",
+ "_internal/vm/lib/string_patch.dart",
+ "_internal/vm/lib/type_patch.dart",
+ "_internal/vm/lib/uri_patch.dart",
+ "_internal/vm/lib/weak_property.dart"
],
"uri": "core/core.dart"
},
"async": {
"patches": [
- "../../runtime/lib/async_patch.dart",
- "../../runtime/lib/deferred_load_patch.dart",
- "../../runtime/lib/schedule_microtask_patch.dart",
- "../../runtime/lib/timer_patch.dart"
+ "_internal/vm/lib/async_patch.dart",
+ "_internal/vm/lib/deferred_load_patch.dart",
+ "_internal/vm/lib/schedule_microtask_patch.dart",
+ "_internal/vm/lib/timer_patch.dart"
],
"uri": "async/async.dart"
},
"collection": {
"patches": [
- "../../runtime/lib/collection_patch.dart",
- "../../runtime/lib/compact_hash.dart"
+ "_internal/vm/lib/collection_patch.dart",
+ "_internal/vm/lib/compact_hash.dart"
],
"uri": "collection/collection.dart"
},
"ffi": {
"patches": [
- "../../runtime/lib/ffi_patch.dart",
- "../../runtime/lib/ffi_dynamic_library_patch.dart",
- "../../runtime/lib/ffi_native_type_patch.dart"
+ "_internal/vm/lib/ffi_patch.dart",
+ "_internal/vm/lib/ffi_dynamic_library_patch.dart",
+ "_internal/vm/lib/ffi_native_type_patch.dart"
],
"uri": "ffi/ffi.dart"
},
- "wasm": {
- "patches": [
- "../../runtime/lib/wasm_patch.dart"
- ],
- "uri": "wasm/wasm.dart"
- },
"typed_data": {
- "patches": "../../runtime/lib/typed_data_patch.dart",
+ "patches": "_internal/vm/lib/typed_data_patch.dart",
"uri": "typed_data/typed_data.dart"
},
"nativewrappers": {
"uri": "html/dartium/nativewrappers.dart"
},
+ "mirrors": {
+ "patches": [
+ "_internal/vm/lib/mirrors_patch.dart",
+ "_internal/vm/lib/mirrors_impl.dart",
+ "_internal/vm/lib/mirror_reference.dart"
+ ],
+ "uri": "mirrors/mirrors.dart"
+ },
"developer": {
"patches": [
- "../../runtime/lib/developer.dart",
- "../../runtime/lib/profiler.dart",
- "../../runtime/lib/timeline.dart"
+ "_internal/vm/lib/developer.dart",
+ "_internal/vm/lib/profiler.dart",
+ "_internal/vm/lib/timeline.dart"
],
"uri": "developer/developer.dart"
},
"isolate": {
"patches": [
- "../../runtime/lib/isolate_patch.dart",
- "../../runtime/lib/timer_impl.dart"
+ "_internal/vm/lib/isolate_patch.dart",
+ "_internal/vm/lib/timer_impl.dart"
],
"uri": "isolate/isolate.dart"
},
- "mirrors": {
- "patches": [
- "../../runtime/lib/mirrors_patch.dart",
- "../../runtime/lib/mirrors_impl.dart",
- "../../runtime/lib/mirror_reference.dart"
- ],
- "uri": "mirrors/mirrors.dart"
- },
"_vmservice": {
"uri": "vmservice/vmservice.dart"
},
+ "wasm": {
+ "patches": [
+ "_internal/vm/lib/wasm_patch.dart"
+ ],
+ "uri": "wasm/wasm.dart"
+ },
"io": {
"patches": [
- "../../runtime/bin/common_patch.dart",
- "../../runtime/bin/directory_patch.dart",
- "../../runtime/bin/eventhandler_patch.dart",
- "../../runtime/bin/file_patch.dart",
- "../../runtime/bin/file_system_entity_patch.dart",
- "../../runtime/bin/filter_patch.dart",
- "../../runtime/bin/io_service_patch.dart",
- "../../runtime/bin/namespace_patch.dart",
- "../../runtime/bin/platform_patch.dart",
- "../../runtime/bin/process_patch.dart",
- "../../runtime/bin/socket_patch.dart",
- "../../runtime/bin/stdio_patch.dart",
- "../../runtime/bin/secure_socket_patch.dart",
- "../../runtime/bin/sync_socket_patch.dart"
+ "_internal/vm/bin/common_patch.dart",
+ "_internal/vm/bin/directory_patch.dart",
+ "_internal/vm/bin/eventhandler_patch.dart",
+ "_internal/vm/bin/file_patch.dart",
+ "_internal/vm/bin/file_system_entity_patch.dart",
+ "_internal/vm/bin/filter_patch.dart",
+ "_internal/vm/bin/io_service_patch.dart",
+ "_internal/vm/bin/namespace_patch.dart",
+ "_internal/vm/bin/platform_patch.dart",
+ "_internal/vm/bin/process_patch.dart",
+ "_internal/vm/bin/socket_patch.dart",
+ "_internal/vm/bin/stdio_patch.dart",
+ "_internal/vm/bin/secure_socket_patch.dart",
+ "_internal/vm/bin/sync_socket_patch.dart"
],
"uri": "io/io.dart"
},
"_internal": {
"patches": [
- "../../runtime/lib/internal_patch.dart",
- "../../runtime/lib/class_id_fasta.dart",
- "../../runtime/lib/print_patch.dart",
- "../../runtime/lib/symbol_patch.dart",
+ "_internal/vm/lib/internal_patch.dart",
+ "_internal/vm/lib/class_id_fasta.dart",
+ "_internal/vm/lib/print_patch.dart",
+ "_internal/vm/lib/symbol_patch.dart",
"internal/patch.dart"
],
"uri": "internal/internal.dart"
},
"convert": {
- "patches": "../../runtime/lib/convert_patch.dart",
+ "patches": "_internal/vm/lib/convert_patch.dart",
"uri": "convert/convert.dart"
},
"profiler": {
"uri": "profiler/profiler.dart"
},
"math": {
- "patches": "../../runtime/lib/math_patch.dart",
+ "patches": "_internal/vm/lib/math_patch.dart",
"uri": "math/math.dart"
},
"_http": {
@@ -487,4 +487,4 @@
}
}
}
-}
+}
\ No newline at end of file
diff --git a/sdk_nnbd/lib/libraries.yaml b/sdk_nnbd/lib/libraries.yaml
index f33a42b..8d56624 100644
--- a/sdk_nnbd/lib/libraries.yaml
+++ b/sdk_nnbd/lib/libraries.yaml
@@ -5,7 +5,7 @@
# Note: if you edit this file, you must also edit libraries.json in this
# directory:
#
-# python ./tools/yaml2json.py sdk/lib/libraries.yaml sdk/lib/libraries.json
+# python ./tools/yaml2json.py sdk_nnbd/lib/libraries.yaml sdk_nnbd/lib/libraries.json
#
# We currently have several different files that needs to be updated when
# changing libraries, sources, and patch files. See
@@ -17,87 +17,87 @@
vm:
libraries:
_builtin:
- uri: "../../runtime/bin/builtin.dart"
+ uri: "_internal/vm/bin/builtin.dart"
_internal:
uri: "internal/internal.dart"
patches:
- - "../../runtime/lib/internal_patch.dart"
- - "../../runtime/lib/class_id_fasta.dart"
- - "../../runtime/lib/print_patch.dart"
- - "../../runtime/lib/symbol_patch.dart"
+ - "_internal/vm/lib/internal_patch.dart"
+ - "_internal/vm/lib/class_id_fasta.dart"
+ - "_internal/vm/lib/print_patch.dart"
+ - "_internal/vm/lib/symbol_patch.dart"
- "internal/patch.dart"
async:
uri: "async/async.dart"
patches:
- - "../../runtime/lib/async_patch.dart"
- - "../../runtime/lib/deferred_load_patch.dart"
- - "../../runtime/lib/schedule_microtask_patch.dart"
- - "../../runtime/lib/timer_patch.dart"
+ - "_internal/vm/lib/async_patch.dart"
+ - "_internal/vm/lib/deferred_load_patch.dart"
+ - "_internal/vm/lib/schedule_microtask_patch.dart"
+ - "_internal/vm/lib/timer_patch.dart"
collection:
uri: "collection/collection.dart"
patches:
- - "../../runtime/lib/collection_patch.dart"
- - "../../runtime/lib/compact_hash.dart"
+ - "_internal/vm/lib/collection_patch.dart"
+ - "_internal/vm/lib/compact_hash.dart"
convert:
uri: "convert/convert.dart"
- patches: "../../runtime/lib/convert_patch.dart"
+ patches: "_internal/vm/lib/convert_patch.dart"
core:
uri: "core/core.dart"
patches:
- - "../../runtime/lib/core_patch.dart"
- - "../../runtime/lib/array.dart"
- - "../../runtime/lib/array_patch.dart"
- - "../../runtime/lib/bigint_patch.dart"
- - "../../runtime/lib/bool_patch.dart"
- - "../../runtime/lib/date_patch.dart"
- - "../../runtime/lib/double.dart"
- - "../../runtime/lib/double_patch.dart"
- - "../../runtime/lib/errors_patch.dart"
- - "../../runtime/lib/expando_patch.dart"
- - "../../runtime/lib/function.dart"
- - "../../runtime/lib/function_patch.dart"
- - "../../runtime/lib/growable_array.dart"
- - "../../runtime/lib/identical_patch.dart"
- - "../../runtime/lib/immutable_map.dart"
- - "../../runtime/lib/integers.dart"
- - "../../runtime/lib/integers_patch.dart"
- - "../../runtime/lib/invocation_mirror_patch.dart"
- - "../../runtime/lib/lib_prefix.dart"
- - "../../runtime/lib/map_patch.dart"
- - "../../runtime/lib/null_patch.dart"
- - "../../runtime/lib/object_patch.dart"
- - "../../runtime/lib/regexp_patch.dart"
- - "../../runtime/lib/stacktrace.dart"
- - "../../runtime/lib/stopwatch_patch.dart"
- - "../../runtime/lib/string_buffer_patch.dart"
- - "../../runtime/lib/string_patch.dart"
- - "../../runtime/lib/type_patch.dart"
- - "../../runtime/lib/uri_patch.dart"
- - "../../runtime/lib/weak_property.dart"
+ - "_internal/vm/lib/core_patch.dart"
+ - "_internal/vm/lib/array.dart"
+ - "_internal/vm/lib/array_patch.dart"
+ - "_internal/vm/lib/bigint_patch.dart"
+ - "_internal/vm/lib/bool_patch.dart"
+ - "_internal/vm/lib/date_patch.dart"
+ - "_internal/vm/lib/double.dart"
+ - "_internal/vm/lib/double_patch.dart"
+ - "_internal/vm/lib/errors_patch.dart"
+ - "_internal/vm/lib/expando_patch.dart"
+ - "_internal/vm/lib/function.dart"
+ - "_internal/vm/lib/function_patch.dart"
+ - "_internal/vm/lib/growable_array.dart"
+ - "_internal/vm/lib/identical_patch.dart"
+ - "_internal/vm/lib/immutable_map.dart"
+ - "_internal/vm/lib/integers.dart"
+ - "_internal/vm/lib/integers_patch.dart"
+ - "_internal/vm/lib/invocation_mirror_patch.dart"
+ - "_internal/vm/lib/lib_prefix.dart"
+ - "_internal/vm/lib/map_patch.dart"
+ - "_internal/vm/lib/null_patch.dart"
+ - "_internal/vm/lib/object_patch.dart"
+ - "_internal/vm/lib/regexp_patch.dart"
+ - "_internal/vm/lib/stacktrace.dart"
+ - "_internal/vm/lib/stopwatch_patch.dart"
+ - "_internal/vm/lib/string_buffer_patch.dart"
+ - "_internal/vm/lib/string_patch.dart"
+ - "_internal/vm/lib/type_patch.dart"
+ - "_internal/vm/lib/uri_patch.dart"
+ - "_internal/vm/lib/weak_property.dart"
developer:
uri: "developer/developer.dart"
patches:
- - "../../runtime/lib/developer.dart"
- - "../../runtime/lib/profiler.dart"
- - "../../runtime/lib/timeline.dart"
+ - "_internal/vm/lib/developer.dart"
+ - "_internal/vm/lib/profiler.dart"
+ - "_internal/vm/lib/timeline.dart"
ffi:
uri: "ffi/ffi.dart"
patches:
- - "../../runtime/lib/ffi_patch.dart"
- - "../../runtime/lib/ffi_dynamic_library_patch.dart"
- - "../../runtime/lib/ffi_native_type_patch.dart"
+ - "_internal/vm/lib/ffi_patch.dart"
+ - "_internal/vm/lib/ffi_dynamic_library_patch.dart"
+ - "_internal/vm/lib/ffi_native_type_patch.dart"
wasm:
uri: "wasm/wasm.dart"
patches:
- - "../../runtime/lib/wasm_patch.dart"
+ - "_internal/vm/lib/wasm_patch.dart"
_http:
uri: "_http/http.dart"
@@ -105,37 +105,37 @@
io:
uri: "io/io.dart"
patches:
- - "../../runtime/bin/common_patch.dart"
- - "../../runtime/bin/directory_patch.dart"
- - "../../runtime/bin/eventhandler_patch.dart"
- - "../../runtime/bin/file_patch.dart"
- - "../../runtime/bin/file_system_entity_patch.dart"
- - "../../runtime/bin/filter_patch.dart"
- - "../../runtime/bin/io_service_patch.dart"
- - "../../runtime/bin/namespace_patch.dart"
- - "../../runtime/bin/platform_patch.dart"
- - "../../runtime/bin/process_patch.dart"
- - "../../runtime/bin/socket_patch.dart"
- - "../../runtime/bin/stdio_patch.dart"
- - "../../runtime/bin/secure_socket_patch.dart"
- - "../../runtime/bin/sync_socket_patch.dart"
+ - "_internal/vm/bin/common_patch.dart"
+ - "_internal/vm/bin/directory_patch.dart"
+ - "_internal/vm/bin/eventhandler_patch.dart"
+ - "_internal/vm/bin/file_patch.dart"
+ - "_internal/vm/bin/file_system_entity_patch.dart"
+ - "_internal/vm/bin/filter_patch.dart"
+ - "_internal/vm/bin/io_service_patch.dart"
+ - "_internal/vm/bin/namespace_patch.dart"
+ - "_internal/vm/bin/platform_patch.dart"
+ - "_internal/vm/bin/process_patch.dart"
+ - "_internal/vm/bin/socket_patch.dart"
+ - "_internal/vm/bin/stdio_patch.dart"
+ - "_internal/vm/bin/secure_socket_patch.dart"
+ - "_internal/vm/bin/sync_socket_patch.dart"
isolate:
uri: "isolate/isolate.dart"
patches:
- - "../../runtime/lib/isolate_patch.dart"
- - "../../runtime/lib/timer_impl.dart"
+ - "_internal/vm/lib/isolate_patch.dart"
+ - "_internal/vm/lib/timer_impl.dart"
math:
uri: "math/math.dart"
- patches: "../../runtime/lib/math_patch.dart"
+ patches: "_internal/vm/lib/math_patch.dart"
mirrors:
uri: "mirrors/mirrors.dart"
patches:
- - "../../runtime/lib/mirrors_patch.dart"
- - "../../runtime/lib/mirrors_impl.dart"
- - "../../runtime/lib/mirror_reference.dart"
+ - "_internal/vm/lib/mirrors_patch.dart"
+ - "_internal/vm/lib/mirrors_impl.dart"
+ - "_internal/vm/lib/mirror_reference.dart"
nativewrappers:
uri: "html/dartium/nativewrappers.dart"
@@ -146,11 +146,11 @@
cli:
uri: "cli/cli.dart"
patches:
- - "../../runtime/bin/cli_patch.dart"
+ - "_internal/vm/bin/cli_patch.dart"
typed_data:
uri: "typed_data/typed_data.dart"
- patches: "../../runtime/lib/typed_data_patch.dart"
+ patches: "_internal/vm/lib/typed_data_patch.dart"
_vmservice:
uri: "vmservice/vmservice.dart"
diff --git a/sdk_nnbd/lib/math/jenkins_smi_hash.dart b/sdk_nnbd/lib/math/jenkins_smi_hash.dart
index d756b37..0cc69b0 100644
--- a/sdk_nnbd/lib/math/jenkins_smi_hash.dart
+++ b/sdk_nnbd/lib/math/jenkins_smi_hash.dart
@@ -1,6 +1,8 @@
// 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
// BSD-style license that can be found in the LICENSE file.
+// @dart = 2.5
+
part of dart.math;
/// This is the [Jenkins hash function][1] but using masking to keep
diff --git a/sdk_nnbd/lib/math/math.dart b/sdk_nnbd/lib/math/math.dart
index 548fb59..16583df 100644
--- a/sdk_nnbd/lib/math/math.dart
+++ b/sdk_nnbd/lib/math/math.dart
@@ -2,6 +2,8 @@
// 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.5
+
/// Mathematical constants and functions, plus a random number generator.
///
/// To use this library in your code:
diff --git a/sdk_nnbd/lib/math/point.dart b/sdk_nnbd/lib/math/point.dart
index 1015e7b..a7c91f6 100644
--- a/sdk_nnbd/lib/math/point.dart
+++ b/sdk_nnbd/lib/math/point.dart
@@ -1,6 +1,8 @@
// 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
// BSD-style license that can be found in the LICENSE file.
+// @dart = 2.5
+
part of dart.math;
/// A utility class for representing two-dimensional positions.
diff --git a/sdk_nnbd/lib/math/random.dart b/sdk_nnbd/lib/math/random.dart
index 80e588b..de7d36c 100644
--- a/sdk_nnbd/lib/math/random.dart
+++ b/sdk_nnbd/lib/math/random.dart
@@ -2,6 +2,8 @@
// 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.5
+
part of dart.math;
/// A generator of random bool, int, or double values.
diff --git a/sdk_nnbd/lib/math/rectangle.dart b/sdk_nnbd/lib/math/rectangle.dart
index 6e72036..0c14d42 100644
--- a/sdk_nnbd/lib/math/rectangle.dart
+++ b/sdk_nnbd/lib/math/rectangle.dart
@@ -1,6 +1,8 @@
// 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
// BSD-style license that can be found in the LICENSE file.
+// @dart = 2.5
+
part of dart.math;
/// A base class for representing two-dimensional axis-aligned rectangles.
diff --git a/sdk_nnbd/lib/mirrors/mirrors.dart b/sdk_nnbd/lib/mirrors/mirrors.dart
index 64f88a2..ee68e01 100644
--- a/sdk_nnbd/lib/mirrors/mirrors.dart
+++ b/sdk_nnbd/lib/mirrors/mirrors.dart
@@ -2,6 +2,8 @@
// 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.5
+
// For the purposes of the mirrors library, we adopt a naming
// convention with respect to getters and setters. Specifically, for
// some variable or field...
diff --git a/sdk_nnbd/lib/profiler/profiler.dart b/sdk_nnbd/lib/profiler/profiler.dart
deleted file mode 100644
index 1b96dfe..0000000
--- a/sdk_nnbd/lib/profiler/profiler.dart
+++ /dev/null
@@ -1,10 +0,0 @@
-// Copyright (c) 2014, 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.
-
-/// Please see 'dart:developer'.
-@Deprecated("Dart SDK 1.12")
-library dart.profiler;
-
-export 'dart:developer'
- show getCurrentTag, Counter, Gauge, Metric, Metrics, UserTag;
diff --git a/sdk_nnbd/lib/profiler/profiler_sources.gni b/sdk_nnbd/lib/profiler/profiler_sources.gni
deleted file mode 100644
index adbf447..0000000
--- a/sdk_nnbd/lib/profiler/profiler_sources.gni
+++ /dev/null
@@ -1,8 +0,0 @@
-# Copyright (c) 2017, 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.
-
-profiler_sdk_sources = [
- "profiler.dart",
- # The above file needs to be first if additional parts are added to the lib.
-]
diff --git a/sdk_nnbd/lib/svg/dart2js/svg_dart2js.dart b/sdk_nnbd/lib/svg/dart2js/svg_dart2js.dart
index 7966fd7..bdf30e3 100644
--- a/sdk_nnbd/lib/svg/dart2js/svg_dart2js.dart
+++ b/sdk_nnbd/lib/svg/dart2js/svg_dart2js.dart
@@ -1,3 +1,5 @@
+// @dart = 2.5
+
/**
* Scalable Vector Graphics:
* Two-dimensional vector graphics with support for events and animation.
diff --git a/sdk_nnbd/lib/typed_data/typed_data.dart b/sdk_nnbd/lib/typed_data/typed_data.dart
index 89c9496..a5e37bd 100644
--- a/sdk_nnbd/lib/typed_data/typed_data.dart
+++ b/sdk_nnbd/lib/typed_data/typed_data.dart
@@ -2,6 +2,8 @@
// 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.5
+
/// Lists that efficiently handle fixed sized data
/// (for example, unsigned 8 byte integers) and SIMD numeric types.
///
diff --git a/sdk_nnbd/lib/typed_data/unmodifiable_typed_data.dart b/sdk_nnbd/lib/typed_data/unmodifiable_typed_data.dart
index 3549041..f3def8f 100644
--- a/sdk_nnbd/lib/typed_data/unmodifiable_typed_data.dart
+++ b/sdk_nnbd/lib/typed_data/unmodifiable_typed_data.dart
@@ -2,6 +2,8 @@
// 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.5
+
part of dart.typed_data;
/**
diff --git a/sdk_nnbd/lib/vmservice/asset.dart b/sdk_nnbd/lib/vmservice/asset.dart
index d5772e2..a6b3927 100644
--- a/sdk_nnbd/lib/vmservice/asset.dart
+++ b/sdk_nnbd/lib/vmservice/asset.dart
@@ -2,6 +2,8 @@
// 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.5
+
part of dart._vmservice;
class Asset {
diff --git a/sdk_nnbd/lib/vmservice/client.dart b/sdk_nnbd/lib/vmservice/client.dart
index efe33c0..70d978c 100644
--- a/sdk_nnbd/lib/vmservice/client.dart
+++ b/sdk_nnbd/lib/vmservice/client.dart
@@ -2,6 +2,8 @@
// 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.5
+
part of dart._vmservice;
typedef void ClientServiceHandle(Message response);
diff --git a/sdk_nnbd/lib/vmservice/constants.dart b/sdk_nnbd/lib/vmservice/constants.dart
index 914576b..5edd3ef 100644
--- a/sdk_nnbd/lib/vmservice/constants.dart
+++ b/sdk_nnbd/lib/vmservice/constants.dart
@@ -2,6 +2,8 @@
// 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.5
+
part of dart._vmservice;
// These must be kept in sync with runtime/vm/service.cc.
diff --git a/sdk_nnbd/lib/vmservice/devfs.dart b/sdk_nnbd/lib/vmservice/devfs.dart
index 20e0573..d5ca40f 100644
--- a/sdk_nnbd/lib/vmservice/devfs.dart
+++ b/sdk_nnbd/lib/vmservice/devfs.dart
@@ -2,6 +2,8 @@
// 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.5
+
part of dart._vmservice;
String _encodeDevFSDisabledError(Message message) {
diff --git a/sdk_nnbd/lib/vmservice/message.dart b/sdk_nnbd/lib/vmservice/message.dart
index 9e4375a..efe0f06 100644
--- a/sdk_nnbd/lib/vmservice/message.dart
+++ b/sdk_nnbd/lib/vmservice/message.dart
@@ -2,6 +2,8 @@
// 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.5
+
part of dart._vmservice;
enum MessageType { Request, Notification, Response }
diff --git a/sdk_nnbd/lib/vmservice/message_router.dart b/sdk_nnbd/lib/vmservice/message_router.dart
index 4c1b307..6c6c746 100644
--- a/sdk_nnbd/lib/vmservice/message_router.dart
+++ b/sdk_nnbd/lib/vmservice/message_router.dart
@@ -2,6 +2,8 @@
// 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.5
+
part of dart._vmservice;
abstract class MessageRouter {
diff --git a/sdk_nnbd/lib/vmservice/named_lookup.dart b/sdk_nnbd/lib/vmservice/named_lookup.dart
index 7087c94..a53c57a 100644
--- a/sdk_nnbd/lib/vmservice/named_lookup.dart
+++ b/sdk_nnbd/lib/vmservice/named_lookup.dart
@@ -2,6 +2,8 @@
// 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.5
+
part of dart._vmservice;
/// Set like containes which automatically generated String ids for its items
diff --git a/sdk_nnbd/lib/vmservice/running_isolate.dart b/sdk_nnbd/lib/vmservice/running_isolate.dart
index 8a6dd36..cfe9be9 100644
--- a/sdk_nnbd/lib/vmservice/running_isolate.dart
+++ b/sdk_nnbd/lib/vmservice/running_isolate.dart
@@ -2,6 +2,8 @@
// 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.5
+
part of dart._vmservice;
class RunningIsolate implements MessageRouter {
diff --git a/sdk_nnbd/lib/vmservice/running_isolates.dart b/sdk_nnbd/lib/vmservice/running_isolates.dart
index 24b155c..e925e03 100644
--- a/sdk_nnbd/lib/vmservice/running_isolates.dart
+++ b/sdk_nnbd/lib/vmservice/running_isolates.dart
@@ -2,6 +2,8 @@
// 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.5
+
part of dart._vmservice;
class RunningIsolates implements MessageRouter {
diff --git a/sdk_nnbd/lib/vmservice/vmservice.dart b/sdk_nnbd/lib/vmservice/vmservice.dart
index 0c340ee..c1540ab 100644
--- a/sdk_nnbd/lib/vmservice/vmservice.dart
+++ b/sdk_nnbd/lib/vmservice/vmservice.dart
@@ -2,6 +2,8 @@
// 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.5
+
library dart._vmservice;
import 'dart:async';
diff --git a/sdk_nnbd/lib/wasm/wasm.dart b/sdk_nnbd/lib/wasm/wasm.dart
index edf0887..631dc22 100644
--- a/sdk_nnbd/lib/wasm/wasm.dart
+++ b/sdk_nnbd/lib/wasm/wasm.dart
@@ -2,12 +2,82 @@
// 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.5
+
/// {@category VM}
/// {@nodoc}
library dart.wasm;
-int callWasm(String name, int arg) {
- return _callWasm(name, arg);
+import 'dart:typed_data';
+
+// Represents the WASM 32-bit int type.
+class Int32 {}
+
+// Represents the WASM 64-bit int type.
+class Int64 {}
+
+// Represents the WASM 32-bit float type.
+class Float {}
+
+// Represents the WASM 64-bit float type.
+class Double {}
+
+// Represents the return type of a void function in WASM.
+class Void {}
+
+// WasmModule is a compiled module that can be instantiated.
+abstract class WasmModule {
+ // Compile a module.
+ external factory WasmModule(Uint8List data);
+
+ // Instantiate the module with the given imports.
+ WasmInstance instantiate(WasmImports imports);
}
-external int _callWasm(String name, int arg);
+// WasmImports holds all the imports for a WasmInstance.
+abstract class WasmImports {
+ // Create an imports object.
+ external factory WasmImports(String moduleName);
+
+ // Add a global variable to the imports.
+ void addGlobal<T>(String name, num value, bool mutable);
+
+ // Add a memory to the imports.
+ void addMemory(String name, WasmMemory memory);
+}
+
+// WasmMemory is a sandbox for a WasmInstance to run in.
+abstract class WasmMemory {
+ // Create a new memory with the given number of initial pages, and optional
+ // maximum number of pages.
+ external factory WasmMemory(int initialPages, [int maxPages]);
+
+ // The WASM spec defines the page size as 64KiB.
+ static const int kPageSizeInBytes = 64 * 1024;
+
+ // Returns the length of the memory in pages.
+ int get lengthInPages;
+
+ // Returns the length of the memory in bytes.
+ int get lengthInBytes;
+
+ // Returns the byte at the given index.
+ int operator [](int index);
+
+ // Sets the byte at the iven index to value.
+ void operator []=(int index, int value);
+
+ // Grow the memory by deltaPages. Returns the number of pages before resizing.
+ int grow(int deltaPages);
+}
+
+// WasmInstance is an instantiated WasmModule.
+abstract class WasmInstance {
+ // Find an exported function with the given signature.
+ WasmFunction<T> lookupFunction<T extends Function>(String name);
+}
+
+// WasmFunction is a callable function in a WasmInstance.
+abstract class WasmFunction<T extends Function> {
+ num call(List<num> args);
+}
diff --git a/sdk_nnbd/lib/web_audio/dart2js/web_audio_dart2js.dart b/sdk_nnbd/lib/web_audio/dart2js/web_audio_dart2js.dart
index ef2ee67..95a7805 100644
--- a/sdk_nnbd/lib/web_audio/dart2js/web_audio_dart2js.dart
+++ b/sdk_nnbd/lib/web_audio/dart2js/web_audio_dart2js.dart
@@ -1,3 +1,5 @@
+// @dart = 2.5
+
/**
* High-fidelity audio programming in the browser.
*
diff --git a/sdk_nnbd/lib/web_gl/dart2js/web_gl_dart2js.dart b/sdk_nnbd/lib/web_gl/dart2js/web_gl_dart2js.dart
index 80e36b1..b7cf4b8 100644
--- a/sdk_nnbd/lib/web_gl/dart2js/web_gl_dart2js.dart
+++ b/sdk_nnbd/lib/web_gl/dart2js/web_gl_dart2js.dart
@@ -1,3 +1,5 @@
+// @dart = 2.5
+
/**
* 3D programming in the browser.
*
diff --git a/sdk_nnbd/lib/web_sql/dart2js/web_sql_dart2js.dart b/sdk_nnbd/lib/web_sql/dart2js/web_sql_dart2js.dart
index 0f703f9..d7a857a 100644
--- a/sdk_nnbd/lib/web_sql/dart2js/web_sql_dart2js.dart
+++ b/sdk_nnbd/lib/web_sql/dart2js/web_sql_dart2js.dart
@@ -1,3 +1,5 @@
+// @dart = 2.5
+
/**
* An API for storing data in the browser that can be queried with SQL.
*
diff --git a/tests/compiler/dart2js/end_to_end/dill_loader_test.dart b/tests/compiler/dart2js/end_to_end/dill_loader_test.dart
index bc2076e..64062ed 100644
--- a/tests/compiler/dart2js/end_to_end/dill_loader_test.dart
+++ b/tests/compiler/dart2js/end_to_end/dill_loader_test.dart
@@ -28,7 +28,7 @@
Uri entryPoint = Uri.parse('memory:main.dill');
var options = new CompilerOptions()
- ..target = new Dart2jsTarget("dart2js", new TargetFlags(legacyMode: true))
+ ..target = new Dart2jsTarget("dart2js", new TargetFlags())
..packagesFileUri = Uri.base.resolve('.packages')
..linkedDependencies = <Uri>[
computePlatformBinariesLocation().resolve("dart2js_platform.dill"),
diff --git a/tests/compiler/dart2js_extra/constant_folding_test.dart b/tests/compiler/dart2js_extra/constant_folding_test.dart
index af4b614..b9b050b 100644
--- a/tests/compiler/dart2js_extra/constant_folding_test.dart
+++ b/tests/compiler/dart2js_extra/constant_folding_test.dart
@@ -387,6 +387,7 @@
const TruncatingDivide(-9007199254740991, 0.5, -18014398509481982).check();
const TruncatingDivide(-9007199254740991, -0.5, 18014398509481982).check();
const TruncatingDivide(0x8000000000000000, -1, -0x8000000000000000).check();
+ const TruncatingDivide(0x6000000000000000, 0.5, 0xC000000000000000).check();
const TruncatingDivide(2.71828, 3.14159, 0).check();
const TruncatingDivide(2.71828, 1, 2).check();
const TruncatingDivide(2.71828, -1, -2).check();
diff --git a/tests/corelib_2/corelib_2.status b/tests/corelib_2/corelib_2.status
index 04290fc..f11deb7 100644
--- a/tests/corelib_2/corelib_2.status
+++ b/tests/corelib_2/corelib_2.status
@@ -50,9 +50,6 @@
[ $runtime == jsshell ]
string_case_test/01: Fail, OK # German double S.
-[ $runtime != none ]
-nsm_invocation_generic_test: RuntimeError # Not implemented yet. Issue 27323.
-
[ $runtime == safari ]
double_round3_test: Fail, OK # Runtime rounds 0.49999999999999994 to 1.
double_round_to_double2_test: Fail, OK # Runtime rounds 0.49999999999999994 to 1.
diff --git a/tests/corelib_2/int_from_environment_test.dart b/tests/corelib_2/int_from_environment_test.dart
index 62b1f1a..2e6d28e 100644
--- a/tests/corelib_2/int_from_environment_test.dart
+++ b/tests/corelib_2/int_from_environment_test.dart
@@ -1,7 +1,7 @@
// 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
// BSD-style license that can be found in the LICENSE file.
-// SharedOptions=-Da=1 -Db=-12 -Dc=0x123 -Dd=-0x1234 -De=+0x112296 -Df=-9007199254740991 -Dg=9007199254740991
+// SharedOptions=-Da=1 -Db=-12 -Dc=0x123 -Dd=-0x1234 -De=+0x112296 -Df=-9007199254740991 -Dg=9007199254740991 -Dh=-0x8000000000000000 -Di=0x8000000000000000 -Dj=0xDEADBEEFCAFE0000
import "package:expect/expect.dart";
@@ -13,4 +13,7 @@
Expect.equals(0x112296, const int.fromEnvironment('e'));
Expect.equals(-9007199254740991, const int.fromEnvironment('f'));
Expect.equals(9007199254740991, const int.fromEnvironment('g'));
+ Expect.equals(-0x8000000000000000, const int.fromEnvironment('h'));
+ Expect.equals(0x8000000000000000, const int.fromEnvironment('i'));
+ Expect.equals(0xDEADBEEFCAFE0000, const int.fromEnvironment('j'));
}
diff --git a/tests/corelib_2/nsm_invocation_generic_test.dart b/tests/corelib_2/nsm_invocation_generic_test.dart
index 5813857..5d899d0 100644
--- a/tests/corelib_2/nsm_invocation_generic_test.dart
+++ b/tests/corelib_2/nsm_invocation_generic_test.dart
@@ -19,7 +19,7 @@
nsm.name<int>(arg: argument));
expectInvocation(
new Invocation.genericMethod(#name, [int], [argument], {#arg: argument2}),
- nsm.name<int>(argument, arg: argument));
+ nsm.name<int>(argument, arg: argument2));
// Call invocation.
expectInvocation(new Invocation.genericMethod(#call, [int], []), nsm<int>());
expectInvocation(new Invocation.genericMethod(#call, [int], [argument]),
@@ -29,7 +29,7 @@
nsm<int>(arg: argument));
expectInvocation(
new Invocation.genericMethod(#call, [int], [argument], {#arg: argument2}),
- nsm<int>(argument, arg: argument));
+ nsm<int>(argument, arg: argument2));
}
dynamic nsm = new Recorder();
diff --git a/tests/ffi/ffi.status b/tests/ffi/ffi.status
index 46f4755..a6caf81 100644
--- a/tests/ffi/ffi.status
+++ b/tests/ffi/ffi.status
@@ -36,3 +36,6 @@
[ $arch == simarm || $arch == simarm64 ]
*: Skip # FFI not yet supported on the arm simulator.
+
+[ $system == android ]
+*: Slow # https://github.com/dart-lang/sdk/issues/38489
diff --git a/tests/ffi/function_callbacks_test.dart b/tests/ffi/function_callbacks_test.dart
index 1c5eca5..ca2197f 100644
--- a/tests/ffi/function_callbacks_test.dart
+++ b/tests/ffi/function_callbacks_test.dart
@@ -8,6 +8,10 @@
// VMOptions=--enable-testing-pragmas --stacktrace-every=100
// VMOptions=--enable-testing-pragmas --write-protect-code --no-dual-map-code
// VMOptions=--enable-testing-pragmas --write-protect-code --no-dual-map-code --stacktrace-every=100
+// VMOptions=--use-slow-path --enable-testing-pragmas
+// VMOptions=--use-slow-path --enable-testing-pragmas --stacktrace-every=100
+// VMOptions=--use-slow-path --enable-testing-pragmas --write-protect-code --no-dual-map-code
+// VMOptions=--use-slow-path --enable-testing-pragmas --write-protect-code --no-dual-map-code --stacktrace-every=100
// SharedObjects=ffi_test_functions
library FfiTest;
diff --git a/tests/language_2/call_method_implicit_tear_off_implements_function_test.dart b/tests/language_2/call_method_implicit_tear_off_implements_function_test.dart
deleted file mode 100644
index 610baab..0000000
--- a/tests/language_2/call_method_implicit_tear_off_implements_function_test.dart
+++ /dev/null
@@ -1,103 +0,0 @@
-// Copyright (c) 2018, 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 test program to test arithmetic operations.
-
-import "dart:async";
-import "package:expect/expect.dart";
-
-class B {}
-
-class C implements Function {
- B call(B b) => b;
-}
-
-typedef B BToB(B x);
-
-typedef Object NullToObject(Null x);
-
-C c = new C();
-
-void check1(BToB f) {
- Expect.isFalse(identical(c, f));
- Expect.equals(c.call, f);
- B b = new B();
- Expect.identical(f(b), b);
-}
-
-void check2(FutureOr<BToB> f) {
- Expect.isFalse(identical(c, f));
- Expect.equals(c.call, f);
- BToB f2 = f;
- B b = new B();
- Expect.identical(f2(b), b);
-}
-
-void check3(NullToObject f) {
- Expect.isFalse(identical(c, f));
- Expect.equals(c.call, f);
- Expect.isNull(f(null));
-}
-
-void check4(FutureOr<NullToObject> f) {
- Expect.isFalse(identical(c, f));
- Expect.equals(c.call, f);
- NullToObject f2 = f;
- Expect.isNull(f2(null));
-}
-
-void check5(Function f) {
- Expect.isFalse(identical(c, f));
- Expect.equals(c.call, f);
- B b = new B();
- Expect.identical(f(b), b);
-}
-
-void check6(FutureOr<Function> f) {
- Expect.isFalse(identical(c, f));
- Expect.equals(c.call, f);
- B b = new B();
- Function f2 = f;
- Expect.identical(f2(b), b);
-}
-
-void check7(C x) {
- Expect.identical(c, x);
-}
-
-void check8(FutureOr<C> x) {
- Expect.identical(c, x);
-}
-
-void check9(Object o) {
- Expect.identical(c, o);
-}
-
-void check10(FutureOr<Object> o) {
- Expect.identical(c, o);
-}
-
-void check11(dynamic d) {
- Expect.identical(c, d);
-}
-
-void check12(FutureOr<dynamic> d) {
- Expect.identical(c, d);
-}
-
-main() {
- // Implicitly tears off c.call
- check1(c); //# 01: ok
- check2(c); //# 02: ok
- check3(c); //# 03: ok
- check4(c); //# 04: ok
- check5(c); //# 05: ok
- check6(c); //# 06: ok
- // Does not tear off c.call
- check7(c); //# 07: ok
- check8(c); //# 08: ok
- check9(c); //# 09: ok
- check10(c); //# 10: ok
- check11(c); //# 11: ok
- check12(c); //# 12: ok
-}
diff --git a/tests/language_2/config_import_lib1a.dart b/tests/language_2/config_import_lib1a.dart
deleted file mode 100644
index 814c15e..0000000
--- a/tests/language_2/config_import_lib1a.dart
+++ /dev/null
@@ -1,5 +0,0 @@
-// Copyright (c) 2015, 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.
-
-String lib1() => "a";
diff --git a/tests/language_2/config_import_lib1b.dart b/tests/language_2/config_import_lib1b.dart
deleted file mode 100644
index 59212de..0000000
--- a/tests/language_2/config_import_lib1b.dart
+++ /dev/null
@@ -1,5 +0,0 @@
-// Copyright (c) 2015, 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.
-
-String lib1() => "b";
diff --git a/tests/language_2/config_import_lib1c.dart b/tests/language_2/config_import_lib1c.dart
deleted file mode 100644
index 86fd9e9..0000000
--- a/tests/language_2/config_import_lib1c.dart
+++ /dev/null
@@ -1,5 +0,0 @@
-// Copyright (c) 2015, 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.
-
-String lib1() => "c";
diff --git a/tests/language_2/config_import_lib2a.dart b/tests/language_2/config_import_lib2a.dart
deleted file mode 100644
index 00665dd..0000000
--- a/tests/language_2/config_import_lib2a.dart
+++ /dev/null
@@ -1,5 +0,0 @@
-// Copyright (c) 2015, 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.
-
-String lib2() => "a";
diff --git a/tests/language_2/config_import_lib2b.dart b/tests/language_2/config_import_lib2b.dart
deleted file mode 100644
index 6d91daf..0000000
--- a/tests/language_2/config_import_lib2b.dart
+++ /dev/null
@@ -1,5 +0,0 @@
-// Copyright (c) 2015, 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.
-
-String lib2() => "b";
diff --git a/tests/language_2/config_import_lib2c.dart b/tests/language_2/config_import_lib2c.dart
deleted file mode 100644
index 6ed0235..0000000
--- a/tests/language_2/config_import_lib2c.dart
+++ /dev/null
@@ -1,5 +0,0 @@
-// Copyright (c) 2015, 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.
-
-String lib2() => "c";
diff --git a/tests/language_2/config_import_lib3a.dart b/tests/language_2/config_import_lib3a.dart
deleted file mode 100644
index c2f9fec..0000000
--- a/tests/language_2/config_import_lib3a.dart
+++ /dev/null
@@ -1,5 +0,0 @@
-// Copyright (c) 2015, 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.
-
-String lib3() => "a";
diff --git a/tests/language_2/config_import_lib3b.dart b/tests/language_2/config_import_lib3b.dart
deleted file mode 100644
index b6d5afc..0000000
--- a/tests/language_2/config_import_lib3b.dart
+++ /dev/null
@@ -1,5 +0,0 @@
-// Copyright (c) 2015, 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.
-
-String lib3() => "b";
diff --git a/tests/language_2/config_import_lib3c.dart b/tests/language_2/config_import_lib3c.dart
deleted file mode 100644
index b984783..0000000
--- a/tests/language_2/config_import_lib3c.dart
+++ /dev/null
@@ -1,5 +0,0 @@
-// Copyright (c) 2015, 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.
-
-String lib3() => "c";
diff --git a/tests/language_2/config_import_lib4a.dart b/tests/language_2/config_import_lib4a.dart
deleted file mode 100644
index 1607f07..0000000
--- a/tests/language_2/config_import_lib4a.dart
+++ /dev/null
@@ -1,5 +0,0 @@
-// Copyright (c) 2015, 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.
-
-String lib4() => "a";
diff --git a/tests/language_2/config_import_lib4b.dart b/tests/language_2/config_import_lib4b.dart
deleted file mode 100644
index 9e2f08c..0000000
--- a/tests/language_2/config_import_lib4b.dart
+++ /dev/null
@@ -1,5 +0,0 @@
-// Copyright (c) 2015, 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.
-
-String lib4() => "b";
diff --git a/tests/language_2/config_import_lib4c.dart b/tests/language_2/config_import_lib4c.dart
deleted file mode 100644
index f4a1972..0000000
--- a/tests/language_2/config_import_lib4c.dart
+++ /dev/null
@@ -1,5 +0,0 @@
-// Copyright (c) 2015, 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.
-
-String lib4() => "c";
diff --git a/tests/language_2/config_import_test.dart b/tests/language_2/config_import_test.dart
deleted file mode 100644
index 2e15460..0000000
--- a/tests/language_2/config_import_test.dart
+++ /dev/null
@@ -1,30 +0,0 @@
-// Copyright (c) 2015, 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.
-//
-// SharedOptions=-Did=true -Ddotted.id=some_string -Dlots.of.dots.In.id=false
-
-import 'package:expect/expect.dart';
-
-import 'config_import_lib1a.dart'
- if (id) 'config_import_lib1b.dart'
- if (not.set.id) 'config_import_lib1c.dart';
-
-import 'config_import_lib2a.dart'
- if (not.set.id) 'config_import_lib2b.dart'
- if (not.set.either) 'config_import_lib2c.dart';
-
-import 'config_import_lib3a.dart'
- if (dotted.id == "some_string") 'config_import_lib3b.dart'
- if (id) 'config_import_lib3c.dart';
-
-import 'config_import_lib4a.dart'
- if (lots.of.dots.In.id == "other") 'config_import_lib4b.dart'
- if (lots.of.dots.In.id == "false") 'config_import_lib4c.dart';
-
-main() {
- Expect.equals("b", lib1());
- Expect.equals("a", lib2());
- Expect.equals("b", lib3());
- Expect.equals("c", lib4());
-}
diff --git a/tests/language_2/extension_methods/helpers/class_no_shadow.dart b/tests/language_2/extension_methods/helpers/class_no_shadow.dart
index efc929a..cba1e87 100644
--- a/tests/language_2/extension_methods/helpers/class_no_shadow.dart
+++ b/tests/language_2/extension_methods/helpers/class_no_shadow.dart
@@ -19,5 +19,6 @@
set setterInInstanceScope(String x) {
checkInstanceValue(x);
}
+
String methodInInstanceScope() => instanceValue;
}
diff --git a/tests/language_2/extension_methods/helpers/class_shadow.dart b/tests/language_2/extension_methods/helpers/class_shadow.dart
index 90bd522..73925be 100644
--- a/tests/language_2/extension_methods/helpers/class_shadow.dart
+++ b/tests/language_2/extension_methods/helpers/class_shadow.dart
@@ -11,11 +11,11 @@
// A class which has its own instance methods, which also
// shadows the global scope
class AGlobal extends A {
-
String fieldInGlobalScope = instanceValue;
String get getterInGlobalScope => instanceValue;
set setterInGlobalScope(String x) {
checkInstanceValue(x);
}
+
String methodInGlobalScope() => instanceValue;
}
diff --git a/tests/language_2/extension_methods/helpers/extension_all.dart b/tests/language_2/extension_methods/helpers/extension_all.dart
index 1154462..518948d 100644
--- a/tests/language_2/extension_methods/helpers/extension_all.dart
+++ b/tests/language_2/extension_methods/helpers/extension_all.dart
@@ -20,6 +20,7 @@
set setterInGlobalScope(double x) {
checkOtherExtensionValue(x);
}
+
double methodInGlobalScope() => otherExtensionValue;
double get fieldInInstanceScope => otherExtensionValue;
@@ -27,6 +28,7 @@
set setterInInstanceScope(double x) {
checkOtherExtensionValue(x);
}
+
double methodInInstanceScope() => otherExtensionValue;
double get fieldInExtensionScope => otherExtensionValue;
@@ -34,6 +36,7 @@
set setterInExtensionScope(double x) {
checkOtherExtensionValue(x);
}
+
double methodInExtensionScope() => otherExtensionValue;
double get fieldInOtherExtensionScope => otherExtensionValue;
@@ -41,6 +44,6 @@
set setterInOtherExtensionScope(double x) {
checkOtherExtensionValue(x);
}
- double methodInOtherExtensionScope() => otherExtensionValue;
-}
\ No newline at end of file
+ double methodInOtherExtensionScope() => otherExtensionValue;
+}
diff --git a/tests/language_2/extension_methods/helpers/extension_global_instance.dart b/tests/language_2/extension_methods/helpers/extension_global_instance.dart
index a874be0..fd33bcb 100644
--- a/tests/language_2/extension_methods/helpers/extension_global_instance.dart
+++ b/tests/language_2/extension_methods/helpers/extension_global_instance.dart
@@ -20,6 +20,7 @@
set setterInGlobalScope(double x) {
checkOtherExtensionValue(x);
}
+
double methodInGlobalScope() => otherExtensionValue;
double get fieldInInstanceScope => otherExtensionValue;
@@ -27,6 +28,7 @@
set setterInInstanceScope(double x) {
checkOtherExtensionValue(x);
}
+
double methodInInstanceScope() => otherExtensionValue;
double get fieldInOtherExtensionScope => otherExtensionValue;
@@ -34,6 +36,6 @@
set setterInOtherExtensionScope(double x) {
checkOtherExtensionValue(x);
}
- double methodInOtherExtensionScope() => otherExtensionValue;
-}
\ No newline at end of file
+ double methodInOtherExtensionScope() => otherExtensionValue;
+}
diff --git a/tests/language_2/extension_methods/helpers/extension_only.dart b/tests/language_2/extension_methods/helpers/extension_only.dart
index fdf55ef..da7d1c4 100644
--- a/tests/language_2/extension_methods/helpers/extension_only.dart
+++ b/tests/language_2/extension_methods/helpers/extension_only.dart
@@ -20,6 +20,6 @@
set setterInOtherExtensionScope(double x) {
checkOtherExtensionValue(x);
}
- double methodInOtherExtensionScope() => otherExtensionValue;
-}
\ No newline at end of file
+ double methodInOtherExtensionScope() => otherExtensionValue;
+}
diff --git a/tests/language_2/extension_methods/helpers/global_scope.dart b/tests/language_2/extension_methods/helpers/global_scope.dart
index 6c98097..2ba1533 100644
--- a/tests/language_2/extension_methods/helpers/global_scope.dart
+++ b/tests/language_2/extension_methods/helpers/global_scope.dart
@@ -18,4 +18,5 @@
set setterInGlobalScope(int x) {
checkGlobalValue(x);
}
+
int methodInGlobalScope() => globalValue;
diff --git a/tests/language_2/extension_methods/static_extension_bounds_error_test.dart b/tests/language_2/extension_methods/static_extension_bounds_error_test.dart
index 1707f79..04f6825 100644
--- a/tests/language_2/extension_methods/static_extension_bounds_error_test.dart
+++ b/tests/language_2/extension_methods/static_extension_bounds_error_test.dart
@@ -26,7 +26,6 @@
class RecSolution extends Rec<RecSolution> {}
-
void main() {
String s = "s";
int i = 0;
@@ -132,4 +131,4 @@
// ^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS
// [cfe] unspecified
-}
\ No newline at end of file
+}
diff --git a/tests/language_2/extension_methods/static_extension_getter_setter_conflicts_test.dart b/tests/language_2/extension_methods/static_extension_getter_setter_conflicts_test.dart
index e1baee5..c24bc36 100644
--- a/tests/language_2/extension_methods/static_extension_getter_setter_conflicts_test.dart
+++ b/tests/language_2/extension_methods/static_extension_getter_setter_conflicts_test.dart
@@ -50,8 +50,7 @@
// Conflicting extensions.
-class C1<T> {
-}
+class C1<T> {}
extension E1A<T> on C1<T> {
int get m1 => 0;
@@ -79,7 +78,7 @@
c1a.m2 = 0;
- C1<Object> c1b = C1<Null>(); // Neither extension is more specific.
+ C1<Object> c1b = C1<Null>(); // Neither extension is more specific.
c1b.m1;
// ^^
@@ -133,25 +132,6 @@
this.mc.toRadixString(16);
// Check that `this.me` refers to `E2.me`.
this.me.substring(0);
-
- // An unqualified identifier is matched against the extension (by basename).
-
- m1 = 0;
- 1 + m1;
- // ^^
- // [analyzer] COMPILE_TIME_ERROR.UNDEFINED_EXTENSION_GETTER
- // [cfe] unspecified
-
- 1 + m2;
- if (true) m2 = 0; // for the indent!
- // ^^^^^^
- // [analyzer] COMPILE_TIME_ERROR.UNDEFINED_EXTENSION_SETTER
- // [cfe] unspecified
-
- // Check that `mc` refers to `C2.me`.
- mc.toRadixString(16);
- // Check that `me` refers to `E2.me`.
- me.substring(0);
}
}
diff --git a/tests/language_2/extension_methods/static_extension_getter_setter_test.dart b/tests/language_2/extension_methods/static_extension_getter_setter_test.dart
index 8358a18..e112a87 100644
--- a/tests/language_2/extension_methods/static_extension_getter_setter_test.dart
+++ b/tests/language_2/extension_methods/static_extension_getter_setter_test.dart
@@ -4,7 +4,7 @@
// SharedOptions=--enable-experiment=extension-methods
-// Tests interactions between getters and setters where one or both is defined
+// Tests getters and setters where one or both is defined
// by an extension.
import "package:expect/expect.dart";
@@ -14,37 +14,27 @@
// v1: C get, C set
expectGet("C.v1", c.v1);
expectSet("C.v1=1", c.v1 = Result("1"));
- // v2: C get, E1 set
+ // v2: C get, E1 get/set, C wins.
expectGet("C.v2", c.v2);
- expectSet("E1.v2=2", c.v2 = Result("2"));
- // v3: E1 get, C set
- expectGet("E1.v3", c.v3);
+ expectSet("E1.v2=2", E1(c).v2 = Result("2"));
+ // v3: E1 get/set, C set, C wins.
+ expectGet("E1.v3", E1(c).v3);
expectSet("C.v3=3", c.v3 = Result("3"));
- // v4: E1 get, E1 set
+ // v4: E1 get/set
expectGet("E1.v4", c.v4);
expectSet("E1.v4=4", c.v4 = Result("4"));
- // v5: E1 get, E2 set
- expectGet("E1.v5", c.v5);
- expectSet("E2.v5=5", c.v5 = Result("5"));
+ // v5: E1 get, E2 set, neither more specific.
+ expectGet("E1.v5", E1(c).v5);
+ expectSet("E2.v5=5", E2(c).v5 = Result("5"));
expectSet("C.v1=C.v1+1", c.v1++);
- expectSet("E1.v2=C.v2+1", c.v2++);
- expectSet("C.v3=E1.v3+1", c.v3++);
expectSet("E1.v4=E1.v4+1", c.v4++);
- expectSet("E2.v5=E1.v5+1", c.v5++);
expectSet("C.v1=C.v1+a", c.v1 += "a");
expectSet("C.v1=C.v1-b", c.v1 -= "b");
+ expectSet("E1.v4=E1.v4-b", c.v4 -= "b");
- // Cascades work.
- expectSet(
- "E1.v4=E2.v4+[C.v1=[E1.v2=a]]",
- c
- ..v2 = Result("a")
- ..v1 = Result("[$lastSetter]")
- ..v4 += Result("[$lastSetter]"));
-
- // Override used by all accesses of read/write operations
+ // Explicit application used by all accesses of read/write operations
expectSet("E1.v1=E1.v1+1", E1(c).v1++);
expectSet("E1.v2=E1.v2+1", E1(c).v2++);
expectSet("E1.v3=E1.v3+1", E1(c).v3++);
@@ -56,6 +46,14 @@
expectSet("E1.v1=E1.v1+1", E1(c).v1 = E1(c).v1 + 1);
expectSet("E1.v2=E1.v2+1", E1(c).v2 = E1(c).v2 + 1);
expectSet("E1.v3=E1.v3+1", E1(c).v3 = E1(c).v3 + 1);
+
+ // Cascades work.
+ expectSet(
+ "E1.v4=E1.v4+[C.v1=C.v1-[C.v3=a]]",
+ c
+ ..v3 = Result("a")
+ ..v1 -= Result("[$lastSetter]")
+ ..v4 += Result("[$lastSetter]"));
}
/// Expect the value of [result] to be the [expected] string
@@ -105,41 +103,41 @@
/// Declares [v4] getter and setter, and [v5] getter
/// which are supplemented by a setter from the [E2] extension.
extension E1 on C {
- // Overlaps with C on both.
+ // Same basename as C getter and setter.
Result get v1 => Result("E1.v1");
void set v1(Result value) {
lastSetter = "E1.v1=$value";
}
- // Overlaps with C on getter.
+ // Same basename as C getter.
Result get v2 => Result("E1.v2");
void set v2(Result value) {
lastSetter = "E1.v2=$value";
}
- // Overlaps with C on setter.
+ // Same basename as C setter.
Result get v3 => Result("E1.v3");
void set v3(Result value) {
lastSetter = "E1.v3=$value";
}
- // Overlaps with nothing.
+ // No other declarations with same basename.
Result get v4 => Result("E1.v4");
+
void set v4(Result value) {
lastSetter = "E1.v4=$value";
}
- // Combines with E2 setter.
+ // Same basename as E2 setter.
Result get v5 => Result("E1.v5");
}
/// A different extension than [E1] on [C].
///
/// Declares [v5] setter.
-/// Together with [E1], this defined both getter and setter.
extension E2 on C {
void set v5(Result value) {
lastSetter = "E2.v5=$value";
diff --git a/tests/language_2/extension_methods/static_extension_inference_test.dart b/tests/language_2/extension_methods/static_extension_inference_test.dart
index 98fc240..81c90cf 100644
--- a/tests/language_2/extension_methods/static_extension_inference_test.dart
+++ b/tests/language_2/extension_methods/static_extension_inference_test.dart
@@ -172,7 +172,7 @@
List<T> get argList5 => <T>[];
List<Object> get argDynList5 => <T>[];
List<Object> get selfList5 {
- var result = [this];
+ var result = [self];
return result;
}
}
diff --git a/tests/language_2/extension_methods/static_extension_internal_basename_shadowing_error_test.dart b/tests/language_2/extension_methods/static_extension_internal_basename_shadowing_error_test.dart
index 855cf6d..4158947 100644
--- a/tests/language_2/extension_methods/static_extension_internal_basename_shadowing_error_test.dart
+++ b/tests/language_2/extension_methods/static_extension_internal_basename_shadowing_error_test.dart
@@ -212,7 +212,7 @@
// Define extensions on A6.
extension E5 on A6 {
- void set extensionSetter(int _) {};
+ void set extensionSetter(int _) {}
int extensionMethod(int x) => -3;
}
diff --git a/tests/language_2/extension_methods/static_extension_internal_name_conflict_error_test.dart b/tests/language_2/extension_methods/static_extension_internal_name_conflict_error_test.dart
index 4bd5a29..0e55982 100644
--- a/tests/language_2/extension_methods/static_extension_internal_name_conflict_error_test.dart
+++ b/tests/language_2/extension_methods/static_extension_internal_name_conflict_error_test.dart
@@ -21,7 +21,6 @@
// [analyzer] COMPILE_TIME_ERROR.DUPLICATE_DEFINITION
// [cfe] unspecified
-
class E2 {}
// ^^
// [analyzer] COMPILE_TIME_ERROR.DUPLICATE_DEFINITION
@@ -108,7 +107,6 @@
// [cfe] unspecified
}
-
// Check static members colliding with static members (of the same kind).
extension E5 on int {
static int method() => 0;
@@ -239,4 +237,4 @@
// [cfe] unspecified
}
-void main() {}
\ No newline at end of file
+void main() {}
diff --git a/tests/language_2/extension_methods/static_extension_internal_resolution_0_test.dart b/tests/language_2/extension_methods/static_extension_internal_resolution_0_test.dart
index 3110880..418ba2b 100644
--- a/tests/language_2/extension_methods/static_extension_internal_resolution_0_test.dart
+++ b/tests/language_2/extension_methods/static_extension_internal_resolution_0_test.dart
@@ -71,10 +71,9 @@
double t2 = methodInOtherExtensionScope();
checkOtherExtensionValue(t2);
}
-
}
- void testIdentifiersOnThis() {
+ void testIdentifiersOnThis() {
// Instance members resolve to the instance methods and not the members
// of the other extension (when present)
{
@@ -125,7 +124,6 @@
self.setterInOtherExtensionScope = otherExtensionValue;
double t2 = self.methodInOtherExtensionScope();
checkOtherExtensionValue(t2);
-
}
}
@@ -207,5 +205,4 @@
double t2 = a.methodInOtherExtensionScope();
checkOtherExtensionValue(t2);
}
-
-}
\ No newline at end of file
+}
diff --git a/tests/language_2/extension_methods/static_extension_internal_resolution_1_test.dart b/tests/language_2/extension_methods/static_extension_internal_resolution_1_test.dart
index 9bea1cf..052ab86 100644
--- a/tests/language_2/extension_methods/static_extension_internal_resolution_1_test.dart
+++ b/tests/language_2/extension_methods/static_extension_internal_resolution_1_test.dart
@@ -72,7 +72,6 @@
double t2 = methodInOtherExtensionScope();
checkOtherExtensionValue(t2);
}
-
}
void testIdentifiersOnThis() {
@@ -149,7 +148,6 @@
self.setterInOtherExtensionScope = otherExtensionValue;
double t2 = self.methodInOtherExtensionScope();
checkOtherExtensionValue(t2);
-
}
}
@@ -243,5 +241,4 @@
double t2 = a.methodInOtherExtensionScope();
checkOtherExtensionValue(t2);
}
-
-}
\ No newline at end of file
+}
diff --git a/tests/language_2/extension_methods/static_extension_internal_resolution_2_test.dart b/tests/language_2/extension_methods/static_extension_internal_resolution_2_test.dart
index 643581d..861bb4b 100644
--- a/tests/language_2/extension_methods/static_extension_internal_resolution_2_test.dart
+++ b/tests/language_2/extension_methods/static_extension_internal_resolution_2_test.dart
@@ -44,6 +44,7 @@
set setterInGlobalScope(bool x) {
Expect.equals(true, x);
}
+
bool methodInGlobalScope() => true;
bool get fieldInInstanceScope => true;
@@ -51,6 +52,7 @@
set setterInInstanceScope(bool x) {
Expect.equals(true, x);
}
+
bool methodInInstanceScope() => true;
bool get fieldInExtensionScope => true;
@@ -58,6 +60,7 @@
set setterInExtensionScope(bool x) {
Expect.equals(true, x);
}
+
bool methodInExtensionScope() => true;
void testNakedIdentifiers() {
@@ -106,7 +109,6 @@
double t2 = methodInOtherExtensionScope();
checkOtherExtensionValue(t2);
}
-
}
void testIdentifiersOnThis() {
@@ -214,7 +216,6 @@
}
}
-
class B extends A {
void testNakedIdentifiers() {
// Globals should resolve to the global name space, and not to the members
@@ -321,5 +322,4 @@
double t2 = a.methodInOtherExtensionScope();
checkOtherExtensionValue(t2);
}
-
-}
\ No newline at end of file
+}
diff --git a/tests/language_2/extension_methods/static_extension_internal_resolution_3_error_test.dart b/tests/language_2/extension_methods/static_extension_internal_resolution_3_error_test.dart
index 8803cad..8d47a88 100644
--- a/tests/language_2/extension_methods/static_extension_internal_resolution_3_error_test.dart
+++ b/tests/language_2/extension_methods/static_extension_internal_resolution_3_error_test.dart
@@ -47,6 +47,7 @@
set setterInGlobalScope(bool x) {
checkExtensionValue(x);
}
+
bool methodInGlobalScope() => extensionValue;
bool get fieldInInstanceScope => extensionValue;
@@ -54,6 +55,7 @@
set setterInInstanceScope(bool x) {
checkExtensionValue(x);
}
+
bool methodInInstanceScope() => extensionValue;
bool get fieldInExtensionScope => extensionValue;
@@ -61,6 +63,7 @@
set setterInExtensionScope(bool x) {
checkExtensionValue(x);
}
+
bool methodInExtensionScope() => extensionValue;
void testNakedIdentifiers() {
@@ -85,7 +88,6 @@
{
// No errors: see static_extension_internal_resolution_3_test.dart
}
-
}
void testIdentifiersOnThis() {
@@ -189,7 +191,6 @@
}
}
-
class B extends A {
void testNakedIdentifiers() {
// Globals should resolve to the global name space, and not to the members
@@ -210,7 +211,7 @@
// No errors: see static_extension_internal_resolution_3_test.dart
}
- // Extension members resolve to the extension methods in the other
+ // Extension members resolve to the extension methods in the other
// extension (unresolved identifier "id" gets turned into "this.id",
// which is then subject to extension method lookup).
{
@@ -270,5 +271,4 @@
{
// No errors: see static_extension_internal_resolution_3_test.dart
}
-
-}
\ No newline at end of file
+}
diff --git a/tests/language_2/extension_methods/static_extension_internal_resolution_3_test.dart b/tests/language_2/extension_methods/static_extension_internal_resolution_3_test.dart
index d1da8bf..f6c57e9 100644
--- a/tests/language_2/extension_methods/static_extension_internal_resolution_3_test.dart
+++ b/tests/language_2/extension_methods/static_extension_internal_resolution_3_test.dart
@@ -47,6 +47,7 @@
set setterInGlobalScope(bool x) {
checkExtensionValue(x);
}
+
bool methodInGlobalScope() => extensionValue;
bool get fieldInInstanceScope => extensionValue;
@@ -54,6 +55,7 @@
set setterInInstanceScope(bool x) {
checkExtensionValue(x);
}
+
bool methodInInstanceScope() => extensionValue;
bool get fieldInExtensionScope => extensionValue;
@@ -61,6 +63,7 @@
set setterInExtensionScope(bool x) {
checkExtensionValue(x);
}
+
bool methodInExtensionScope() => extensionValue;
void testNakedIdentifiers() {
@@ -109,7 +112,6 @@
double t2 = methodInOtherExtensionScope();
checkOtherExtensionValue(t2);
}
-
}
void testIdentifiersOnThis() {
@@ -205,7 +207,6 @@
}
}
-
class B extends A {
void testNakedIdentifiers() {
// Globals should resolve to the global name space, and not to the members
@@ -305,5 +306,4 @@
double t2 = a.methodInOtherExtensionScope();
checkOtherExtensionValue(t2);
}
-
-}
\ No newline at end of file
+}
diff --git a/tests/language_2/extension_methods/static_extension_internal_resolution_4_error_test.dart b/tests/language_2/extension_methods/static_extension_internal_resolution_4_error_test.dart
index 5679856..b8e80b1 100644
--- a/tests/language_2/extension_methods/static_extension_internal_resolution_4_error_test.dart
+++ b/tests/language_2/extension_methods/static_extension_internal_resolution_4_error_test.dart
@@ -47,6 +47,7 @@
set setterInGlobalScope(bool x) {
checkExtensionValue(x);
}
+
bool methodInGlobalScope() => extensionValue;
bool get fieldInInstanceScope => extensionValue;
@@ -54,6 +55,7 @@
set setterInInstanceScope(bool x) {
checkExtensionValue(x);
}
+
bool methodInInstanceScope() => extensionValue;
bool get fieldInExtensionScope => extensionValue;
@@ -61,6 +63,7 @@
set setterInExtensionScope(bool x) {
checkExtensionValue(x);
}
+
bool methodInExtensionScope() => extensionValue;
void testNakedIdentifiers() {
@@ -85,7 +88,6 @@
{
// No errors: see static_extension_internal_resolution_4_test.dart
}
-
}
void testIdentifiersOnThis() {
@@ -233,7 +235,6 @@
}
}
-
class B extends A {
void testNakedIdentifiers() {
// Globals should resolve to the global name space, and not to the members
@@ -283,7 +284,7 @@
checkExtensionValue(t2);
}
- // Extension members resolve to the extension methods in the other
+ // Extension members resolve to the extension methods in the other
// extension (unresolved identifier "id" gets turned into "this.id",
// which is then subject to extension method lookup).
{
@@ -364,5 +365,4 @@
{
// No errors: see static_extension_internal_resolution_4_test.dart
}
-
-}
\ No newline at end of file
+}
diff --git a/tests/language_2/extension_methods/static_extension_internal_resolution_4_test.dart b/tests/language_2/extension_methods/static_extension_internal_resolution_4_test.dart
index 3cd6f90..93955cb 100644
--- a/tests/language_2/extension_methods/static_extension_internal_resolution_4_test.dart
+++ b/tests/language_2/extension_methods/static_extension_internal_resolution_4_test.dart
@@ -47,6 +47,7 @@
set setterInGlobalScope(bool x) {
checkExtensionValue(x);
}
+
bool methodInGlobalScope() => extensionValue;
bool get fieldInInstanceScope => extensionValue;
@@ -54,6 +55,7 @@
set setterInInstanceScope(bool x) {
checkExtensionValue(x);
}
+
bool methodInInstanceScope() => extensionValue;
bool get fieldInExtensionScope => extensionValue;
@@ -61,6 +63,7 @@
set setterInExtensionScope(bool x) {
checkExtensionValue(x);
}
+
bool methodInExtensionScope() => extensionValue;
void testNakedIdentifiers() {
@@ -109,7 +112,6 @@
double t2 = methodInOtherExtensionScope();
checkOtherExtensionValue(t2);
}
-
}
void testIdentifiersOnThis() {
@@ -193,7 +195,6 @@
}
}
-
class B extends A {
void testNakedIdentifiers() {
// Globals should resolve to the global name space, and not to the members
@@ -225,7 +226,7 @@
// Error cases tested in static_extension_internal_resolution_4_error_test.dart
}
- // Extension members resolve to the extension methods in the other
+ // Extension members resolve to the extension methods in the other
// extension (unresolved identifier "id" gets turned into "this.id",
// which is then subject to extension method lookup).
{
@@ -280,5 +281,4 @@
double t2 = a.methodInOtherExtensionScope();
checkOtherExtensionValue(t2);
}
-
-}
\ No newline at end of file
+}
diff --git a/tests/language_2/extension_methods/static_extension_internal_resolution_5_test.dart b/tests/language_2/extension_methods/static_extension_internal_resolution_5_test.dart
index 1a567a4..0334769 100644
--- a/tests/language_2/extension_methods/static_extension_internal_resolution_5_test.dart
+++ b/tests/language_2/extension_methods/static_extension_internal_resolution_5_test.dart
@@ -28,7 +28,6 @@
import "helpers/class_shadow.dart";
import "helpers/class_no_shadow.dart";
-
const bool extensionValue = true;
void checkExtensionValue(bool x) {
@@ -41,6 +40,7 @@
set setterInExtensionScope(int x) {
checkGlobalValue(x);
}
+
int methodInExtensionScope() => globalValue;
// Put the superclass members in the global scope
@@ -49,16 +49,17 @@
set setterInInstanceScope(int x) {
checkGlobalValue(x);
}
+
int methodInInstanceScope() => globalValue;
// An extension which defines only its own members
extension MyExt on AGlobal {
-
bool get fieldInExtensionScope => extensionValue;
bool get getterInExtensionScope => extensionValue;
set setterInExtensionScope(bool x) {
checkExtensionValue(x);
}
+
bool methodInExtensionScope() => extensionValue;
bool get fieldInInstanceScope => extensionValue;
@@ -66,6 +67,7 @@
set setterInInstanceScope(bool x) {
checkExtensionValue(x);
}
+
bool methodInInstanceScope() => extensionValue;
void testNakedIdentifiers() {
@@ -158,4 +160,4 @@
var a = new AGlobal();
a.instanceTest();
new B().testNakedIdentifiers();
-}
\ No newline at end of file
+}
diff --git a/tests/language_2/extension_methods/static_extension_internal_resolution_6_error_test.dart b/tests/language_2/extension_methods/static_extension_internal_resolution_6_error_test.dart
index bd1ddf0..c7e3949 100644
--- a/tests/language_2/extension_methods/static_extension_internal_resolution_6_error_test.dart
+++ b/tests/language_2/extension_methods/static_extension_internal_resolution_6_error_test.dart
@@ -35,6 +35,7 @@
// ^^^
// [cfe] unspecified
}
+
void castToShadowedTypeParam<T>() {
dynamic s = self;
(s as T);
@@ -46,7 +47,6 @@
}
}
-
const bool extensionValue = true;
void checkExtensionValue(bool x) {
@@ -62,10 +62,11 @@
// ^^^^^^^^^^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.EXTENSION_CONFLICTING_STATIC_AND_INSTANCE
static set setterInInstanceScope(bool x) {
- // ^^^^^^^^^^^^^^^^^^^^^
- // [analyzer] COMPILE_TIME_ERROR.EXTENSION_CONFLICTING_STATIC_AND_INSTANCE
+ // ^^^^^^^^^^^^^^^^^^^^^
+ // [analyzer] COMPILE_TIME_ERROR.EXTENSION_CONFLICTING_STATIC_AND_INSTANCE
checkExtensionValue(x);
}
+
static bool methodInInstanceScope() => extensionValue;
// ^^^^^^^^^^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.EXTENSION_CONFLICTING_STATIC_AND_INSTANCE
@@ -76,6 +77,7 @@
static set setterInGlobalScope(bool x) {
checkExtensionValue(x);
}
+
static bool methodInGlobalScope() => extensionValue;
// Invalid to overlap the static and extension scopes
@@ -86,15 +88,15 @@
// ^^^
// [cfe] unspecified
set setterInInstanceScope(bool x) {
- // ^^^
- // [cfe] unspecified
+ //^^^
+ // [cfe] unspecified
checkExtensionValue(x);
}
+
bool methodInInstanceScope() => extensionValue;
// ^^^
// [cfe] unspecified
-
void testNakedIdentifiers() {
// Symbols in the global scope and the local static scope resolve to
// the local static scope.
@@ -108,6 +110,7 @@
// No errors: see static_extension_internal_resolution_6_test.dart
}
}
+
void instanceTest() {
StaticExt(this).testNakedIdentifiers();
}
@@ -119,4 +122,4 @@
Expect.throwsCastError(() => 3.castToShadowedTypeParam<String>());
Expect.throwsCastError(() => 3.castToShadowedTypeList<String>());
-}
\ No newline at end of file
+}
diff --git a/tests/language_2/extension_methods/static_extension_internal_resolution_6_test.dart b/tests/language_2/extension_methods/static_extension_internal_resolution_6_test.dart
index 9c63c3b..929b306 100644
--- a/tests/language_2/extension_methods/static_extension_internal_resolution_6_test.dart
+++ b/tests/language_2/extension_methods/static_extension_internal_resolution_6_test.dart
@@ -37,7 +37,6 @@
}
}
-
const bool extensionValue = true;
void checkExtensionValue(bool x) {
@@ -51,6 +50,7 @@
static set setterInInstanceScope(bool x) {
checkExtensionValue(x);
}
+
static bool methodInInstanceScope() => extensionValue;
// Add the global symbols
@@ -59,6 +59,7 @@
static set setterInGlobalScope(bool x) {
checkExtensionValue(x);
}
+
static bool methodInGlobalScope() => extensionValue;
void testNakedIdentifiers() {
@@ -86,6 +87,7 @@
checkExtensionValue(t2);
}
}
+
void instanceTest() {
StaticExt(this).testNakedIdentifiers();
}
@@ -96,4 +98,4 @@
a.instanceTest();
Expect.throwsCastError(() => 3.castToShadowedTypeParam<String>());
-}
\ No newline at end of file
+}
diff --git a/tests/language_2/extension_methods/static_extension_operators_test.dart b/tests/language_2/extension_methods/static_extension_operators_test.dart
index ebada0d..6f902c8 100644
--- a/tests/language_2/extension_methods/static_extension_operators_test.dart
+++ b/tests/language_2/extension_methods/static_extension_operators_test.dart
@@ -75,7 +75,7 @@
expect("a[b]", a[b]--, "a[b]=(a[b]-1)");
// Combinations.
- expect("(a+b[b(c)](a*b))", a + b[c[a] = b(c)](a * b), "c[a]=b(c)");
+ expect("(a+b[b(c)]((a*b)))", a + b[c[a] = b(c)](a * b), "c[a]=b(c)");
// Operator precedence is unaffected by being extensions.
expect("(c<((-a)|(b^((~c)&((a<<b)>>((c-a)+((((b*c)~/a)%b)/c)))))))",
diff --git a/tests/language_2/extension_methods/static_extension_setter_getter_assignability_error_test.dart b/tests/language_2/extension_methods/static_extension_setter_getter_assignability_error_test.dart
index e5005da..1cff35a 100644
--- a/tests/language_2/extension_methods/static_extension_setter_getter_assignability_error_test.dart
+++ b/tests/language_2/extension_methods/static_extension_setter_getter_assignability_error_test.dart
@@ -26,4 +26,4 @@
// [cfe] unspecified
}
-void main() {}
\ No newline at end of file
+void main() {}
diff --git a/tests/language_2/extension_methods/static_extension_silly_types_test.dart b/tests/language_2/extension_methods/static_extension_silly_types_test.dart
index 3b13f19..6f69e79 100644
--- a/tests/language_2/extension_methods/static_extension_silly_types_test.dart
+++ b/tests/language_2/extension_methods/static_extension_silly_types_test.dart
@@ -77,7 +77,6 @@
class C = Object with M;
-
extension on M {
int get m => 1;
}
@@ -87,8 +86,8 @@
testVoid() {
// No access on void. Static type of `this` is void!
this //
- .toString() //# 01: compile-time error
- ;
+ .toString() //# 01: compile-time error
+ ;
}
}
diff --git a/tests/language_2/extension_methods/static_extension_syntax_test.dart b/tests/language_2/extension_methods/static_extension_syntax_test.dart
index 1ab928a..0d71b60 100644
--- a/tests/language_2/extension_methods/static_extension_syntax_test.dart
+++ b/tests/language_2/extension_methods/static_extension_syntax_test.dart
@@ -141,7 +141,7 @@
List<T> get list17 => <T>[];
}
-extension <T extends Rec<T>> on T {
+extension<T extends Rec<T>> on T {
int get e19 => 19;
List<T> get list19 => <T>[];
}
diff --git a/tests/language_2/external_test.dart b/tests/language_2/external_test.dart
index 9901999..c021505 100644
--- a/tests/language_2/external_test.dart
+++ b/tests/language_2/external_test.dart
@@ -16,18 +16,15 @@
external var x01; // //# 01: syntax error
external int x02; // //# 02: syntax error
- external f10(); // //# 10: runtime error
external f11() { } // //# 11: syntax error
external f12() => 1; // //# 12: syntax error
- external static f13(); // //# 13: runtime error
static external f14(); // //# 14: syntax error
int external f16(); // //# 16: syntax error
- external Foo.n20(val); // //# 20: runtime error
- external Foo.n21(val) : x = 1; // //# 21: runtime error
+ external Foo.n21(val) : x = 1; // //# 21: syntax error
external Foo.n22(val) { x = 1; } // //# 22: syntax error
external factory Foo.n23(val) => new Foo(); // //# 23: syntax error
- external Foo.n24(this.x); // //# 24: runtime error
+ external Foo.n24(this.x); // //# 24: compile-time error
external factory Foo.n25(val) = Bar; // //# 25: syntax error
}
@@ -38,16 +35,11 @@
// Ensure Foo class is compiled.
var foo = new Foo();
- // Try calling an unpatched external function.
- new Foo().f10(); // //# 10: continued
new Foo().f11(); // //# 11: continued
new Foo().f12(); // //# 12: continued
- Foo.f13(); // //# 13: continued
Foo.f14(); // //# 14: continued
new Foo().f16(); // //# 16: continued
- // Try calling an unpatched external constructor.
- new Foo.n20(1); // //# 20: continued
new Foo.n21(1); // //# 21: continued
new Foo.n22(1); // //# 22: continued
new Foo.n23(1); // //# 23: continued
diff --git a/tests/language_2/flatten_test.dart b/tests/language_2/flatten_test.dart
index 618c0b6..2ff13e9 100644
--- a/tests/language_2/flatten_test.dart
+++ b/tests/language_2/flatten_test.dart
@@ -12,13 +12,9 @@
noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
}
-// TODO(vsm): Restore when https://github.com/dart-lang/sdk/issues/25611
-// is fixed.
-/*
class Divergent<T> implements Future<Divergent<Divergent<T>>> {
noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
}
-*/
test() async {
// flatten(Derived<int>) = int
@@ -27,9 +23,6 @@
Future<int> f() async { return new Derived<int>(); } //# 03: ok
Future<int> x = (() async => new Derived<int>())(); //# 04: runtime error
- // TODO(vsm): Restore when https://github.com/dart-lang/sdk/issues/25611
- // is fixed.
- /*
// flatten(FixedPoint<int>) = FixedPoint<int>
FixedPoint<int> x = await new FixedPoint<int>(); //# 05: runtime error
Future<FixedPoint<int>> f() async => new FixedPoint<int>(); //# 06: ok
@@ -41,7 +34,6 @@
Future<Divergent<Divergent<int>>> f() async => new Divergent<int>(); //# 10: ok
Future<Divergent<Divergent<int>>> f() async { return new Divergent<int>(); } //# 11: ok
Future<Divergent<Divergent<int>>> x = (() async => new Divergent<int>())(); //# 12: runtime error
- */
}
main() {
diff --git a/tests/language_2/generic_mock_test.dart b/tests/language_2/generic_mock_test.dart
new file mode 100644
index 0000000..f30e43e
--- /dev/null
+++ b/tests/language_2/generic_mock_test.dart
@@ -0,0 +1,19 @@
+// Copyright (c) 2019, 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.
+
+// Regression test for https://github.com/dart-lang/sdk/issues/38384
+
+class Built<X, Y> {}
+
+class Foo {
+ foo<S extends Built<S, B>, B extends Built<S, B>>() {}
+}
+
+class Mock {
+ noSuchMethod(Invocation i) {}
+}
+
+class MockFoo extends Mock implements Foo {}
+
+main() {}
diff --git a/tests/language_2/generic_no_such_method_dispatcher_simple_test.dart b/tests/language_2/generic_no_such_method_dispatcher_simple_test.dart
deleted file mode 100644
index a829f56..0000000
--- a/tests/language_2/generic_no_such_method_dispatcher_simple_test.dart
+++ /dev/null
@@ -1,32 +0,0 @@
-// Copyright (c) 2017, 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.
-// VMOptions=--reify-generic-functions --optimization-counter-threshold=10 --no-use-osr --no-background-compilation
-
-library generic_no_such_method_dispatcher_test_simple;
-
-import "package:expect/expect.dart";
-
-// A simple test that noSuchMethod dispatching works correctly with generic
-// functions. We will remove this once the more complex version of this test
-// 'generic_no_such_method_dispatcher_test' can be compiled by Fasta.
-
-class A {}
-
-class B extends A {
- foo() => super.foo<int>();
-}
-
-test(fn) {
- try {
- fn();
- } catch (e) {
- Expect.isTrue(e.toString().contains("foo<int>"));
- }
-}
-
-main() {
- test(() => (new B()).foo()); // missing generic super call
- test(() => foo<int>()); // missing generic static call
- test(() => (new A()).foo<int>()); // missing generic method call
-}
diff --git a/tests/language_2/language_2.status b/tests/language_2/language_2.status
index d03e859..9e9b7a4 100644
--- a/tests/language_2/language_2.status
+++ b/tests/language_2/language_2.status
@@ -53,12 +53,6 @@
partial_instantiation_static_bounds_check_test/02: MissingCompileTimeError # Issue 34327
partial_instantiation_static_bounds_check_test/03: MissingCompileTimeError # Issue 34327
-[ $compiler != compare_analyzer_cfe && $compiler != spec_parser ]
-mixin_constructor_forwarding/const_constructor_test/none: CompileTimeError # Issue 32223
-mixin_constructor_forwarding/const_constructor_with_field_test/none: CompileTimeError # Issue 32223
-mixin_constructor_forwarding/optional_named_parameters_test/none: CompileTimeError # Issue 31543
-mixin_constructor_forwarding/optional_positional_parameters_test/none: CompileTimeError # Issue 31543
-
[ $compiler != dart2js && $compiler != dartdevc && !$checked ]
function_type/*: Skip # Needs checked mode.
diff --git a/tests/language_2/language_2_analyzer.status b/tests/language_2/language_2_analyzer.status
index cddcbd3..372d94b 100644
--- a/tests/language_2/language_2_analyzer.status
+++ b/tests/language_2/language_2_analyzer.status
@@ -5,7 +5,6 @@
# Sections in this file should contain "$compiler == dart2analyzer".
[ $compiler == dart2analyzer ]
-generic_no_such_method_dispatcher_simple_test: Skip # failing-by-design: This test is just for kernel
large_class_declaration_test: Slow
vm/debug_break_enabled_vm_test: Skip
vm/debug_break_vm_test/*: Skip
diff --git a/tests/language_2/language_2_dart2js.status b/tests/language_2/language_2_dart2js.status
index 2478e07..fb8135f 100644
--- a/tests/language_2/language_2_dart2js.status
+++ b/tests/language_2/language_2_dart2js.status
@@ -14,8 +14,6 @@
call_method_must_not_be_getter_test/03: RuntimeError # Issue 32155
canonical_const2_test: RuntimeError, OK # non JS number semantics
closure_type_arguments_test: Crash # Issue 34272
-config_import_corelib_test: CompileTimeError # we need a special platform.dill file for categories=all. Once we fix that, all dart:* are supported when using '--categories=all' so this will become a RuntimeError, OK.
-config_import_test: RuntimeError # Test flag is not passed to the compiler.
const_constructor3_test/04: MissingCompileTimeError # OK - Subtype check uses JS number semantics.
const_dynamic_type_literal_test/03: Pass # but it shouldn't until we fix issue 17207
const_switch_test/02: RuntimeError, OK # constant identity based on JS constants
@@ -27,9 +25,6 @@
double_identical_test: RuntimeError # Negative and positive zero are distinct, but not in dart2js; bug #11551.
double_int_to_string_test: RuntimeError, OK # non JS number semantics
expect_test: RuntimeError, OK # Issue 13080
-external_test/10: CompileTimeError # External non-js-interop function are treated as compile-time errors.
-external_test/13: CompileTimeError # External non-js-interop function are treated as compile-time errors.
-external_test/20: CompileTimeError # External non-js-interop function are treated as compile-time errors.
full_stacktrace1_test: RuntimeError # Issue 12698
full_stacktrace2_test: RuntimeError # Issue 12698
full_stacktrace3_test: RuntimeError # Issue 12698
diff --git a/tests/language_2/language_2_dartdevc.status b/tests/language_2/language_2_dartdevc.status
index 9afe4d1..4abcf1c 100644
--- a/tests/language_2/language_2_dartdevc.status
+++ b/tests/language_2/language_2_dartdevc.status
@@ -9,7 +9,6 @@
const_double_in_int_op_test/id6: Skip # Triple shift
const_double_in_int_op_test/ii6: Skip # Triple shift
extension_methods/*: SkipByDesign # Analyzer DDC is expected to be turned down before releasing extension methods.
-generic_no_such_method_dispatcher_simple_test: Skip # This test is just for kernel.
large_class_declaration_test: Slow
nnbd/*: Skip
diff --git a/tests/language_2/language_2_kernel.status b/tests/language_2/language_2_kernel.status
index 0f1d7ea..9b43134 100644
--- a/tests/language_2/language_2_kernel.status
+++ b/tests/language_2/language_2_kernel.status
@@ -52,7 +52,6 @@
inference_enum_list_test: Skip # Issue 35885
[ $compiler == dartkp && $mode == debug && $runtime == dart_precompiled ]
-external_test/13: Crash
vm/precompiled_static_initializer_test: Slow
# ==== dartkp + dart_precompiled status lines ====
diff --git a/tests/language_2/language_2_precompiled.status b/tests/language_2/language_2_precompiled.status
index 4149ec3..f89d8f4 100644
--- a/tests/language_2/language_2_precompiled.status
+++ b/tests/language_2/language_2_precompiled.status
@@ -23,8 +23,6 @@
enum_duplicate_test/*: Skip # Uses Enum.toString()
enum_private_test/*: Skip # Uses Enum.toString()
enum_test: Skip # Uses Enum.toString()
-f_bounded_quantification4_test: Skip
-f_bounded_quantification5_test: Skip
full_stacktrace1_test: Skip
full_stacktrace2_test: Skip
full_stacktrace3_test: Skip
diff --git a/tests/language_2/language_2_spec_parser.status b/tests/language_2/language_2_spec_parser.status
index 28ae988..171c316 100644
--- a/tests/language_2/language_2_spec_parser.status
+++ b/tests/language_2/language_2_spec_parser.status
@@ -7,14 +7,11 @@
closure_type_test: Pass # Marked as RuntimeError for all in language_2.status.
conditional_import_string_test: Fail # Uses conditional import.
conditional_import_test: Fail # Uses conditional import.
-config_import_corelib_test: Fail # Uses conditional import.
-config_import_test: Fail # Uses conditional import.
const_native_factory_test: Skip # Uses `native`.
deep_nesting_expression_test: Skip # JVM stack overflow.
deep_nesting_statement_test: Skip # JVM stack overflow.
double_invalid_test: Skip # Contains illegaly formatted double.
extension_methods: Skip # Not yet supported.
-external_test/21: Fail # Test expects `runtime error`, it is a syntax error.
getter_declaration_negative_test: Fail # Negative, uses getter with parameter.
inst_field_initializer1_negative_test: Skip # Negative, not syntax.
instance_call_wrong_argument_count_negative_test: Skip # Negative, not syntax.
diff --git a/tests/language_2/mixin_constructor_forwarding/const_constructor_test.dart b/tests/language_2/mixin_constructor_forwarding/const_constructor_test.dart
index aa59e5e..ba57bdf 100644
--- a/tests/language_2/mixin_constructor_forwarding/const_constructor_test.dart
+++ b/tests/language_2/mixin_constructor_forwarding/const_constructor_test.dart
@@ -40,8 +40,6 @@
class Application = Base with Mixin;
-class Application2 extends Base with Mixin {}
-
main() {
Expect.equals(42, new Application.c1(42).m);
Expect.equals(42, new Application.c2(42).m);
@@ -59,53 +57,22 @@
Expect.equals(42, const Application.c14(42).m);
Expect.equals(42, const Application.c15(x: 42).m);
- Expect.equals(37, new Application.c2().m);
+ Expect.equals(37, new Application.c2().m); //# issue38304: ok
Expect.equals(37, new Application.c3().m);
- Expect.equals(37, const Application.c5().m);
+ Expect.equals(37, const Application.c5().m); //# issue38304: continued
Expect.equals(37, const Application.c6().m);
- Expect.equals(87, const Application.c8().m);
+ Expect.equals(87, const Application.c8().m); //# issue38304: continued
Expect.equals(87, const Application.c9().m);
- Expect.equals(87, const Application.c11().m);
+ Expect.equals(87, const Application.c11().m); //# issue38304: continued
Expect.equals(87, const Application.c12().m);
- Expect.equals(87, const Application.c14().m);
+ Expect.equals(87, const Application.c14().m); //# issue38304: continued
Expect.equals(87, const Application.c15().m);
- Expect.equals(42, new Application2.c1(42).m);
- Expect.equals(42, new Application2.c2(42).m);
- Expect.equals(42, new Application2.c3(x: 42).m);
- Expect.equals(42, const Application2.c4(42).m);
- Expect.equals(42, const Application2.c5(42).m);
- Expect.equals(42, const Application2.c6(x: 42).m);
- Expect.equals(42, const Application2.c7(42).m);
- Expect.equals(42, const Application2.c8(42).m);
- Expect.equals(42, const Application2.c9(x: 42).m);
- Expect.equals(42, const Application2.c10(42).m);
- Expect.equals(42, const Application2.c11(42).m);
- Expect.equals(42, const Application2.c12(x: 42).m);
- Expect.equals(42, const Application2.c13(42).m);
- Expect.equals(42, const Application2.c14(42).m);
- Expect.equals(42, const Application2.c15(x: 42).m);
-
- Expect.equals(37, new Application2.c2().m);
- Expect.equals(37, new Application2.c3().m);
- Expect.equals(37, const Application2.c5().m);
- Expect.equals(37, const Application2.c6().m);
- Expect.equals(87, const Application2.c8().m);
- Expect.equals(87, const Application2.c9().m);
- Expect.equals(87, const Application2.c11().m);
- Expect.equals(87, const Application2.c12().m);
- Expect.equals(87, const Application2.c14().m);
- Expect.equals(87, const Application2.c15().m);
-
// Only make forwarders const if original constructor is const.
const Application.c1(0); //# 01: compile-time error
const Application.c2(0); //# 02: compile-time error
const Application.c3(x: 0); //# 03: compile-time error
- const Application2.c1(0); //# 04: compile-time error
- const Application2.c2(0); //# 05: compile-time error
- const Application2.c3(x: 0); //# 06: compile-time error
// Only insert forwarders for generative constructors.
- new Application(); //# 07: compile-time error
- new Application2(); //# 08: compile-time error
+ new Application(); //# 04: compile-time error
}
diff --git a/tests/language_2/mixin_constructor_forwarding/const_constructor_with_field_test.dart b/tests/language_2/mixin_constructor_forwarding/const_constructor_with_field_test.dart
index ee9bad7..e22be63 100644
--- a/tests/language_2/mixin_constructor_forwarding/const_constructor_with_field_test.dart
+++ b/tests/language_2/mixin_constructor_forwarding/const_constructor_with_field_test.dart
@@ -44,8 +44,6 @@
class Application = Base with Mixin;
-class Application2 extends Base with Mixin {}
-
main() {
Expect.equals(42, new Application.c1(42).m);
Expect.equals(42, new Application.c2(42).m);
@@ -63,44 +61,17 @@
Expect.equals(42, new Application.c14(42).m);
Expect.equals(42, new Application.c15(x: 42).m);
- Expect.equals(37, new Application.c2().m);
+ Expect.equals(37, new Application.c2().m); //# issue38304: ok
Expect.equals(37, new Application.c3().m);
- Expect.equals(37, new Application.c5().m);
+ Expect.equals(37, new Application.c5().m); //# issue38304: continued
Expect.equals(37, new Application.c6().m);
- Expect.equals(87, new Application.c8().m);
+ Expect.equals(87, new Application.c8().m); //# issue38304: continued
Expect.equals(87, new Application.c9().m);
- Expect.equals(87, new Application.c11().m);
+ Expect.equals(87, new Application.c11().m); //# issue38304: continued
Expect.equals(87, new Application.c12().m);
- Expect.equals(87, new Application.c14().m);
+ Expect.equals(87, new Application.c14().m); //# issue38304: continued
Expect.equals(87, new Application.c15().m);
- Expect.equals(42, new Application2.c1(42).m);
- Expect.equals(42, new Application2.c2(42).m);
- Expect.equals(42, new Application2.c3(x: 42).m);
- Expect.equals(42, new Application2.c4(42).m);
- Expect.equals(42, new Application2.c5(42).m);
- Expect.equals(42, new Application2.c6(x: 42).m);
- Expect.equals(42, new Application2.c7(42).m);
- Expect.equals(42, new Application2.c8(42).m);
- Expect.equals(42, new Application2.c9(x: 42).m);
- Expect.equals(42, new Application2.c10(42).m);
- Expect.equals(42, new Application2.c11(42).m);
- Expect.equals(42, new Application2.c12(x: 42).m);
- Expect.equals(42, new Application2.c13(42).m);
- Expect.equals(42, new Application2.c14(42).m);
- Expect.equals(42, new Application2.c15(x: 42).m);
-
- Expect.equals(37, new Application2.c2().m);
- Expect.equals(37, new Application2.c3().m);
- Expect.equals(37, new Application2.c5().m);
- Expect.equals(37, new Application2.c6().m);
- Expect.equals(87, new Application2.c8().m);
- Expect.equals(87, new Application2.c9().m);
- Expect.equals(87, new Application2.c11().m);
- Expect.equals(87, new Application2.c12().m);
- Expect.equals(87, new Application2.c14().m);
- Expect.equals(87, new Application2.c15().m);
-
// Don't make constructors const if mixin declares instance variable.
const Application.c4(42); //# 00: compile-time error
const Application.c5(42); //# 01: compile-time error
@@ -115,20 +86,6 @@
const Application.c14(42); //# 10: compile-time error
const Application.c15(x: 42); //# 11: compile-time error
- const Application2.c4(42); //# 12: compile-time error
- const Application2.c5(42); //# 13: compile-time error
- const Application2.c6(x: 42); //# 14: compile-time error
- const Application2.c7(42); //# 15: compile-time error
- const Application2.c8(42); //# 16: compile-time error
- const Application2.c9(x: 42); //# 17: compile-time error
- const Application2.c10(42); //# 18: compile-time error
- const Application2.c11(42); //# 19: compile-time error
- const Application2.c12(x: 42); //# 20: compile-time error
- const Application2.c13(42); //# 21: compile-time error
- const Application2.c14(42); //# 22: compile-time error
- const Application2.c15(x: 42); //# 23: compile-time error
-
// Only insert forwarders for generative constructors.
- new Application(); //# 24: compile-time error
- new Application2(); //# 25: compile-time error
+ new Application(); //# 12: compile-time error
}
diff --git a/tests/language_2/mixin_constructor_forwarding/optional_named_parameters_test.dart b/tests/language_2/mixin_constructor_forwarding/optional_named_parameters_test.dart
index e4b7c58..8cab4c5 100644
--- a/tests/language_2/mixin_constructor_forwarding/optional_named_parameters_test.dart
+++ b/tests/language_2/mixin_constructor_forwarding/optional_named_parameters_test.dart
@@ -22,8 +22,6 @@
class Application = Base with Mixin;
-class Application2 extends Base with Mixin {}
-
main() {
Expect.equals(42, new Application.c1(42).m);
Expect.equals(42, new Application.c2(x: 42).m);
@@ -35,17 +33,6 @@
Expect.equals(37, new Application.c4().m);
Expect.equals(37, new Application.c6().m);
- Expect.equals(42, new Application2.c1(42).m);
- Expect.equals(42, new Application2.c2(x: 42).m);
- Expect.equals(42, new Application2.c3(42).m);
- Expect.equals(42, new Application2.c4(x: 42).m);
- Expect.equals(42, new Application2.c5(42).m);
- Expect.equals(42, new Application2.c6(x: 42).m);
- Expect.equals(37, new Application2.c2().m);
- Expect.equals(37, new Application2.c4().m);
- Expect.equals(37, new Application2.c6().m);
-
// Only insert forwarders for generative constructors.
new Application(); //# 01: compile-time error
- new Application2(); //# 02: compile-time error
}
diff --git a/tests/language_2/mixin_constructor_forwarding/optional_positional_parameters_test.dart b/tests/language_2/mixin_constructor_forwarding/optional_positional_parameters_test.dart
index cf84a97..1411223 100644
--- a/tests/language_2/mixin_constructor_forwarding/optional_positional_parameters_test.dart
+++ b/tests/language_2/mixin_constructor_forwarding/optional_positional_parameters_test.dart
@@ -22,8 +22,6 @@
class Application = Base with Mixin;
-class Application2 extends Base with Mixin {}
-
main() {
Expect.equals(42, new Application.c1(42).m);
Expect.equals(42, new Application.c2(42).m);
@@ -35,17 +33,6 @@
Expect.equals(37, new Application.c4().m);
Expect.equals(37, new Application.c6().m);
- Expect.equals(42, new Application2.c1(42).m);
- Expect.equals(42, new Application2.c2(42).m);
- Expect.equals(42, new Application2.c3(42).m);
- Expect.equals(42, new Application2.c4(42).m);
- Expect.equals(42, new Application2.c5(42).m);
- Expect.equals(42, new Application2.c6(42).m);
- Expect.equals(37, new Application2.c2().m);
- Expect.equals(37, new Application2.c4().m);
- Expect.equals(37, new Application2.c6().m);
-
// Only insert forwarders for generative constructors.
new Application(); //# 01: compile-time error
- new Application2(); //# 02: compile-time error
}
diff --git a/tests/language_2/override_const_field_test.dart b/tests/language_2/override_const_field_test.dart
new file mode 100644
index 0000000..8018296
--- /dev/null
+++ b/tests/language_2/override_const_field_test.dart
@@ -0,0 +1,23 @@
+// Copyright (c) 2019, 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 test checking that static/instance field shadowing do not conflict.
+
+import 'package:expect/expect.dart';
+
+class A {
+ final field;
+ const A(this.field);
+}
+
+class B extends A {
+ final field;
+ const B(this.field, fieldA) : super(fieldA);
+ get fieldA => super.field;
+}
+
+main() {
+ const b = B(1, 2);
+ Expect.equals(1, b.field);
+ Expect.equals(2, b.fieldA);
+}
diff --git a/tests/language_2/setter_no_getter_test.dart b/tests/language_2/setter_no_getter_test.dart
index c6371c1..756ccb0 100644
--- a/tests/language_2/setter_no_getter_test.dart
+++ b/tests/language_2/setter_no_getter_test.dart
@@ -2,13 +2,21 @@
// 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.
-import "package:expect/expect.dart";
-
-/* // //# 01: runtime error
-get topLevel => 42;
-*/ // //# 01: continued
set topLevel(var value) {}
+class Example {
+ set foo(var value) {}
+}
+
main() {
- Expect.equals(42, topLevel++); //# 01: continued
+ print(topLevel++);
+ // ^
+ // [analyzer] unspecified
+ // [cfe] Getter not found: 'topLevel'.
+
+ Example ex = new Example();
+ print(ex.foo++);
+ // ^
+ // [analyzer] unspecified
+ // [cfe] The getter 'foo' isn't defined for the class 'Example'.
}
diff --git a/tests/language_2/super_call4_test.dart b/tests/language_2/super_call4_test.dart
index dbff2ea..aced9d7 100644
--- a/tests/language_2/super_call4_test.dart
+++ b/tests/language_2/super_call4_test.dart
@@ -4,12 +4,7 @@
import "package:expect/expect.dart";
-// Checks that noSuchMethod is resolved in the super class and not in the
-// current class.
-
class C {
- E e = new E();
-
bool foo();
bool bar(int a);
bool baz({int b});
@@ -21,34 +16,30 @@
class D extends C {
bool noSuchMethod(Invocation im) => false;
+ // `super.foo()` et al. will statically use [C]'s [noSuchMethod] forwarder,
+ // but the forwarder will (virtually) call [D]'s [noSuchMethod] at runtime.
+
test1() {
- return super.foo(); //# 01: compile-time error
+ return super.foo();
}
test2() {
- return super.bar(1); //# 01: compile-time error
+ return super.bar(1);
}
test3() {
- return super.baz(b: 2); //# 01: compile-time error
+ return super.baz(b: 2);
}
test4() {
- return super.boz(1, c: 2); //# 01: compile-time error
+ return super.boz(1, c: 2);
}
}
-class E {
- bool foo() => true;
- bool bar(int a) => a == 1;
- bool baz({int b}) => b == 2;
- bool boz(int a, {int c}) => a == 1 && c == 2;
-}
-
main() {
var d = new D();
- Expect.isNull(d.test1());
- Expect.isNull(d.test2());
- Expect.isNull(d.test3());
- Expect.isNull(d.test4());
+ Expect.isFalse(d.test1());
+ Expect.isFalse(d.test2());
+ Expect.isFalse(d.test3());
+ Expect.isFalse(d.test4());
}
diff --git a/tests/language_2/syntax_test.dart b/tests/language_2/syntax_test.dart
index 5946a1d..107e022 100644
--- a/tests/language_2/syntax_test.dart
+++ b/tests/language_2/syntax_test.dart
@@ -232,8 +232,8 @@
G<> t; //# 57: syntax error
G<null> t; //# 58: syntax error
A<void> a = null; //# 59: compile-time error
- void v; //# 60: compile-time error
- void v = null; //# 61: compile-time error
+ void v; //# 60: ok
+ void v = null; //# 61: ok
print(null is void); //# 62: syntax error
new A();
new B();
diff --git a/tests/language_2/type_variable_bound_access_test.dart b/tests/language_2/type_variable_bound_access_test.dart
new file mode 100644
index 0000000..019a75f
--- /dev/null
+++ b/tests/language_2/type_variable_bound_access_test.dart
@@ -0,0 +1,29 @@
+// Copyright (c) 2019, 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.
+
+class DynamicClass<T extends dynamic, S extends T> {
+ T field1;
+ T field2;
+
+ DynamicClass(this.field1, this.field2);
+
+ method() => field1 * field2;
+}
+
+class NumClass<T extends num, S extends T> {
+ T field1;
+ S field2;
+
+ NumClass(this.field1, this.field2);
+
+ num method1() => field1 * field2;
+
+ num method2() => field1 + field2.length; //# 01: compile-time error
+}
+
+main() {
+ new DynamicClass<num, int>(0.5, 2).method();
+ new NumClass<num, double>(2, 0.5).method1();
+ new NumClass<num, double>(2, 0.5).method2(); //# 01: continued
+}
diff --git a/tests/language_2/variance/syntax/variance_disabled_syntax_test.dart b/tests/language_2/variance/syntax/variance_disabled_syntax_test.dart
new file mode 100644
index 0000000..9230532
--- /dev/null
+++ b/tests/language_2/variance/syntax/variance_disabled_syntax_test.dart
@@ -0,0 +1,41 @@
+// Copyright (c) 2019, 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.
+
+// Tests that since `variance` flag is disabled, correct variance modifier usage will issue an error.
+
+class A<in X> {}
+// ^^
+// [analyzer] COMPILE_TIME_ERROR.BUILT_IN_IDENTIFIER_AS_TYPE_PARAMETER_NAME
+// [cfe] Expected an identifier, but got 'in'.
+// ^^
+// [analyzer] SYNTACTIC_ERROR.MISSING_IDENTIFIER
+// ^
+// [analyzer] SYNTACTIC_ERROR.EXPECTED_TOKEN
+// [cfe] Expected ',' before this.
+
+class B<out X, in Y, inout Z> {}
+// ^
+// [analyzer] SYNTACTIC_ERROR.EXPECTED_TOKEN
+// [cfe] Expected ',' before this.
+// ^^
+// [analyzer] COMPILE_TIME_ERROR.BUILT_IN_IDENTIFIER_AS_TYPE_PARAMETER_NAME
+// [cfe] Expected an identifier, but got 'in'.
+// ^^
+// [analyzer] SYNTACTIC_ERROR.MISSING_IDENTIFIER
+// ^
+// [analyzer] SYNTACTIC_ERROR.EXPECTED_TOKEN
+// [cfe] Expected ',' before this.
+// ^
+// [analyzer] SYNTACTIC_ERROR.EXPECTED_TOKEN
+// [cfe] Expected ',' before this.
+
+mixin C<inout T> {}
+// ^
+// [analyzer] SYNTACTIC_ERROR.EXPECTED_TOKEN
+// [cfe] Expected ',' before this.
+
+typedef D<out T> = T Function();
+// ^
+// [analyzer] SYNTACTIC_ERROR.EXPECTED_TOKEN
+// [cfe] Expected ',' before this.
diff --git a/tests/language_2/variance/syntax/variance_keyword_identifier_syntax_test.dart b/tests/language_2/variance/syntax/variance_keyword_identifier_syntax_test.dart
new file mode 100644
index 0000000..5028b51
--- /dev/null
+++ b/tests/language_2/variance/syntax/variance_keyword_identifier_syntax_test.dart
@@ -0,0 +1,36 @@
+// Copyright (c) 2019, 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.
+
+// Tests identifier usage of keywords `out` and `inout`, correct usage of `in`.
+
+import "package:expect/expect.dart";
+
+class OutParameter {
+ var out = 3;
+ int func(int out) {
+ return out;
+ }
+}
+
+class inout {
+ void out(int x) {}
+}
+
+var out = 5;
+
+main() {
+ OutParameter x = new OutParameter();
+ Expect.equals(2, x.func(2));
+ Expect.equals(3, x.out);
+
+ inout foo = inout();
+ foo.out(4);
+
+ Expect.equals(5, out);
+
+ var collection = [0, 1, 2];
+ for (var x in collection) {
+ Expect.isTrue(x is int);
+ }
+}
diff --git a/tests/language_2/vm/regression_38231_test.dart b/tests/language_2/vm/regression_38231_test.dart
new file mode 100644
index 0000000..a269d67
--- /dev/null
+++ b/tests/language_2/vm/regression_38231_test.dart
@@ -0,0 +1,126 @@
+// Copyright (c) 2019, 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.
+
+// VMOptions=--optimization_counter_threshold=1
+
+import "package:expect/expect.dart";
+
+import 'dart:typed_data';
+
+// Found by DartFuzzing: would sometimes crash on OSR
+// https://github.com/dart-lang/sdk/issues/38231
+
+import 'dart:async';
+import 'dart:cli';
+import 'dart:collection';
+import 'dart:convert';
+import 'dart:core';
+import 'dart:io';
+import 'dart:isolate';
+import 'dart:math';
+import 'dart:typed_data';
+
+Map<int, String> var0 = {
+ 41: 'V\u2665Y\u2665#Xs',
+ for (int loc0 in {
+ if (true) for (int loc0 in {-2147483649}) -4294967167 else if (false) -1,
+ -60,
+ -82,
+ -21,
+ for (int loc0 in [
+ -9223372036854771712,
+ for (int loc0 = 0; loc0 < 53; loc0++) 96
+ ])
+ 1,
+ -58,
+ 77
+ })
+ 95: '',
+ 5: 'z2\u2665e',
+ if (false) for (int loc0 in [-87, -2147483649, 0, 97, -53, 95]) 10: '#synP3',
+ 22: ''
+};
+String var1 = ')LIpwG';
+double var2 = 0.30016980633333135;
+bool var3 = true;
+bool var4 = true;
+int var5 = -9223372036854774808;
+double var6 = 0.7012235530406754;
+String var7 = 'H';
+List<int> var8 = [90, -50, -34, -97, -33, 1];
+Set<int> var9 = {
+ 42,
+ 36,
+ 9223372034707292159,
+ ...{52},
+ 97,
+ for (int loc0 in {
+ if (true) ...{13} else -54,
+ -26,
+ -38,
+ 9223372032559808513,
+ 60
+ })
+ for (int loc1 in {
+ for (int loc1 in {19, 60}) -4294967280,
+ -17,
+ -62
+ }) ...{23, 11},
+ for (int loc0 = 0; loc0 < 30; loc0++) -44
+};
+Map<int, String> var10 = {
+ for (int loc0 in {
+ ...{
+ -52,
+ -9223372030412324864,
+ if (true) 82,
+ ...{76, 5, 9223372032559841279, 98, 58, 97, -127, 72},
+ for (int loc0 in [-97]) -14,
+ for (int loc0 = 0; loc0 < 21; loc0++) 88
+ },
+ -52,
+ for (int loc0 = 0; loc0 < 63; loc0++) ...{64, 0},
+ for (int loc0 = 0; loc0 < 67; loc0++) ...{67}
+ })
+ 54: '',
+ 41: 'cvokV0',
+ 4: '9\u2665',
+ 35: 'vRkv',
+ 41: '\u2665',
+ 63: 'Nu+u\u26659S'
+};
+
+class X0 {}
+
+class X1 with X0 {
+ bool foo1_0(List<int> par1, bool par2) => true;
+ Map<int, String> foo1_1(Set<int> par1, bool par2, Set<int> par3) {
+ return {1: "a", 2: "b"};
+ }
+}
+
+main() {
+ try {
+ X1().foo1_0([1, 2], true);
+ } catch (exception, stackTrace) {
+ print('X1().foo1_0() throws');
+ }
+ try {
+ X1().foo1_1(
+ {
+ 32,
+ -94,
+ -2147483649,
+ -43,
+ for (int loc0 in {56, -31}) -9223372032559775745,
+ 53,
+ 86,
+ 4294967296
+ },
+ var4,
+ {1, 2});
+ } catch (exception, stackTrace) {
+ print('X1().foo1_1() throws');
+ }
+}
diff --git a/tests/lib_2/async/stream_distinct_test.dart b/tests/lib_2/async/stream_distinct_test.dart
index bc642d4..354c258 100644
--- a/tests/lib_2/async/stream_distinct_test.dart
+++ b/tests/lib_2/async/stream_distinct_test.dart
@@ -66,7 +66,7 @@
new Stream.fromIterable([1, 1, 2, 2, 1, 3])
.map((v) => new T(v))
.distinct()
- .transform(reifyErrors)
+ .transform(reifyErrors.cast<T, dynamic>())
.map((v) => v is T ? v.value : "$v"),
[1, "[2]", "[2]", 3],
"==-throws");
diff --git a/tests/lib_2/async/timer_not_available_test.dart b/tests/lib_2/async/timer_not_available_test.dart
deleted file mode 100644
index fcbcc13..0000000
--- a/tests/lib_2/async/timer_not_available_test.dart
+++ /dev/null
@@ -1,27 +0,0 @@
-// Copyright (c) 2011, 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.
-
-library timerNotAvailable;
-
-import 'package:expect/expect.dart';
-import 'dart:async';
-
-main() {
- final ms = const Duration(milliseconds: 1);
- bool failed = false;
- try {
- new Timer(ms * 5, () {});
- } on UnsupportedError catch (e) {
- failed = true;
- }
- Expect.isTrue(failed);
- failed = false;
- try {
- var t = new Timer.periodic(ms * 10, (_) {});
- t.cancel();
- } on UnsupportedError catch (e) {
- failed = true;
- }
- Expect.isTrue(failed);
-}
diff --git a/tests/lib_2/html/postmessage_anonymous_test.dart b/tests/lib_2/html/postmessage_anonymous_test.dart
new file mode 100644
index 0000000..ab3b1ec
--- /dev/null
+++ b/tests/lib_2/html/postmessage_anonymous_test.dart
@@ -0,0 +1,53 @@
+// Copyright (c) 2019, 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.
+
+@JS()
+library postmessage_anonymous_test;
+
+import 'dart:async';
+import 'dart:html';
+import 'package:expect/expect.dart';
+import 'package:js/js.dart';
+
+const String JS_CODE = """
+window.addEventListener('message', handler);
+function handler(e) {
+ var data = e.data;
+ if (typeof data == 'string') return;
+ if (data.recipient != 'JS') return;
+ var response = {recipient: 'DART', msg: data.msg};
+ window.removeEventListener('message', handler);
+ window.postMessage(response, '*');
+}
+""";
+
+const String TEST_MSG = "hello world";
+
+@JS()
+@anonymous
+class Message {
+ external String get recipient;
+ external String get msg;
+ external factory Message({String recipient, String msg});
+}
+
+main() {
+ var subscription;
+ subscription = window.onMessage.listen((e) {
+ var data = e.data;
+ if (data is String) return;
+ if (data['recipient'] != 'DART') return;
+ subscription.cancel();
+ Expect.equals(TEST_MSG, data['msg']);
+ });
+ injectSource(JS_CODE);
+ window.postMessage(Message(recipient: 'JS', msg: TEST_MSG), '*');
+}
+
+void injectSource(String code) {
+ final script = new ScriptElement();
+ script.type = 'text/javascript';
+ script.innerHtml = code;
+ document.body.append(script);
+}
diff --git a/tests/lib_2/lib_2_precompiled.status b/tests/lib_2/lib_2_precompiled.status
index eb79746..5f9922d 100644
--- a/tests/lib_2/lib_2_precompiled.status
+++ b/tests/lib_2/lib_2_precompiled.status
@@ -4,7 +4,6 @@
[ $compiler == none ]
async/future_or_strong_test: RuntimeError
-async/timer_not_available_test: SkipByDesign # only meant to test when there is no way to implement timer (currently only in d8)
isolate/compile_time_error_test/01: Skip # Issue 12587
isolate/ping_test: Skip # Resolve test issues
mirrors/symbol_validation_test: RuntimeError # Issue 13596
diff --git a/tests/lib_2/mirrors/mirrors_reader_test.dart b/tests/lib_2/mirrors/mirrors_reader_test.dart
index 8717f45..81154d6 100644
--- a/tests/lib_2/mirrors/mirrors_reader_test.dart
+++ b/tests/lib_2/mirrors/mirrors_reader_test.dart
@@ -31,7 +31,7 @@
}
bool allowUnsupported(var receiver, String tag, UnsupportedError exception) {
- if (mirrorSystemType == '_LocalMirrorSystem') {
+ if (mirrorSystemType == '_MirrorSystem') {
// VM mirror system.
if (tag.endsWith('location')) {
return receiver is ParameterMirror;
@@ -49,7 +49,7 @@
// [DeclarationMirror.location] is intentionally not supported in runtime
// mirrors.
- if (mirrorSystemType == '_LocalMirrorSystem') {
+ if (mirrorSystemType == '_MirrorSystem') {
// VM mirror system.
} else if (mirrorSystemType == 'JsMirrorSystem') {
// Dart2js runtime mirror system.
diff --git a/tests/lib_2/mirrors/parameter_abstract_test.dart b/tests/lib_2/mirrors/parameter_abstract_test.dart
index 298f5e9..252d9e5 100644
--- a/tests/lib_2/mirrors/parameter_abstract_test.dart
+++ b/tests/lib_2/mirrors/parameter_abstract_test.dart
@@ -2,8 +2,6 @@
// 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.
-// BOGUS: Note that both AST and bytecode modes are missing default values.
-
import 'dart:mirrors';
import 'package:expect/expect.dart';
@@ -23,12 +21,12 @@
MethodMirror foo1 = cm.declarations[#foo1];
expect('Method(s(foo1) in s(C), abstract)', foo1);
expect(
- 'Parameter(s(x) in s(foo1), optional, named, value = Instance(value = 1), type = Class(s(int) in s(dart.core), top-level))',
+ 'Parameter(s(x) in s(foo1), optional, named, type = Class(s(int) in s(dart.core), top-level))',
foo1.parameters[0]);
expect(
- 'Parameter(s(y) in s(foo1), optional, named, value = Instance(value = 2), type = Class(s(int) in s(dart.core), top-level))',
+ 'Parameter(s(y) in s(foo1), optional, named, type = Class(s(int) in s(dart.core), top-level))',
foo1.parameters[1]);
expect(
- 'Parameter(s(z) in s(foo1), optional, named, value = Instance(value = 3), type = Class(s(int) in s(dart.core), top-level))',
+ 'Parameter(s(z) in s(foo1), optional, named, type = Class(s(int) in s(dart.core), top-level))',
foo1.parameters[2]);
}
diff --git a/tests/lib_2/mirrors/stringify.dart b/tests/lib_2/mirrors/stringify.dart
index b726832..6ff5c3f 100644
--- a/tests/lib_2/mirrors/stringify.dart
+++ b/tests/lib_2/mirrors/stringify.dart
@@ -175,7 +175,7 @@
throw 'Unexpected value: $value';
}
-expect(expected, actual, [String reason]) {
+expect(expected, actual, [String reason = ""]) {
Expect.stringEquals(expected, stringify(actual), reason);
}
diff --git a/tests/lib_2/wasm/basic_test.dart b/tests/lib_2/wasm/basic_test.dart
new file mode 100644
index 0000000..34ae182
--- /dev/null
+++ b/tests/lib_2/wasm/basic_test.dart
@@ -0,0 +1,30 @@
+// Copyright (c) 2019, 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.
+
+// Test that we can load a wasm module, find a function, and call it.
+
+import "package:expect/expect.dart";
+import "dart:wasm";
+import "dart:typed_data";
+
+void main() {
+ // int64_t square(int64_t n) { return n * n; }
+ var data = Uint8List.fromList([
+ 0x00, 0x61, 0x73, 0x6d, 0x01, 0x00, 0x00, 0x00, 0x01, 0x06, 0x01, 0x60,
+ 0x01, 0x7e, 0x01, 0x7e, 0x03, 0x02, 0x01, 0x00, 0x04, 0x05, 0x01, 0x70,
+ 0x01, 0x01, 0x01, 0x05, 0x03, 0x01, 0x00, 0x02, 0x06, 0x08, 0x01, 0x7f,
+ 0x01, 0x41, 0x80, 0x88, 0x04, 0x0b, 0x07, 0x13, 0x02, 0x06, 0x6d, 0x65,
+ 0x6d, 0x6f, 0x72, 0x79, 0x02, 0x00, 0x06, 0x73, 0x71, 0x75, 0x61, 0x72,
+ 0x65, 0x00, 0x00, 0x0a, 0x09, 0x01, 0x07, 0x00, 0x20, 0x00, 0x20, 0x00,
+ 0x7e, 0x0b,
+ ]);
+
+ var inst = WasmModule(data).instantiate(WasmImports("env")
+ ..addMemory("memory", WasmMemory(256, 1024))
+ ..addGlobal<Int32>("__memory_base", 1024, false));
+ var fn = inst.lookupFunction<Int64 Function(Int64)>("square");
+ int n = fn.call([1234]);
+
+ Expect.equals(1234 * 1234, n);
+}
diff --git a/tests/lib_2/wasm/corrupted_error_test.dart b/tests/lib_2/wasm/corrupted_error_test.dart
new file mode 100644
index 0000000..fcc4085
--- /dev/null
+++ b/tests/lib_2/wasm/corrupted_error_test.dart
@@ -0,0 +1,20 @@
+// Copyright (c) 2019, 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.
+
+// Test error thrown when the wasm module is corrupted.
+
+import "package:expect/expect.dart";
+import "dart:wasm";
+import "dart:typed_data";
+
+void main() {
+ var data = Uint8List.fromList([
+ 0x01, 0x00, 0x00, 0x00, 0x01, 0x06, 0x01, 0x60, 0x01, 0x7e, 0x01, 0x7e,
+ 0x07, 0x13, 0x02, 0x06, 0x6d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x02, 0x00,
+ 0x06, 0x73, 0x71, 0x75, 0x61, 0x72, 0x65, 0x00, 0x00, 0x00, 0x20, 0x00,
+ 0x7e, 0x0b,
+ ]);
+
+ Expect.throwsArgumentError(() => WasmModule(data));
+}
diff --git a/tests/lib_2/wasm/fn_call_error_test.dart b/tests/lib_2/wasm/fn_call_error_test.dart
new file mode 100644
index 0000000..e1d2441
--- /dev/null
+++ b/tests/lib_2/wasm/fn_call_error_test.dart
@@ -0,0 +1,31 @@
+// Copyright (c) 2019, 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.
+
+// Test error thrown when a function is called with the wrong args.
+
+import "package:expect/expect.dart";
+import "dart:wasm";
+import "dart:typed_data";
+
+void main() {
+ // int64_t square(int64_t n) { return n * n; }
+ var data = Uint8List.fromList([
+ 0x00, 0x61, 0x73, 0x6d, 0x01, 0x00, 0x00, 0x00, 0x01, 0x06, 0x01, 0x60,
+ 0x01, 0x7e, 0x01, 0x7e, 0x03, 0x02, 0x01, 0x00, 0x04, 0x05, 0x01, 0x70,
+ 0x01, 0x01, 0x01, 0x05, 0x03, 0x01, 0x00, 0x02, 0x06, 0x08, 0x01, 0x7f,
+ 0x01, 0x41, 0x80, 0x88, 0x04, 0x0b, 0x07, 0x13, 0x02, 0x06, 0x6d, 0x65,
+ 0x6d, 0x6f, 0x72, 0x79, 0x02, 0x00, 0x06, 0x73, 0x71, 0x75, 0x61, 0x72,
+ 0x65, 0x00, 0x00, 0x0a, 0x09, 0x01, 0x07, 0x00, 0x20, 0x00, 0x20, 0x00,
+ 0x7e, 0x0b,
+ ]);
+
+ var inst = WasmModule(data).instantiate(WasmImports("env")
+ ..addMemory("memory", WasmMemory(256, 1024))
+ ..addGlobal<Int32>("__memory_base", 1024, false));
+ var fn = inst.lookupFunction<Int64 Function(Int64)>("square");
+
+ Expect.throwsArgumentError(() => fn.call([]));
+ Expect.throwsArgumentError(() => fn.call([1, 2, 3]));
+ Expect.throwsArgumentError(() => fn.call([1.23]));
+}
diff --git a/tests/lib_2/wasm/fn_mismatch_error_test.dart b/tests/lib_2/wasm/fn_mismatch_error_test.dart
new file mode 100644
index 0000000..308a829
--- /dev/null
+++ b/tests/lib_2/wasm/fn_mismatch_error_test.dart
@@ -0,0 +1,37 @@
+// Copyright (c) 2019, 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.
+
+// Test error thrown when the loaded function can't be found.
+
+import "package:expect/expect.dart";
+import "dart:wasm";
+import "dart:typed_data";
+
+void main() {
+ // int64_t square(int64_t n) { return n * n; }
+ var data = Uint8List.fromList([
+ 0x00, 0x61, 0x73, 0x6d, 0x01, 0x00, 0x00, 0x00, 0x01, 0x06, 0x01, 0x60,
+ 0x01, 0x7e, 0x01, 0x7e, 0x03, 0x02, 0x01, 0x00, 0x04, 0x05, 0x01, 0x70,
+ 0x01, 0x01, 0x01, 0x05, 0x03, 0x01, 0x00, 0x02, 0x06, 0x08, 0x01, 0x7f,
+ 0x01, 0x41, 0x80, 0x88, 0x04, 0x0b, 0x07, 0x13, 0x02, 0x06, 0x6d, 0x65,
+ 0x6d, 0x6f, 0x72, 0x79, 0x02, 0x00, 0x06, 0x73, 0x71, 0x75, 0x61, 0x72,
+ 0x65, 0x00, 0x00, 0x0a, 0x09, 0x01, 0x07, 0x00, 0x20, 0x00, 0x20, 0x00,
+ 0x7e, 0x0b,
+ ]);
+
+ var inst = WasmModule(data).instantiate(WasmImports("env")
+ ..addMemory("memory", WasmMemory(256, 1024))
+ ..addGlobal<Int32>("__memory_base", 1024, false));
+ Expect.isNotNull(inst.lookupFunction<Int64 Function(Int64)>("square"));
+ Expect.throwsArgumentError(
+ () => inst.lookupFunction<Int64 Function(Int64)>("blah"));
+ Expect.throwsArgumentError(
+ () => inst.lookupFunction<Int64 Function()>("square"));
+ Expect.throwsArgumentError(
+ () => inst.lookupFunction<Int64 Function(Int64, Int64)>("square"));
+ Expect.throwsArgumentError(
+ () => inst.lookupFunction<Void Function(Int64)>("square"));
+ Expect.throwsArgumentError(
+ () => inst.lookupFunction<Void Function(dynamic)>("square"));
+}
diff --git a/tests/lib_2/wasm/numerics_test.dart b/tests/lib_2/wasm/numerics_test.dart
new file mode 100644
index 0000000..1d7a199
--- /dev/null
+++ b/tests/lib_2/wasm/numerics_test.dart
@@ -0,0 +1,51 @@
+// Copyright (c) 2019, 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.
+
+// Test numeric types.
+
+import "package:expect/expect.dart";
+import "dart:wasm";
+import "dart:typed_data";
+
+void main() {
+ // int64_t addI64(int64_t x, int64_t y) { return x + y; }
+ // int32_t addI32(int32_t x, int32_t y) { return x + y; }
+ // double addF64(double x, double y) { return x + y; }
+ // float addF32(float x, float y) { return x + y; }
+ var data = Uint8List.fromList([
+ 0x00, 0x61, 0x73, 0x6d, 0x01, 0x00, 0x00, 0x00, 0x01, 0x19, 0x04, 0x60,
+ 0x02, 0x7e, 0x7e, 0x01, 0x7e, 0x60, 0x02, 0x7f, 0x7f, 0x01, 0x7f, 0x60,
+ 0x02, 0x7c, 0x7c, 0x01, 0x7c, 0x60, 0x02, 0x7d, 0x7d, 0x01, 0x7d, 0x03,
+ 0x05, 0x04, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x01, 0x70, 0x01, 0x01,
+ 0x01, 0x05, 0x03, 0x01, 0x00, 0x02, 0x06, 0x08, 0x01, 0x7f, 0x01, 0x41,
+ 0x80, 0x88, 0x04, 0x0b, 0x07, 0x2e, 0x05, 0x06, 0x6d, 0x65, 0x6d, 0x6f,
+ 0x72, 0x79, 0x02, 0x00, 0x06, 0x61, 0x64, 0x64, 0x49, 0x36, 0x34, 0x00,
+ 0x00, 0x06, 0x61, 0x64, 0x64, 0x49, 0x33, 0x32, 0x00, 0x01, 0x06, 0x61,
+ 0x64, 0x64, 0x46, 0x36, 0x34, 0x00, 0x02, 0x06, 0x61, 0x64, 0x64, 0x46,
+ 0x33, 0x32, 0x00, 0x03, 0x0a, 0x21, 0x04, 0x07, 0x00, 0x20, 0x01, 0x20,
+ 0x00, 0x7c, 0x0b, 0x07, 0x00, 0x20, 0x01, 0x20, 0x00, 0x6a, 0x0b, 0x07,
+ 0x00, 0x20, 0x00, 0x20, 0x01, 0xa0, 0x0b, 0x07, 0x00, 0x20, 0x00, 0x20,
+ 0x01, 0x92, 0x0b,
+ ]);
+
+ var inst = WasmModule(data).instantiate(WasmImports("env")
+ ..addMemory("memory", WasmMemory(256, 1024))
+ ..addGlobal<Int32>("__memory_base", 1024, false));
+ var addI64 = inst.lookupFunction<Int64 Function(Int64, Int64)>("addI64");
+ var addI32 = inst.lookupFunction<Int32 Function(Int32, Int32)>("addI32");
+ var addF64 = inst.lookupFunction<Double Function(Double, Double)>("addF64");
+ var addF32 = inst.lookupFunction<Float Function(Float, Float)>("addF32");
+
+ int i64 = addI64.call([0x123456789ABCDEF, 0xFEDCBA987654321]);
+ Expect.equals(0x1111111111111110, i64);
+
+ int i32 = addI32.call([0xABCDEF, 0xFEDCBA]);
+ Expect.equals(0x1aaaaa9, i32);
+
+ double f64 = addF64.call([1234.5678, 8765.4321]);
+ Expect.approxEquals(9999.9999, f64, 1e-6);
+
+ double f32 = addF32.call([1234.5678, 8765.4321]);
+ Expect.approxEquals(9999.9999, f32, 1e-3);
+}
diff --git a/tests/lib_2/wasm/void_test.dart b/tests/lib_2/wasm/void_test.dart
new file mode 100644
index 0000000..c2f0707
--- /dev/null
+++ b/tests/lib_2/wasm/void_test.dart
@@ -0,0 +1,36 @@
+// Copyright (c) 2019, 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.
+
+// Test functions with void return type, and functions that take no args.
+
+import "package:expect/expect.dart";
+import "dart:wasm";
+import "dart:typed_data";
+
+void main() {
+ // int64_t x = 0;
+ // void set(int64_t a, int64_t b) { x = a + b; }
+ // int64_t get() { return x; }
+ var data = Uint8List.fromList([
+ 0x00, 0x61, 0x73, 0x6d, 0x01, 0x00, 0x00, 0x00, 0x01, 0x0a, 0x02, 0x60,
+ 0x02, 0x7e, 0x7e, 0x00, 0x60, 0x00, 0x01, 0x7e, 0x03, 0x03, 0x02, 0x00,
+ 0x01, 0x04, 0x05, 0x01, 0x70, 0x01, 0x01, 0x01, 0x05, 0x03, 0x01, 0x00,
+ 0x02, 0x06, 0x08, 0x01, 0x7f, 0x01, 0x41, 0x90, 0x88, 0x04, 0x0b, 0x07,
+ 0x16, 0x03, 0x06, 0x6d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x02, 0x00, 0x03,
+ 0x73, 0x65, 0x74, 0x00, 0x00, 0x03, 0x67, 0x65, 0x74, 0x00, 0x01, 0x0a,
+ 0x1e, 0x02, 0x10, 0x00, 0x41, 0x00, 0x20, 0x01, 0x20, 0x00, 0x7c, 0x37,
+ 0x03, 0x80, 0x88, 0x80, 0x80, 0x00, 0x0b, 0x0b, 0x00, 0x41, 0x00, 0x29,
+ 0x03, 0x80, 0x88, 0x80, 0x80, 0x00, 0x0b, 0x0b, 0x0f, 0x01, 0x00, 0x41,
+ 0x80, 0x08, 0x0b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ ]);
+
+ var inst = WasmModule(data).instantiate(WasmImports("env")
+ ..addMemory("memory", WasmMemory(256, 1024))
+ ..addGlobal<Int32>("__memory_base", 1024, false));
+ var setFn = inst.lookupFunction<Void Function(Int64, Int64)>("set");
+ var getFn = inst.lookupFunction<Int64 Function()>("get");
+ Expect.isNull(setFn.call([123, 456]));
+ int n = getFn.call([]);
+ Expect.equals(123 + 456, n);
+}
diff --git a/tests/modular/nnbd/main.dart b/tests/modular/nnbd/main.dart
new file mode 100644
index 0000000..70b498a
--- /dev/null
+++ b/tests/modular/nnbd/main.dart
@@ -0,0 +1,17 @@
+// Copyright (c) 2019, 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.
+import 'package:expect/expect.dart';
+
+void main() {
+ int x = 42;
+ int? y;
+
+ Expect.equals(null, y);
+ Expect.throws(() { x = y!;});
+ Expect.equals(42, x);
+
+ y = 17;
+ x = y!;
+ Expect.equals(17, x);
+}
\ No newline at end of file
diff --git a/tests/modular/nnbd/modules.yaml b/tests/modular/nnbd/modules.yaml
new file mode 100644
index 0000000..9b67253
--- /dev/null
+++ b/tests/modular/nnbd/modules.yaml
@@ -0,0 +1,9 @@
+# Copyright (c) 2019, 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.
+#
+# NNBD modular test
+dependencies:
+ main: expect
+flags:
+ - non-nullable
\ No newline at end of file
diff --git a/third_party/wasmer/Cargo.toml b/third_party/wasmer/Cargo.toml
index 6253430..9f08f16 100644
--- a/third_party/wasmer/Cargo.toml
+++ b/third_party/wasmer/Cargo.toml
@@ -1,6 +1,6 @@
[package]
name = "wasmer"
-version = "0.6.0"
+version = "0.7.0"
[lib]
name = "wasmer"
@@ -8,4 +8,4 @@
path = "wasmer.rs"
[dependencies]
-wasmer-runtime-c-api = "0.6.0"
+wasmer-runtime-c-api = "0.7.0"
diff --git a/tools/VERSION b/tools/VERSION
index da78ef9..be73740 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -33,7 +33,7 @@
MAJOR 2
MINOR 6
PATCH 0
-PRERELEASE 1
+PRERELEASE 2
PRERELEASE_PATCH 0
-ABI_VERSION 14
-OLDEST_SUPPORTED_ABI_VERSION 13
+ABI_VERSION 16
+OLDEST_SUPPORTED_ABI_VERSION 16
diff --git a/tools/bots/flutter/compile_flutter.sh b/tools/bots/flutter/compile_flutter.sh
index 1c81fba..b86d351 100755
--- a/tools/bots/flutter/compile_flutter.sh
+++ b/tools/bots/flutter/compile_flutter.sh
@@ -30,8 +30,8 @@
popd
# Directly in temp directory again.
-mkdir engine
-pushd engine
+mkdir src
+pushd src
git clone -vv --depth 1 https://chromium.googlesource.com/external/github.com/flutter/engine flutter
mkdir third_party
pushd third_party
@@ -39,10 +39,12 @@
popd
popd
+./src/third_party/dart/tools/patches/flutter-engine/apply.sh || true
+
mkdir flutter_patched_sdk
$checkout/tools/sdks/dart-sdk/bin/dart --packages=$checkout/.packages $checkout/pkg/front_end/tool/_fasta/compile_platform.dart dart:core --single-root-scheme=org-dartlang-sdk --single-root-base=$checkout/ org-dartlang-sdk:///sdk/lib/libraries.json vm_outline_strong.dill vm_platform_strong.dill vm_outline_strong.dill
-$checkout/tools/sdks/dart-sdk/bin/dart --packages=$checkout/.packages $checkout/pkg/front_end/tool/_fasta/compile_platform.dart --target=flutter dart:core --single-root-scheme=org-dartlang-sdk --single-root-base=engine org-dartlang-sdk:///flutter/lib/snapshot/libraries.json vm_outline_strong.dill flutter_patched_sdk/platform_strong.dill flutter_patched_sdk/outline_strong.dill
+$checkout/tools/sdks/dart-sdk/bin/dart --packages=$checkout/.packages $checkout/pkg/front_end/tool/_fasta/compile_platform.dart --target=flutter dart:core --single-root-scheme=org-dartlang-sdk --single-root-base=src org-dartlang-sdk:///flutter/lib/snapshot/libraries.json vm_outline_strong.dill flutter_patched_sdk/platform_strong.dill flutter_patched_sdk/outline_strong.dill
popd
diff --git a/tools/bots/test_matrix.json b/tools/bots/test_matrix.json
index 64de89d..acd6fcf 100644
--- a/tools/bots/test_matrix.json
+++ b/tools/bots/test_matrix.json
@@ -987,6 +987,18 @@
]
},
{
+ "name": "ddc analyzer modular tests",
+ "script": "out/ReleaseX64/dart-sdk/bin/dart",
+ "testRunner": true,
+ "arguments": [
+ "pkg/dev_compiler/test/modular_ddc_suite.dart",
+ "--configuration-name",
+ "dartdevc-${system}-release",
+ "--verbose",
+ "--use-sdk"
+ ]
+ },
+ {
"name": "ddc kernel modular tests",
"script": "out/ReleaseX64/dart-sdk/bin/dart",
"testRunner": true,
diff --git a/tools/experimental_features.yaml b/tools/experimental_features.yaml
index 495b6d5..dff4c0e 100644
--- a/tools/experimental_features.yaml
+++ b/tools/experimental_features.yaml
@@ -79,6 +79,9 @@
triple-shift:
help: "Triple-shift operator"
+variance:
+ help: "Sound variance."
+
#
# Flags below this line are shipped, retired, or rejected, cannot be specified
# on the command line, and will eventually be removed.
diff --git a/tools/gn.py b/tools/gn.py
index 908bda9..5cdcc3e 100755
--- a/tools/gn.py
+++ b/tools/gn.py
@@ -408,10 +408,15 @@
other_group.add_argument(
'--bytecode',
'-b',
- help='Include bytecode in the VMs platform dill',
- default=False,
+ help='Use bytecode in Dart VM',
+ default=True,
action="store_true")
other_group.add_argument(
+ '--no-bytecode',
+ help='Disable bytecode in Dart VM',
+ dest='bytecode',
+ action="store_false")
+ other_group.add_argument(
'--clang', help='Use Clang', default=True, action='store_true')
other_group.add_argument(
'--no-clang', help='Disable Clang', dest='clang', action='store_false')
diff --git a/tools/patches/flutter-engine/cb80ea7ba9124fd42a34c1d021232113e20d21b1.patch b/tools/patches/flutter-engine/cb80ea7ba9124fd42a34c1d021232113e20d21b1.patch
new file mode 100644
index 0000000..6151279
--- /dev/null
+++ b/tools/patches/flutter-engine/cb80ea7ba9124fd42a34c1d021232113e20d21b1.patch
@@ -0,0 +1,1305 @@
+diff --git a/lib/snapshot/libraries.json b/lib/snapshot/libraries.json
+index b6ffcef58..c4783158b 100644
+--- a/lib/snapshot/libraries.json
++++ b/lib/snapshot/libraries.json
+@@ -4,69 +4,69 @@
+ "flutter": {
+ "libraries": {
+ "_builtin": {
+- "uri": "../../../third_party/dart/runtime/bin/builtin.dart"
++ "uri": "../../../third_party/dart/sdk/lib/_internal/vm/bin/builtin.dart"
+ },
+ "core": {
+ "patches": [
+- "../../../third_party/dart/runtime/lib/core_patch.dart",
+- "../../../third_party/dart/runtime/lib/array.dart",
+- "../../../third_party/dart/runtime/lib/array_patch.dart",
+- "../../../third_party/dart/runtime/lib/bigint_patch.dart",
+- "../../../third_party/dart/runtime/lib/bool_patch.dart",
+- "../../../third_party/dart/runtime/lib/date_patch.dart",
+- "../../../third_party/dart/runtime/lib/double.dart",
+- "../../../third_party/dart/runtime/lib/double_patch.dart",
+- "../../../third_party/dart/runtime/lib/errors_patch.dart",
+- "../../../third_party/dart/runtime/lib/expando_patch.dart",
+- "../../../third_party/dart/runtime/lib/function.dart",
+- "../../../third_party/dart/runtime/lib/function_patch.dart",
+- "../../../third_party/dart/runtime/lib/growable_array.dart",
+- "../../../third_party/dart/runtime/lib/identical_patch.dart",
+- "../../../third_party/dart/runtime/lib/immutable_map.dart",
+- "../../../third_party/dart/runtime/lib/integers.dart",
+- "../../../third_party/dart/runtime/lib/integers_patch.dart",
+- "../../../third_party/dart/runtime/lib/invocation_mirror_patch.dart",
+- "../../../third_party/dart/runtime/lib/lib_prefix.dart",
+- "../../../third_party/dart/runtime/lib/map_patch.dart",
+- "../../../third_party/dart/runtime/lib/null_patch.dart",
+- "../../../third_party/dart/runtime/lib/object_patch.dart",
+- "../../../third_party/dart/runtime/lib/regexp_patch.dart",
+- "../../../third_party/dart/runtime/lib/stacktrace.dart",
+- "../../../third_party/dart/runtime/lib/stopwatch_patch.dart",
+- "../../../third_party/dart/runtime/lib/string_buffer_patch.dart",
+- "../../../third_party/dart/runtime/lib/string_patch.dart",
+- "../../../third_party/dart/runtime/lib/type_patch.dart",
+- "../../../third_party/dart/runtime/lib/uri_patch.dart",
+- "../../../third_party/dart/runtime/lib/weak_property.dart"
++ "../../../third_party/dart/sdk/lib/_internal/vm/lib/core_patch.dart",
++ "../../../third_party/dart/sdk/lib/_internal/vm/lib/array.dart",
++ "../../../third_party/dart/sdk/lib/_internal/vm/lib/array_patch.dart",
++ "../../../third_party/dart/sdk/lib/_internal/vm/lib/bigint_patch.dart",
++ "../../../third_party/dart/sdk/lib/_internal/vm/lib/bool_patch.dart",
++ "../../../third_party/dart/sdk/lib/_internal/vm/lib/date_patch.dart",
++ "../../../third_party/dart/sdk/lib/_internal/vm/lib/double.dart",
++ "../../../third_party/dart/sdk/lib/_internal/vm/lib/double_patch.dart",
++ "../../../third_party/dart/sdk/lib/_internal/vm/lib/errors_patch.dart",
++ "../../../third_party/dart/sdk/lib/_internal/vm/lib/expando_patch.dart",
++ "../../../third_party/dart/sdk/lib/_internal/vm/lib/function.dart",
++ "../../../third_party/dart/sdk/lib/_internal/vm/lib/function_patch.dart",
++ "../../../third_party/dart/sdk/lib/_internal/vm/lib/growable_array.dart",
++ "../../../third_party/dart/sdk/lib/_internal/vm/lib/identical_patch.dart",
++ "../../../third_party/dart/sdk/lib/_internal/vm/lib/immutable_map.dart",
++ "../../../third_party/dart/sdk/lib/_internal/vm/lib/integers.dart",
++ "../../../third_party/dart/sdk/lib/_internal/vm/lib/integers_patch.dart",
++ "../../../third_party/dart/sdk/lib/_internal/vm/lib/invocation_mirror_patch.dart",
++ "../../../third_party/dart/sdk/lib/_internal/vm/lib/lib_prefix.dart",
++ "../../../third_party/dart/sdk/lib/_internal/vm/lib/map_patch.dart",
++ "../../../third_party/dart/sdk/lib/_internal/vm/lib/null_patch.dart",
++ "../../../third_party/dart/sdk/lib/_internal/vm/lib/object_patch.dart",
++ "../../../third_party/dart/sdk/lib/_internal/vm/lib/regexp_patch.dart",
++ "../../../third_party/dart/sdk/lib/_internal/vm/lib/stacktrace.dart",
++ "../../../third_party/dart/sdk/lib/_internal/vm/lib/stopwatch_patch.dart",
++ "../../../third_party/dart/sdk/lib/_internal/vm/lib/string_buffer_patch.dart",
++ "../../../third_party/dart/sdk/lib/_internal/vm/lib/string_patch.dart",
++ "../../../third_party/dart/sdk/lib/_internal/vm/lib/type_patch.dart",
++ "../../../third_party/dart/sdk/lib/_internal/vm/lib/uri_patch.dart",
++ "../../../third_party/dart/sdk/lib/_internal/vm/lib/weak_property.dart"
+ ],
+ "uri": "../../../third_party/dart/sdk/lib/core/core.dart"
+ },
+ "async": {
+ "patches": [
+- "../../../third_party/dart/runtime/lib/async_patch.dart",
+- "../../../third_party/dart/runtime/lib/deferred_load_patch.dart",
+- "../../../third_party/dart/runtime/lib/schedule_microtask_patch.dart",
+- "../../../third_party/dart/runtime/lib/timer_patch.dart"
++ "../../../third_party/dart/sdk/lib/_internal/vm/lib/async_patch.dart",
++ "../../../third_party/dart/sdk/lib/_internal/vm/lib/deferred_load_patch.dart",
++ "../../../third_party/dart/sdk/lib/_internal/vm/lib/schedule_microtask_patch.dart",
++ "../../../third_party/dart/sdk/lib/_internal/vm/lib/timer_patch.dart"
+ ],
+ "uri": "../../../third_party/dart/sdk/lib/async/async.dart"
+ },
+ "collection": {
+ "patches": [
+- "../../../third_party/dart/runtime/lib/collection_patch.dart",
+- "../../../third_party/dart/runtime/lib/compact_hash.dart"
++ "../../../third_party/dart/sdk/lib/_internal/vm/lib/collection_patch.dart",
++ "../../../third_party/dart/sdk/lib/_internal/vm/lib/compact_hash.dart"
+ ],
+ "uri": "../../../third_party/dart/sdk/lib/collection/collection.dart"
+ },
+ "ffi": {
+ "patches": [
+- "../../../third_party/dart/runtime/lib/ffi_dynamic_library_patch.dart",
+- "../../../third_party/dart/runtime/lib/ffi_native_type_patch.dart",
+- "../../../third_party/dart/runtime/lib/ffi_patch.dart"
++ "../../../third_party/dart/sdk/lib/_internal/vm/lib/ffi_dynamic_library_patch.dart",
++ "../../../third_party/dart/sdk/lib/_internal/vm/lib/ffi_native_type_patch.dart",
++ "../../../third_party/dart/sdk/lib/_internal/vm/lib/ffi_patch.dart"
+ ],
+ "uri": "../../../third_party/dart/sdk/lib/ffi/ffi.dart"
+ },
+ "typed_data": {
+- "patches": "../../../third_party/dart/runtime/lib/typed_data_patch.dart",
++ "patches": "../../../third_party/dart/sdk/lib/_internal/vm/lib/typed_data_patch.dart",
+ "uri": "../../../third_party/dart/sdk/lib/typed_data/typed_data.dart"
+ },
+ "nativewrappers": {
+@@ -74,24 +74,24 @@
+ },
+ "mirrors": {
+ "patches": [
+- "../../../third_party/dart/runtime/lib/mirrors_patch.dart",
+- "../../../third_party/dart/runtime/lib/mirrors_impl.dart",
+- "../../../third_party/dart/runtime/lib/mirror_reference.dart"
++ "../../../third_party/dart/sdk/lib/_internal/vm/lib/mirrors_patch.dart",
++ "../../../third_party/dart/sdk/lib/_internal/vm/lib/mirrors_impl.dart",
++ "../../../third_party/dart/sdk/lib/_internal/vm/lib/mirror_reference.dart"
+ ],
+ "uri": "../../../third_party/dart/sdk/lib/mirrors/mirrors.dart"
+ },
+ "developer": {
+ "patches": [
+- "../../../third_party/dart/runtime/lib/developer.dart",
+- "../../../third_party/dart/runtime/lib/profiler.dart",
+- "../../../third_party/dart/runtime/lib/timeline.dart"
++ "../../../third_party/dart/sdk/lib/_internal/vm/lib/developer.dart",
++ "../../../third_party/dart/sdk/lib/_internal/vm/lib/profiler.dart",
++ "../../../third_party/dart/sdk/lib/_internal/vm/lib/timeline.dart"
+ ],
+ "uri": "../../../third_party/dart/sdk/lib/developer/developer.dart"
+ },
+ "isolate": {
+ "patches": [
+- "../../../third_party/dart/runtime/lib/isolate_patch.dart",
+- "../../../third_party/dart/runtime/lib/timer_impl.dart"
++ "../../../third_party/dart/sdk/lib/_internal/vm/lib/isolate_patch.dart",
++ "../../../third_party/dart/sdk/lib/_internal/vm/lib/timer_impl.dart"
+ ],
+ "uri": "../../../third_party/dart/sdk/lib/isolate/isolate.dart"
+ },
+@@ -100,48 +100,48 @@
+ },
+ "wasm": {
+ "patches": [
+- "../../../third_party/dart/runtime/lib/wasm_patch.dart"
++ "../../../third_party/dart/sdk/lib/_internal/vm/lib/wasm_patch.dart"
+ ],
+ "uri": "../../../third_party/dart/sdk/lib/wasm/wasm.dart"
+ },
+ "io": {
+ "patches": [
+- "../../../third_party/dart/runtime/bin/common_patch.dart",
+- "../../../third_party/dart/runtime/bin/directory_patch.dart",
+- "../../../third_party/dart/runtime/bin/eventhandler_patch.dart",
+- "../../../third_party/dart/runtime/bin/file_patch.dart",
+- "../../../third_party/dart/runtime/bin/file_system_entity_patch.dart",
+- "../../../third_party/dart/runtime/bin/filter_patch.dart",
+- "../../../third_party/dart/runtime/bin/io_service_patch.dart",
+- "../../../third_party/dart/runtime/bin/namespace_patch.dart",
+- "../../../third_party/dart/runtime/bin/platform_patch.dart",
+- "../../../third_party/dart/runtime/bin/process_patch.dart",
+- "../../../third_party/dart/runtime/bin/socket_patch.dart",
+- "../../../third_party/dart/runtime/bin/stdio_patch.dart",
+- "../../../third_party/dart/runtime/bin/secure_socket_patch.dart",
+- "../../../third_party/dart/runtime/bin/sync_socket_patch.dart"
++ "../../../third_party/dart/sdk/lib/_internal/vm/bin/common_patch.dart",
++ "../../../third_party/dart/sdk/lib/_internal/vm/bin/directory_patch.dart",
++ "../../../third_party/dart/sdk/lib/_internal/vm/bin/eventhandler_patch.dart",
++ "../../../third_party/dart/sdk/lib/_internal/vm/bin/file_patch.dart",
++ "../../../third_party/dart/sdk/lib/_internal/vm/bin/file_system_entity_patch.dart",
++ "../../../third_party/dart/sdk/lib/_internal/vm/bin/filter_patch.dart",
++ "../../../third_party/dart/sdk/lib/_internal/vm/bin/io_service_patch.dart",
++ "../../../third_party/dart/sdk/lib/_internal/vm/bin/namespace_patch.dart",
++ "../../../third_party/dart/sdk/lib/_internal/vm/bin/platform_patch.dart",
++ "../../../third_party/dart/sdk/lib/_internal/vm/bin/process_patch.dart",
++ "../../../third_party/dart/sdk/lib/_internal/vm/bin/socket_patch.dart",
++ "../../../third_party/dart/sdk/lib/_internal/vm/bin/stdio_patch.dart",
++ "../../../third_party/dart/sdk/lib/_internal/vm/bin/secure_socket_patch.dart",
++ "../../../third_party/dart/sdk/lib/_internal/vm/bin/sync_socket_patch.dart"
+ ],
+ "uri": "../../../third_party/dart/sdk/lib/io/io.dart"
+ },
+ "_internal": {
+ "patches": [
+- "../../../third_party/dart/runtime/lib/internal_patch.dart",
+- "../../../third_party/dart/runtime/lib/class_id_fasta.dart",
+- "../../../third_party/dart/runtime/lib/print_patch.dart",
+- "../../../third_party/dart/runtime/lib/symbol_patch.dart",
++ "../../../third_party/dart/sdk/lib/_internal/vm/lib/internal_patch.dart",
++ "../../../third_party/dart/sdk/lib/_internal/vm/lib/class_id_fasta.dart",
++ "../../../third_party/dart/sdk/lib/_internal/vm/lib/print_patch.dart",
++ "../../../third_party/dart/sdk/lib/_internal/vm/lib/symbol_patch.dart",
+ "../../../third_party/dart/sdk/lib/internal/patch.dart"
+ ],
+ "uri": "../../../third_party/dart/sdk/lib/internal/internal.dart"
+ },
+ "convert": {
+- "patches": "../../../third_party/dart/runtime/lib/convert_patch.dart",
++ "patches": "../../../third_party/dart/sdk/lib/_internal/vm/lib/convert_patch.dart",
+ "uri": "../../../third_party/dart/sdk/lib/convert/convert.dart"
+ },
+ "profiler": {
+ "uri": "../../../third_party/dart/sdk/lib/profiler/profiler.dart"
+ },
+ "math": {
+- "patches": "../../../third_party/dart/runtime/lib/math_patch.dart",
++ "patches": "../../../third_party/dart/sdk/lib/_internal/vm/lib/math_patch.dart",
+ "uri": "../../../third_party/dart/sdk/lib/math/math.dart"
+ },
+ "_http": {
+diff --git a/lib/snapshot/libraries.yaml b/lib/snapshot/libraries.yaml
+index 392e0500b..7269819f7 100644
+--- a/lib/snapshot/libraries.yaml
++++ b/lib/snapshot/libraries.yaml
+@@ -14,87 +14,87 @@
+ flutter:
+ libraries:
+ _builtin:
+- uri: "../../../third_party/dart/runtime/bin/builtin.dart"
++ uri: "../../../third_party/dart/sdk/lib/_internal/vm/bin/builtin.dart"
+
+ _internal:
+ uri: "../../../third_party/dart/sdk/lib/internal/internal.dart"
+ patches:
+- - "../../../third_party/dart/runtime/lib/internal_patch.dart"
+- - "../../../third_party/dart/runtime/lib/class_id_fasta.dart"
+- - "../../../third_party/dart/runtime/lib/print_patch.dart"
+- - "../../../third_party/dart/runtime/lib/symbol_patch.dart"
++ - "../../../third_party/dart/sdk/lib/_internal/vm/lib/internal_patch.dart"
++ - "../../../third_party/dart/sdk/lib/_internal/vm/lib/class_id_fasta.dart"
++ - "../../../third_party/dart/sdk/lib/_internal/vm/lib/print_patch.dart"
++ - "../../../third_party/dart/sdk/lib/_internal/vm/lib/symbol_patch.dart"
+ - "../../../third_party/dart/sdk/lib/internal/patch.dart"
+
+ async:
+ uri: "../../../third_party/dart/sdk/lib/async/async.dart"
+ patches:
+- - "../../../third_party/dart/runtime/lib/async_patch.dart"
+- - "../../../third_party/dart/runtime/lib/deferred_load_patch.dart"
+- - "../../../third_party/dart/runtime/lib/schedule_microtask_patch.dart"
+- - "../../../third_party/dart/runtime/lib/timer_patch.dart"
++ - "../../../third_party/dart/sdk/lib/_internal/vm/lib/async_patch.dart"
++ - "../../../third_party/dart/sdk/lib/_internal/vm/lib/deferred_load_patch.dart"
++ - "../../../third_party/dart/sdk/lib/_internal/vm/lib/schedule_microtask_patch.dart"
++ - "../../../third_party/dart/sdk/lib/_internal/vm/lib/timer_patch.dart"
+
+ collection:
+ uri: "../../../third_party/dart/sdk/lib/collection/collection.dart"
+ patches:
+- - "../../../third_party/dart/runtime/lib/collection_patch.dart"
+- - "../../../third_party/dart/runtime/lib/compact_hash.dart"
++ - "../../../third_party/dart/sdk/lib/_internal/vm/lib/collection_patch.dart"
++ - "../../../third_party/dart/sdk/lib/_internal/vm/lib/compact_hash.dart"
+
+ convert:
+ uri: "../../../third_party/dart/sdk/lib/convert/convert.dart"
+- patches: "../../../third_party/dart/runtime/lib/convert_patch.dart"
++ patches: "../../../third_party/dart/sdk/lib/_internal/vm/lib/convert_patch.dart"
+
+ core:
+ uri: "../../../third_party/dart/sdk/lib/core/core.dart"
+ patches:
+- - "../../../third_party/dart/runtime/lib/core_patch.dart"
+- - "../../../third_party/dart/runtime/lib/array.dart"
+- - "../../../third_party/dart/runtime/lib/array_patch.dart"
+- - "../../../third_party/dart/runtime/lib/bigint_patch.dart"
+- - "../../../third_party/dart/runtime/lib/bool_patch.dart"
+- - "../../../third_party/dart/runtime/lib/date_patch.dart"
+- - "../../../third_party/dart/runtime/lib/double.dart"
+- - "../../../third_party/dart/runtime/lib/double_patch.dart"
+- - "../../../third_party/dart/runtime/lib/errors_patch.dart"
+- - "../../../third_party/dart/runtime/lib/expando_patch.dart"
+- - "../../../third_party/dart/runtime/lib/function.dart"
+- - "../../../third_party/dart/runtime/lib/function_patch.dart"
+- - "../../../third_party/dart/runtime/lib/growable_array.dart"
+- - "../../../third_party/dart/runtime/lib/identical_patch.dart"
+- - "../../../third_party/dart/runtime/lib/immutable_map.dart"
+- - "../../../third_party/dart/runtime/lib/integers.dart"
+- - "../../../third_party/dart/runtime/lib/integers_patch.dart"
+- - "../../../third_party/dart/runtime/lib/invocation_mirror_patch.dart"
+- - "../../../third_party/dart/runtime/lib/lib_prefix.dart"
+- - "../../../third_party/dart/runtime/lib/map_patch.dart"
+- - "../../../third_party/dart/runtime/lib/null_patch.dart"
+- - "../../../third_party/dart/runtime/lib/object_patch.dart"
+- - "../../../third_party/dart/runtime/lib/regexp_patch.dart"
+- - "../../../third_party/dart/runtime/lib/stacktrace.dart"
+- - "../../../third_party/dart/runtime/lib/stopwatch_patch.dart"
+- - "../../../third_party/dart/runtime/lib/string_buffer_patch.dart"
+- - "../../../third_party/dart/runtime/lib/string_patch.dart"
+- - "../../../third_party/dart/runtime/lib/type_patch.dart"
+- - "../../../third_party/dart/runtime/lib/uri_patch.dart"
+- - "../../../third_party/dart/runtime/lib/weak_property.dart"
++ - "../../../third_party/dart/sdk/lib/_internal/vm/lib/core_patch.dart"
++ - "../../../third_party/dart/sdk/lib/_internal/vm/lib/array.dart"
++ - "../../../third_party/dart/sdk/lib/_internal/vm/lib/array_patch.dart"
++ - "../../../third_party/dart/sdk/lib/_internal/vm/lib/bigint_patch.dart"
++ - "../../../third_party/dart/sdk/lib/_internal/vm/lib/bool_patch.dart"
++ - "../../../third_party/dart/sdk/lib/_internal/vm/lib/date_patch.dart"
++ - "../../../third_party/dart/sdk/lib/_internal/vm/lib/double.dart"
++ - "../../../third_party/dart/sdk/lib/_internal/vm/lib/double_patch.dart"
++ - "../../../third_party/dart/sdk/lib/_internal/vm/lib/errors_patch.dart"
++ - "../../../third_party/dart/sdk/lib/_internal/vm/lib/expando_patch.dart"
++ - "../../../third_party/dart/sdk/lib/_internal/vm/lib/function.dart"
++ - "../../../third_party/dart/sdk/lib/_internal/vm/lib/function_patch.dart"
++ - "../../../third_party/dart/sdk/lib/_internal/vm/lib/growable_array.dart"
++ - "../../../third_party/dart/sdk/lib/_internal/vm/lib/identical_patch.dart"
++ - "../../../third_party/dart/sdk/lib/_internal/vm/lib/immutable_map.dart"
++ - "../../../third_party/dart/sdk/lib/_internal/vm/lib/integers.dart"
++ - "../../../third_party/dart/sdk/lib/_internal/vm/lib/integers_patch.dart"
++ - "../../../third_party/dart/sdk/lib/_internal/vm/lib/invocation_mirror_patch.dart"
++ - "../../../third_party/dart/sdk/lib/_internal/vm/lib/lib_prefix.dart"
++ - "../../../third_party/dart/sdk/lib/_internal/vm/lib/map_patch.dart"
++ - "../../../third_party/dart/sdk/lib/_internal/vm/lib/null_patch.dart"
++ - "../../../third_party/dart/sdk/lib/_internal/vm/lib/object_patch.dart"
++ - "../../../third_party/dart/sdk/lib/_internal/vm/lib/regexp_patch.dart"
++ - "../../../third_party/dart/sdk/lib/_internal/vm/lib/stacktrace.dart"
++ - "../../../third_party/dart/sdk/lib/_internal/vm/lib/stopwatch_patch.dart"
++ - "../../../third_party/dart/sdk/lib/_internal/vm/lib/string_buffer_patch.dart"
++ - "../../../third_party/dart/sdk/lib/_internal/vm/lib/string_patch.dart"
++ - "../../../third_party/dart/sdk/lib/_internal/vm/lib/type_patch.dart"
++ - "../../../third_party/dart/sdk/lib/_internal/vm/lib/uri_patch.dart"
++ - "../../../third_party/dart/sdk/lib/_internal/vm/lib/weak_property.dart"
+
+ developer:
+ uri: "../../../third_party/dart/sdk/lib/developer/developer.dart"
+ patches:
+- - "../../../third_party/dart/runtime/lib/developer.dart"
+- - "../../../third_party/dart/runtime/lib/profiler.dart"
+- - "../../../third_party/dart/runtime/lib/timeline.dart"
++ - "../../../third_party/dart/sdk/lib/_internal/vm/lib/developer.dart"
++ - "../../../third_party/dart/sdk/lib/_internal/vm/lib/profiler.dart"
++ - "../../../third_party/dart/sdk/lib/_internal/vm/lib/timeline.dart"
+
+ ffi:
+ uri: "../../../third_party/dart/sdk/lib/ffi/ffi.dart"
+ patches:
+- - "../../../third_party/dart/runtime/lib/ffi_dynamic_library_patch.dart"
+- - "../../../third_party/dart/runtime/lib/ffi_native_type_patch.dart"
+- - "../../../third_party/dart/runtime/lib/ffi_patch.dart"
++ - "../../../third_party/dart/sdk/lib/_internal/vm/lib/ffi_dynamic_library_patch.dart"
++ - "../../../third_party/dart/sdk/lib/_internal/vm/lib/ffi_native_type_patch.dart"
++ - "../../../third_party/dart/sdk/lib/_internal/vm/lib/ffi_patch.dart"
+
+ wasm:
+ uri: "../../../third_party/dart/sdk/lib/wasm/wasm.dart"
+ patches:
+- - "../../../third_party/dart/runtime/lib/wasm_patch.dart"
++ - "../../../third_party/dart/sdk/lib/_internal/vm/lib/wasm_patch.dart"
+
+ _http:
+ uri: "../../../third_party/dart/sdk/lib/_http/http.dart"
+@@ -102,37 +102,37 @@ flutter:
+ io:
+ uri: "../../../third_party/dart/sdk/lib/io/io.dart"
+ patches:
+- - "../../../third_party/dart/runtime/bin/common_patch.dart"
+- - "../../../third_party/dart/runtime/bin/directory_patch.dart"
+- - "../../../third_party/dart/runtime/bin/eventhandler_patch.dart"
+- - "../../../third_party/dart/runtime/bin/file_patch.dart"
+- - "../../../third_party/dart/runtime/bin/file_system_entity_patch.dart"
+- - "../../../third_party/dart/runtime/bin/filter_patch.dart"
+- - "../../../third_party/dart/runtime/bin/io_service_patch.dart"
+- - "../../../third_party/dart/runtime/bin/namespace_patch.dart"
+- - "../../../third_party/dart/runtime/bin/platform_patch.dart"
+- - "../../../third_party/dart/runtime/bin/process_patch.dart"
+- - "../../../third_party/dart/runtime/bin/socket_patch.dart"
+- - "../../../third_party/dart/runtime/bin/stdio_patch.dart"
+- - "../../../third_party/dart/runtime/bin/secure_socket_patch.dart"
+- - "../../../third_party/dart/runtime/bin/sync_socket_patch.dart"
++ - "../../../third_party/dart/sdk/lib/_internal/vm/bin/common_patch.dart"
++ - "../../../third_party/dart/sdk/lib/_internal/vm/bin/directory_patch.dart"
++ - "../../../third_party/dart/sdk/lib/_internal/vm/bin/eventhandler_patch.dart"
++ - "../../../third_party/dart/sdk/lib/_internal/vm/bin/file_patch.dart"
++ - "../../../third_party/dart/sdk/lib/_internal/vm/bin/file_system_entity_patch.dart"
++ - "../../../third_party/dart/sdk/lib/_internal/vm/bin/filter_patch.dart"
++ - "../../../third_party/dart/sdk/lib/_internal/vm/bin/io_service_patch.dart"
++ - "../../../third_party/dart/sdk/lib/_internal/vm/bin/namespace_patch.dart"
++ - "../../../third_party/dart/sdk/lib/_internal/vm/bin/platform_patch.dart"
++ - "../../../third_party/dart/sdk/lib/_internal/vm/bin/process_patch.dart"
++ - "../../../third_party/dart/sdk/lib/_internal/vm/bin/socket_patch.dart"
++ - "../../../third_party/dart/sdk/lib/_internal/vm/bin/stdio_patch.dart"
++ - "../../../third_party/dart/sdk/lib/_internal/vm/bin/secure_socket_patch.dart"
++ - "../../../third_party/dart/sdk/lib/_internal/vm/bin/sync_socket_patch.dart"
+
+ isolate:
+ uri: "../../../third_party/dart/sdk/lib/isolate/isolate.dart"
+ patches:
+- - "../../../third_party/dart/runtime/lib/isolate_patch.dart"
+- - "../../../third_party/dart/runtime/lib/timer_impl.dart"
++ - "../../../third_party/dart/sdk/lib/_internal/vm/lib/isolate_patch.dart"
++ - "../../../third_party/dart/sdk/lib/_internal/vm/lib/timer_impl.dart"
+
+ math:
+ uri: "../../../third_party/dart/sdk/lib/math/math.dart"
+- patches: "../../../third_party/dart/runtime/lib/math_patch.dart"
++ patches: "../../../third_party/dart/sdk/lib/_internal/vm/lib/math_patch.dart"
+
+ mirrors:
+ uri: "../../../third_party/dart/sdk/lib/mirrors/mirrors.dart"
+ patches:
+- - "../../../third_party/dart/runtime/lib/mirrors_patch.dart"
+- - "../../../third_party/dart/runtime/lib/mirrors_impl.dart"
+- - "../../../third_party/dart/runtime/lib/mirror_reference.dart"
++ - "../../../third_party/dart/sdk/lib/_internal/vm/lib/mirrors_patch.dart"
++ - "../../../third_party/dart/sdk/lib/_internal/vm/lib/mirrors_impl.dart"
++ - "../../../third_party/dart/sdk/lib/_internal/vm/lib/mirror_reference.dart"
+
+ nativewrappers:
+ uri: "../../../third_party/dart/sdk/lib/html/dartium/nativewrappers.dart"
+@@ -142,7 +142,7 @@ flutter:
+
+ typed_data:
+ uri: "../../../third_party/dart/sdk/lib/typed_data/typed_data.dart"
+- patches: "../../../third_party/dart/runtime/lib/typed_data_patch.dart"
++ patches: "../../../third_party/dart/sdk/lib/_internal/vm/lib/typed_data_patch.dart"
+
+ ui:
+ uri: "../../lib/ui/ui.dart"
+diff --git a/shell/platform/fuchsia/dart_runner/kernel/libraries.json b/shell/platform/fuchsia/dart_runner/kernel/libraries.json
+index 0abe212e6..24c664852 100644
+--- a/shell/platform/fuchsia/dart_runner/kernel/libraries.json
++++ b/shell/platform/fuchsia/dart_runner/kernel/libraries.json
+@@ -1,43 +1,43 @@
+ {
+ "comment:0": "NOTE: THIS FILE IS GENERATED. DO NOT EDIT.",
+- "comment:1": "Instead modify 'shell/platform/fuchsia/dart_runner/kernel/libraries.yaml' and follow the instructions therein.",
++ "comment:1": "Instead modify 'flutter/shell/platform/fuchsia/dart_runner/kernel/libraries.yaml' and follow the instructions therein.",
+ "dart_runner": {
+ "libraries": {
+ "_builtin": {
+- "uri": "../../../../../../third_party/dart/runtime/bin/builtin.dart"
++ "uri": "../../../../../../third_party/dart/sdk/lib/_internal/vm/bin/builtin.dart"
+ },
+ "core": {
+ "patches": [
+- "../../../../../../third_party/dart/runtime/lib/core_patch.dart",
+- "../../../../../../third_party/dart/runtime/lib/array.dart",
+- "../../../../../../third_party/dart/runtime/lib/array_patch.dart",
+- "../../../../../../third_party/dart/runtime/lib/bigint_patch.dart",
+- "../../../../../../third_party/dart/runtime/lib/bool_patch.dart",
+- "../../../../../../third_party/dart/runtime/lib/date_patch.dart",
+- "../../../../../../third_party/dart/runtime/lib/double.dart",
+- "../../../../../../third_party/dart/runtime/lib/double_patch.dart",
+- "../../../../../../third_party/dart/runtime/lib/errors_patch.dart",
+- "../../../../../../third_party/dart/runtime/lib/expando_patch.dart",
+- "../../../../../../third_party/dart/runtime/lib/function.dart",
+- "../../../../../../third_party/dart/runtime/lib/function_patch.dart",
+- "../../../../../../third_party/dart/runtime/lib/growable_array.dart",
+- "../../../../../../third_party/dart/runtime/lib/identical_patch.dart",
+- "../../../../../../third_party/dart/runtime/lib/immutable_map.dart",
+- "../../../../../../third_party/dart/runtime/lib/integers.dart",
+- "../../../../../../third_party/dart/runtime/lib/integers_patch.dart",
+- "../../../../../../third_party/dart/runtime/lib/invocation_mirror_patch.dart",
+- "../../../../../../third_party/dart/runtime/lib/lib_prefix.dart",
+- "../../../../../../third_party/dart/runtime/lib/map_patch.dart",
+- "../../../../../../third_party/dart/runtime/lib/null_patch.dart",
+- "../../../../../../third_party/dart/runtime/lib/object_patch.dart",
+- "../../../../../../third_party/dart/runtime/lib/regexp_patch.dart",
+- "../../../../../../third_party/dart/runtime/lib/stacktrace.dart",
+- "../../../../../../third_party/dart/runtime/lib/stopwatch_patch.dart",
+- "../../../../../../third_party/dart/runtime/lib/string_buffer_patch.dart",
+- "../../../../../../third_party/dart/runtime/lib/string_patch.dart",
+- "../../../../../../third_party/dart/runtime/lib/type_patch.dart",
+- "../../../../../../third_party/dart/runtime/lib/uri_patch.dart",
+- "../../../../../../third_party/dart/runtime/lib/weak_property.dart"
++ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/core_patch.dart",
++ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/array.dart",
++ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/array_patch.dart",
++ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/bigint_patch.dart",
++ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/bool_patch.dart",
++ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/date_patch.dart",
++ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/double.dart",
++ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/double_patch.dart",
++ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/errors_patch.dart",
++ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/expando_patch.dart",
++ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/function.dart",
++ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/function_patch.dart",
++ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/growable_array.dart",
++ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/identical_patch.dart",
++ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/immutable_map.dart",
++ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/integers.dart",
++ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/integers_patch.dart",
++ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/invocation_mirror_patch.dart",
++ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/lib_prefix.dart",
++ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/map_patch.dart",
++ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/null_patch.dart",
++ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/object_patch.dart",
++ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/regexp_patch.dart",
++ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/stacktrace.dart",
++ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/stopwatch_patch.dart",
++ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/string_buffer_patch.dart",
++ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/string_patch.dart",
++ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/type_patch.dart",
++ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/uri_patch.dart",
++ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/weak_property.dart"
+ ],
+ "uri": "../../../../../../third_party/dart/sdk/lib/core/core.dart"
+ },
+@@ -46,30 +46,30 @@
+ },
+ "async": {
+ "patches": [
+- "../../../../../../third_party/dart/runtime/lib/async_patch.dart",
+- "../../../../../../third_party/dart/runtime/lib/deferred_load_patch.dart",
+- "../../../../../../third_party/dart/runtime/lib/schedule_microtask_patch.dart",
+- "../../../../../../third_party/dart/runtime/lib/timer_patch.dart"
++ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/async_patch.dart",
++ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/deferred_load_patch.dart",
++ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/schedule_microtask_patch.dart",
++ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/timer_patch.dart"
+ ],
+ "uri": "../../../../../../third_party/dart/sdk/lib/async/async.dart"
+ },
+ "collection": {
+ "patches": [
+- "../../../../../../third_party/dart/runtime/lib/collection_patch.dart",
+- "../../../../../../third_party/dart/runtime/lib/compact_hash.dart"
++ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/collection_patch.dart",
++ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/compact_hash.dart"
+ ],
+ "uri": "../../../../../../third_party/dart/sdk/lib/collection/collection.dart"
+ },
+ "ffi": {
+ "patches": [
+- "../../../../../../third_party/dart/runtime/lib/ffi_dynamic_library_patch.dart",
+- "../../../../../../third_party/dart/runtime/lib/ffi_native_type_patch.dart",
+- "../../../../../../third_party/dart/runtime/lib/ffi_patch.dart"
++ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/ffi_dynamic_library_patch.dart",
++ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/ffi_native_type_patch.dart",
++ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/ffi_patch.dart"
+ ],
+ "uri": "../../../../../../third_party/dart/sdk/lib/ffi/ffi.dart"
+ },
+ "typed_data": {
+- "patches": "../../../../../../third_party/dart/runtime/lib/typed_data_patch.dart",
++ "patches": "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/typed_data_patch.dart",
+ "uri": "../../../../../../third_party/dart/sdk/lib/typed_data/typed_data.dart"
+ },
+ "nativewrappers": {
+@@ -77,24 +77,24 @@
+ },
+ "mirrors": {
+ "patches": [
+- "../../../../../../third_party/dart/runtime/lib/mirrors_patch.dart",
+- "../../../../../../third_party/dart/runtime/lib/mirrors_impl.dart",
+- "../../../../../../third_party/dart/runtime/lib/mirror_reference.dart"
++ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/mirrors_patch.dart",
++ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/mirrors_impl.dart",
++ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/mirror_reference.dart"
+ ],
+ "uri": "../../../../../../third_party/dart/sdk/lib/mirrors/mirrors.dart"
+ },
+ "developer": {
+ "patches": [
+- "../../../../../../third_party/dart/runtime/lib/developer.dart",
+- "../../../../../../third_party/dart/runtime/lib/profiler.dart",
+- "../../../../../../third_party/dart/runtime/lib/timeline.dart"
++ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/developer.dart",
++ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/profiler.dart",
++ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/timeline.dart"
+ ],
+ "uri": "../../../../../../third_party/dart/sdk/lib/developer/developer.dart"
+ },
+ "isolate": {
+ "patches": [
+- "../../../../../../third_party/dart/runtime/lib/isolate_patch.dart",
+- "../../../../../../third_party/dart/runtime/lib/timer_impl.dart"
++ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/isolate_patch.dart",
++ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/timer_impl.dart"
+ ],
+ "uri": "../../../../../../third_party/dart/sdk/lib/isolate/isolate.dart"
+ },
+@@ -103,48 +103,48 @@
+ },
+ "wasm": {
+ "patches": [
+- "../../../../../../third_party/dart/runtime/lib/wasm_patch.dart"
++ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/wasm_patch.dart"
+ ],
+ "uri": "../../../../../../third_party/dart/sdk/lib/wasm/wasm.dart"
+ },
+ "io": {
+ "patches": [
+- "../../../../../../third_party/dart/runtime/bin/common_patch.dart",
+- "../../../../../../third_party/dart/runtime/bin/directory_patch.dart",
+- "../../../../../../third_party/dart/runtime/bin/eventhandler_patch.dart",
+- "../../../../../../third_party/dart/runtime/bin/file_patch.dart",
+- "../../../../../../third_party/dart/runtime/bin/file_system_entity_patch.dart",
+- "../../../../../../third_party/dart/runtime/bin/filter_patch.dart",
+- "../../../../../../third_party/dart/runtime/bin/io_service_patch.dart",
+- "../../../../../../third_party/dart/runtime/bin/namespace_patch.dart",
+- "../../../../../../third_party/dart/runtime/bin/platform_patch.dart",
+- "../../../../../../third_party/dart/runtime/bin/process_patch.dart",
+- "../../../../../../third_party/dart/runtime/bin/socket_patch.dart",
+- "../../../../../../third_party/dart/runtime/bin/stdio_patch.dart",
+- "../../../../../../third_party/dart/runtime/bin/secure_socket_patch.dart",
+- "../../../../../../third_party/dart/runtime/bin/sync_socket_patch.dart"
++ "../../../../../../third_party/dart/sdk/lib/_internal/vm/bin/common_patch.dart",
++ "../../../../../../third_party/dart/sdk/lib/_internal/vm/bin/directory_patch.dart",
++ "../../../../../../third_party/dart/sdk/lib/_internal/vm/bin/eventhandler_patch.dart",
++ "../../../../../../third_party/dart/sdk/lib/_internal/vm/bin/file_patch.dart",
++ "../../../../../../third_party/dart/sdk/lib/_internal/vm/bin/file_system_entity_patch.dart",
++ "../../../../../../third_party/dart/sdk/lib/_internal/vm/bin/filter_patch.dart",
++ "../../../../../../third_party/dart/sdk/lib/_internal/vm/bin/io_service_patch.dart",
++ "../../../../../../third_party/dart/sdk/lib/_internal/vm/bin/namespace_patch.dart",
++ "../../../../../../third_party/dart/sdk/lib/_internal/vm/bin/platform_patch.dart",
++ "../../../../../../third_party/dart/sdk/lib/_internal/vm/bin/process_patch.dart",
++ "../../../../../../third_party/dart/sdk/lib/_internal/vm/bin/socket_patch.dart",
++ "../../../../../../third_party/dart/sdk/lib/_internal/vm/bin/stdio_patch.dart",
++ "../../../../../../third_party/dart/sdk/lib/_internal/vm/bin/secure_socket_patch.dart",
++ "../../../../../../third_party/dart/sdk/lib/_internal/vm/bin/sync_socket_patch.dart"
+ ],
+ "uri": "../../../../../../third_party/dart/sdk/lib/io/io.dart"
+ },
+ "_internal": {
+ "patches": [
+- "../../../../../../third_party/dart/runtime/lib/internal_patch.dart",
+- "../../../../../../third_party/dart/runtime/lib/class_id_fasta.dart",
+- "../../../../../../third_party/dart/runtime/lib/print_patch.dart",
+- "../../../../../../third_party/dart/runtime/lib/symbol_patch.dart",
++ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/internal_patch.dart",
++ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/class_id_fasta.dart",
++ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/print_patch.dart",
++ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/symbol_patch.dart",
+ "../../../../../../third_party/dart/sdk/lib/internal/patch.dart"
+ ],
+ "uri": "../../../../../../third_party/dart/sdk/lib/internal/internal.dart"
+ },
+ "convert": {
+- "patches": "../../../../../../third_party/dart/runtime/lib/convert_patch.dart",
++ "patches": "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/convert_patch.dart",
+ "uri": "../../../../../../third_party/dart/sdk/lib/convert/convert.dart"
+ },
+ "profiler": {
+ "uri": "../../../../../../third_party/dart/sdk/lib/profiler/profiler.dart"
+ },
+ "math": {
+- "patches": "../../../../../../third_party/dart/runtime/lib/math_patch.dart",
++ "patches": "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/math_patch.dart",
+ "uri": "../../../../../../third_party/dart/sdk/lib/math/math.dart"
+ },
+ "_http": {
+diff --git a/shell/platform/fuchsia/dart_runner/kernel/libraries.yaml b/shell/platform/fuchsia/dart_runner/kernel/libraries.yaml
+index cab901e60..5e1f638cd 100644
+--- a/shell/platform/fuchsia/dart_runner/kernel/libraries.yaml
++++ b/shell/platform/fuchsia/dart_runner/kernel/libraries.yaml
+@@ -14,87 +14,87 @@
+ dart_runner:
+ libraries:
+ _builtin:
+- uri: "../../../../../../third_party/dart/runtime/bin/builtin.dart"
++ uri: "../../../../../../third_party/dart/sdk/lib/_internal/vm/bin/builtin.dart"
+
+ _internal:
+ uri: "../../../../../../third_party/dart/sdk/lib/internal/internal.dart"
+ patches:
+- - "../../../../../../third_party/dart/runtime/lib/internal_patch.dart"
+- - "../../../../../../third_party/dart/runtime/lib/class_id_fasta.dart"
+- - "../../../../../../third_party/dart/runtime/lib/print_patch.dart"
+- - "../../../../../../third_party/dart/runtime/lib/symbol_patch.dart"
++ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/internal_patch.dart"
++ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/class_id_fasta.dart"
++ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/print_patch.dart"
++ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/symbol_patch.dart"
+ - "../../../../../../third_party/dart/sdk/lib/internal/patch.dart"
+
+ async:
+ uri: "../../../../../../third_party/dart/sdk/lib/async/async.dart"
+ patches:
+- - "../../../../../../third_party/dart/runtime/lib/async_patch.dart"
+- - "../../../../../../third_party/dart/runtime/lib/deferred_load_patch.dart"
+- - "../../../../../../third_party/dart/runtime/lib/schedule_microtask_patch.dart"
+- - "../../../../../../third_party/dart/runtime/lib/timer_patch.dart"
++ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/async_patch.dart"
++ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/deferred_load_patch.dart"
++ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/schedule_microtask_patch.dart"
++ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/timer_patch.dart"
+
+ collection:
+ uri: "../../../../../../third_party/dart/sdk/lib/collection/collection.dart"
+ patches:
+- - "../../../../../../third_party/dart/runtime/lib/collection_patch.dart"
+- - "../../../../../../third_party/dart/runtime/lib/compact_hash.dart"
++ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/collection_patch.dart"
++ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/compact_hash.dart"
+
+ convert:
+ uri: "../../../../../../third_party/dart/sdk/lib/convert/convert.dart"
+- patches: "../../../../../../third_party/dart/runtime/lib/convert_patch.dart"
++ patches: "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/convert_patch.dart"
+
+ core:
+ uri: "../../../../../../third_party/dart/sdk/lib/core/core.dart"
+ patches:
+- - "../../../../../../third_party/dart/runtime/lib/core_patch.dart"
+- - "../../../../../../third_party/dart/runtime/lib/array.dart"
+- - "../../../../../../third_party/dart/runtime/lib/array_patch.dart"
+- - "../../../../../../third_party/dart/runtime/lib/bigint_patch.dart"
+- - "../../../../../../third_party/dart/runtime/lib/bool_patch.dart"
+- - "../../../../../../third_party/dart/runtime/lib/date_patch.dart"
+- - "../../../../../../third_party/dart/runtime/lib/double.dart"
+- - "../../../../../../third_party/dart/runtime/lib/double_patch.dart"
+- - "../../../../../../third_party/dart/runtime/lib/errors_patch.dart"
+- - "../../../../../../third_party/dart/runtime/lib/expando_patch.dart"
+- - "../../../../../../third_party/dart/runtime/lib/function.dart"
+- - "../../../../../../third_party/dart/runtime/lib/function_patch.dart"
+- - "../../../../../../third_party/dart/runtime/lib/growable_array.dart"
+- - "../../../../../../third_party/dart/runtime/lib/identical_patch.dart"
+- - "../../../../../../third_party/dart/runtime/lib/immutable_map.dart"
+- - "../../../../../../third_party/dart/runtime/lib/integers.dart"
+- - "../../../../../../third_party/dart/runtime/lib/integers_patch.dart"
+- - "../../../../../../third_party/dart/runtime/lib/invocation_mirror_patch.dart"
+- - "../../../../../../third_party/dart/runtime/lib/lib_prefix.dart"
+- - "../../../../../../third_party/dart/runtime/lib/map_patch.dart"
+- - "../../../../../../third_party/dart/runtime/lib/null_patch.dart"
+- - "../../../../../../third_party/dart/runtime/lib/object_patch.dart"
+- - "../../../../../../third_party/dart/runtime/lib/regexp_patch.dart"
+- - "../../../../../../third_party/dart/runtime/lib/stacktrace.dart"
+- - "../../../../../../third_party/dart/runtime/lib/stopwatch_patch.dart"
+- - "../../../../../../third_party/dart/runtime/lib/string_buffer_patch.dart"
+- - "../../../../../../third_party/dart/runtime/lib/string_patch.dart"
+- - "../../../../../../third_party/dart/runtime/lib/type_patch.dart"
+- - "../../../../../../third_party/dart/runtime/lib/uri_patch.dart"
+- - "../../../../../../third_party/dart/runtime/lib/weak_property.dart"
++ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/core_patch.dart"
++ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/array.dart"
++ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/array_patch.dart"
++ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/bigint_patch.dart"
++ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/bool_patch.dart"
++ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/date_patch.dart"
++ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/double.dart"
++ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/double_patch.dart"
++ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/errors_patch.dart"
++ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/expando_patch.dart"
++ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/function.dart"
++ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/function_patch.dart"
++ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/growable_array.dart"
++ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/identical_patch.dart"
++ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/immutable_map.dart"
++ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/integers.dart"
++ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/integers_patch.dart"
++ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/invocation_mirror_patch.dart"
++ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/lib_prefix.dart"
++ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/map_patch.dart"
++ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/null_patch.dart"
++ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/object_patch.dart"
++ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/regexp_patch.dart"
++ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/stacktrace.dart"
++ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/stopwatch_patch.dart"
++ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/string_buffer_patch.dart"
++ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/string_patch.dart"
++ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/type_patch.dart"
++ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/uri_patch.dart"
++ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/weak_property.dart"
+
+ developer:
+ uri: "../../../../../../third_party/dart/sdk/lib/developer/developer.dart"
+ patches:
+- - "../../../../../../third_party/dart/runtime/lib/developer.dart"
+- - "../../../../../../third_party/dart/runtime/lib/profiler.dart"
+- - "../../../../../../third_party/dart/runtime/lib/timeline.dart"
++ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/developer.dart"
++ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/profiler.dart"
++ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/timeline.dart"
+
+ ffi:
+ uri: "../../../../../../third_party/dart/sdk/lib/ffi/ffi.dart"
+ patches:
+- - "../../../../../../third_party/dart/runtime/lib/ffi_dynamic_library_patch.dart"
+- - "../../../../../../third_party/dart/runtime/lib/ffi_native_type_patch.dart"
+- - "../../../../../../third_party/dart/runtime/lib/ffi_patch.dart"
++ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/ffi_dynamic_library_patch.dart"
++ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/ffi_native_type_patch.dart"
++ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/ffi_patch.dart"
+
+ wasm:
+ uri: "../../../../../../third_party/dart/sdk/lib/wasm/wasm.dart"
+ patches:
+- - "../../../../../../third_party/dart/runtime/lib/wasm_patch.dart"
++ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/wasm_patch.dart"
+
+ _http:
+ uri: "../../../../../../third_party/dart/sdk/lib/_http/http.dart"
+@@ -102,37 +102,37 @@ dart_runner:
+ io:
+ uri: "../../../../../../third_party/dart/sdk/lib/io/io.dart"
+ patches:
+- - "../../../../../../third_party/dart/runtime/bin/common_patch.dart"
+- - "../../../../../../third_party/dart/runtime/bin/directory_patch.dart"
+- - "../../../../../../third_party/dart/runtime/bin/eventhandler_patch.dart"
+- - "../../../../../../third_party/dart/runtime/bin/file_patch.dart"
+- - "../../../../../../third_party/dart/runtime/bin/file_system_entity_patch.dart"
+- - "../../../../../../third_party/dart/runtime/bin/filter_patch.dart"
+- - "../../../../../../third_party/dart/runtime/bin/io_service_patch.dart"
+- - "../../../../../../third_party/dart/runtime/bin/namespace_patch.dart"
+- - "../../../../../../third_party/dart/runtime/bin/platform_patch.dart"
+- - "../../../../../../third_party/dart/runtime/bin/process_patch.dart"
+- - "../../../../../../third_party/dart/runtime/bin/socket_patch.dart"
+- - "../../../../../../third_party/dart/runtime/bin/stdio_patch.dart"
+- - "../../../../../../third_party/dart/runtime/bin/secure_socket_patch.dart"
+- - "../../../../../../third_party/dart/runtime/bin/sync_socket_patch.dart"
++ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/bin/common_patch.dart"
++ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/bin/directory_patch.dart"
++ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/bin/eventhandler_patch.dart"
++ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/bin/file_patch.dart"
++ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/bin/file_system_entity_patch.dart"
++ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/bin/filter_patch.dart"
++ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/bin/io_service_patch.dart"
++ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/bin/namespace_patch.dart"
++ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/bin/platform_patch.dart"
++ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/bin/process_patch.dart"
++ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/bin/socket_patch.dart"
++ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/bin/stdio_patch.dart"
++ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/bin/secure_socket_patch.dart"
++ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/bin/sync_socket_patch.dart"
+
+ isolate:
+ uri: "../../../../../../third_party/dart/sdk/lib/isolate/isolate.dart"
+ patches:
+- - "../../../../../../third_party/dart/runtime/lib/isolate_patch.dart"
+- - "../../../../../../third_party/dart/runtime/lib/timer_impl.dart"
++ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/isolate_patch.dart"
++ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/timer_impl.dart"
+
+ math:
+ uri: "../../../../../../third_party/dart/sdk/lib/math/math.dart"
+- patches: "../../../../../../third_party/dart/runtime/lib/math_patch.dart"
++ patches: "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/math_patch.dart"
+
+ mirrors:
+ uri: "../../../../../../third_party/dart/sdk/lib/mirrors/mirrors.dart"
+ patches:
+- - "../../../../../../third_party/dart/runtime/lib/mirrors_patch.dart"
+- - "../../../../../../third_party/dart/runtime/lib/mirrors_impl.dart"
+- - "../../../../../../third_party/dart/runtime/lib/mirror_reference.dart"
++ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/mirrors_patch.dart"
++ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/mirrors_impl.dart"
++ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/mirror_reference.dart"
+
+ nativewrappers:
+ uri: "../../../../../../third_party/dart/sdk/lib/html/dartium/nativewrappers.dart"
+@@ -142,7 +142,7 @@ dart_runner:
+
+ typed_data:
+ uri: "../../../../../../third_party/dart/sdk/lib/typed_data/typed_data.dart"
+- patches: "../../../../../../third_party/dart/runtime/lib/typed_data_patch.dart"
++ patches: "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/typed_data_patch.dart"
+
+ fuchsia.builtin:
+ uri: "../../../../../../flutter/shell/platform/fuchsia/dart_runner/embedder/builtin.dart"
+diff --git a/shell/platform/fuchsia/flutter/kernel/libraries.json b/shell/platform/fuchsia/flutter/kernel/libraries.json
+index 5a4602d8c..a8436200f 100644
+--- a/shell/platform/fuchsia/flutter/kernel/libraries.json
++++ b/shell/platform/fuchsia/flutter/kernel/libraries.json
+@@ -1,43 +1,43 @@
+ {
+ "comment:0": "NOTE: THIS FILE IS GENERATED. DO NOT EDIT.",
+- "comment:1": "Instead modify 'shell/platform/fuchsia/flutter/kernel/libraries.yaml' and follow the instructions therein.",
++ "comment:1": "Instead modify 'flutter/shell/platform/fuchsia/flutter/kernel/libraries.yaml' and follow the instructions therein.",
+ "flutter_runner": {
+ "libraries": {
+ "_builtin": {
+- "uri": "../../../../../../third_party/dart/runtime/bin/builtin.dart"
++ "uri": "../../../../../../third_party/dart/sdk/lib/_internal/vm/bin/builtin.dart"
+ },
+ "core": {
+ "patches": [
+- "../../../../../../third_party/dart/runtime/lib/core_patch.dart",
+- "../../../../../../third_party/dart/runtime/lib/array.dart",
+- "../../../../../../third_party/dart/runtime/lib/array_patch.dart",
+- "../../../../../../third_party/dart/runtime/lib/bigint_patch.dart",
+- "../../../../../../third_party/dart/runtime/lib/bool_patch.dart",
+- "../../../../../../third_party/dart/runtime/lib/date_patch.dart",
+- "../../../../../../third_party/dart/runtime/lib/double.dart",
+- "../../../../../../third_party/dart/runtime/lib/double_patch.dart",
+- "../../../../../../third_party/dart/runtime/lib/errors_patch.dart",
+- "../../../../../../third_party/dart/runtime/lib/expando_patch.dart",
+- "../../../../../../third_party/dart/runtime/lib/function.dart",
+- "../../../../../../third_party/dart/runtime/lib/function_patch.dart",
+- "../../../../../../third_party/dart/runtime/lib/growable_array.dart",
+- "../../../../../../third_party/dart/runtime/lib/identical_patch.dart",
+- "../../../../../../third_party/dart/runtime/lib/immutable_map.dart",
+- "../../../../../../third_party/dart/runtime/lib/integers.dart",
+- "../../../../../../third_party/dart/runtime/lib/integers_patch.dart",
+- "../../../../../../third_party/dart/runtime/lib/invocation_mirror_patch.dart",
+- "../../../../../../third_party/dart/runtime/lib/lib_prefix.dart",
+- "../../../../../../third_party/dart/runtime/lib/map_patch.dart",
+- "../../../../../../third_party/dart/runtime/lib/null_patch.dart",
+- "../../../../../../third_party/dart/runtime/lib/object_patch.dart",
+- "../../../../../../third_party/dart/runtime/lib/regexp_patch.dart",
+- "../../../../../../third_party/dart/runtime/lib/stacktrace.dart",
+- "../../../../../../third_party/dart/runtime/lib/stopwatch_patch.dart",
+- "../../../../../../third_party/dart/runtime/lib/string_buffer_patch.dart",
+- "../../../../../../third_party/dart/runtime/lib/string_patch.dart",
+- "../../../../../../third_party/dart/runtime/lib/type_patch.dart",
+- "../../../../../../third_party/dart/runtime/lib/uri_patch.dart",
+- "../../../../../../third_party/dart/runtime/lib/weak_property.dart"
++ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/core_patch.dart",
++ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/array.dart",
++ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/array_patch.dart",
++ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/bigint_patch.dart",
++ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/bool_patch.dart",
++ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/date_patch.dart",
++ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/double.dart",
++ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/double_patch.dart",
++ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/errors_patch.dart",
++ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/expando_patch.dart",
++ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/function.dart",
++ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/function_patch.dart",
++ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/growable_array.dart",
++ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/identical_patch.dart",
++ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/immutable_map.dart",
++ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/integers.dart",
++ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/integers_patch.dart",
++ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/invocation_mirror_patch.dart",
++ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/lib_prefix.dart",
++ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/map_patch.dart",
++ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/null_patch.dart",
++ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/object_patch.dart",
++ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/regexp_patch.dart",
++ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/stacktrace.dart",
++ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/stopwatch_patch.dart",
++ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/string_buffer_patch.dart",
++ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/string_patch.dart",
++ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/type_patch.dart",
++ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/uri_patch.dart",
++ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/weak_property.dart"
+ ],
+ "uri": "../../../../../../third_party/dart/sdk/lib/core/core.dart"
+ },
+@@ -46,30 +46,30 @@
+ },
+ "async": {
+ "patches": [
+- "../../../../../../third_party/dart/runtime/lib/async_patch.dart",
+- "../../../../../../third_party/dart/runtime/lib/deferred_load_patch.dart",
+- "../../../../../../third_party/dart/runtime/lib/schedule_microtask_patch.dart",
+- "../../../../../../third_party/dart/runtime/lib/timer_patch.dart"
++ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/async_patch.dart",
++ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/deferred_load_patch.dart",
++ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/schedule_microtask_patch.dart",
++ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/timer_patch.dart"
+ ],
+ "uri": "../../../../../../third_party/dart/sdk/lib/async/async.dart"
+ },
+ "collection": {
+ "patches": [
+- "../../../../../../third_party/dart/runtime/lib/collection_patch.dart",
+- "../../../../../../third_party/dart/runtime/lib/compact_hash.dart"
++ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/collection_patch.dart",
++ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/compact_hash.dart"
+ ],
+ "uri": "../../../../../../third_party/dart/sdk/lib/collection/collection.dart"
+ },
+ "ffi": {
+ "patches": [
+- "../../../../../../third_party/dart/runtime/lib/ffi_dynamic_library_patch.dart",
+- "../../../../../../third_party/dart/runtime/lib/ffi_native_type_patch.dart",
+- "../../../../../../third_party/dart/runtime/lib/ffi_patch.dart"
++ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/ffi_dynamic_library_patch.dart",
++ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/ffi_native_type_patch.dart",
++ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/ffi_patch.dart"
+ ],
+ "uri": "../../../../../../third_party/dart/sdk/lib/ffi/ffi.dart"
+ },
+ "typed_data": {
+- "patches": "../../../../../../third_party/dart/runtime/lib/typed_data_patch.dart",
++ "patches": "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/typed_data_patch.dart",
+ "uri": "../../../../../../third_party/dart/sdk/lib/typed_data/typed_data.dart"
+ },
+ "nativewrappers": {
+@@ -77,24 +77,24 @@
+ },
+ "mirrors": {
+ "patches": [
+- "../../../../../../third_party/dart/runtime/lib/mirrors_patch.dart",
+- "../../../../../../third_party/dart/runtime/lib/mirrors_impl.dart",
+- "../../../../../../third_party/dart/runtime/lib/mirror_reference.dart"
++ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/mirrors_patch.dart",
++ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/mirrors_impl.dart",
++ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/mirror_reference.dart"
+ ],
+ "uri": "../../../../../../third_party/dart/sdk/lib/mirrors/mirrors.dart"
+ },
+ "developer": {
+ "patches": [
+- "../../../../../../third_party/dart/runtime/lib/developer.dart",
+- "../../../../../../third_party/dart/runtime/lib/profiler.dart",
+- "../../../../../../third_party/dart/runtime/lib/timeline.dart"
++ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/developer.dart",
++ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/profiler.dart",
++ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/timeline.dart"
+ ],
+ "uri": "../../../../../../third_party/dart/sdk/lib/developer/developer.dart"
+ },
+ "isolate": {
+ "patches": [
+- "../../../../../../third_party/dart/runtime/lib/isolate_patch.dart",
+- "../../../../../../third_party/dart/runtime/lib/timer_impl.dart"
++ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/isolate_patch.dart",
++ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/timer_impl.dart"
+ ],
+ "uri": "../../../../../../third_party/dart/sdk/lib/isolate/isolate.dart"
+ },
+@@ -103,48 +103,48 @@
+ },
+ "wasm": {
+ "patches": [
+- "../../../../../../third_party/dart/runtime/lib/wasm_patch.dart"
++ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/wasm_patch.dart"
+ ],
+ "uri": "../../../../../../third_party/dart/sdk/lib/wasm/wasm.dart"
+ },
+ "io": {
+ "patches": [
+- "../../../../../../third_party/dart/runtime/bin/common_patch.dart",
+- "../../../../../../third_party/dart/runtime/bin/directory_patch.dart",
+- "../../../../../../third_party/dart/runtime/bin/eventhandler_patch.dart",
+- "../../../../../../third_party/dart/runtime/bin/file_patch.dart",
+- "../../../../../../third_party/dart/runtime/bin/file_system_entity_patch.dart",
+- "../../../../../../third_party/dart/runtime/bin/filter_patch.dart",
+- "../../../../../../third_party/dart/runtime/bin/io_service_patch.dart",
+- "../../../../../../third_party/dart/runtime/bin/namespace_patch.dart",
+- "../../../../../../third_party/dart/runtime/bin/platform_patch.dart",
+- "../../../../../../third_party/dart/runtime/bin/process_patch.dart",
+- "../../../../../../third_party/dart/runtime/bin/socket_patch.dart",
+- "../../../../../../third_party/dart/runtime/bin/stdio_patch.dart",
+- "../../../../../../third_party/dart/runtime/bin/secure_socket_patch.dart",
+- "../../../../../../third_party/dart/runtime/bin/sync_socket_patch.dart"
++ "../../../../../../third_party/dart/sdk/lib/_internal/vm/bin/common_patch.dart",
++ "../../../../../../third_party/dart/sdk/lib/_internal/vm/bin/directory_patch.dart",
++ "../../../../../../third_party/dart/sdk/lib/_internal/vm/bin/eventhandler_patch.dart",
++ "../../../../../../third_party/dart/sdk/lib/_internal/vm/bin/file_patch.dart",
++ "../../../../../../third_party/dart/sdk/lib/_internal/vm/bin/file_system_entity_patch.dart",
++ "../../../../../../third_party/dart/sdk/lib/_internal/vm/bin/filter_patch.dart",
++ "../../../../../../third_party/dart/sdk/lib/_internal/vm/bin/io_service_patch.dart",
++ "../../../../../../third_party/dart/sdk/lib/_internal/vm/bin/namespace_patch.dart",
++ "../../../../../../third_party/dart/sdk/lib/_internal/vm/bin/platform_patch.dart",
++ "../../../../../../third_party/dart/sdk/lib/_internal/vm/bin/process_patch.dart",
++ "../../../../../../third_party/dart/sdk/lib/_internal/vm/bin/socket_patch.dart",
++ "../../../../../../third_party/dart/sdk/lib/_internal/vm/bin/stdio_patch.dart",
++ "../../../../../../third_party/dart/sdk/lib/_internal/vm/bin/secure_socket_patch.dart",
++ "../../../../../../third_party/dart/sdk/lib/_internal/vm/bin/sync_socket_patch.dart"
+ ],
+ "uri": "../../../../../../third_party/dart/sdk/lib/io/io.dart"
+ },
+ "_internal": {
+ "patches": [
+- "../../../../../../third_party/dart/runtime/lib/internal_patch.dart",
+- "../../../../../../third_party/dart/runtime/lib/class_id_fasta.dart",
+- "../../../../../../third_party/dart/runtime/lib/print_patch.dart",
+- "../../../../../../third_party/dart/runtime/lib/symbol_patch.dart",
++ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/internal_patch.dart",
++ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/class_id_fasta.dart",
++ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/print_patch.dart",
++ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/symbol_patch.dart",
+ "../../../../../../third_party/dart/sdk/lib/internal/patch.dart"
+ ],
+ "uri": "../../../../../../third_party/dart/sdk/lib/internal/internal.dart"
+ },
+ "convert": {
+- "patches": "../../../../../../third_party/dart/runtime/lib/convert_patch.dart",
++ "patches": "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/convert_patch.dart",
+ "uri": "../../../../../../third_party/dart/sdk/lib/convert/convert.dart"
+ },
+ "profiler": {
+ "uri": "../../../../../../third_party/dart/sdk/lib/profiler/profiler.dart"
+ },
+ "math": {
+- "patches": "../../../../../../third_party/dart/runtime/lib/math_patch.dart",
++ "patches": "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/math_patch.dart",
+ "uri": "../../../../../../third_party/dart/sdk/lib/math/math.dart"
+ },
+ "_http": {
+@@ -160,7 +160,7 @@
+ "uri": "../../../../../../flutter/lib/ui/ui.dart"
+ },
+ "vmservice_io": {
+- "uri": "../../../../../../third_party/dart/runtime/bin/vmservice/vmservice_io.dart"
++ "uri": "../../../../../../third_party/dart/sdk/lib/_internal/vm/bin/vmservice/vmservice_io.dart"
+ }
+ }
+ }
+diff --git a/shell/platform/fuchsia/flutter/kernel/libraries.yaml b/shell/platform/fuchsia/flutter/kernel/libraries.yaml
+index f8385ca29..05b7f4f9f 100644
+--- a/shell/platform/fuchsia/flutter/kernel/libraries.yaml
++++ b/shell/platform/fuchsia/flutter/kernel/libraries.yaml
+@@ -14,87 +14,87 @@
+ flutter_runner:
+ libraries:
+ _builtin:
+- uri: "../../../../../../third_party/dart/runtime/bin/builtin.dart"
++ uri: "../../../../../../third_party/dart/sdk/lib/_internal/vm/bin/builtin.dart"
+
+ _internal:
+ uri: "../../../../../../third_party/dart/sdk/lib/internal/internal.dart"
+ patches:
+- - "../../../../../../third_party/dart/runtime/lib/internal_patch.dart"
+- - "../../../../../../third_party/dart/runtime/lib/class_id_fasta.dart"
+- - "../../../../../../third_party/dart/runtime/lib/print_patch.dart"
+- - "../../../../../../third_party/dart/runtime/lib/symbol_patch.dart"
++ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/internal_patch.dart"
++ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/class_id_fasta.dart"
++ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/print_patch.dart"
++ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/symbol_patch.dart"
+ - "../../../../../../third_party/dart/sdk/lib/internal/patch.dart"
+
+ async:
+ uri: "../../../../../../third_party/dart/sdk/lib/async/async.dart"
+ patches:
+- - "../../../../../../third_party/dart/runtime/lib/async_patch.dart"
+- - "../../../../../../third_party/dart/runtime/lib/deferred_load_patch.dart"
+- - "../../../../../../third_party/dart/runtime/lib/schedule_microtask_patch.dart"
+- - "../../../../../../third_party/dart/runtime/lib/timer_patch.dart"
++ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/async_patch.dart"
++ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/deferred_load_patch.dart"
++ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/schedule_microtask_patch.dart"
++ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/timer_patch.dart"
+
+ collection:
+ uri: "../../../../../../third_party/dart/sdk/lib/collection/collection.dart"
+ patches:
+- - "../../../../../../third_party/dart/runtime/lib/collection_patch.dart"
+- - "../../../../../../third_party/dart/runtime/lib/compact_hash.dart"
++ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/collection_patch.dart"
++ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/compact_hash.dart"
+
+ convert:
+ uri: "../../../../../../third_party/dart/sdk/lib/convert/convert.dart"
+- patches: "../../../../../../third_party/dart/runtime/lib/convert_patch.dart"
++ patches: "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/convert_patch.dart"
+
+ core:
+ uri: "../../../../../../third_party/dart/sdk/lib/core/core.dart"
+ patches:
+- - "../../../../../../third_party/dart/runtime/lib/core_patch.dart"
+- - "../../../../../../third_party/dart/runtime/lib/array.dart"
+- - "../../../../../../third_party/dart/runtime/lib/array_patch.dart"
+- - "../../../../../../third_party/dart/runtime/lib/bigint_patch.dart"
+- - "../../../../../../third_party/dart/runtime/lib/bool_patch.dart"
+- - "../../../../../../third_party/dart/runtime/lib/date_patch.dart"
+- - "../../../../../../third_party/dart/runtime/lib/double.dart"
+- - "../../../../../../third_party/dart/runtime/lib/double_patch.dart"
+- - "../../../../../../third_party/dart/runtime/lib/errors_patch.dart"
+- - "../../../../../../third_party/dart/runtime/lib/expando_patch.dart"
+- - "../../../../../../third_party/dart/runtime/lib/function.dart"
+- - "../../../../../../third_party/dart/runtime/lib/function_patch.dart"
+- - "../../../../../../third_party/dart/runtime/lib/growable_array.dart"
+- - "../../../../../../third_party/dart/runtime/lib/identical_patch.dart"
+- - "../../../../../../third_party/dart/runtime/lib/immutable_map.dart"
+- - "../../../../../../third_party/dart/runtime/lib/integers.dart"
+- - "../../../../../../third_party/dart/runtime/lib/integers_patch.dart"
+- - "../../../../../../third_party/dart/runtime/lib/invocation_mirror_patch.dart"
+- - "../../../../../../third_party/dart/runtime/lib/lib_prefix.dart"
+- - "../../../../../../third_party/dart/runtime/lib/map_patch.dart"
+- - "../../../../../../third_party/dart/runtime/lib/null_patch.dart"
+- - "../../../../../../third_party/dart/runtime/lib/object_patch.dart"
+- - "../../../../../../third_party/dart/runtime/lib/regexp_patch.dart"
+- - "../../../../../../third_party/dart/runtime/lib/stacktrace.dart"
+- - "../../../../../../third_party/dart/runtime/lib/stopwatch_patch.dart"
+- - "../../../../../../third_party/dart/runtime/lib/string_buffer_patch.dart"
+- - "../../../../../../third_party/dart/runtime/lib/string_patch.dart"
+- - "../../../../../../third_party/dart/runtime/lib/type_patch.dart"
+- - "../../../../../../third_party/dart/runtime/lib/uri_patch.dart"
+- - "../../../../../../third_party/dart/runtime/lib/weak_property.dart"
++ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/core_patch.dart"
++ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/array.dart"
++ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/array_patch.dart"
++ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/bigint_patch.dart"
++ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/bool_patch.dart"
++ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/date_patch.dart"
++ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/double.dart"
++ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/double_patch.dart"
++ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/errors_patch.dart"
++ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/expando_patch.dart"
++ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/function.dart"
++ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/function_patch.dart"
++ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/growable_array.dart"
++ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/identical_patch.dart"
++ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/immutable_map.dart"
++ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/integers.dart"
++ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/integers_patch.dart"
++ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/invocation_mirror_patch.dart"
++ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/lib_prefix.dart"
++ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/map_patch.dart"
++ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/null_patch.dart"
++ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/object_patch.dart"
++ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/regexp_patch.dart"
++ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/stacktrace.dart"
++ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/stopwatch_patch.dart"
++ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/string_buffer_patch.dart"
++ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/string_patch.dart"
++ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/type_patch.dart"
++ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/uri_patch.dart"
++ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/weak_property.dart"
+
+ developer:
+ uri: "../../../../../../third_party/dart/sdk/lib/developer/developer.dart"
+ patches:
+- - "../../../../../../third_party/dart/runtime/lib/developer.dart"
+- - "../../../../../../third_party/dart/runtime/lib/profiler.dart"
+- - "../../../../../../third_party/dart/runtime/lib/timeline.dart"
++ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/developer.dart"
++ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/profiler.dart"
++ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/timeline.dart"
+
+ ffi:
+ uri: "../../../../../../third_party/dart/sdk/lib/ffi/ffi.dart"
+ patches:
+- - "../../../../../../third_party/dart/runtime/lib/ffi_dynamic_library_patch.dart"
+- - "../../../../../../third_party/dart/runtime/lib/ffi_native_type_patch.dart"
+- - "../../../../../../third_party/dart/runtime/lib/ffi_patch.dart"
++ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/ffi_dynamic_library_patch.dart"
++ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/ffi_native_type_patch.dart"
++ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/ffi_patch.dart"
+
+ wasm:
+ uri: "../../../../../../third_party/dart/sdk/lib/wasm/wasm.dart"
+ patches:
+- - "../../../../../../third_party/dart/runtime/lib/wasm_patch.dart"
++ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/wasm_patch.dart"
+
+ _http:
+ uri: "../../../../../../third_party/dart/sdk/lib/_http/http.dart"
+@@ -102,37 +102,37 @@ flutter_runner:
+ io:
+ uri: "../../../../../../third_party/dart/sdk/lib/io/io.dart"
+ patches:
+- - "../../../../../../third_party/dart/runtime/bin/common_patch.dart"
+- - "../../../../../../third_party/dart/runtime/bin/directory_patch.dart"
+- - "../../../../../../third_party/dart/runtime/bin/eventhandler_patch.dart"
+- - "../../../../../../third_party/dart/runtime/bin/file_patch.dart"
+- - "../../../../../../third_party/dart/runtime/bin/file_system_entity_patch.dart"
+- - "../../../../../../third_party/dart/runtime/bin/filter_patch.dart"
+- - "../../../../../../third_party/dart/runtime/bin/io_service_patch.dart"
+- - "../../../../../../third_party/dart/runtime/bin/namespace_patch.dart"
+- - "../../../../../../third_party/dart/runtime/bin/platform_patch.dart"
+- - "../../../../../../third_party/dart/runtime/bin/process_patch.dart"
+- - "../../../../../../third_party/dart/runtime/bin/socket_patch.dart"
+- - "../../../../../../third_party/dart/runtime/bin/stdio_patch.dart"
+- - "../../../../../../third_party/dart/runtime/bin/secure_socket_patch.dart"
+- - "../../../../../../third_party/dart/runtime/bin/sync_socket_patch.dart"
++ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/bin/common_patch.dart"
++ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/bin/directory_patch.dart"
++ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/bin/eventhandler_patch.dart"
++ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/bin/file_patch.dart"
++ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/bin/file_system_entity_patch.dart"
++ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/bin/filter_patch.dart"
++ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/bin/io_service_patch.dart"
++ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/bin/namespace_patch.dart"
++ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/bin/platform_patch.dart"
++ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/bin/process_patch.dart"
++ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/bin/socket_patch.dart"
++ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/bin/stdio_patch.dart"
++ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/bin/secure_socket_patch.dart"
++ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/bin/sync_socket_patch.dart"
+
+ isolate:
+ uri: "../../../../../../third_party/dart/sdk/lib/isolate/isolate.dart"
+ patches:
+- - "../../../../../../third_party/dart/runtime/lib/isolate_patch.dart"
+- - "../../../../../../third_party/dart/runtime/lib/timer_impl.dart"
++ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/isolate_patch.dart"
++ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/timer_impl.dart"
+
+ math:
+ uri: "../../../../../../third_party/dart/sdk/lib/math/math.dart"
+- patches: "../../../../../../third_party/dart/runtime/lib/math_patch.dart"
++ patches: "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/math_patch.dart"
+
+ mirrors:
+ uri: "../../../../../../third_party/dart/sdk/lib/mirrors/mirrors.dart"
+ patches:
+- - "../../../../../../third_party/dart/runtime/lib/mirrors_patch.dart"
+- - "../../../../../../third_party/dart/runtime/lib/mirrors_impl.dart"
+- - "../../../../../../third_party/dart/runtime/lib/mirror_reference.dart"
++ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/mirrors_patch.dart"
++ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/mirrors_impl.dart"
++ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/mirror_reference.dart"
+
+ nativewrappers:
+ uri: "../../../../../../third_party/dart/sdk/lib/html/dartium/nativewrappers.dart"
+@@ -142,7 +142,7 @@ flutter_runner:
+
+ typed_data:
+ uri: "../../../../../../third_party/dart/sdk/lib/typed_data/typed_data.dart"
+- patches: "../../../../../../third_party/dart/runtime/lib/typed_data_patch.dart"
++ patches: "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/typed_data_patch.dart"
+
+ fuchsia.builtin:
+ uri: "../../../../../../flutter/shell/platform/fuchsia/dart_runner/embedder/builtin.dart"
+@@ -160,4 +160,4 @@ flutter_runner:
+ uri: "../../../../../../third_party/dart/sdk/lib/vmservice/vmservice.dart"
+
+ vmservice_io:
+- uri: "../../../../../../third_party/dart/runtime/bin/vmservice/vmservice_io.dart"
++ uri: "../../../../../../third_party/dart/sdk/lib/_internal/vm/bin/vmservice/vmservice_io.dart"
diff --git a/tools/patches/flutter-engine/ea969c358e24f71b865d5f720c0c1c8456a53bad.patch b/tools/patches/flutter-engine/ea969c358e24f71b865d5f720c0c1c8456a53bad.patch
new file mode 100644
index 0000000..6151279
--- /dev/null
+++ b/tools/patches/flutter-engine/ea969c358e24f71b865d5f720c0c1c8456a53bad.patch
@@ -0,0 +1,1305 @@
+diff --git a/lib/snapshot/libraries.json b/lib/snapshot/libraries.json
+index b6ffcef58..c4783158b 100644
+--- a/lib/snapshot/libraries.json
++++ b/lib/snapshot/libraries.json
+@@ -4,69 +4,69 @@
+ "flutter": {
+ "libraries": {
+ "_builtin": {
+- "uri": "../../../third_party/dart/runtime/bin/builtin.dart"
++ "uri": "../../../third_party/dart/sdk/lib/_internal/vm/bin/builtin.dart"
+ },
+ "core": {
+ "patches": [
+- "../../../third_party/dart/runtime/lib/core_patch.dart",
+- "../../../third_party/dart/runtime/lib/array.dart",
+- "../../../third_party/dart/runtime/lib/array_patch.dart",
+- "../../../third_party/dart/runtime/lib/bigint_patch.dart",
+- "../../../third_party/dart/runtime/lib/bool_patch.dart",
+- "../../../third_party/dart/runtime/lib/date_patch.dart",
+- "../../../third_party/dart/runtime/lib/double.dart",
+- "../../../third_party/dart/runtime/lib/double_patch.dart",
+- "../../../third_party/dart/runtime/lib/errors_patch.dart",
+- "../../../third_party/dart/runtime/lib/expando_patch.dart",
+- "../../../third_party/dart/runtime/lib/function.dart",
+- "../../../third_party/dart/runtime/lib/function_patch.dart",
+- "../../../third_party/dart/runtime/lib/growable_array.dart",
+- "../../../third_party/dart/runtime/lib/identical_patch.dart",
+- "../../../third_party/dart/runtime/lib/immutable_map.dart",
+- "../../../third_party/dart/runtime/lib/integers.dart",
+- "../../../third_party/dart/runtime/lib/integers_patch.dart",
+- "../../../third_party/dart/runtime/lib/invocation_mirror_patch.dart",
+- "../../../third_party/dart/runtime/lib/lib_prefix.dart",
+- "../../../third_party/dart/runtime/lib/map_patch.dart",
+- "../../../third_party/dart/runtime/lib/null_patch.dart",
+- "../../../third_party/dart/runtime/lib/object_patch.dart",
+- "../../../third_party/dart/runtime/lib/regexp_patch.dart",
+- "../../../third_party/dart/runtime/lib/stacktrace.dart",
+- "../../../third_party/dart/runtime/lib/stopwatch_patch.dart",
+- "../../../third_party/dart/runtime/lib/string_buffer_patch.dart",
+- "../../../third_party/dart/runtime/lib/string_patch.dart",
+- "../../../third_party/dart/runtime/lib/type_patch.dart",
+- "../../../third_party/dart/runtime/lib/uri_patch.dart",
+- "../../../third_party/dart/runtime/lib/weak_property.dart"
++ "../../../third_party/dart/sdk/lib/_internal/vm/lib/core_patch.dart",
++ "../../../third_party/dart/sdk/lib/_internal/vm/lib/array.dart",
++ "../../../third_party/dart/sdk/lib/_internal/vm/lib/array_patch.dart",
++ "../../../third_party/dart/sdk/lib/_internal/vm/lib/bigint_patch.dart",
++ "../../../third_party/dart/sdk/lib/_internal/vm/lib/bool_patch.dart",
++ "../../../third_party/dart/sdk/lib/_internal/vm/lib/date_patch.dart",
++ "../../../third_party/dart/sdk/lib/_internal/vm/lib/double.dart",
++ "../../../third_party/dart/sdk/lib/_internal/vm/lib/double_patch.dart",
++ "../../../third_party/dart/sdk/lib/_internal/vm/lib/errors_patch.dart",
++ "../../../third_party/dart/sdk/lib/_internal/vm/lib/expando_patch.dart",
++ "../../../third_party/dart/sdk/lib/_internal/vm/lib/function.dart",
++ "../../../third_party/dart/sdk/lib/_internal/vm/lib/function_patch.dart",
++ "../../../third_party/dart/sdk/lib/_internal/vm/lib/growable_array.dart",
++ "../../../third_party/dart/sdk/lib/_internal/vm/lib/identical_patch.dart",
++ "../../../third_party/dart/sdk/lib/_internal/vm/lib/immutable_map.dart",
++ "../../../third_party/dart/sdk/lib/_internal/vm/lib/integers.dart",
++ "../../../third_party/dart/sdk/lib/_internal/vm/lib/integers_patch.dart",
++ "../../../third_party/dart/sdk/lib/_internal/vm/lib/invocation_mirror_patch.dart",
++ "../../../third_party/dart/sdk/lib/_internal/vm/lib/lib_prefix.dart",
++ "../../../third_party/dart/sdk/lib/_internal/vm/lib/map_patch.dart",
++ "../../../third_party/dart/sdk/lib/_internal/vm/lib/null_patch.dart",
++ "../../../third_party/dart/sdk/lib/_internal/vm/lib/object_patch.dart",
++ "../../../third_party/dart/sdk/lib/_internal/vm/lib/regexp_patch.dart",
++ "../../../third_party/dart/sdk/lib/_internal/vm/lib/stacktrace.dart",
++ "../../../third_party/dart/sdk/lib/_internal/vm/lib/stopwatch_patch.dart",
++ "../../../third_party/dart/sdk/lib/_internal/vm/lib/string_buffer_patch.dart",
++ "../../../third_party/dart/sdk/lib/_internal/vm/lib/string_patch.dart",
++ "../../../third_party/dart/sdk/lib/_internal/vm/lib/type_patch.dart",
++ "../../../third_party/dart/sdk/lib/_internal/vm/lib/uri_patch.dart",
++ "../../../third_party/dart/sdk/lib/_internal/vm/lib/weak_property.dart"
+ ],
+ "uri": "../../../third_party/dart/sdk/lib/core/core.dart"
+ },
+ "async": {
+ "patches": [
+- "../../../third_party/dart/runtime/lib/async_patch.dart",
+- "../../../third_party/dart/runtime/lib/deferred_load_patch.dart",
+- "../../../third_party/dart/runtime/lib/schedule_microtask_patch.dart",
+- "../../../third_party/dart/runtime/lib/timer_patch.dart"
++ "../../../third_party/dart/sdk/lib/_internal/vm/lib/async_patch.dart",
++ "../../../third_party/dart/sdk/lib/_internal/vm/lib/deferred_load_patch.dart",
++ "../../../third_party/dart/sdk/lib/_internal/vm/lib/schedule_microtask_patch.dart",
++ "../../../third_party/dart/sdk/lib/_internal/vm/lib/timer_patch.dart"
+ ],
+ "uri": "../../../third_party/dart/sdk/lib/async/async.dart"
+ },
+ "collection": {
+ "patches": [
+- "../../../third_party/dart/runtime/lib/collection_patch.dart",
+- "../../../third_party/dart/runtime/lib/compact_hash.dart"
++ "../../../third_party/dart/sdk/lib/_internal/vm/lib/collection_patch.dart",
++ "../../../third_party/dart/sdk/lib/_internal/vm/lib/compact_hash.dart"
+ ],
+ "uri": "../../../third_party/dart/sdk/lib/collection/collection.dart"
+ },
+ "ffi": {
+ "patches": [
+- "../../../third_party/dart/runtime/lib/ffi_dynamic_library_patch.dart",
+- "../../../third_party/dart/runtime/lib/ffi_native_type_patch.dart",
+- "../../../third_party/dart/runtime/lib/ffi_patch.dart"
++ "../../../third_party/dart/sdk/lib/_internal/vm/lib/ffi_dynamic_library_patch.dart",
++ "../../../third_party/dart/sdk/lib/_internal/vm/lib/ffi_native_type_patch.dart",
++ "../../../third_party/dart/sdk/lib/_internal/vm/lib/ffi_patch.dart"
+ ],
+ "uri": "../../../third_party/dart/sdk/lib/ffi/ffi.dart"
+ },
+ "typed_data": {
+- "patches": "../../../third_party/dart/runtime/lib/typed_data_patch.dart",
++ "patches": "../../../third_party/dart/sdk/lib/_internal/vm/lib/typed_data_patch.dart",
+ "uri": "../../../third_party/dart/sdk/lib/typed_data/typed_data.dart"
+ },
+ "nativewrappers": {
+@@ -74,24 +74,24 @@
+ },
+ "mirrors": {
+ "patches": [
+- "../../../third_party/dart/runtime/lib/mirrors_patch.dart",
+- "../../../third_party/dart/runtime/lib/mirrors_impl.dart",
+- "../../../third_party/dart/runtime/lib/mirror_reference.dart"
++ "../../../third_party/dart/sdk/lib/_internal/vm/lib/mirrors_patch.dart",
++ "../../../third_party/dart/sdk/lib/_internal/vm/lib/mirrors_impl.dart",
++ "../../../third_party/dart/sdk/lib/_internal/vm/lib/mirror_reference.dart"
+ ],
+ "uri": "../../../third_party/dart/sdk/lib/mirrors/mirrors.dart"
+ },
+ "developer": {
+ "patches": [
+- "../../../third_party/dart/runtime/lib/developer.dart",
+- "../../../third_party/dart/runtime/lib/profiler.dart",
+- "../../../third_party/dart/runtime/lib/timeline.dart"
++ "../../../third_party/dart/sdk/lib/_internal/vm/lib/developer.dart",
++ "../../../third_party/dart/sdk/lib/_internal/vm/lib/profiler.dart",
++ "../../../third_party/dart/sdk/lib/_internal/vm/lib/timeline.dart"
+ ],
+ "uri": "../../../third_party/dart/sdk/lib/developer/developer.dart"
+ },
+ "isolate": {
+ "patches": [
+- "../../../third_party/dart/runtime/lib/isolate_patch.dart",
+- "../../../third_party/dart/runtime/lib/timer_impl.dart"
++ "../../../third_party/dart/sdk/lib/_internal/vm/lib/isolate_patch.dart",
++ "../../../third_party/dart/sdk/lib/_internal/vm/lib/timer_impl.dart"
+ ],
+ "uri": "../../../third_party/dart/sdk/lib/isolate/isolate.dart"
+ },
+@@ -100,48 +100,48 @@
+ },
+ "wasm": {
+ "patches": [
+- "../../../third_party/dart/runtime/lib/wasm_patch.dart"
++ "../../../third_party/dart/sdk/lib/_internal/vm/lib/wasm_patch.dart"
+ ],
+ "uri": "../../../third_party/dart/sdk/lib/wasm/wasm.dart"
+ },
+ "io": {
+ "patches": [
+- "../../../third_party/dart/runtime/bin/common_patch.dart",
+- "../../../third_party/dart/runtime/bin/directory_patch.dart",
+- "../../../third_party/dart/runtime/bin/eventhandler_patch.dart",
+- "../../../third_party/dart/runtime/bin/file_patch.dart",
+- "../../../third_party/dart/runtime/bin/file_system_entity_patch.dart",
+- "../../../third_party/dart/runtime/bin/filter_patch.dart",
+- "../../../third_party/dart/runtime/bin/io_service_patch.dart",
+- "../../../third_party/dart/runtime/bin/namespace_patch.dart",
+- "../../../third_party/dart/runtime/bin/platform_patch.dart",
+- "../../../third_party/dart/runtime/bin/process_patch.dart",
+- "../../../third_party/dart/runtime/bin/socket_patch.dart",
+- "../../../third_party/dart/runtime/bin/stdio_patch.dart",
+- "../../../third_party/dart/runtime/bin/secure_socket_patch.dart",
+- "../../../third_party/dart/runtime/bin/sync_socket_patch.dart"
++ "../../../third_party/dart/sdk/lib/_internal/vm/bin/common_patch.dart",
++ "../../../third_party/dart/sdk/lib/_internal/vm/bin/directory_patch.dart",
++ "../../../third_party/dart/sdk/lib/_internal/vm/bin/eventhandler_patch.dart",
++ "../../../third_party/dart/sdk/lib/_internal/vm/bin/file_patch.dart",
++ "../../../third_party/dart/sdk/lib/_internal/vm/bin/file_system_entity_patch.dart",
++ "../../../third_party/dart/sdk/lib/_internal/vm/bin/filter_patch.dart",
++ "../../../third_party/dart/sdk/lib/_internal/vm/bin/io_service_patch.dart",
++ "../../../third_party/dart/sdk/lib/_internal/vm/bin/namespace_patch.dart",
++ "../../../third_party/dart/sdk/lib/_internal/vm/bin/platform_patch.dart",
++ "../../../third_party/dart/sdk/lib/_internal/vm/bin/process_patch.dart",
++ "../../../third_party/dart/sdk/lib/_internal/vm/bin/socket_patch.dart",
++ "../../../third_party/dart/sdk/lib/_internal/vm/bin/stdio_patch.dart",
++ "../../../third_party/dart/sdk/lib/_internal/vm/bin/secure_socket_patch.dart",
++ "../../../third_party/dart/sdk/lib/_internal/vm/bin/sync_socket_patch.dart"
+ ],
+ "uri": "../../../third_party/dart/sdk/lib/io/io.dart"
+ },
+ "_internal": {
+ "patches": [
+- "../../../third_party/dart/runtime/lib/internal_patch.dart",
+- "../../../third_party/dart/runtime/lib/class_id_fasta.dart",
+- "../../../third_party/dart/runtime/lib/print_patch.dart",
+- "../../../third_party/dart/runtime/lib/symbol_patch.dart",
++ "../../../third_party/dart/sdk/lib/_internal/vm/lib/internal_patch.dart",
++ "../../../third_party/dart/sdk/lib/_internal/vm/lib/class_id_fasta.dart",
++ "../../../third_party/dart/sdk/lib/_internal/vm/lib/print_patch.dart",
++ "../../../third_party/dart/sdk/lib/_internal/vm/lib/symbol_patch.dart",
+ "../../../third_party/dart/sdk/lib/internal/patch.dart"
+ ],
+ "uri": "../../../third_party/dart/sdk/lib/internal/internal.dart"
+ },
+ "convert": {
+- "patches": "../../../third_party/dart/runtime/lib/convert_patch.dart",
++ "patches": "../../../third_party/dart/sdk/lib/_internal/vm/lib/convert_patch.dart",
+ "uri": "../../../third_party/dart/sdk/lib/convert/convert.dart"
+ },
+ "profiler": {
+ "uri": "../../../third_party/dart/sdk/lib/profiler/profiler.dart"
+ },
+ "math": {
+- "patches": "../../../third_party/dart/runtime/lib/math_patch.dart",
++ "patches": "../../../third_party/dart/sdk/lib/_internal/vm/lib/math_patch.dart",
+ "uri": "../../../third_party/dart/sdk/lib/math/math.dart"
+ },
+ "_http": {
+diff --git a/lib/snapshot/libraries.yaml b/lib/snapshot/libraries.yaml
+index 392e0500b..7269819f7 100644
+--- a/lib/snapshot/libraries.yaml
++++ b/lib/snapshot/libraries.yaml
+@@ -14,87 +14,87 @@
+ flutter:
+ libraries:
+ _builtin:
+- uri: "../../../third_party/dart/runtime/bin/builtin.dart"
++ uri: "../../../third_party/dart/sdk/lib/_internal/vm/bin/builtin.dart"
+
+ _internal:
+ uri: "../../../third_party/dart/sdk/lib/internal/internal.dart"
+ patches:
+- - "../../../third_party/dart/runtime/lib/internal_patch.dart"
+- - "../../../third_party/dart/runtime/lib/class_id_fasta.dart"
+- - "../../../third_party/dart/runtime/lib/print_patch.dart"
+- - "../../../third_party/dart/runtime/lib/symbol_patch.dart"
++ - "../../../third_party/dart/sdk/lib/_internal/vm/lib/internal_patch.dart"
++ - "../../../third_party/dart/sdk/lib/_internal/vm/lib/class_id_fasta.dart"
++ - "../../../third_party/dart/sdk/lib/_internal/vm/lib/print_patch.dart"
++ - "../../../third_party/dart/sdk/lib/_internal/vm/lib/symbol_patch.dart"
+ - "../../../third_party/dart/sdk/lib/internal/patch.dart"
+
+ async:
+ uri: "../../../third_party/dart/sdk/lib/async/async.dart"
+ patches:
+- - "../../../third_party/dart/runtime/lib/async_patch.dart"
+- - "../../../third_party/dart/runtime/lib/deferred_load_patch.dart"
+- - "../../../third_party/dart/runtime/lib/schedule_microtask_patch.dart"
+- - "../../../third_party/dart/runtime/lib/timer_patch.dart"
++ - "../../../third_party/dart/sdk/lib/_internal/vm/lib/async_patch.dart"
++ - "../../../third_party/dart/sdk/lib/_internal/vm/lib/deferred_load_patch.dart"
++ - "../../../third_party/dart/sdk/lib/_internal/vm/lib/schedule_microtask_patch.dart"
++ - "../../../third_party/dart/sdk/lib/_internal/vm/lib/timer_patch.dart"
+
+ collection:
+ uri: "../../../third_party/dart/sdk/lib/collection/collection.dart"
+ patches:
+- - "../../../third_party/dart/runtime/lib/collection_patch.dart"
+- - "../../../third_party/dart/runtime/lib/compact_hash.dart"
++ - "../../../third_party/dart/sdk/lib/_internal/vm/lib/collection_patch.dart"
++ - "../../../third_party/dart/sdk/lib/_internal/vm/lib/compact_hash.dart"
+
+ convert:
+ uri: "../../../third_party/dart/sdk/lib/convert/convert.dart"
+- patches: "../../../third_party/dart/runtime/lib/convert_patch.dart"
++ patches: "../../../third_party/dart/sdk/lib/_internal/vm/lib/convert_patch.dart"
+
+ core:
+ uri: "../../../third_party/dart/sdk/lib/core/core.dart"
+ patches:
+- - "../../../third_party/dart/runtime/lib/core_patch.dart"
+- - "../../../third_party/dart/runtime/lib/array.dart"
+- - "../../../third_party/dart/runtime/lib/array_patch.dart"
+- - "../../../third_party/dart/runtime/lib/bigint_patch.dart"
+- - "../../../third_party/dart/runtime/lib/bool_patch.dart"
+- - "../../../third_party/dart/runtime/lib/date_patch.dart"
+- - "../../../third_party/dart/runtime/lib/double.dart"
+- - "../../../third_party/dart/runtime/lib/double_patch.dart"
+- - "../../../third_party/dart/runtime/lib/errors_patch.dart"
+- - "../../../third_party/dart/runtime/lib/expando_patch.dart"
+- - "../../../third_party/dart/runtime/lib/function.dart"
+- - "../../../third_party/dart/runtime/lib/function_patch.dart"
+- - "../../../third_party/dart/runtime/lib/growable_array.dart"
+- - "../../../third_party/dart/runtime/lib/identical_patch.dart"
+- - "../../../third_party/dart/runtime/lib/immutable_map.dart"
+- - "../../../third_party/dart/runtime/lib/integers.dart"
+- - "../../../third_party/dart/runtime/lib/integers_patch.dart"
+- - "../../../third_party/dart/runtime/lib/invocation_mirror_patch.dart"
+- - "../../../third_party/dart/runtime/lib/lib_prefix.dart"
+- - "../../../third_party/dart/runtime/lib/map_patch.dart"
+- - "../../../third_party/dart/runtime/lib/null_patch.dart"
+- - "../../../third_party/dart/runtime/lib/object_patch.dart"
+- - "../../../third_party/dart/runtime/lib/regexp_patch.dart"
+- - "../../../third_party/dart/runtime/lib/stacktrace.dart"
+- - "../../../third_party/dart/runtime/lib/stopwatch_patch.dart"
+- - "../../../third_party/dart/runtime/lib/string_buffer_patch.dart"
+- - "../../../third_party/dart/runtime/lib/string_patch.dart"
+- - "../../../third_party/dart/runtime/lib/type_patch.dart"
+- - "../../../third_party/dart/runtime/lib/uri_patch.dart"
+- - "../../../third_party/dart/runtime/lib/weak_property.dart"
++ - "../../../third_party/dart/sdk/lib/_internal/vm/lib/core_patch.dart"
++ - "../../../third_party/dart/sdk/lib/_internal/vm/lib/array.dart"
++ - "../../../third_party/dart/sdk/lib/_internal/vm/lib/array_patch.dart"
++ - "../../../third_party/dart/sdk/lib/_internal/vm/lib/bigint_patch.dart"
++ - "../../../third_party/dart/sdk/lib/_internal/vm/lib/bool_patch.dart"
++ - "../../../third_party/dart/sdk/lib/_internal/vm/lib/date_patch.dart"
++ - "../../../third_party/dart/sdk/lib/_internal/vm/lib/double.dart"
++ - "../../../third_party/dart/sdk/lib/_internal/vm/lib/double_patch.dart"
++ - "../../../third_party/dart/sdk/lib/_internal/vm/lib/errors_patch.dart"
++ - "../../../third_party/dart/sdk/lib/_internal/vm/lib/expando_patch.dart"
++ - "../../../third_party/dart/sdk/lib/_internal/vm/lib/function.dart"
++ - "../../../third_party/dart/sdk/lib/_internal/vm/lib/function_patch.dart"
++ - "../../../third_party/dart/sdk/lib/_internal/vm/lib/growable_array.dart"
++ - "../../../third_party/dart/sdk/lib/_internal/vm/lib/identical_patch.dart"
++ - "../../../third_party/dart/sdk/lib/_internal/vm/lib/immutable_map.dart"
++ - "../../../third_party/dart/sdk/lib/_internal/vm/lib/integers.dart"
++ - "../../../third_party/dart/sdk/lib/_internal/vm/lib/integers_patch.dart"
++ - "../../../third_party/dart/sdk/lib/_internal/vm/lib/invocation_mirror_patch.dart"
++ - "../../../third_party/dart/sdk/lib/_internal/vm/lib/lib_prefix.dart"
++ - "../../../third_party/dart/sdk/lib/_internal/vm/lib/map_patch.dart"
++ - "../../../third_party/dart/sdk/lib/_internal/vm/lib/null_patch.dart"
++ - "../../../third_party/dart/sdk/lib/_internal/vm/lib/object_patch.dart"
++ - "../../../third_party/dart/sdk/lib/_internal/vm/lib/regexp_patch.dart"
++ - "../../../third_party/dart/sdk/lib/_internal/vm/lib/stacktrace.dart"
++ - "../../../third_party/dart/sdk/lib/_internal/vm/lib/stopwatch_patch.dart"
++ - "../../../third_party/dart/sdk/lib/_internal/vm/lib/string_buffer_patch.dart"
++ - "../../../third_party/dart/sdk/lib/_internal/vm/lib/string_patch.dart"
++ - "../../../third_party/dart/sdk/lib/_internal/vm/lib/type_patch.dart"
++ - "../../../third_party/dart/sdk/lib/_internal/vm/lib/uri_patch.dart"
++ - "../../../third_party/dart/sdk/lib/_internal/vm/lib/weak_property.dart"
+
+ developer:
+ uri: "../../../third_party/dart/sdk/lib/developer/developer.dart"
+ patches:
+- - "../../../third_party/dart/runtime/lib/developer.dart"
+- - "../../../third_party/dart/runtime/lib/profiler.dart"
+- - "../../../third_party/dart/runtime/lib/timeline.dart"
++ - "../../../third_party/dart/sdk/lib/_internal/vm/lib/developer.dart"
++ - "../../../third_party/dart/sdk/lib/_internal/vm/lib/profiler.dart"
++ - "../../../third_party/dart/sdk/lib/_internal/vm/lib/timeline.dart"
+
+ ffi:
+ uri: "../../../third_party/dart/sdk/lib/ffi/ffi.dart"
+ patches:
+- - "../../../third_party/dart/runtime/lib/ffi_dynamic_library_patch.dart"
+- - "../../../third_party/dart/runtime/lib/ffi_native_type_patch.dart"
+- - "../../../third_party/dart/runtime/lib/ffi_patch.dart"
++ - "../../../third_party/dart/sdk/lib/_internal/vm/lib/ffi_dynamic_library_patch.dart"
++ - "../../../third_party/dart/sdk/lib/_internal/vm/lib/ffi_native_type_patch.dart"
++ - "../../../third_party/dart/sdk/lib/_internal/vm/lib/ffi_patch.dart"
+
+ wasm:
+ uri: "../../../third_party/dart/sdk/lib/wasm/wasm.dart"
+ patches:
+- - "../../../third_party/dart/runtime/lib/wasm_patch.dart"
++ - "../../../third_party/dart/sdk/lib/_internal/vm/lib/wasm_patch.dart"
+
+ _http:
+ uri: "../../../third_party/dart/sdk/lib/_http/http.dart"
+@@ -102,37 +102,37 @@ flutter:
+ io:
+ uri: "../../../third_party/dart/sdk/lib/io/io.dart"
+ patches:
+- - "../../../third_party/dart/runtime/bin/common_patch.dart"
+- - "../../../third_party/dart/runtime/bin/directory_patch.dart"
+- - "../../../third_party/dart/runtime/bin/eventhandler_patch.dart"
+- - "../../../third_party/dart/runtime/bin/file_patch.dart"
+- - "../../../third_party/dart/runtime/bin/file_system_entity_patch.dart"
+- - "../../../third_party/dart/runtime/bin/filter_patch.dart"
+- - "../../../third_party/dart/runtime/bin/io_service_patch.dart"
+- - "../../../third_party/dart/runtime/bin/namespace_patch.dart"
+- - "../../../third_party/dart/runtime/bin/platform_patch.dart"
+- - "../../../third_party/dart/runtime/bin/process_patch.dart"
+- - "../../../third_party/dart/runtime/bin/socket_patch.dart"
+- - "../../../third_party/dart/runtime/bin/stdio_patch.dart"
+- - "../../../third_party/dart/runtime/bin/secure_socket_patch.dart"
+- - "../../../third_party/dart/runtime/bin/sync_socket_patch.dart"
++ - "../../../third_party/dart/sdk/lib/_internal/vm/bin/common_patch.dart"
++ - "../../../third_party/dart/sdk/lib/_internal/vm/bin/directory_patch.dart"
++ - "../../../third_party/dart/sdk/lib/_internal/vm/bin/eventhandler_patch.dart"
++ - "../../../third_party/dart/sdk/lib/_internal/vm/bin/file_patch.dart"
++ - "../../../third_party/dart/sdk/lib/_internal/vm/bin/file_system_entity_patch.dart"
++ - "../../../third_party/dart/sdk/lib/_internal/vm/bin/filter_patch.dart"
++ - "../../../third_party/dart/sdk/lib/_internal/vm/bin/io_service_patch.dart"
++ - "../../../third_party/dart/sdk/lib/_internal/vm/bin/namespace_patch.dart"
++ - "../../../third_party/dart/sdk/lib/_internal/vm/bin/platform_patch.dart"
++ - "../../../third_party/dart/sdk/lib/_internal/vm/bin/process_patch.dart"
++ - "../../../third_party/dart/sdk/lib/_internal/vm/bin/socket_patch.dart"
++ - "../../../third_party/dart/sdk/lib/_internal/vm/bin/stdio_patch.dart"
++ - "../../../third_party/dart/sdk/lib/_internal/vm/bin/secure_socket_patch.dart"
++ - "../../../third_party/dart/sdk/lib/_internal/vm/bin/sync_socket_patch.dart"
+
+ isolate:
+ uri: "../../../third_party/dart/sdk/lib/isolate/isolate.dart"
+ patches:
+- - "../../../third_party/dart/runtime/lib/isolate_patch.dart"
+- - "../../../third_party/dart/runtime/lib/timer_impl.dart"
++ - "../../../third_party/dart/sdk/lib/_internal/vm/lib/isolate_patch.dart"
++ - "../../../third_party/dart/sdk/lib/_internal/vm/lib/timer_impl.dart"
+
+ math:
+ uri: "../../../third_party/dart/sdk/lib/math/math.dart"
+- patches: "../../../third_party/dart/runtime/lib/math_patch.dart"
++ patches: "../../../third_party/dart/sdk/lib/_internal/vm/lib/math_patch.dart"
+
+ mirrors:
+ uri: "../../../third_party/dart/sdk/lib/mirrors/mirrors.dart"
+ patches:
+- - "../../../third_party/dart/runtime/lib/mirrors_patch.dart"
+- - "../../../third_party/dart/runtime/lib/mirrors_impl.dart"
+- - "../../../third_party/dart/runtime/lib/mirror_reference.dart"
++ - "../../../third_party/dart/sdk/lib/_internal/vm/lib/mirrors_patch.dart"
++ - "../../../third_party/dart/sdk/lib/_internal/vm/lib/mirrors_impl.dart"
++ - "../../../third_party/dart/sdk/lib/_internal/vm/lib/mirror_reference.dart"
+
+ nativewrappers:
+ uri: "../../../third_party/dart/sdk/lib/html/dartium/nativewrappers.dart"
+@@ -142,7 +142,7 @@ flutter:
+
+ typed_data:
+ uri: "../../../third_party/dart/sdk/lib/typed_data/typed_data.dart"
+- patches: "../../../third_party/dart/runtime/lib/typed_data_patch.dart"
++ patches: "../../../third_party/dart/sdk/lib/_internal/vm/lib/typed_data_patch.dart"
+
+ ui:
+ uri: "../../lib/ui/ui.dart"
+diff --git a/shell/platform/fuchsia/dart_runner/kernel/libraries.json b/shell/platform/fuchsia/dart_runner/kernel/libraries.json
+index 0abe212e6..24c664852 100644
+--- a/shell/platform/fuchsia/dart_runner/kernel/libraries.json
++++ b/shell/platform/fuchsia/dart_runner/kernel/libraries.json
+@@ -1,43 +1,43 @@
+ {
+ "comment:0": "NOTE: THIS FILE IS GENERATED. DO NOT EDIT.",
+- "comment:1": "Instead modify 'shell/platform/fuchsia/dart_runner/kernel/libraries.yaml' and follow the instructions therein.",
++ "comment:1": "Instead modify 'flutter/shell/platform/fuchsia/dart_runner/kernel/libraries.yaml' and follow the instructions therein.",
+ "dart_runner": {
+ "libraries": {
+ "_builtin": {
+- "uri": "../../../../../../third_party/dart/runtime/bin/builtin.dart"
++ "uri": "../../../../../../third_party/dart/sdk/lib/_internal/vm/bin/builtin.dart"
+ },
+ "core": {
+ "patches": [
+- "../../../../../../third_party/dart/runtime/lib/core_patch.dart",
+- "../../../../../../third_party/dart/runtime/lib/array.dart",
+- "../../../../../../third_party/dart/runtime/lib/array_patch.dart",
+- "../../../../../../third_party/dart/runtime/lib/bigint_patch.dart",
+- "../../../../../../third_party/dart/runtime/lib/bool_patch.dart",
+- "../../../../../../third_party/dart/runtime/lib/date_patch.dart",
+- "../../../../../../third_party/dart/runtime/lib/double.dart",
+- "../../../../../../third_party/dart/runtime/lib/double_patch.dart",
+- "../../../../../../third_party/dart/runtime/lib/errors_patch.dart",
+- "../../../../../../third_party/dart/runtime/lib/expando_patch.dart",
+- "../../../../../../third_party/dart/runtime/lib/function.dart",
+- "../../../../../../third_party/dart/runtime/lib/function_patch.dart",
+- "../../../../../../third_party/dart/runtime/lib/growable_array.dart",
+- "../../../../../../third_party/dart/runtime/lib/identical_patch.dart",
+- "../../../../../../third_party/dart/runtime/lib/immutable_map.dart",
+- "../../../../../../third_party/dart/runtime/lib/integers.dart",
+- "../../../../../../third_party/dart/runtime/lib/integers_patch.dart",
+- "../../../../../../third_party/dart/runtime/lib/invocation_mirror_patch.dart",
+- "../../../../../../third_party/dart/runtime/lib/lib_prefix.dart",
+- "../../../../../../third_party/dart/runtime/lib/map_patch.dart",
+- "../../../../../../third_party/dart/runtime/lib/null_patch.dart",
+- "../../../../../../third_party/dart/runtime/lib/object_patch.dart",
+- "../../../../../../third_party/dart/runtime/lib/regexp_patch.dart",
+- "../../../../../../third_party/dart/runtime/lib/stacktrace.dart",
+- "../../../../../../third_party/dart/runtime/lib/stopwatch_patch.dart",
+- "../../../../../../third_party/dart/runtime/lib/string_buffer_patch.dart",
+- "../../../../../../third_party/dart/runtime/lib/string_patch.dart",
+- "../../../../../../third_party/dart/runtime/lib/type_patch.dart",
+- "../../../../../../third_party/dart/runtime/lib/uri_patch.dart",
+- "../../../../../../third_party/dart/runtime/lib/weak_property.dart"
++ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/core_patch.dart",
++ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/array.dart",
++ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/array_patch.dart",
++ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/bigint_patch.dart",
++ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/bool_patch.dart",
++ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/date_patch.dart",
++ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/double.dart",
++ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/double_patch.dart",
++ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/errors_patch.dart",
++ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/expando_patch.dart",
++ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/function.dart",
++ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/function_patch.dart",
++ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/growable_array.dart",
++ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/identical_patch.dart",
++ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/immutable_map.dart",
++ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/integers.dart",
++ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/integers_patch.dart",
++ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/invocation_mirror_patch.dart",
++ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/lib_prefix.dart",
++ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/map_patch.dart",
++ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/null_patch.dart",
++ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/object_patch.dart",
++ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/regexp_patch.dart",
++ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/stacktrace.dart",
++ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/stopwatch_patch.dart",
++ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/string_buffer_patch.dart",
++ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/string_patch.dart",
++ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/type_patch.dart",
++ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/uri_patch.dart",
++ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/weak_property.dart"
+ ],
+ "uri": "../../../../../../third_party/dart/sdk/lib/core/core.dart"
+ },
+@@ -46,30 +46,30 @@
+ },
+ "async": {
+ "patches": [
+- "../../../../../../third_party/dart/runtime/lib/async_patch.dart",
+- "../../../../../../third_party/dart/runtime/lib/deferred_load_patch.dart",
+- "../../../../../../third_party/dart/runtime/lib/schedule_microtask_patch.dart",
+- "../../../../../../third_party/dart/runtime/lib/timer_patch.dart"
++ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/async_patch.dart",
++ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/deferred_load_patch.dart",
++ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/schedule_microtask_patch.dart",
++ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/timer_patch.dart"
+ ],
+ "uri": "../../../../../../third_party/dart/sdk/lib/async/async.dart"
+ },
+ "collection": {
+ "patches": [
+- "../../../../../../third_party/dart/runtime/lib/collection_patch.dart",
+- "../../../../../../third_party/dart/runtime/lib/compact_hash.dart"
++ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/collection_patch.dart",
++ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/compact_hash.dart"
+ ],
+ "uri": "../../../../../../third_party/dart/sdk/lib/collection/collection.dart"
+ },
+ "ffi": {
+ "patches": [
+- "../../../../../../third_party/dart/runtime/lib/ffi_dynamic_library_patch.dart",
+- "../../../../../../third_party/dart/runtime/lib/ffi_native_type_patch.dart",
+- "../../../../../../third_party/dart/runtime/lib/ffi_patch.dart"
++ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/ffi_dynamic_library_patch.dart",
++ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/ffi_native_type_patch.dart",
++ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/ffi_patch.dart"
+ ],
+ "uri": "../../../../../../third_party/dart/sdk/lib/ffi/ffi.dart"
+ },
+ "typed_data": {
+- "patches": "../../../../../../third_party/dart/runtime/lib/typed_data_patch.dart",
++ "patches": "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/typed_data_patch.dart",
+ "uri": "../../../../../../third_party/dart/sdk/lib/typed_data/typed_data.dart"
+ },
+ "nativewrappers": {
+@@ -77,24 +77,24 @@
+ },
+ "mirrors": {
+ "patches": [
+- "../../../../../../third_party/dart/runtime/lib/mirrors_patch.dart",
+- "../../../../../../third_party/dart/runtime/lib/mirrors_impl.dart",
+- "../../../../../../third_party/dart/runtime/lib/mirror_reference.dart"
++ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/mirrors_patch.dart",
++ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/mirrors_impl.dart",
++ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/mirror_reference.dart"
+ ],
+ "uri": "../../../../../../third_party/dart/sdk/lib/mirrors/mirrors.dart"
+ },
+ "developer": {
+ "patches": [
+- "../../../../../../third_party/dart/runtime/lib/developer.dart",
+- "../../../../../../third_party/dart/runtime/lib/profiler.dart",
+- "../../../../../../third_party/dart/runtime/lib/timeline.dart"
++ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/developer.dart",
++ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/profiler.dart",
++ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/timeline.dart"
+ ],
+ "uri": "../../../../../../third_party/dart/sdk/lib/developer/developer.dart"
+ },
+ "isolate": {
+ "patches": [
+- "../../../../../../third_party/dart/runtime/lib/isolate_patch.dart",
+- "../../../../../../third_party/dart/runtime/lib/timer_impl.dart"
++ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/isolate_patch.dart",
++ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/timer_impl.dart"
+ ],
+ "uri": "../../../../../../third_party/dart/sdk/lib/isolate/isolate.dart"
+ },
+@@ -103,48 +103,48 @@
+ },
+ "wasm": {
+ "patches": [
+- "../../../../../../third_party/dart/runtime/lib/wasm_patch.dart"
++ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/wasm_patch.dart"
+ ],
+ "uri": "../../../../../../third_party/dart/sdk/lib/wasm/wasm.dart"
+ },
+ "io": {
+ "patches": [
+- "../../../../../../third_party/dart/runtime/bin/common_patch.dart",
+- "../../../../../../third_party/dart/runtime/bin/directory_patch.dart",
+- "../../../../../../third_party/dart/runtime/bin/eventhandler_patch.dart",
+- "../../../../../../third_party/dart/runtime/bin/file_patch.dart",
+- "../../../../../../third_party/dart/runtime/bin/file_system_entity_patch.dart",
+- "../../../../../../third_party/dart/runtime/bin/filter_patch.dart",
+- "../../../../../../third_party/dart/runtime/bin/io_service_patch.dart",
+- "../../../../../../third_party/dart/runtime/bin/namespace_patch.dart",
+- "../../../../../../third_party/dart/runtime/bin/platform_patch.dart",
+- "../../../../../../third_party/dart/runtime/bin/process_patch.dart",
+- "../../../../../../third_party/dart/runtime/bin/socket_patch.dart",
+- "../../../../../../third_party/dart/runtime/bin/stdio_patch.dart",
+- "../../../../../../third_party/dart/runtime/bin/secure_socket_patch.dart",
+- "../../../../../../third_party/dart/runtime/bin/sync_socket_patch.dart"
++ "../../../../../../third_party/dart/sdk/lib/_internal/vm/bin/common_patch.dart",
++ "../../../../../../third_party/dart/sdk/lib/_internal/vm/bin/directory_patch.dart",
++ "../../../../../../third_party/dart/sdk/lib/_internal/vm/bin/eventhandler_patch.dart",
++ "../../../../../../third_party/dart/sdk/lib/_internal/vm/bin/file_patch.dart",
++ "../../../../../../third_party/dart/sdk/lib/_internal/vm/bin/file_system_entity_patch.dart",
++ "../../../../../../third_party/dart/sdk/lib/_internal/vm/bin/filter_patch.dart",
++ "../../../../../../third_party/dart/sdk/lib/_internal/vm/bin/io_service_patch.dart",
++ "../../../../../../third_party/dart/sdk/lib/_internal/vm/bin/namespace_patch.dart",
++ "../../../../../../third_party/dart/sdk/lib/_internal/vm/bin/platform_patch.dart",
++ "../../../../../../third_party/dart/sdk/lib/_internal/vm/bin/process_patch.dart",
++ "../../../../../../third_party/dart/sdk/lib/_internal/vm/bin/socket_patch.dart",
++ "../../../../../../third_party/dart/sdk/lib/_internal/vm/bin/stdio_patch.dart",
++ "../../../../../../third_party/dart/sdk/lib/_internal/vm/bin/secure_socket_patch.dart",
++ "../../../../../../third_party/dart/sdk/lib/_internal/vm/bin/sync_socket_patch.dart"
+ ],
+ "uri": "../../../../../../third_party/dart/sdk/lib/io/io.dart"
+ },
+ "_internal": {
+ "patches": [
+- "../../../../../../third_party/dart/runtime/lib/internal_patch.dart",
+- "../../../../../../third_party/dart/runtime/lib/class_id_fasta.dart",
+- "../../../../../../third_party/dart/runtime/lib/print_patch.dart",
+- "../../../../../../third_party/dart/runtime/lib/symbol_patch.dart",
++ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/internal_patch.dart",
++ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/class_id_fasta.dart",
++ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/print_patch.dart",
++ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/symbol_patch.dart",
+ "../../../../../../third_party/dart/sdk/lib/internal/patch.dart"
+ ],
+ "uri": "../../../../../../third_party/dart/sdk/lib/internal/internal.dart"
+ },
+ "convert": {
+- "patches": "../../../../../../third_party/dart/runtime/lib/convert_patch.dart",
++ "patches": "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/convert_patch.dart",
+ "uri": "../../../../../../third_party/dart/sdk/lib/convert/convert.dart"
+ },
+ "profiler": {
+ "uri": "../../../../../../third_party/dart/sdk/lib/profiler/profiler.dart"
+ },
+ "math": {
+- "patches": "../../../../../../third_party/dart/runtime/lib/math_patch.dart",
++ "patches": "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/math_patch.dart",
+ "uri": "../../../../../../third_party/dart/sdk/lib/math/math.dart"
+ },
+ "_http": {
+diff --git a/shell/platform/fuchsia/dart_runner/kernel/libraries.yaml b/shell/platform/fuchsia/dart_runner/kernel/libraries.yaml
+index cab901e60..5e1f638cd 100644
+--- a/shell/platform/fuchsia/dart_runner/kernel/libraries.yaml
++++ b/shell/platform/fuchsia/dart_runner/kernel/libraries.yaml
+@@ -14,87 +14,87 @@
+ dart_runner:
+ libraries:
+ _builtin:
+- uri: "../../../../../../third_party/dart/runtime/bin/builtin.dart"
++ uri: "../../../../../../third_party/dart/sdk/lib/_internal/vm/bin/builtin.dart"
+
+ _internal:
+ uri: "../../../../../../third_party/dart/sdk/lib/internal/internal.dart"
+ patches:
+- - "../../../../../../third_party/dart/runtime/lib/internal_patch.dart"
+- - "../../../../../../third_party/dart/runtime/lib/class_id_fasta.dart"
+- - "../../../../../../third_party/dart/runtime/lib/print_patch.dart"
+- - "../../../../../../third_party/dart/runtime/lib/symbol_patch.dart"
++ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/internal_patch.dart"
++ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/class_id_fasta.dart"
++ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/print_patch.dart"
++ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/symbol_patch.dart"
+ - "../../../../../../third_party/dart/sdk/lib/internal/patch.dart"
+
+ async:
+ uri: "../../../../../../third_party/dart/sdk/lib/async/async.dart"
+ patches:
+- - "../../../../../../third_party/dart/runtime/lib/async_patch.dart"
+- - "../../../../../../third_party/dart/runtime/lib/deferred_load_patch.dart"
+- - "../../../../../../third_party/dart/runtime/lib/schedule_microtask_patch.dart"
+- - "../../../../../../third_party/dart/runtime/lib/timer_patch.dart"
++ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/async_patch.dart"
++ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/deferred_load_patch.dart"
++ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/schedule_microtask_patch.dart"
++ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/timer_patch.dart"
+
+ collection:
+ uri: "../../../../../../third_party/dart/sdk/lib/collection/collection.dart"
+ patches:
+- - "../../../../../../third_party/dart/runtime/lib/collection_patch.dart"
+- - "../../../../../../third_party/dart/runtime/lib/compact_hash.dart"
++ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/collection_patch.dart"
++ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/compact_hash.dart"
+
+ convert:
+ uri: "../../../../../../third_party/dart/sdk/lib/convert/convert.dart"
+- patches: "../../../../../../third_party/dart/runtime/lib/convert_patch.dart"
++ patches: "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/convert_patch.dart"
+
+ core:
+ uri: "../../../../../../third_party/dart/sdk/lib/core/core.dart"
+ patches:
+- - "../../../../../../third_party/dart/runtime/lib/core_patch.dart"
+- - "../../../../../../third_party/dart/runtime/lib/array.dart"
+- - "../../../../../../third_party/dart/runtime/lib/array_patch.dart"
+- - "../../../../../../third_party/dart/runtime/lib/bigint_patch.dart"
+- - "../../../../../../third_party/dart/runtime/lib/bool_patch.dart"
+- - "../../../../../../third_party/dart/runtime/lib/date_patch.dart"
+- - "../../../../../../third_party/dart/runtime/lib/double.dart"
+- - "../../../../../../third_party/dart/runtime/lib/double_patch.dart"
+- - "../../../../../../third_party/dart/runtime/lib/errors_patch.dart"
+- - "../../../../../../third_party/dart/runtime/lib/expando_patch.dart"
+- - "../../../../../../third_party/dart/runtime/lib/function.dart"
+- - "../../../../../../third_party/dart/runtime/lib/function_patch.dart"
+- - "../../../../../../third_party/dart/runtime/lib/growable_array.dart"
+- - "../../../../../../third_party/dart/runtime/lib/identical_patch.dart"
+- - "../../../../../../third_party/dart/runtime/lib/immutable_map.dart"
+- - "../../../../../../third_party/dart/runtime/lib/integers.dart"
+- - "../../../../../../third_party/dart/runtime/lib/integers_patch.dart"
+- - "../../../../../../third_party/dart/runtime/lib/invocation_mirror_patch.dart"
+- - "../../../../../../third_party/dart/runtime/lib/lib_prefix.dart"
+- - "../../../../../../third_party/dart/runtime/lib/map_patch.dart"
+- - "../../../../../../third_party/dart/runtime/lib/null_patch.dart"
+- - "../../../../../../third_party/dart/runtime/lib/object_patch.dart"
+- - "../../../../../../third_party/dart/runtime/lib/regexp_patch.dart"
+- - "../../../../../../third_party/dart/runtime/lib/stacktrace.dart"
+- - "../../../../../../third_party/dart/runtime/lib/stopwatch_patch.dart"
+- - "../../../../../../third_party/dart/runtime/lib/string_buffer_patch.dart"
+- - "../../../../../../third_party/dart/runtime/lib/string_patch.dart"
+- - "../../../../../../third_party/dart/runtime/lib/type_patch.dart"
+- - "../../../../../../third_party/dart/runtime/lib/uri_patch.dart"
+- - "../../../../../../third_party/dart/runtime/lib/weak_property.dart"
++ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/core_patch.dart"
++ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/array.dart"
++ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/array_patch.dart"
++ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/bigint_patch.dart"
++ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/bool_patch.dart"
++ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/date_patch.dart"
++ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/double.dart"
++ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/double_patch.dart"
++ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/errors_patch.dart"
++ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/expando_patch.dart"
++ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/function.dart"
++ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/function_patch.dart"
++ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/growable_array.dart"
++ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/identical_patch.dart"
++ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/immutable_map.dart"
++ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/integers.dart"
++ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/integers_patch.dart"
++ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/invocation_mirror_patch.dart"
++ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/lib_prefix.dart"
++ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/map_patch.dart"
++ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/null_patch.dart"
++ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/object_patch.dart"
++ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/regexp_patch.dart"
++ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/stacktrace.dart"
++ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/stopwatch_patch.dart"
++ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/string_buffer_patch.dart"
++ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/string_patch.dart"
++ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/type_patch.dart"
++ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/uri_patch.dart"
++ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/weak_property.dart"
+
+ developer:
+ uri: "../../../../../../third_party/dart/sdk/lib/developer/developer.dart"
+ patches:
+- - "../../../../../../third_party/dart/runtime/lib/developer.dart"
+- - "../../../../../../third_party/dart/runtime/lib/profiler.dart"
+- - "../../../../../../third_party/dart/runtime/lib/timeline.dart"
++ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/developer.dart"
++ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/profiler.dart"
++ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/timeline.dart"
+
+ ffi:
+ uri: "../../../../../../third_party/dart/sdk/lib/ffi/ffi.dart"
+ patches:
+- - "../../../../../../third_party/dart/runtime/lib/ffi_dynamic_library_patch.dart"
+- - "../../../../../../third_party/dart/runtime/lib/ffi_native_type_patch.dart"
+- - "../../../../../../third_party/dart/runtime/lib/ffi_patch.dart"
++ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/ffi_dynamic_library_patch.dart"
++ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/ffi_native_type_patch.dart"
++ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/ffi_patch.dart"
+
+ wasm:
+ uri: "../../../../../../third_party/dart/sdk/lib/wasm/wasm.dart"
+ patches:
+- - "../../../../../../third_party/dart/runtime/lib/wasm_patch.dart"
++ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/wasm_patch.dart"
+
+ _http:
+ uri: "../../../../../../third_party/dart/sdk/lib/_http/http.dart"
+@@ -102,37 +102,37 @@ dart_runner:
+ io:
+ uri: "../../../../../../third_party/dart/sdk/lib/io/io.dart"
+ patches:
+- - "../../../../../../third_party/dart/runtime/bin/common_patch.dart"
+- - "../../../../../../third_party/dart/runtime/bin/directory_patch.dart"
+- - "../../../../../../third_party/dart/runtime/bin/eventhandler_patch.dart"
+- - "../../../../../../third_party/dart/runtime/bin/file_patch.dart"
+- - "../../../../../../third_party/dart/runtime/bin/file_system_entity_patch.dart"
+- - "../../../../../../third_party/dart/runtime/bin/filter_patch.dart"
+- - "../../../../../../third_party/dart/runtime/bin/io_service_patch.dart"
+- - "../../../../../../third_party/dart/runtime/bin/namespace_patch.dart"
+- - "../../../../../../third_party/dart/runtime/bin/platform_patch.dart"
+- - "../../../../../../third_party/dart/runtime/bin/process_patch.dart"
+- - "../../../../../../third_party/dart/runtime/bin/socket_patch.dart"
+- - "../../../../../../third_party/dart/runtime/bin/stdio_patch.dart"
+- - "../../../../../../third_party/dart/runtime/bin/secure_socket_patch.dart"
+- - "../../../../../../third_party/dart/runtime/bin/sync_socket_patch.dart"
++ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/bin/common_patch.dart"
++ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/bin/directory_patch.dart"
++ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/bin/eventhandler_patch.dart"
++ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/bin/file_patch.dart"
++ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/bin/file_system_entity_patch.dart"
++ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/bin/filter_patch.dart"
++ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/bin/io_service_patch.dart"
++ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/bin/namespace_patch.dart"
++ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/bin/platform_patch.dart"
++ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/bin/process_patch.dart"
++ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/bin/socket_patch.dart"
++ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/bin/stdio_patch.dart"
++ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/bin/secure_socket_patch.dart"
++ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/bin/sync_socket_patch.dart"
+
+ isolate:
+ uri: "../../../../../../third_party/dart/sdk/lib/isolate/isolate.dart"
+ patches:
+- - "../../../../../../third_party/dart/runtime/lib/isolate_patch.dart"
+- - "../../../../../../third_party/dart/runtime/lib/timer_impl.dart"
++ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/isolate_patch.dart"
++ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/timer_impl.dart"
+
+ math:
+ uri: "../../../../../../third_party/dart/sdk/lib/math/math.dart"
+- patches: "../../../../../../third_party/dart/runtime/lib/math_patch.dart"
++ patches: "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/math_patch.dart"
+
+ mirrors:
+ uri: "../../../../../../third_party/dart/sdk/lib/mirrors/mirrors.dart"
+ patches:
+- - "../../../../../../third_party/dart/runtime/lib/mirrors_patch.dart"
+- - "../../../../../../third_party/dart/runtime/lib/mirrors_impl.dart"
+- - "../../../../../../third_party/dart/runtime/lib/mirror_reference.dart"
++ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/mirrors_patch.dart"
++ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/mirrors_impl.dart"
++ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/mirror_reference.dart"
+
+ nativewrappers:
+ uri: "../../../../../../third_party/dart/sdk/lib/html/dartium/nativewrappers.dart"
+@@ -142,7 +142,7 @@ dart_runner:
+
+ typed_data:
+ uri: "../../../../../../third_party/dart/sdk/lib/typed_data/typed_data.dart"
+- patches: "../../../../../../third_party/dart/runtime/lib/typed_data_patch.dart"
++ patches: "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/typed_data_patch.dart"
+
+ fuchsia.builtin:
+ uri: "../../../../../../flutter/shell/platform/fuchsia/dart_runner/embedder/builtin.dart"
+diff --git a/shell/platform/fuchsia/flutter/kernel/libraries.json b/shell/platform/fuchsia/flutter/kernel/libraries.json
+index 5a4602d8c..a8436200f 100644
+--- a/shell/platform/fuchsia/flutter/kernel/libraries.json
++++ b/shell/platform/fuchsia/flutter/kernel/libraries.json
+@@ -1,43 +1,43 @@
+ {
+ "comment:0": "NOTE: THIS FILE IS GENERATED. DO NOT EDIT.",
+- "comment:1": "Instead modify 'shell/platform/fuchsia/flutter/kernel/libraries.yaml' and follow the instructions therein.",
++ "comment:1": "Instead modify 'flutter/shell/platform/fuchsia/flutter/kernel/libraries.yaml' and follow the instructions therein.",
+ "flutter_runner": {
+ "libraries": {
+ "_builtin": {
+- "uri": "../../../../../../third_party/dart/runtime/bin/builtin.dart"
++ "uri": "../../../../../../third_party/dart/sdk/lib/_internal/vm/bin/builtin.dart"
+ },
+ "core": {
+ "patches": [
+- "../../../../../../third_party/dart/runtime/lib/core_patch.dart",
+- "../../../../../../third_party/dart/runtime/lib/array.dart",
+- "../../../../../../third_party/dart/runtime/lib/array_patch.dart",
+- "../../../../../../third_party/dart/runtime/lib/bigint_patch.dart",
+- "../../../../../../third_party/dart/runtime/lib/bool_patch.dart",
+- "../../../../../../third_party/dart/runtime/lib/date_patch.dart",
+- "../../../../../../third_party/dart/runtime/lib/double.dart",
+- "../../../../../../third_party/dart/runtime/lib/double_patch.dart",
+- "../../../../../../third_party/dart/runtime/lib/errors_patch.dart",
+- "../../../../../../third_party/dart/runtime/lib/expando_patch.dart",
+- "../../../../../../third_party/dart/runtime/lib/function.dart",
+- "../../../../../../third_party/dart/runtime/lib/function_patch.dart",
+- "../../../../../../third_party/dart/runtime/lib/growable_array.dart",
+- "../../../../../../third_party/dart/runtime/lib/identical_patch.dart",
+- "../../../../../../third_party/dart/runtime/lib/immutable_map.dart",
+- "../../../../../../third_party/dart/runtime/lib/integers.dart",
+- "../../../../../../third_party/dart/runtime/lib/integers_patch.dart",
+- "../../../../../../third_party/dart/runtime/lib/invocation_mirror_patch.dart",
+- "../../../../../../third_party/dart/runtime/lib/lib_prefix.dart",
+- "../../../../../../third_party/dart/runtime/lib/map_patch.dart",
+- "../../../../../../third_party/dart/runtime/lib/null_patch.dart",
+- "../../../../../../third_party/dart/runtime/lib/object_patch.dart",
+- "../../../../../../third_party/dart/runtime/lib/regexp_patch.dart",
+- "../../../../../../third_party/dart/runtime/lib/stacktrace.dart",
+- "../../../../../../third_party/dart/runtime/lib/stopwatch_patch.dart",
+- "../../../../../../third_party/dart/runtime/lib/string_buffer_patch.dart",
+- "../../../../../../third_party/dart/runtime/lib/string_patch.dart",
+- "../../../../../../third_party/dart/runtime/lib/type_patch.dart",
+- "../../../../../../third_party/dart/runtime/lib/uri_patch.dart",
+- "../../../../../../third_party/dart/runtime/lib/weak_property.dart"
++ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/core_patch.dart",
++ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/array.dart",
++ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/array_patch.dart",
++ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/bigint_patch.dart",
++ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/bool_patch.dart",
++ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/date_patch.dart",
++ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/double.dart",
++ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/double_patch.dart",
++ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/errors_patch.dart",
++ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/expando_patch.dart",
++ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/function.dart",
++ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/function_patch.dart",
++ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/growable_array.dart",
++ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/identical_patch.dart",
++ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/immutable_map.dart",
++ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/integers.dart",
++ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/integers_patch.dart",
++ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/invocation_mirror_patch.dart",
++ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/lib_prefix.dart",
++ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/map_patch.dart",
++ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/null_patch.dart",
++ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/object_patch.dart",
++ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/regexp_patch.dart",
++ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/stacktrace.dart",
++ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/stopwatch_patch.dart",
++ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/string_buffer_patch.dart",
++ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/string_patch.dart",
++ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/type_patch.dart",
++ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/uri_patch.dart",
++ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/weak_property.dart"
+ ],
+ "uri": "../../../../../../third_party/dart/sdk/lib/core/core.dart"
+ },
+@@ -46,30 +46,30 @@
+ },
+ "async": {
+ "patches": [
+- "../../../../../../third_party/dart/runtime/lib/async_patch.dart",
+- "../../../../../../third_party/dart/runtime/lib/deferred_load_patch.dart",
+- "../../../../../../third_party/dart/runtime/lib/schedule_microtask_patch.dart",
+- "../../../../../../third_party/dart/runtime/lib/timer_patch.dart"
++ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/async_patch.dart",
++ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/deferred_load_patch.dart",
++ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/schedule_microtask_patch.dart",
++ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/timer_patch.dart"
+ ],
+ "uri": "../../../../../../third_party/dart/sdk/lib/async/async.dart"
+ },
+ "collection": {
+ "patches": [
+- "../../../../../../third_party/dart/runtime/lib/collection_patch.dart",
+- "../../../../../../third_party/dart/runtime/lib/compact_hash.dart"
++ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/collection_patch.dart",
++ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/compact_hash.dart"
+ ],
+ "uri": "../../../../../../third_party/dart/sdk/lib/collection/collection.dart"
+ },
+ "ffi": {
+ "patches": [
+- "../../../../../../third_party/dart/runtime/lib/ffi_dynamic_library_patch.dart",
+- "../../../../../../third_party/dart/runtime/lib/ffi_native_type_patch.dart",
+- "../../../../../../third_party/dart/runtime/lib/ffi_patch.dart"
++ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/ffi_dynamic_library_patch.dart",
++ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/ffi_native_type_patch.dart",
++ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/ffi_patch.dart"
+ ],
+ "uri": "../../../../../../third_party/dart/sdk/lib/ffi/ffi.dart"
+ },
+ "typed_data": {
+- "patches": "../../../../../../third_party/dart/runtime/lib/typed_data_patch.dart",
++ "patches": "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/typed_data_patch.dart",
+ "uri": "../../../../../../third_party/dart/sdk/lib/typed_data/typed_data.dart"
+ },
+ "nativewrappers": {
+@@ -77,24 +77,24 @@
+ },
+ "mirrors": {
+ "patches": [
+- "../../../../../../third_party/dart/runtime/lib/mirrors_patch.dart",
+- "../../../../../../third_party/dart/runtime/lib/mirrors_impl.dart",
+- "../../../../../../third_party/dart/runtime/lib/mirror_reference.dart"
++ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/mirrors_patch.dart",
++ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/mirrors_impl.dart",
++ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/mirror_reference.dart"
+ ],
+ "uri": "../../../../../../third_party/dart/sdk/lib/mirrors/mirrors.dart"
+ },
+ "developer": {
+ "patches": [
+- "../../../../../../third_party/dart/runtime/lib/developer.dart",
+- "../../../../../../third_party/dart/runtime/lib/profiler.dart",
+- "../../../../../../third_party/dart/runtime/lib/timeline.dart"
++ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/developer.dart",
++ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/profiler.dart",
++ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/timeline.dart"
+ ],
+ "uri": "../../../../../../third_party/dart/sdk/lib/developer/developer.dart"
+ },
+ "isolate": {
+ "patches": [
+- "../../../../../../third_party/dart/runtime/lib/isolate_patch.dart",
+- "../../../../../../third_party/dart/runtime/lib/timer_impl.dart"
++ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/isolate_patch.dart",
++ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/timer_impl.dart"
+ ],
+ "uri": "../../../../../../third_party/dart/sdk/lib/isolate/isolate.dart"
+ },
+@@ -103,48 +103,48 @@
+ },
+ "wasm": {
+ "patches": [
+- "../../../../../../third_party/dart/runtime/lib/wasm_patch.dart"
++ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/wasm_patch.dart"
+ ],
+ "uri": "../../../../../../third_party/dart/sdk/lib/wasm/wasm.dart"
+ },
+ "io": {
+ "patches": [
+- "../../../../../../third_party/dart/runtime/bin/common_patch.dart",
+- "../../../../../../third_party/dart/runtime/bin/directory_patch.dart",
+- "../../../../../../third_party/dart/runtime/bin/eventhandler_patch.dart",
+- "../../../../../../third_party/dart/runtime/bin/file_patch.dart",
+- "../../../../../../third_party/dart/runtime/bin/file_system_entity_patch.dart",
+- "../../../../../../third_party/dart/runtime/bin/filter_patch.dart",
+- "../../../../../../third_party/dart/runtime/bin/io_service_patch.dart",
+- "../../../../../../third_party/dart/runtime/bin/namespace_patch.dart",
+- "../../../../../../third_party/dart/runtime/bin/platform_patch.dart",
+- "../../../../../../third_party/dart/runtime/bin/process_patch.dart",
+- "../../../../../../third_party/dart/runtime/bin/socket_patch.dart",
+- "../../../../../../third_party/dart/runtime/bin/stdio_patch.dart",
+- "../../../../../../third_party/dart/runtime/bin/secure_socket_patch.dart",
+- "../../../../../../third_party/dart/runtime/bin/sync_socket_patch.dart"
++ "../../../../../../third_party/dart/sdk/lib/_internal/vm/bin/common_patch.dart",
++ "../../../../../../third_party/dart/sdk/lib/_internal/vm/bin/directory_patch.dart",
++ "../../../../../../third_party/dart/sdk/lib/_internal/vm/bin/eventhandler_patch.dart",
++ "../../../../../../third_party/dart/sdk/lib/_internal/vm/bin/file_patch.dart",
++ "../../../../../../third_party/dart/sdk/lib/_internal/vm/bin/file_system_entity_patch.dart",
++ "../../../../../../third_party/dart/sdk/lib/_internal/vm/bin/filter_patch.dart",
++ "../../../../../../third_party/dart/sdk/lib/_internal/vm/bin/io_service_patch.dart",
++ "../../../../../../third_party/dart/sdk/lib/_internal/vm/bin/namespace_patch.dart",
++ "../../../../../../third_party/dart/sdk/lib/_internal/vm/bin/platform_patch.dart",
++ "../../../../../../third_party/dart/sdk/lib/_internal/vm/bin/process_patch.dart",
++ "../../../../../../third_party/dart/sdk/lib/_internal/vm/bin/socket_patch.dart",
++ "../../../../../../third_party/dart/sdk/lib/_internal/vm/bin/stdio_patch.dart",
++ "../../../../../../third_party/dart/sdk/lib/_internal/vm/bin/secure_socket_patch.dart",
++ "../../../../../../third_party/dart/sdk/lib/_internal/vm/bin/sync_socket_patch.dart"
+ ],
+ "uri": "../../../../../../third_party/dart/sdk/lib/io/io.dart"
+ },
+ "_internal": {
+ "patches": [
+- "../../../../../../third_party/dart/runtime/lib/internal_patch.dart",
+- "../../../../../../third_party/dart/runtime/lib/class_id_fasta.dart",
+- "../../../../../../third_party/dart/runtime/lib/print_patch.dart",
+- "../../../../../../third_party/dart/runtime/lib/symbol_patch.dart",
++ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/internal_patch.dart",
++ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/class_id_fasta.dart",
++ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/print_patch.dart",
++ "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/symbol_patch.dart",
+ "../../../../../../third_party/dart/sdk/lib/internal/patch.dart"
+ ],
+ "uri": "../../../../../../third_party/dart/sdk/lib/internal/internal.dart"
+ },
+ "convert": {
+- "patches": "../../../../../../third_party/dart/runtime/lib/convert_patch.dart",
++ "patches": "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/convert_patch.dart",
+ "uri": "../../../../../../third_party/dart/sdk/lib/convert/convert.dart"
+ },
+ "profiler": {
+ "uri": "../../../../../../third_party/dart/sdk/lib/profiler/profiler.dart"
+ },
+ "math": {
+- "patches": "../../../../../../third_party/dart/runtime/lib/math_patch.dart",
++ "patches": "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/math_patch.dart",
+ "uri": "../../../../../../third_party/dart/sdk/lib/math/math.dart"
+ },
+ "_http": {
+@@ -160,7 +160,7 @@
+ "uri": "../../../../../../flutter/lib/ui/ui.dart"
+ },
+ "vmservice_io": {
+- "uri": "../../../../../../third_party/dart/runtime/bin/vmservice/vmservice_io.dart"
++ "uri": "../../../../../../third_party/dart/sdk/lib/_internal/vm/bin/vmservice/vmservice_io.dart"
+ }
+ }
+ }
+diff --git a/shell/platform/fuchsia/flutter/kernel/libraries.yaml b/shell/platform/fuchsia/flutter/kernel/libraries.yaml
+index f8385ca29..05b7f4f9f 100644
+--- a/shell/platform/fuchsia/flutter/kernel/libraries.yaml
++++ b/shell/platform/fuchsia/flutter/kernel/libraries.yaml
+@@ -14,87 +14,87 @@
+ flutter_runner:
+ libraries:
+ _builtin:
+- uri: "../../../../../../third_party/dart/runtime/bin/builtin.dart"
++ uri: "../../../../../../third_party/dart/sdk/lib/_internal/vm/bin/builtin.dart"
+
+ _internal:
+ uri: "../../../../../../third_party/dart/sdk/lib/internal/internal.dart"
+ patches:
+- - "../../../../../../third_party/dart/runtime/lib/internal_patch.dart"
+- - "../../../../../../third_party/dart/runtime/lib/class_id_fasta.dart"
+- - "../../../../../../third_party/dart/runtime/lib/print_patch.dart"
+- - "../../../../../../third_party/dart/runtime/lib/symbol_patch.dart"
++ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/internal_patch.dart"
++ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/class_id_fasta.dart"
++ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/print_patch.dart"
++ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/symbol_patch.dart"
+ - "../../../../../../third_party/dart/sdk/lib/internal/patch.dart"
+
+ async:
+ uri: "../../../../../../third_party/dart/sdk/lib/async/async.dart"
+ patches:
+- - "../../../../../../third_party/dart/runtime/lib/async_patch.dart"
+- - "../../../../../../third_party/dart/runtime/lib/deferred_load_patch.dart"
+- - "../../../../../../third_party/dart/runtime/lib/schedule_microtask_patch.dart"
+- - "../../../../../../third_party/dart/runtime/lib/timer_patch.dart"
++ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/async_patch.dart"
++ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/deferred_load_patch.dart"
++ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/schedule_microtask_patch.dart"
++ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/timer_patch.dart"
+
+ collection:
+ uri: "../../../../../../third_party/dart/sdk/lib/collection/collection.dart"
+ patches:
+- - "../../../../../../third_party/dart/runtime/lib/collection_patch.dart"
+- - "../../../../../../third_party/dart/runtime/lib/compact_hash.dart"
++ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/collection_patch.dart"
++ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/compact_hash.dart"
+
+ convert:
+ uri: "../../../../../../third_party/dart/sdk/lib/convert/convert.dart"
+- patches: "../../../../../../third_party/dart/runtime/lib/convert_patch.dart"
++ patches: "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/convert_patch.dart"
+
+ core:
+ uri: "../../../../../../third_party/dart/sdk/lib/core/core.dart"
+ patches:
+- - "../../../../../../third_party/dart/runtime/lib/core_patch.dart"
+- - "../../../../../../third_party/dart/runtime/lib/array.dart"
+- - "../../../../../../third_party/dart/runtime/lib/array_patch.dart"
+- - "../../../../../../third_party/dart/runtime/lib/bigint_patch.dart"
+- - "../../../../../../third_party/dart/runtime/lib/bool_patch.dart"
+- - "../../../../../../third_party/dart/runtime/lib/date_patch.dart"
+- - "../../../../../../third_party/dart/runtime/lib/double.dart"
+- - "../../../../../../third_party/dart/runtime/lib/double_patch.dart"
+- - "../../../../../../third_party/dart/runtime/lib/errors_patch.dart"
+- - "../../../../../../third_party/dart/runtime/lib/expando_patch.dart"
+- - "../../../../../../third_party/dart/runtime/lib/function.dart"
+- - "../../../../../../third_party/dart/runtime/lib/function_patch.dart"
+- - "../../../../../../third_party/dart/runtime/lib/growable_array.dart"
+- - "../../../../../../third_party/dart/runtime/lib/identical_patch.dart"
+- - "../../../../../../third_party/dart/runtime/lib/immutable_map.dart"
+- - "../../../../../../third_party/dart/runtime/lib/integers.dart"
+- - "../../../../../../third_party/dart/runtime/lib/integers_patch.dart"
+- - "../../../../../../third_party/dart/runtime/lib/invocation_mirror_patch.dart"
+- - "../../../../../../third_party/dart/runtime/lib/lib_prefix.dart"
+- - "../../../../../../third_party/dart/runtime/lib/map_patch.dart"
+- - "../../../../../../third_party/dart/runtime/lib/null_patch.dart"
+- - "../../../../../../third_party/dart/runtime/lib/object_patch.dart"
+- - "../../../../../../third_party/dart/runtime/lib/regexp_patch.dart"
+- - "../../../../../../third_party/dart/runtime/lib/stacktrace.dart"
+- - "../../../../../../third_party/dart/runtime/lib/stopwatch_patch.dart"
+- - "../../../../../../third_party/dart/runtime/lib/string_buffer_patch.dart"
+- - "../../../../../../third_party/dart/runtime/lib/string_patch.dart"
+- - "../../../../../../third_party/dart/runtime/lib/type_patch.dart"
+- - "../../../../../../third_party/dart/runtime/lib/uri_patch.dart"
+- - "../../../../../../third_party/dart/runtime/lib/weak_property.dart"
++ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/core_patch.dart"
++ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/array.dart"
++ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/array_patch.dart"
++ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/bigint_patch.dart"
++ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/bool_patch.dart"
++ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/date_patch.dart"
++ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/double.dart"
++ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/double_patch.dart"
++ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/errors_patch.dart"
++ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/expando_patch.dart"
++ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/function.dart"
++ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/function_patch.dart"
++ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/growable_array.dart"
++ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/identical_patch.dart"
++ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/immutable_map.dart"
++ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/integers.dart"
++ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/integers_patch.dart"
++ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/invocation_mirror_patch.dart"
++ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/lib_prefix.dart"
++ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/map_patch.dart"
++ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/null_patch.dart"
++ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/object_patch.dart"
++ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/regexp_patch.dart"
++ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/stacktrace.dart"
++ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/stopwatch_patch.dart"
++ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/string_buffer_patch.dart"
++ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/string_patch.dart"
++ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/type_patch.dart"
++ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/uri_patch.dart"
++ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/weak_property.dart"
+
+ developer:
+ uri: "../../../../../../third_party/dart/sdk/lib/developer/developer.dart"
+ patches:
+- - "../../../../../../third_party/dart/runtime/lib/developer.dart"
+- - "../../../../../../third_party/dart/runtime/lib/profiler.dart"
+- - "../../../../../../third_party/dart/runtime/lib/timeline.dart"
++ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/developer.dart"
++ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/profiler.dart"
++ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/timeline.dart"
+
+ ffi:
+ uri: "../../../../../../third_party/dart/sdk/lib/ffi/ffi.dart"
+ patches:
+- - "../../../../../../third_party/dart/runtime/lib/ffi_dynamic_library_patch.dart"
+- - "../../../../../../third_party/dart/runtime/lib/ffi_native_type_patch.dart"
+- - "../../../../../../third_party/dart/runtime/lib/ffi_patch.dart"
++ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/ffi_dynamic_library_patch.dart"
++ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/ffi_native_type_patch.dart"
++ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/ffi_patch.dart"
+
+ wasm:
+ uri: "../../../../../../third_party/dart/sdk/lib/wasm/wasm.dart"
+ patches:
+- - "../../../../../../third_party/dart/runtime/lib/wasm_patch.dart"
++ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/wasm_patch.dart"
+
+ _http:
+ uri: "../../../../../../third_party/dart/sdk/lib/_http/http.dart"
+@@ -102,37 +102,37 @@ flutter_runner:
+ io:
+ uri: "../../../../../../third_party/dart/sdk/lib/io/io.dart"
+ patches:
+- - "../../../../../../third_party/dart/runtime/bin/common_patch.dart"
+- - "../../../../../../third_party/dart/runtime/bin/directory_patch.dart"
+- - "../../../../../../third_party/dart/runtime/bin/eventhandler_patch.dart"
+- - "../../../../../../third_party/dart/runtime/bin/file_patch.dart"
+- - "../../../../../../third_party/dart/runtime/bin/file_system_entity_patch.dart"
+- - "../../../../../../third_party/dart/runtime/bin/filter_patch.dart"
+- - "../../../../../../third_party/dart/runtime/bin/io_service_patch.dart"
+- - "../../../../../../third_party/dart/runtime/bin/namespace_patch.dart"
+- - "../../../../../../third_party/dart/runtime/bin/platform_patch.dart"
+- - "../../../../../../third_party/dart/runtime/bin/process_patch.dart"
+- - "../../../../../../third_party/dart/runtime/bin/socket_patch.dart"
+- - "../../../../../../third_party/dart/runtime/bin/stdio_patch.dart"
+- - "../../../../../../third_party/dart/runtime/bin/secure_socket_patch.dart"
+- - "../../../../../../third_party/dart/runtime/bin/sync_socket_patch.dart"
++ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/bin/common_patch.dart"
++ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/bin/directory_patch.dart"
++ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/bin/eventhandler_patch.dart"
++ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/bin/file_patch.dart"
++ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/bin/file_system_entity_patch.dart"
++ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/bin/filter_patch.dart"
++ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/bin/io_service_patch.dart"
++ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/bin/namespace_patch.dart"
++ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/bin/platform_patch.dart"
++ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/bin/process_patch.dart"
++ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/bin/socket_patch.dart"
++ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/bin/stdio_patch.dart"
++ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/bin/secure_socket_patch.dart"
++ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/bin/sync_socket_patch.dart"
+
+ isolate:
+ uri: "../../../../../../third_party/dart/sdk/lib/isolate/isolate.dart"
+ patches:
+- - "../../../../../../third_party/dart/runtime/lib/isolate_patch.dart"
+- - "../../../../../../third_party/dart/runtime/lib/timer_impl.dart"
++ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/isolate_patch.dart"
++ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/timer_impl.dart"
+
+ math:
+ uri: "../../../../../../third_party/dart/sdk/lib/math/math.dart"
+- patches: "../../../../../../third_party/dart/runtime/lib/math_patch.dart"
++ patches: "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/math_patch.dart"
+
+ mirrors:
+ uri: "../../../../../../third_party/dart/sdk/lib/mirrors/mirrors.dart"
+ patches:
+- - "../../../../../../third_party/dart/runtime/lib/mirrors_patch.dart"
+- - "../../../../../../third_party/dart/runtime/lib/mirrors_impl.dart"
+- - "../../../../../../third_party/dart/runtime/lib/mirror_reference.dart"
++ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/mirrors_patch.dart"
++ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/mirrors_impl.dart"
++ - "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/mirror_reference.dart"
+
+ nativewrappers:
+ uri: "../../../../../../third_party/dart/sdk/lib/html/dartium/nativewrappers.dart"
+@@ -142,7 +142,7 @@ flutter_runner:
+
+ typed_data:
+ uri: "../../../../../../third_party/dart/sdk/lib/typed_data/typed_data.dart"
+- patches: "../../../../../../third_party/dart/runtime/lib/typed_data_patch.dart"
++ patches: "../../../../../../third_party/dart/sdk/lib/_internal/vm/lib/typed_data_patch.dart"
+
+ fuchsia.builtin:
+ uri: "../../../../../../flutter/shell/platform/fuchsia/dart_runner/embedder/builtin.dart"
+@@ -160,4 +160,4 @@ flutter_runner:
+ uri: "../../../../../../third_party/dart/sdk/lib/vmservice/vmservice.dart"
+
+ vmservice_io:
+- uri: "../../../../../../third_party/dart/runtime/bin/vmservice/vmservice_io.dart"
++ uri: "../../../../../../third_party/dart/sdk/lib/_internal/vm/bin/vmservice/vmservice_io.dart"
diff --git a/tools/run_abi_tests.py b/tools/run_abi_tests.py
index 4f4f049..e32f008 100644
--- a/tools/run_abi_tests.py
+++ b/tools/run_abi_tests.py
@@ -140,7 +140,7 @@
def diffResults(results):
outResult = pickOne(results)
exp = results[None]['result'] if None in results else None
- outResult['configuration'] = 'vm-dartkb-linux-release-x64-abi'
+ outResult['configuration'] = 'dartkb-abi-linux-release-x64'
outResult['expected'] = exp
outResult['result'] = exp
outResult['matches'] = True
@@ -163,7 +163,7 @@
logs = ["%s: %s" % (str(v), l['log']) for v, l in logRecords.items()]
return {
'name': result['name'],
- 'configuration': 'vm-dartkb-linux-release-x64-abi',
+ 'configuration': 'dartkb-abi-linux-release-x64',
'result': result['result'],
'log': '\n\n\n'.join([repr(diffs)] + logs),
}
diff --git a/utils/application_snapshot.gni b/utils/application_snapshot.gni
index 2c257a2..4356f1c 100644
--- a/utils/application_snapshot.gni
+++ b/utils/application_snapshot.gni
@@ -74,11 +74,62 @@
if (defined(invoker.output)) {
output = invoker.output
}
+
+ # Build the kernel file using the prebuilt VM to speed up the debug and
+ # simulator builds.
+ prebuilt_dart_action(target_name + "_dill") {
+ deps =
+ extra_deps + [
+ "$_dart_root/runtime/vm:kernel_platform_files($dart_host_toolchain)",
+ "$_dart_root/runtime/vm:vm_platform",
+ ]
+ gen_kernel_script = "$_dart_root/pkg/vm/bin/gen_kernel.dart"
+ platform_dill = "$root_out_dir/vm_platform_strong.dill"
+
+ inputs = extra_inputs + [
+ gen_kernel_script,
+ platform_dill,
+ main_dart,
+ dot_packages,
+ ]
+ output = "$target_gen_dir/$name.dart.dill"
+ outputs = [
+ output,
+ ]
+
+ depfile = "$output.d"
+ abs_depfile = rebase_path(depfile)
+ rebased_output = rebase_path(output, root_build_dir)
+ vm_args = [
+ "--depfile=$abs_depfile",
+ "--depfile_output_filename=$rebased_output",
+ ]
+
+ script = gen_kernel_script
+
+ args = [
+ "--packages=" + rebase_path(dot_packages),
+ "--platform=" + rebase_path(platform_dill),
+ "--no-aot",
+ "--no-embed-sources",
+ "--no-link-platform",
+ "--output=" + rebase_path(output),
+ ]
+ if (dart_platform_bytecode) {
+ args += [
+ "--gen-bytecode",
+ "--drop-ast",
+ "--bytecode-options=source-positions",
+ ]
+ }
+ args += [ rebase_path(main_dart) ]
+ }
+
dart_action(target_name) {
- deps = extra_deps
+ deps = extra_deps + [ ":${target_name}_dill" ]
depfile = "$output.d"
- script = main_dart
+ script = "$target_gen_dir/$name.dart.dill"
inputs = extra_inputs
@@ -90,16 +141,14 @@
abs_output = rebase_path(output, root_build_dir)
vm_args = [
- "--deterministic",
- "--packages=$dot_packages",
- "--snapshot=$abs_output",
- "--snapshot-depfile=$abs_depfile",
- ] + snapshot_vm_args
+ "--deterministic",
+ "--packages=$dot_packages",
+ "--snapshot=$abs_output",
+ "--snapshot-depfile=$abs_depfile",
+ ] + snapshot_vm_args
if (dart_snapshot_kind == "kernel") {
- vm_args += [
- "--snapshot-kind=kernel",
- ]
+ vm_args += [ "--snapshot-kind=kernel" ]
assert(training_args != "", "Ignoring unused argument")
args = []
} else if (dart_snapshot_kind == "app-jit") {
@@ -141,9 +190,7 @@
if (!defined(invoker.deps)) {
deps = []
}
- deps += [
- "$_dart_root/utils/kernel-service:kernel-service"
- ]
+ deps += [ "$_dart_root/utils/kernel-service:kernel-service" ]
}
}
diff --git a/utils/bazel/kernel_worker.dart b/utils/bazel/kernel_worker.dart
index d18212b..8662ed1 100644
--- a/utils/bazel/kernel_worker.dart
+++ b/utils/bazel/kernel_worker.dart
@@ -18,7 +18,7 @@
import 'package:build_integration/file_system/multi_root.dart';
import 'package:dev_compiler/src/kernel/target.dart';
import 'package:front_end/src/api_unstable/bazel_worker.dart' as fe;
-import 'package:kernel/ast.dart' show Component, Library;
+import 'package:kernel/ast.dart' show Component, Library, Reference;
import 'package:kernel/target/targets.dart';
import 'package:vm/target/vm.dart';
import 'package:vm/target/flutter.dart';
@@ -337,10 +337,13 @@
incrementalComponent.problemsAsJson = null;
incrementalComponent.mainMethod = null;
target.performOutlineTransformations(incrementalComponent);
+ makeStable(incrementalComponent);
return Future.value(fe.serializeComponent(incrementalComponent,
includeSources: false, includeOffsets: false));
}
+ makeStable(incrementalComponent);
+
return Future.value(fe.serializeComponent(incrementalComponent,
filter: excludeNonSources
? (library) => sources.contains(library.importUri)
@@ -381,6 +384,22 @@
return new ComputeKernelResult(succeeded, state);
}
+/// Make sure the output is stable by sorting libraries and additional exports.
+void makeStable(Component c) {
+ // Make sure the output is stable.
+ c.libraries.sort((l1, l2) {
+ return "${l1.fileUri}".compareTo("${l2.fileUri}");
+ });
+ c.problemsAsJson?.sort();
+ c.computeCanonicalNames();
+ for (Library library in c.libraries) {
+ library.additionalExports.sort((Reference r1, Reference r2) {
+ return "${r1.canonicalName}".compareTo("${r2.canonicalName}");
+ });
+ library.problemsAsJson?.sort();
+ }
+}
+
/// Extends the DevCompilerTarget to transform outlines to meet the requirements
/// of summaries in bazel and package-build.
///
diff --git a/utils/compiler/BUILD.gn b/utils/compiler/BUILD.gn
index 07e8087..27dfc69 100644
--- a/utils/compiler/BUILD.gn
+++ b/utils/compiler/BUILD.gn
@@ -3,8 +3,8 @@
# BSD-style license that can be found in the LICENSE file.
import("../../utils/compile_platform.gni")
-import("../create_timestamp.gni")
import("../application_snapshot.gni")
+import("../create_timestamp.gni")
create_timestamp_file("dart2js_files_stamp") {
path = rebase_path("../../pkg/compiler/lib")
@@ -21,18 +21,13 @@
output = "$target_gen_dir/dartdoc_files.stamp"
}
-dart_action("dart2js_create_snapshot_entry") {
+prebuilt_dart_action("dart2js_create_snapshot_entry") {
deps = [
":dart2js_files_stamp",
":dartdoc_files_stamp",
":runtime_lib_files_stamp",
]
- # dart_action() needs kernel service snapshot to run in Dart 2 mode.
- # This can't be added as a dependency to dart_action() itself as it will
- # create a circular dependency.
- deps += [ "../../utils/kernel-service:kernel-service" ]
-
output_dir = rebase_path(target_gen_dir)
script = "create_snapshot_entry.dart"
diff --git a/utils/dartdevc/BUILD.gn b/utils/dartdevc/BUILD.gn
index b7b63ce..2048ad4 100644
--- a/utils/dartdevc/BUILD.gn
+++ b/utils/dartdevc/BUILD.gn
@@ -30,7 +30,9 @@
":dartdevc_kernel_sdk_outline",
]
- inputs = [ sdk_dill ]
+ inputs = [
+ sdk_dill,
+ ]
}
sdk_lib_files = exec_script("../../tools/list_dart_files.py",
@@ -62,16 +64,11 @@
abs_main = rebase_path(main)
abs_output = rebase_path(out)
- dart_action(target_name) {
+ prebuilt_dart_action(target_name) {
deps = [
"../compiler:compile_dart2js_platform",
]
- # dart_action() needs kernel service snapshot to run in Dart 2 mode.
- # This can't be added as a dependency to dart_action() itself as it will
- # create a circular dependency.
- deps += [ "../../utils/kernel-service:kernel-service" ]
-
inputs = sdk_lib_files + compiler_files + dev_compiler_files + [
"$root_out_dir/dart2js_platform.dill",
"$root_out_dir/dart2js_outline.dill",
@@ -89,6 +86,7 @@
"-m",
"-o$abs_output",
"--no-source-maps",
+ "--platform-binaries=" + rebase_path("$root_out_dir"),
]
}
}
@@ -211,8 +209,8 @@
group("dartdevc_test") {
deps = [
":dartdevc",
- ":dartdevc_sdk",
":dartdevc_kernel_sdk",
+ ":dartdevc_sdk",
":dartdevc_test_pkg",
"../../sdk:create_sdk",
]
@@ -223,8 +221,8 @@
# building the Dart VM and create_sdk.
group("dartdevc_test_local") {
deps = [
- ":dartdevc_sdk",
":dartdevc_kernel_sdk",
+ ":dartdevc_sdk",
":dartdevc_test_pkg",
]
}
@@ -244,10 +242,10 @@
prebuilt_dart_action("dartdevc_test_pkg") {
deps = [
":dartdevc_files_stamp",
- ":dartdevc_sdk",
":dartdevc_kernel_sdk",
- ":dartdevc_kernel_sdk_outline",
":dartdevc_kernel_sdk_libraries_json",
+ ":dartdevc_kernel_sdk_outline",
+ ":dartdevc_sdk",
"../../pkg:pkg_files_stamp",
]
@@ -319,9 +317,9 @@
prebuilt_dart_action("dartdevc_kernel_sdk_outline") {
deps = [
- "../../pkg:pkg_files_stamp",
":dartdevc_files_stamp",
":dartdevc_sdk_patch_stamp",
+ "../../pkg:pkg_files_stamp",
]
inputs = [
@@ -349,7 +347,7 @@
"--output",
rebase_path(sdk_dill),
"--source",
- "dart:core"
+ "dart:core",
]
}
@@ -365,9 +363,9 @@
# Compiles the DDC SDK's kernel summary and JS code.
prebuilt_dart_action("dartdevc_kernel_sdk") {
deps = [
- "../../pkg:pkg_files_stamp",
":dartdevc_files_stamp",
":dartdevc_sdk_patch_stamp",
+ "../../pkg:pkg_files_stamp",
]
inputs = [
diff --git a/utils/kernel-service/BUILD.gn b/utils/kernel-service/BUILD.gn
index 9f926e3..9ed386a 100644
--- a/utils/kernel-service/BUILD.gn
+++ b/utils/kernel-service/BUILD.gn
@@ -10,7 +10,6 @@
group("kernel-service") {
if (create_kernel_service_snapshot) {
deps = [
- # TODO(rmacnak): Link this into 'dart'.
":copy_kernel-service_snapshot",
]
} else {
@@ -20,16 +19,15 @@
}
}
-# TODO: Switch this to use kernel based app-jit snapshot
-# when we are ready to switch to the kernel based core snapshots.
kernel_application_snapshot("kernel-service_snapshot") {
- main_dart = "$root_gen_dir/kernel_service.dill"
- deps = [
- ":kernel_service_dill",
- ]
+ main_dart = "../../pkg/vm/bin/kernel_service.dart"
training_args = [
"--train",
- "file:///" + rebase_path("../../pkg/compiler/lib/src/dart2js.dart"),
+
+ # Force triple-slashes both on Windows and otherwise.
+ # Becomes e.g. file:///full/path/to/file and "file:///C:/full/path/to/file.
+ # Without the ', "/"' part, on Linux it would get four slashes.
+ "file:///" + rebase_path("../../pkg/compiler/lib/src/dart2js.dart", "/"),
]
if (dart_platform_bytecode) {
training_args += [ "--bytecode" ]
@@ -59,6 +57,7 @@
"--train",
"--sdk-root=$sdk_root/",
"--platform=$sdk_root/vm_platform_strong.dill",
+ rebase_path(main_dart),
]
output = "$root_out_dir/frontend_server.dart.snapshot"
}
@@ -91,16 +90,26 @@
]
script = gen_kernel_script
+ scheme = "org-dartlang-kernel-service"
args =
invoker.extra_args + [
- "--packages=" + rebase_path("../../.packages"),
+ "--packages=" + scheme + ":///.packages",
"--platform=" + rebase_path("$root_out_dir/vm_platform_strong.dill"),
+ "--filesystem-root=" + rebase_path("../../"),
+ "--filesystem-scheme=" + scheme,
"--no-aot",
"--no-embed-sources",
"--output=" + rebase_path(output),
- rebase_path(kernel_service_script),
+ scheme + ":///pkg/vm/bin/kernel_service.dart",
]
+
+ if (dart_platform_bytecode) {
+ args += [
+ "--gen-bytecode",
+ "--drop-ast",
+ ]
+ }
}
}